History

Merge remote-tracking branch 'drm-misc/drm-misc-next' into msm-next

Backmerge drm-misc-next to pick up some dependencies for drm/msm patches, in particular: https://patchwork.freedesktop.org/patch/570219/?series=127251&rev=1 https://patchwork.freedesktop.org/series/123411/

Rob Clark committed 2 years ago

Commit cbaf84e2 parents a08935f fca94481031 files · +58078 −24245Browse files

Unified · Split

1031 files
  1. Documentation/accel/qaic/aic100.rst +8 −3
  2. Documentation/accel/qaic/qaic.rst +36 −1
  3. Documentation/arch/loongarch/introduction.rst +2 −2
  4. Documentation/arch/x86/boot.rst +1 −1
  5. Documentation/core-api/pin_user_pages.rst +2 −0
  6. Documentation/devicetree/bindings/display/bridge/lontium,lt8912b.yaml +21 −0
  7. Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml +3 −0
  8. Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml +1 −0
  9. Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml +1 −1
  10. Documentation/devicetree/bindings/display/panel/panel-simple.yaml +4 −0
  11. Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml +14 −0
  12. Documentation/devicetree/bindings/gpu/arm,mali-utgard.yaml +1 −0
  13. Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml +1 −0
  14. Documentation/devicetree/bindings/gpu/img,powervr.yaml +73 −0
  15. Documentation/devicetree/bindings/net/ethernet-controller.yaml +2 −2
  16. Documentation/devicetree/bindings/ufs/qcom,ufs.yaml +2 −0
  17. Documentation/devicetree/bindings/usb/microchip,usb5744.yaml +6 −1
  18. Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +2 −2
  19. Documentation/devicetree/bindings/usb/usb-hcd.yaml +1 −1
  20. Documentation/filesystems/erofs.rst +4 −0
  21. Documentation/gpu/drivers.rst +2 −0
  22. Documentation/gpu/drm-kms-helpers.rst +6 −0
  23. Documentation/gpu/drm-kms.rst +8 −0
  24. Documentation/gpu/drm-mm.rst +10 −0
  25. Documentation/gpu/drm-vm-bind-locking.rst +582 −0
  26. Documentation/gpu/imagination/index.rst +13 −0
  27. Documentation/gpu/imagination/uapi.rst +171 −0
  28. Documentation/gpu/implementation_guidelines.rst +1 −0
  29. Documentation/gpu/rfc/xe.rst +67 −65
  30. Documentation/gpu/todo.rst +43 −4
  31. Documentation/process/maintainer-netdev.rst +17 −3
  32. Documentation/translations/zh_CN/arch/loongarch/introduction.rst +2 −2
  33. MAINTAINERS +48 −16
  34. Makefile +1 −1
  35. arch/arm/xen/enlighten.c +2 −1
  36. arch/arm64/Makefile +1 −1
  37. arch/arm64/include/asm/setup.h +15 −2
  38. arch/arm64/mm/pageattr.c +3 −4
  39. arch/loongarch/Makefile +3 −0
  40. arch/loongarch/include/asm/asmmacro.h +1 −2
  41. arch/loongarch/include/asm/percpu.h +5 −6
  42. arch/loongarch/include/asm/setup.h +1 −1
  43. arch/loongarch/kernel/relocate.c +9 −1
  44. arch/loongarch/kernel/time.c +9 −14
  45. arch/loongarch/mm/pgtable.c +2 −2
  46. arch/parisc/Kconfig +8 −5
  47. arch/parisc/include/asm/alternative.h +6 −3
  48. arch/parisc/include/asm/assembly.h +1 −0
  49. arch/parisc/include/asm/bug.h +22 −16
  50. arch/parisc/include/asm/elf.h +1 −9
  51. arch/parisc/include/asm/jump_label.h +6 −2
  52. arch/parisc/include/asm/ldcw.h +1 −1
  53. arch/parisc/include/asm/processor.h +2 −0
  54. arch/parisc/include/asm/uaccess.h +1 −0
  55. arch/parisc/include/uapi/asm/errno.h +0 −2
  56. arch/parisc/kernel/processor.c +1 −1
  57. arch/parisc/kernel/sys_parisc.c +1 −1
  58. arch/parisc/kernel/vmlinux.lds.S +1 −0
  59. arch/s390/include/asm/processor.h +0 −1
  60. arch/s390/kernel/ipl.c +1 −0
  61. arch/s390/kernel/perf_pai_crypto.c +5 −6
  62. arch/s390/kernel/perf_pai_ext.c +0 −1
  63. arch/x86/events/intel/core.c +1 −1
  64. arch/x86/hyperv/hv_init.c +21 −4
  65. arch/x86/include/asm/acpi.h +14 −0
  66. arch/x86/include/asm/xen/hypervisor.h +9 −0
  67. arch/x86/kernel/acpi/boot.c +15 −19
  68. arch/x86/kernel/cpu/microcode/amd.c +11 −28
  69. arch/x86/kernel/cpu/microcode/core.c +9 −6
  70. arch/x86/kernel/cpu/microcode/intel.c +7 −10
  71. arch/x86/kernel/cpu/microcode/internal.h +10 −4
  72. arch/x86/kernel/cpu/mshyperv.c +4 −1
  73. arch/x86/kernel/signal_64.c +3 −3
  74. block/bdev.c +2 −0
  75. block/blk-cgroup.c +13 −0
  76. block/blk-cgroup.h +0 −2
  77. block/blk-mq.c +38 −37
  78. block/blk-pm.c +5 −28
  79. block/blk-throttle.c +2 −0
  80. drivers/accel/drm_accel.c +1 −0
  81. drivers/accel/ivpu/Kconfig +6 −5
  82. drivers/accel/ivpu/ivpu_debugfs.c +57 −0
  83. drivers/accel/ivpu/ivpu_drv.c +27 −22
  84. drivers/accel/ivpu/ivpu_drv.h +13 −5
  85. drivers/accel/ivpu/ivpu_fw.c +74 −5
  86. drivers/accel/ivpu/ivpu_fw.h +1 −0
  87. drivers/accel/ivpu/ivpu_gem.c +199 −479
  88. drivers/accel/ivpu/ivpu_gem.h +16 −59
  89. drivers/accel/ivpu/ivpu_hw.h +20 −0
  90. drivers/accel/ivpu/ivpu_hw_37xx.c +69 −36
  91. drivers/accel/ivpu/ivpu_hw_37xx_reg.h +2 −0
  92. drivers/accel/ivpu/ivpu_hw_40xx.c +48 −21
  93. drivers/accel/ivpu/ivpu_ipc.c +157 −94
  94. drivers/accel/ivpu/ivpu_ipc.h +25 −8
  95. drivers/accel/ivpu/ivpu_job.c +31 −68
  96. drivers/accel/ivpu/ivpu_job.h +2 −2
  97. drivers/accel/ivpu/ivpu_jsm_msg.c +38 −0
  98. drivers/accel/ivpu/ivpu_jsm_msg.h +1 −0
  99. drivers/accel/ivpu/ivpu_mmu.c +36 −8
  100. drivers/accel/ivpu/ivpu_mmu_context.c +86 −67
  101. drivers/accel/ivpu/ivpu_mmu_context.h +4 −7
  102. drivers/accel/ivpu/ivpu_pm.c +58 −17
  103. drivers/accel/ivpu/ivpu_pm.h +3 −0
  104. drivers/accel/ivpu/vpu_boot_api.h +81 −9
  105. drivers/accel/ivpu/vpu_jsm_api.h +294 −15
  106. drivers/accel/qaic/Makefile +2 −1
  107. drivers/accel/qaic/mhi_controller.c +40 −4
  108. drivers/accel/qaic/mhi_controller.h +1 −1
  109. drivers/accel/qaic/qaic.h +18 −3
  110. drivers/accel/qaic/qaic_control.c +4 −3
  111. drivers/accel/qaic/qaic_data.c +70 −77
  112. drivers/accel/qaic/qaic_drv.c +57 −41
  113. drivers/accel/qaic/qaic_timesync.c +395 −0
  114. drivers/accel/qaic/qaic_timesync.h +11 −0
  115. drivers/acpi/acpi_video.c +1 −1
  116. drivers/acpi/device_pm.c +13 −0
  117. drivers/acpi/processor_idle.c +1 −1
  118. drivers/acpi/resource.c +7 −0
  119. drivers/ata/pata_isapnp.c +3 −0
  120. drivers/auxdisplay/Kconfig +2 −8
  121. drivers/auxdisplay/cfag12864bfb.c +5 −5
  122. drivers/auxdisplay/ht16k33.c +5 −5
  123. drivers/block/nbd.c +75 −42
  124. drivers/block/null_blk/main.c +13 −12
  125. drivers/char/agp/Makefile +0 −6
  126. drivers/char/agp/agp.h +0 −9
  127. drivers/char/agp/backend.c +0 −11
  128. drivers/char/agp/compat_ioctl.c +0 −291
  129. drivers/char/agp/compat_ioctl.h +0 −106
  130. drivers/char/agp/frontend.c +0 −1068
  131. drivers/dma-buf/dma-buf.c +2 −2
  132. drivers/dma-buf/dma-fence.c +2 −1
  133. drivers/dma-buf/sw_sync.c +82 −0
  134. drivers/dma-buf/sync_debug.h +2 −0
  135. drivers/dma-buf/sync_file.c +19 −0
  136. drivers/dpll/dpll_netlink.c +12 −5
  137. drivers/firmware/Kconfig +1 −1
  138. drivers/firmware/qemu_fw_cfg.c +1 −1
  139. drivers/gpu/drm/Kconfig +9 −27
  140. drivers/gpu/drm/Makefile +2 −12
  141. drivers/gpu/drm/amd/amdgpu/amdgpu.h +1 −0
  142. drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +1 −1
  143. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +1 −1
  144. drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +2 −2
  145. drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +8 −7
  146. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +7 −7
  147. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +10 −0
  148. drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +2 −2
  149. drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +5 −0
  150. drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +1 −0
  151. drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +1 −1
  152. drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +1 −0
  153. drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +1 −0
  154. drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +1 −1
  155. drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +3 −2
  156. drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +4 −3
  157. drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +3 −3
  158. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +19 −14
  159. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +3 −5
  160. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +18 −18
  161. drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +9 −9
  162. drivers/gpu/drm/amd/display/dc/core/dc.c +3 −3
  163. drivers/gpu/drm/amd/display/dc/core/dc_resource.c +3 −0
  164. drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +5 −5
  165. drivers/gpu/drm/amd/display/dc/dc_types.h +1 −0
  166. drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_stream_encoder.c +4 −6
  167. drivers/gpu/drm/amd/display/dc/link/link_detection.c +3 −0
  168. drivers/gpu/drm/amd/display/dmub/dmub_srv.h +14 −8
  169. drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +39 −11
  170. drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h +9 −1
  171. drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +9 −1
  172. drivers/gpu/drm/armada/armada_crtc.c +9 −20
  173. drivers/gpu/drm/armada/armada_drv.c +2 −3
  174. drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +4 −6
  175. drivers/gpu/drm/ast/ast_drv.c +255 −8
  176. drivers/gpu/drm/ast/ast_drv.h +86 −28
  177. drivers/gpu/drm/ast/ast_main.c +14 −230
  178. drivers/gpu/drm/ast/ast_mode.c +70 −18
  179. drivers/gpu/drm/ast/ast_post.c +45 −28
  180. drivers/gpu/drm/ast/ast_reg.h +10 −2
  181. drivers/gpu/drm/bridge/Kconfig +17 −0
  182. drivers/gpu/drm/bridge/Makefile +2 −0
  183. drivers/gpu/drm/bridge/analogix/anx7625.c +36 −18
  184. drivers/gpu/drm/bridge/analogix/anx7625.h +4 −0
  185. drivers/gpu/drm/bridge/aux-bridge.c +140 −0
  186. drivers/gpu/drm/bridge/aux-hpd-bridge.c +163 −0
  187. drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +10 −12
  188. drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +2 −1
  189. drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c +2 −2
  190. drivers/gpu/drm/bridge/lontium-lt8912b.c +58 −0
  191. drivers/gpu/drm/bridge/nxp-ptn3460.c +3 −3
  192. drivers/gpu/drm/bridge/tc358767.c +1 −1
  193. drivers/gpu/drm/bridge/ti-sn65dsi86.c +2 −4
  194. drivers/gpu/drm/bridge/ti-tpd12s015.c +2 −4
  195. drivers/gpu/drm/ci/xfails/requirements.txt +3 −3
  196. drivers/gpu/drm/display/drm_dp_helper.c +161 −0
  197. drivers/gpu/drm/display/drm_dp_mst_topology.c +181 −53
  198. drivers/gpu/drm/drm_agpsupport.c +0 −451
  199. drivers/gpu/drm/drm_atomic.c +9 −0
  200. drivers/gpu/drm/drm_atomic_helper.c +11 −9
  201. drivers/gpu/drm/drm_atomic_state_helper.c +14 −0
  202. drivers/gpu/drm/drm_atomic_uapi.c +91 −6
  203. drivers/gpu/drm/drm_auth.c +1 −7
  204. drivers/gpu/drm/drm_bridge.c +0 −44
  205. drivers/gpu/drm/drm_bridge_connector.c +0 −6
  206. drivers/gpu/drm/drm_bufs.c +0 −1627
  207. drivers/gpu/drm/drm_client.c +1 −11
  208. drivers/gpu/drm/drm_connector.c +6 −0
  209. drivers/gpu/drm/drm_context.c +0 −513
  210. drivers/gpu/drm/drm_crtc_helper.c +2 −5
  211. drivers/gpu/drm/drm_crtc_internal.h +3 −1
  212. drivers/gpu/drm/drm_damage_helper.c +2 −1
  213. drivers/gpu/drm/drm_debugfs.c +62 −3
  214. drivers/gpu/drm/drm_dma.c +0 −178
  215. drivers/gpu/drm/drm_drv.c +8 −19
  216. drivers/gpu/drm/drm_edid.c +31 −12
  217. drivers/gpu/drm/drm_edid_load.c +0 −16
  218. drivers/gpu/drm/drm_eld.c +55 −0
  219. drivers/gpu/drm/drm_encoder.c +4 −0
  220. drivers/gpu/drm/drm_file.c +4 −64
  221. drivers/gpu/drm/drm_flip_work.c +7 −20
  222. drivers/gpu/drm/drm_format_helper.c +162 −53
  223. drivers/gpu/drm/drm_framebuffer.c +54 −23
  224. drivers/gpu/drm/drm_gem_atomic_helper.c +9 −0
  225. drivers/gpu/drm/drm_gpuvm.c +1097 −71
  226. drivers/gpu/drm/drm_hashtab.c +0 −203
  227. drivers/gpu/drm/drm_internal.h +16 −7
  228. drivers/gpu/drm/drm_ioc32.c +2 −611
  229. drivers/gpu/drm/drm_ioctl.c +21 −75
  230. drivers/gpu/drm/drm_irq.c +0 −204
  231. drivers/gpu/drm/drm_kms_helper_common.c +0 −32
  232. drivers/gpu/drm/drm_legacy.h +0 −290
  233. drivers/gpu/drm/drm_legacy_misc.c +0 −105
  234. drivers/gpu/drm/drm_lock.c +0 −373
  235. drivers/gpu/drm/drm_memory.c +0 −138
  236. drivers/gpu/drm/drm_mipi_dbi.c +12 −7
  237. drivers/gpu/drm/drm_mipi_dsi.c +15 −2
  238. drivers/gpu/drm/drm_mode_object.c +1 −1
  239. drivers/gpu/drm/drm_panel_orientation_quirks.c +6 −0
  240. drivers/gpu/drm/drm_pci.c +1 −203
  241. drivers/gpu/drm/drm_plane.c +148 −2
  242. drivers/gpu/drm/drm_plane_helper.c +0 −32
  243. drivers/gpu/drm/drm_scatter.c +0 −220
  244. drivers/gpu/drm/drm_syncobj.c +51 −13
  245. drivers/gpu/drm/drm_vblank.c +0 −101
  246. drivers/gpu/drm/drm_vm.c +0 −665
  247. drivers/gpu/drm/etnaviv/etnaviv_drv.c +2 −4
  248. drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +1 −1
  249. drivers/gpu/drm/etnaviv/etnaviv_gpu.c +3 −4
  250. drivers/gpu/drm/etnaviv/etnaviv_sched.c +1 −1
  251. drivers/gpu/drm/exynos/exynos_drm_gsc.c +5 −4
  252. drivers/gpu/drm/gud/gud_pipe.c +18 −12
  253. drivers/gpu/drm/i915/Kconfig +1 −1
  254. drivers/gpu/drm/i915/Makefile +97 −83
  255. drivers/gpu/drm/i915/display/g4x_dp.c +39 −7
  256. drivers/gpu/drm/i915/display/g4x_hdmi.c +37 −29
  257. drivers/gpu/drm/i915/display/hsw_ips.c +2 −2
  258. drivers/gpu/drm/i915/display/i9xx_wm.c +1 −1
  259. drivers/gpu/drm/i915/display/icl_dsi.c +5 −5
  260. drivers/gpu/drm/i915/display/intel_atomic.c +0 −3
  261. drivers/gpu/drm/i915/display/intel_atomic_plane.c +47 −36
  262. drivers/gpu/drm/i915/display/intel_audio.c +9 −8
  263. drivers/gpu/drm/i915/display/intel_backlight.c +5 −4
  264. drivers/gpu/drm/i915/display/intel_bios.c +27 −5
  265. drivers/gpu/drm/i915/display/intel_cdclk.c +3 −2
  266. drivers/gpu/drm/i915/display/intel_color.c +35 −35
  267. drivers/gpu/drm/i915/display/intel_crt.c +2 −2
  268. drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +1 −0
  269. drivers/gpu/drm/i915/display/intel_cx0_phy.c +125 −35
  270. drivers/gpu/drm/i915/display/intel_cx0_phy.h +8 −8
  271. drivers/gpu/drm/i915/display/intel_ddi.c +134 −43
  272. drivers/gpu/drm/i915/display/intel_ddi.h +5 −0
  273. drivers/gpu/drm/i915/display/intel_display.c +219 −341
  274. drivers/gpu/drm/i915/display/intel_display.h +3 −6
  275. drivers/gpu/drm/i915/display/intel_display_core.h +11 −9
  276. drivers/gpu/drm/i915/display/intel_display_debugfs.c +98 −0
  277. drivers/gpu/drm/i915/display/intel_display_debugfs_params.c +176 −0
  278. drivers/gpu/drm/i915/display/intel_display_debugfs_params.h +13 −0
  279. drivers/gpu/drm/i915/display/intel_display_device.c +11 −2
  280. drivers/gpu/drm/i915/display/intel_display_device.h +1 −0
  281. drivers/gpu/drm/i915/display/intel_display_driver.c +7 −0
  282. drivers/gpu/drm/i915/display/intel_display_params.c +217 −0
  283. drivers/gpu/drm/i915/display/intel_display_params.h +61 −0
  284. drivers/gpu/drm/i915/display/intel_display_power.c +7 −7
  285. drivers/gpu/drm/i915/display/intel_display_power_well.c +9 −14
  286. drivers/gpu/drm/i915/display/intel_display_reset.c +1 −1
  287. drivers/gpu/drm/i915/display/intel_display_types.h +17 −14
  288. drivers/gpu/drm/i915/display/intel_dp.c +392 −110
  289. drivers/gpu/drm/i915/display/intel_dp.h +23 −3
  290. drivers/gpu/drm/i915/display/intel_dp_aux.c +62 −37
  291. drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +2 −2
  292. drivers/gpu/drm/i915/display/intel_dp_aux_regs.h +8 −6
  293. drivers/gpu/drm/i915/display/intel_dp_mst.c +557 −105
  294. drivers/gpu/drm/i915/display/intel_dp_mst.h +5 −0
  295. drivers/gpu/drm/i915/display/intel_dpio_phy.c +94 −77
  296. drivers/gpu/drm/i915/display/intel_dpio_phy.h +5 −0
  297. drivers/gpu/drm/i915/display/intel_dpll.c +220 −50
  298. drivers/gpu/drm/i915/display/intel_dpll.h +7 −2
  299. drivers/gpu/drm/i915/display/intel_dpll_mgr.c +95 −92
  300. drivers/gpu/drm/i915/display/intel_dpll_mgr.h +6 −0
  301. drivers/gpu/drm/i915/display/intel_dpt.c +0 −24
  302. drivers/gpu/drm/i915/display/intel_dpt.h +0 −2
  303. drivers/gpu/drm/i915/display/intel_dpt_common.c +34 −0
  304. drivers/gpu/drm/i915/display/intel_dpt_common.h +13 −0
  305. drivers/gpu/drm/i915/display/intel_dsb.c +36 −62
  306. drivers/gpu/drm/i915/display/intel_dsb_buffer.c +82 −0
  307. drivers/gpu/drm/i915/display/intel_dsb_buffer.h +29 −0
  308. drivers/gpu/drm/i915/display/intel_dsi_vbt.c +135 −218
  309. drivers/gpu/drm/i915/display/intel_fb.c +4 −4
  310. drivers/gpu/drm/i915/display/intel_fbc.c +48 −9
  311. drivers/gpu/drm/i915/display/intel_fdi.c +6 −2
  312. drivers/gpu/drm/i915/display/intel_frontbuffer.c +0 −2
  313. drivers/gpu/drm/i915/display/intel_hdcp.c +29 −8
  314. drivers/gpu/drm/i915/display/intel_hdcp.h +4 −4
  315. drivers/gpu/drm/i915/display/intel_hdmi.c +0 −10
  316. drivers/gpu/drm/i915/display/intel_hotplug_irq.c +16 −0
  317. drivers/gpu/drm/i915/display/intel_link_bw.c +22 −8
  318. drivers/gpu/drm/i915/display/intel_link_bw.h +1 −0
  319. drivers/gpu/drm/i915/display/intel_lvds.c +2 −2
  320. drivers/gpu/drm/i915/display/intel_modeset_setup.c +6 −0
  321. drivers/gpu/drm/i915/display/intel_modeset_verify.c +1 −1
  322. drivers/gpu/drm/i915/display/intel_opregion.c +1 −1
  323. drivers/gpu/drm/i915/display/intel_panel.c +2 −2
  324. drivers/gpu/drm/i915/display/intel_pch_display.c +1 −0
  325. drivers/gpu/drm/i915/display/intel_pps.c +1 −1
  326. drivers/gpu/drm/i915/display/intel_psr.c +274 −95
  327. drivers/gpu/drm/i915/display/intel_psr.h +7 −0
  328. drivers/gpu/drm/i915/display/intel_psr_regs.h +2 −0
  329. drivers/gpu/drm/i915/display/intel_qp_tables.c +0 −3
  330. drivers/gpu/drm/i915/display/intel_sdvo.c +18 −6
  331. drivers/gpu/drm/i915/display/intel_sprite.c +6 −1
  332. drivers/gpu/drm/i915/display/intel_vdsc.c +22 −7
  333. drivers/gpu/drm/i915/display/skl_universal_plane.c +14 −14
  334. drivers/gpu/drm/i915/display/skl_watermark.c +3 −2
  335. drivers/gpu/drm/i915/display/vlv_dsi.c +12 −9
  336. drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +1 −0
  337. drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h +1 −0
  338. drivers/gpu/drm/i915/gt/intel_engine_pm.h +1 −0
  339. drivers/gpu/drm/i915/gt/intel_gt.c +0 −11
  340. drivers/gpu/drm/i915/gt/intel_gt.h +14 −0
  341. drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c +1 −1
  342. drivers/gpu/drm/i915/gvt/cmd_parser.c +1 −1
  343. drivers/gpu/drm/i915/gvt/fb_decoder.c +3 −3
  344. drivers/gpu/drm/i915/gvt/handlers.c +1 −2
  345. drivers/gpu/drm/i915/i915_debugfs.c +3 −1
  346. drivers/gpu/drm/i915/i915_driver.c +3 −9
  347. drivers/gpu/drm/i915/i915_drv.h +1 −19
  348. drivers/gpu/drm/i915/i915_gem.c +0 −2
  349. drivers/gpu/drm/i915/i915_gpu_error.c +4 −1
  350. drivers/gpu/drm/i915/i915_gpu_error.h +2 −0
  351. drivers/gpu/drm/i915/i915_params.c +0 −89
  352. drivers/gpu/drm/i915/i915_params.h +0 −22
  353. drivers/gpu/drm/i915/i915_reg.h +0 −2
  354. drivers/gpu/drm/i915/i915_utils.h +1 −1
  355. drivers/gpu/drm/i915/intel_runtime_pm.h +0 −2
  356. drivers/gpu/drm/i915/selftests/intel_uncore.c +2 −0
  357. drivers/gpu/drm/i915/soc/intel_gmch.c +14 −13
  358. drivers/gpu/drm/i915/vlv_sideband.c +6 −23
  359. drivers/gpu/drm/i915/vlv_sideband.h +3 −6
  360. drivers/gpu/drm/imagination/Kconfig +18 −0
  361. drivers/gpu/drm/imagination/Makefile +35 −0
  362. drivers/gpu/drm/imagination/pvr_ccb.c +645 −0
  363. drivers/gpu/drm/imagination/pvr_ccb.h +71 −0
  364. drivers/gpu/drm/imagination/pvr_cccb.c +267 −0
  365. drivers/gpu/drm/imagination/pvr_cccb.h +110 −0
  366. drivers/gpu/drm/imagination/pvr_context.c +464 −0
  367. drivers/gpu/drm/imagination/pvr_context.h +205 −0
  368. drivers/gpu/drm/imagination/pvr_debugfs.c +53 −0
  369. drivers/gpu/drm/imagination/pvr_debugfs.h +29 −0
  370. drivers/gpu/drm/imagination/pvr_device.c +658 −0
  371. drivers/gpu/drm/imagination/pvr_device.h +721 −0
  372. drivers/gpu/drm/imagination/pvr_device_info.c +255 −0
  373. drivers/gpu/drm/imagination/pvr_device_info.h +186 −0
  374. drivers/gpu/drm/imagination/pvr_drv.c +1501 −0
  375. drivers/gpu/drm/imagination/pvr_drv.h +129 −0
  376. drivers/gpu/drm/imagination/pvr_free_list.c +625 −0
  377. drivers/gpu/drm/imagination/pvr_free_list.h +195 −0
  378. drivers/gpu/drm/imagination/pvr_fw.c +1489 −0
  379. drivers/gpu/drm/imagination/pvr_fw.h +509 −0
  380. drivers/gpu/drm/imagination/pvr_fw_info.h +135 −0
  381. drivers/gpu/drm/imagination/pvr_fw_meta.c +555 −0
  382. drivers/gpu/drm/imagination/pvr_fw_meta.h +14 −0
  383. drivers/gpu/drm/imagination/pvr_fw_mips.c +252 −0
  384. drivers/gpu/drm/imagination/pvr_fw_mips.h +48 −0
  385. drivers/gpu/drm/imagination/pvr_fw_startstop.c +306 −0
  386. drivers/gpu/drm/imagination/pvr_fw_startstop.h +13 −0
  387. drivers/gpu/drm/imagination/pvr_fw_trace.c +471 −0
  388. drivers/gpu/drm/imagination/pvr_fw_trace.h +78 −0
  389. drivers/gpu/drm/imagination/pvr_gem.c +414 −0
  390. drivers/gpu/drm/imagination/pvr_gem.h +170 −0
  391. drivers/gpu/drm/imagination/pvr_hwrt.c +549 −0
  392. drivers/gpu/drm/imagination/pvr_hwrt.h +166 −0
  393. drivers/gpu/drm/imagination/pvr_job.c +786 −0
  394. drivers/gpu/drm/imagination/pvr_job.h +161 −0
  395. drivers/gpu/drm/imagination/pvr_mmu.c +2640 −0
  396. drivers/gpu/drm/imagination/pvr_mmu.h +108 −0
  397. drivers/gpu/drm/imagination/pvr_params.c +147 −0
  398. drivers/gpu/drm/imagination/pvr_params.h +72 −0
  399. drivers/gpu/drm/imagination/pvr_power.c +433 −0
  400. drivers/gpu/drm/imagination/pvr_power.h +41 −0
  401. drivers/gpu/drm/imagination/pvr_queue.c +1432 −0
  402. drivers/gpu/drm/imagination/pvr_queue.h +169 −0
  403. drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h +6193 −0
  404. drivers/gpu/drm/imagination/pvr_rogue_cr_defs_client.h +159 −0
  405. drivers/gpu/drm/imagination/pvr_rogue_defs.h +179 −0
  406. drivers/gpu/drm/imagination/pvr_rogue_fwif.h +2188 −0
  407. drivers/gpu/drm/imagination/pvr_rogue_fwif_check.h +493 −0
  408. drivers/gpu/drm/imagination/pvr_rogue_fwif_client.h +373 −0
  409. drivers/gpu/drm/imagination/pvr_rogue_fwif_client_check.h +133 −0
  410. drivers/gpu/drm/imagination/pvr_rogue_fwif_common.h +60 −0
  411. drivers/gpu/drm/imagination/pvr_rogue_fwif_dev_info.h +113 −0
  412. drivers/gpu/drm/imagination/pvr_rogue_fwif_resetframework.h +28 −0
  413. drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h +1648 −0
  414. drivers/gpu/drm/imagination/pvr_rogue_fwif_shared.h +258 −0
  415. drivers/gpu/drm/imagination/pvr_rogue_fwif_shared_check.h +108 −0
  416. drivers/gpu/drm/imagination/pvr_rogue_fwif_stream.h +78 −0
  417. drivers/gpu/drm/imagination/pvr_rogue_heap_config.h +113 −0
  418. drivers/gpu/drm/imagination/pvr_rogue_meta.h +356 −0
  419. drivers/gpu/drm/imagination/pvr_rogue_mips.h +335 −0
  420. drivers/gpu/drm/imagination/pvr_rogue_mips_check.h +58 −0
  421. drivers/gpu/drm/imagination/pvr_rogue_mmu_defs.h +136 −0
  422. drivers/gpu/drm/imagination/pvr_stream.c +285 −0
  423. drivers/gpu/drm/imagination/pvr_stream.h +75 −0
  424. drivers/gpu/drm/imagination/pvr_stream_defs.c +351 −0
  425. drivers/gpu/drm/imagination/pvr_stream_defs.h +16 −0
  426. drivers/gpu/drm/imagination/pvr_sync.c +289 −0
  427. drivers/gpu/drm/imagination/pvr_sync.h +84 −0
  428. drivers/gpu/drm/imagination/pvr_vm.c +1092 −0
  429. drivers/gpu/drm/imagination/pvr_vm.h +66 −0
  430. drivers/gpu/drm/imagination/pvr_vm_mips.c +237 −0
  431. drivers/gpu/drm/imagination/pvr_vm_mips.h +22 −0
  432. drivers/gpu/drm/imx/dcss/dcss-drv.c +2 −4
  433. drivers/gpu/drm/imx/ipuv3/imx-ldb.c +4 −5
  434. drivers/gpu/drm/imx/lcdc/imx-lcdc.c +2 −13
  435. drivers/gpu/drm/kmb/kmb_drv.c +2 −3
  436. drivers/gpu/drm/lima/lima_device.c +1 −1
  437. drivers/gpu/drm/lima/lima_sched.c +2 −2
  438. drivers/gpu/drm/loongson/Kconfig +1 −0
  439. drivers/gpu/drm/loongson/lsdc_plane.c +0 −1
  440. drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +2 −3
  441. drivers/gpu/drm/mediatek/mtk_ethdr.c +2 −3
  442. drivers/gpu/drm/meson/meson_dw_mipi_dsi.c +2 −4
  443. drivers/gpu/drm/msm/adreno/adreno_device.c +4 −2
  444. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +1 −0
  445. drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +1 −2
  446. drivers/gpu/drm/msm/dp/dp_display.c +10 −5
  447. drivers/gpu/drm/msm/dp/dp_drm.c +3 −0
  448. drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +1 −1
  449. drivers/gpu/drm/msm/msm_drv.c +0 −2
  450. drivers/gpu/drm/msm/msm_gem_submit.c +1 −1
  451. drivers/gpu/drm/msm/msm_gpu.h +1 −1
  452. drivers/gpu/drm/msm/msm_ringbuffer.c +1 −1
  453. drivers/gpu/drm/mxsfb/mxsfb_drv.c +3 −7
  454. drivers/gpu/drm/nouveau/dispnv50/disp.c +6 −4
  455. drivers/gpu/drm/nouveau/include/nvkm/core/event.h +2 −2
  456. drivers/gpu/drm/nouveau/nouveau_abi16.c +6 −13
  457. drivers/gpu/drm/nouveau/nouveau_abi16.h +1 −1
  458. drivers/gpu/drm/nouveau/nouveau_bo.c +12 −3
  459. drivers/gpu/drm/nouveau/nouveau_bo.h +5 −0
  460. drivers/gpu/drm/nouveau/nouveau_display.c +5 −0
  461. drivers/gpu/drm/nouveau/nouveau_drm.c +25 −11
  462. drivers/gpu/drm/nouveau/nouveau_drv.h +9 −10
  463. drivers/gpu/drm/nouveau/nouveau_exec.c +21 −47
  464. drivers/gpu/drm/nouveau/nouveau_exec.h +1 −5
  465. drivers/gpu/drm/nouveau/nouveau_gem.c +8 −2
  466. drivers/gpu/drm/nouveau/nouveau_platform.c +2 −3
  467. drivers/gpu/drm/nouveau/nouveau_sched.c +116 −91
  468. drivers/gpu/drm/nouveau/nouveau_sched.h +17 −26
  469. drivers/gpu/drm/nouveau/nouveau_uvmm.c +198 −182
  470. drivers/gpu/drm/nouveau/nouveau_uvmm.h +1 −11
  471. drivers/gpu/drm/nouveau/nv04_fence.c +1 −1
  472. drivers/gpu/drm/nouveau/nvkm/core/event.c +6 −6
  473. drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +0 −1
  474. drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c +1 −1
  475. drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +3 −3
  476. drivers/gpu/drm/omapdrm/dss/dispc.c +2 −2
  477. drivers/gpu/drm/omapdrm/dss/dss.c +3 −2
  478. drivers/gpu/drm/omapdrm/omap_drv.c +4 −5
  479. drivers/gpu/drm/omapdrm/omap_gem.c +10 −4
  480. drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +5 −4
  481. drivers/gpu/drm/panel/panel-edp.c +127 −11
  482. drivers/gpu/drm/panel/panel-elida-kd35t133.c +3 −34
  483. drivers/gpu/drm/panel/panel-himax-hx8394.c +152 −28
  484. drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +225 −0
  485. drivers/gpu/drm/panel/panel-newvision-nv3051d.c +46 −11
  486. drivers/gpu/drm/panel/panel-novatek-nt35510.c +1 −1
  487. drivers/gpu/drm/panel/panel-simple.c +69 −6
  488. drivers/gpu/drm/panfrost/panfrost_device.c +77 −4
  489. drivers/gpu/drm/panfrost/panfrost_device.h +23 −0
  490. drivers/gpu/drm/panfrost/panfrost_drv.c +4 −1
  491. drivers/gpu/drm/panfrost/panfrost_dump.c +2 −10
  492. drivers/gpu/drm/panfrost/panfrost_gpu.c +86 −33
  493. drivers/gpu/drm/panfrost/panfrost_gpu.h +1 −0
  494. drivers/gpu/drm/panfrost/panfrost_job.c +24 −6
  495. drivers/gpu/drm/panfrost/panfrost_job.h +1 −0
  496. drivers/gpu/drm/panfrost/panfrost_mmu.c +24 −8
  497. drivers/gpu/drm/panfrost/panfrost_mmu.h +1 −0
  498. drivers/gpu/drm/panfrost/panfrost_regs.h +1 −0
  499. drivers/gpu/drm/qxl/qxl_display.c +6 −8
  500. drivers/gpu/drm/qxl/qxl_drv.c +1 −1
  501. drivers/gpu/drm/qxl/qxl_drv.h +0 −7
  502. drivers/gpu/drm/radeon/radeon_audio.c +1 −0
  503. drivers/gpu/drm/radeon/radeon_drv.h +0 −1
  504. drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c +0 −1
  505. drivers/gpu/drm/rockchip/rk3066_hdmi.c +18 −27
  506. drivers/gpu/drm/rockchip/rockchip_drm_vop.c +11 −3
  507. drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +5 −0
  508. drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +2 −0
  509. drivers/gpu/drm/scheduler/gpu_scheduler_trace.h +1 −1
  510. drivers/gpu/drm/scheduler/sched_entity.c +11 −7
  511. drivers/gpu/drm/scheduler/sched_main.c +344 −148
  512. drivers/gpu/drm/solomon/ssd130x.c +32 −6
  513. drivers/gpu/drm/solomon/ssd130x.h +0 −1
  514. drivers/gpu/drm/sprd/sprd_dpu.c +2 −4
  515. drivers/gpu/drm/sprd/sprd_drm.c +2 −3
  516. drivers/gpu/drm/sprd/sprd_dsi.c +2 −4
  517. drivers/gpu/drm/tegra/hdmi.c +1 −0
  518. drivers/gpu/drm/tegra/sor.c +1 −0
  519. drivers/gpu/drm/tests/Makefile +3 −2
  520. drivers/gpu/drm/tests/drm_buddy_test.c +0 −465
  521. drivers/gpu/drm/tests/drm_dp_mst_helper_test.c +163 −3
  522. drivers/gpu/drm/tests/drm_format_helper_test.c +44 −28
  523. drivers/gpu/drm/tests/drm_gem_shmem_test.c +383 −0
  524. drivers/gpu/drm/tests/drm_mm_test.c +56 −1960
  525. drivers/gpu/drm/tidss/tidss_crtc.c +4 −8
  526. drivers/gpu/drm/tidss/tidss_dispc.c +131 −7
  527. drivers/gpu/drm/tidss/tidss_dispc.h +3 −0
  528. drivers/gpu/drm/tidss/tidss_drv.c +13 −3
  529. drivers/gpu/drm/tidss/tidss_irq.c +8 −46
  530. drivers/gpu/drm/tidss/tidss_kms.c +1 −5
  531. drivers/gpu/drm/tilcdc/tilcdc_drv.c +5 −6
  532. drivers/gpu/drm/tiny/arcpgu.c +2 −4
  533. drivers/gpu/drm/tiny/cirrus.c +2 −1
  534. drivers/gpu/drm/tiny/ili9225.c +6 −4
  535. drivers/gpu/drm/tiny/ofdrm.c +15 −2
  536. drivers/gpu/drm/tiny/repaper.c +7 −3
  537. drivers/gpu/drm/tiny/simpledrm.c +41 −3
  538. drivers/gpu/drm/tiny/st7586.c +11 −8
  539. drivers/gpu/drm/ttm/ttm_bo.c +7 −1
  540. drivers/gpu/drm/ttm/ttm_device.c +4 −2
  541. drivers/gpu/drm/udl/udl_modeset.c +17 −2
  542. drivers/gpu/drm/v3d/Makefile +3 −1
  543. drivers/gpu/drm/v3d/v3d_bo.c +51 −0
  544. drivers/gpu/drm/v3d/v3d_debugfs.c +101 −77
  545. drivers/gpu/drm/v3d/v3d_drv.c +49 −1
  546. drivers/gpu/drm/v3d/v3d_drv.h +155 −10
  547. drivers/gpu/drm/v3d/v3d_gem.c +9 −770
  548. drivers/gpu/drm/v3d/v3d_irq.c +74 −19
  549. drivers/gpu/drm/v3d/v3d_regs.h +54 −40
  550. drivers/gpu/drm/v3d/v3d_sched.c +375 −22
  551. drivers/gpu/drm/v3d/v3d_submit.c +1320 −0
  552. drivers/gpu/drm/v3d/v3d_sysfs.c +69 −0
  553. drivers/gpu/drm/v3d/v3d_trace.h +57 −0
  554. drivers/gpu/drm/vboxvideo/vbox_drv.c +1 −1
  555. drivers/gpu/drm/vboxvideo/vbox_mode.c +2 −2
  556. drivers/gpu/drm/virtio/virtgpu_drv.c +1 −1
  557. drivers/gpu/drm/virtio/virtgpu_drv.h +5 −0
  558. drivers/gpu/drm/virtio/virtgpu_ioctl.c +33 −8
  559. drivers/gpu/drm/virtio/virtgpu_plane.c +14 −4
  560. drivers/gpu/drm/vkms/vkms_writeback.c +15 −10
  561. drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +1 −1
  562. drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +13 −7
  563. drivers/gpu/drm/xlnx/zynqmp_kms.c +0 −1
  564. drivers/hid/hid-apple.c +2 −0
  565. drivers/hid/hid-asus.c +23 −4
  566. drivers/hid/hid-core.c +10 −2
  567. drivers/hid/hid-debug.c +3 −0
  568. drivers/hid/hid-glorious.c +14 −2
  569. drivers/hid/hid-ids.h +7 −5
  570. drivers/hid/hid-logitech-dj.c +3 −8
  571. drivers/hid/hid-mcp2221.c +3 −1
  572. drivers/hid/hid-multitouch.c +5 −0
  573. drivers/hid/hid-picolcd_fb.c +1 −0
  574. drivers/hid/hid-quirks.c +1 −0
  575. drivers/i2c/busses/i2c-designware-common.c +8 −8
  576. drivers/i2c/busses/i2c-ocores.c +2 −2
  577. drivers/i2c/busses/i2c-pxa.c +68 −8
  578. drivers/irqchip/irq-gic-v3-its.c +10 −6
  579. drivers/md/bcache/bcache.h +1 −0
  580. drivers/md/bcache/btree.c +10 −1
  581. drivers/md/bcache/super.c +3 −1
  582. drivers/md/bcache/sysfs.c +1 −1
  583. drivers/md/bcache/writeback.c +18 −6
  584. drivers/md/dm-bufio.c +62 −25
  585. drivers/md/dm-crypt.c +1 −1
  586. drivers/md/dm-delay.c +52 −60
  587. drivers/md/dm-verity-fec.c +2 −2
  588. drivers/md/dm-verity-target.c +12 −11
  589. drivers/md/dm-verity.h +1 −1
  590. drivers/md/md.c +2 −1
  591. drivers/media/pci/ivtv/Kconfig +1 −3
  592. drivers/media/pci/ivtv/ivtvfb.c +3 −3
  593. drivers/net/bonding/bond_main.c +6 −0
  594. drivers/net/ethernet/amd/pds_core/adminq.c +1 −1
  595. drivers/net/ethernet/amd/pds_core/core.h +1 −1
  596. drivers/net/ethernet/amd/pds_core/dev.c +6 −2
  597. drivers/net/ethernet/amd/pds_core/devlink.c +1 −1
  598. drivers/net/ethernet/amd/xgbe/xgbe-drv.c +14 −0
  599. drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +8 −3
  600. drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +13 −1
  601. drivers/net/ethernet/broadcom/tg3.c +36 −6
  602. drivers/net/ethernet/broadcom/tg3.h +2 −2
  603. drivers/net/ethernet/cortina/gemini.c +29 −16
  604. drivers/net/ethernet/cortina/gemini.h +2 −2
  605. drivers/net/ethernet/google/gve/gve_main.c +7 −1
  606. drivers/net/ethernet/google/gve/gve_rx.c +0 −4
  607. drivers/net/ethernet/google/gve/gve_tx.c +0 −4
  608. drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +6 −3
  609. drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +1 −1
  610. drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +25 −8
  611. drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +22 −3
  612. drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +1 −0
  613. drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +7 −0
  614. drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +9 −7
  615. drivers/net/ethernet/intel/ice/ice_ddp.c +100 −3
  616. drivers/net/ethernet/intel/ice/ice_dpll.c +9 −12
  617. drivers/net/ethernet/intel/ice/ice_dpll.h +0 −1
  618. drivers/net/ethernet/intel/ice/ice_main.c +3 −9
  619. drivers/net/ethernet/intel/ice/ice_ptp.c +78 −66
  620. drivers/net/ethernet/intel/ice/ice_ptp.h +2 −3
  621. drivers/net/ethernet/intel/ice/ice_ptp_hw.c +54 −0
  622. drivers/net/ethernet/intel/ice/ice_ptp_hw.h +2 −0
  623. drivers/net/ethernet/intel/ice/ice_txrx.c +0 −3
  624. drivers/net/ethernet/intel/ice/ice_txrx.h +0 −1
  625. drivers/net/ethernet/marvell/mvneta.c +20 −8
  626. drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +19 −1
  627. drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +2 −0
  628. drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +16 −4
  629. drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +2 −2
  630. drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +14 −16
  631. drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +9 −4
  632. drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +8 −4
  633. drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +32 −28
  634. drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +2 −2
  635. drivers/net/ethernet/mellanox/mlx5/core/eq.c +19 −6
  636. drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +2 −1
  637. drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c +0 −42
  638. drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +6 −1
  639. drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +3 −3
  640. drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h +3 −0
  641. drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c +2 −1
  642. drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +13 −102
  643. drivers/net/ethernet/realtek/r8169_main.c +32 −14
  644. drivers/net/ethernet/stmicro/stmmac/Kconfig +1 −1
  645. drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2 −1
  646. drivers/net/ethernet/ti/icssg/icssg_prueth.c +10 −5
  647. drivers/net/ethernet/wangxun/libwx/wx_hw.c +5 −3
  648. drivers/net/ethernet/wangxun/ngbe/ngbe_main.c +1 −3
  649. drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +1 −3
  650. drivers/net/ethernet/xilinx/xilinx_axienet_main.c +1 −1
  651. drivers/net/hyperv/netvsc_drv.c +45 −21
  652. drivers/net/ipa/reg/gsi_reg-v5.0.c +1 −1
  653. drivers/net/ipvlan/ipvlan_core.c +25 −16
  654. drivers/net/macvlan.c +1 −1
  655. drivers/net/netkit.c +20 −2
  656. drivers/net/ppp/ppp_synctty.c +5 −1
  657. drivers/net/usb/aqc111.c +4 −4
  658. drivers/net/usb/ax88179_178a.c +2 −2
  659. drivers/net/usb/qmi_wwan.c +1 −0
  660. drivers/net/veth.c +13 −33
  661. drivers/net/vrf.c +10 −28
  662. drivers/net/wireguard/device.c +2 −2
  663. drivers/net/wireguard/receive.c +6 −6
  664. drivers/net/wireguard/send.c +2 −1
  665. drivers/nfc/virtual_ncidev.c +6 −1
  666. drivers/nvme/host/auth.c +3 −2
  667. drivers/nvme/host/core.c +14 −7
  668. drivers/nvme/host/fabrics.c +2 −0
  669. drivers/nvme/host/fc.c +8 −11
  670. drivers/nvme/host/rdma.c +1 −0
  671. drivers/nvme/host/tcp.c +15 −17
  672. drivers/nvme/target/Kconfig +2 −2
  673. drivers/nvme/target/configfs.c +1 −1
  674. drivers/nvme/target/fabrics-cmd.c +4 −0
  675. drivers/nvme/target/tcp.c +3 −1
  676. drivers/parisc/power.c +1 −1
  677. drivers/phy/Kconfig +0 −1
  678. drivers/phy/Makefile +0 −1
  679. drivers/phy/qualcomm/Kconfig +1 −1
  680. drivers/phy/qualcomm/phy-qcom-qmp-combo.c +2 −42
  681. drivers/phy/realtek/Kconfig +0 −32
  682. drivers/phy/realtek/Makefile +0 −3
  683. drivers/phy/realtek/phy-rtk-usb2.c +0 −1325
  684. drivers/phy/realtek/phy-rtk-usb3.c +0 −761
  685. drivers/platform/x86/amd/pmc/pmc.c +2 −29
  686. drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +11 −15
  687. drivers/platform/x86/ideapad-laptop.c +5 −6
  688. drivers/platform/x86/intel/telemetry/core.c +2 −2
  689. drivers/ptp/ptp_chardev.c +2 −1
  690. drivers/ptp/ptp_clock.c +3 −2
  691. drivers/ptp/ptp_private.h +6 −2
  692. drivers/ptp/ptp_sysfs.c +2 −1
  693. drivers/s390/block/dasd.c +13 −11
  694. drivers/s390/block/dasd_int.h +1 −1
  695. drivers/s390/net/Kconfig +2 −1
  696. drivers/s390/net/ism_drv.c +46 −47
  697. drivers/scsi/qla2xxx/qla_os.c +10 −2
  698. drivers/scsi/scsi_debug.c +1 −8
  699. drivers/scsi/sd.c +23 −30
  700. drivers/soc/qcom/Kconfig +1 −0
  701. drivers/soc/qcom/pmic_glink_altmode.c +9 −24
  702. drivers/staging/sm750fb/sm750.c +52 −13
  703. drivers/thunderbolt/switch.c +3 −3
  704. drivers/thunderbolt/tb.c +11 −1
  705. drivers/ufs/core/ufs-mcq.c +4 −1
  706. drivers/usb/cdns3/cdnsp-ring.c +3 −0
  707. drivers/usb/core/config.c +2 −1
  708. drivers/usb/core/hub.c +0 −23
  709. drivers/usb/dwc2/hcd_intr.c +7 −8
  710. drivers/usb/dwc3/core.c +2 −0
  711. drivers/usb/dwc3/drd.c +1 −1
  712. drivers/usb/dwc3/dwc3-qcom.c +47 −22
  713. drivers/usb/dwc3/dwc3-rtk.c +7 −1
  714. drivers/usb/host/xhci-mtk-sch.c +10 −3
  715. drivers/usb/host/xhci-mtk.h +2 −0
  716. drivers/usb/host/xhci-plat.c +30 −20
  717. drivers/usb/misc/onboard_usb_hub.c +2 −0
  718. drivers/usb/misc/onboard_usb_hub.h +7 −0
  719. drivers/usb/misc/usb-ljca.c +4 −13
  720. drivers/usb/serial/option.c +8 −3
  721. drivers/usb/typec/mux/Kconfig +1 −1
  722. drivers/usb/typec/mux/nb7vpq904m.c +2 −42
  723. drivers/usb/typec/tcpm/Kconfig +1 −0
  724. drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c +6 −35
  725. drivers/usb/typec/tcpm/tcpm.c +11 −1
  726. drivers/usb/typec/tipd/core.c +9 −5
  727. drivers/vdpa/vdpa_sim/vdpa_sim_blk.c +2 −2
  728. drivers/vhost/vdpa.c +0 −1
  729. drivers/video/fbdev/Kconfig +12 −38
  730. drivers/video/fbdev/acornfb.c +1 −1
  731. drivers/video/fbdev/amba-clcd.c +2 −0
  732. drivers/video/fbdev/arcfb.c +27 −87
  733. drivers/video/fbdev/au1100fb.c +2 −0
  734. drivers/video/fbdev/au1200fb.c +6 −5
  735. drivers/video/fbdev/clps711x-fb.c +1 −3
  736. drivers/video/fbdev/core/Kconfig +3 −4
  737. drivers/video/fbdev/core/Makefile +1 −1
  738. drivers/video/fbdev/core/cfbcopyarea.c +3 −0
  739. drivers/video/fbdev/core/cfbfillrect.c +3 −0
  740. drivers/video/fbdev/core/cfbimgblt.c +3 −0
  741. drivers/video/fbdev/core/fb_chrdev.c +13 −55
  742. drivers/video/fbdev/core/fb_defio.c +2 −0
  743. drivers/video/fbdev/core/fb_io_fops.c +36 −0
  744. drivers/video/fbdev/core/fb_sys_fops.c +6 −0
  745. drivers/video/fbdev/core/syscopyarea.c +3 −0
  746. drivers/video/fbdev/core/sysfillrect.c +3 −0
  747. drivers/video/fbdev/core/sysimgblt.c +3 −0
  748. drivers/video/fbdev/cyber2000fb.c +1 −8
  749. drivers/video/fbdev/ep93xx-fb.c +2 −0
  750. drivers/video/fbdev/gbefb.c +2 −0
  751. drivers/video/fbdev/omap/omapfb_main.c +2 −0
  752. drivers/video/fbdev/omap2/omapfb/omapfb-main.c +2 −0
  753. drivers/video/fbdev/ps3fb.c +5 −6
  754. drivers/video/fbdev/sa1100fb.c +2 −0
  755. drivers/video/fbdev/sbuslib.c +3 −2
  756. drivers/video/fbdev/sh_mobile_lcdcfb.c +9 −7
  757. drivers/video/fbdev/simplefb.c +127 −5
  758. drivers/video/fbdev/sm712fb.c +2 −4
  759. drivers/video/fbdev/smscufx.c +2 −0
  760. drivers/video/fbdev/udlfb.c +2 −0
  761. drivers/video/fbdev/vermilion/vermilion.c +2 −0
  762. drivers/video/fbdev/vfb.c +5 −5
  763. drivers/video/fbdev/vt8500lcdfb.c +3 −1
  764. drivers/video/fbdev/wm8505fb.c +2 −0
  765. drivers/virtio/virtio_pci_common.c +3 −3
  766. drivers/virtio/virtio_pci_modern_dev.c +4 −3
  767. drivers/xen/events/events_2l.c +4 −4
  768. drivers/xen/events/events_base.c +279 −297
  769. drivers/xen/events/events_internal.h +0 −1
  770. drivers/xen/pcpu.c +22 −0
  771. drivers/xen/privcmd.c +1 −1
  772. drivers/xen/swiotlb-xen.c +1 −0
  773. drivers/xen/xen-front-pgdir-shbuf.c +17 −17
  774. fs/afs/dynroot.c +2 −2
  775. fs/afs/internal.h +1 −0
  776. fs/afs/server_list.c +1 −1
  777. fs/afs/super.c +4 −0
  778. fs/afs/vl_rotate.c +10 −0
  779. fs/autofs/inode.c +21 −35
  780. fs/bcachefs/backpointers.c +5 −5
  781. fs/bcachefs/bcachefs.h +1 −1
  782. fs/bcachefs/btree_iter.c +0 −2
  783. fs/bcachefs/btree_key_cache.c +19 −18
  784. fs/bcachefs/btree_key_cache_types.h +34 −0
  785. fs/bcachefs/btree_trans_commit.c +93 −76
  786. fs/bcachefs/btree_types.h +2 −33
  787. fs/bcachefs/btree_update_interior.c +0 −30
  788. fs/bcachefs/btree_update_interior.h +0 −1
  789. fs/bcachefs/data_update.c +28 −0
  790. fs/bcachefs/disk_groups.c +3 −1
  791. fs/bcachefs/ec.c +14 −2
  792. fs/bcachefs/fs-io-pagecache.c +1 −1
  793. fs/bcachefs/fs-io-pagecache.h +1 −1
  794. fs/bcachefs/fs.c +1 −7
  795. fs/bcachefs/fsck.c +1 −1
  796. fs/bcachefs/inode.c +5 −3
  797. fs/bcachefs/io_write.c +1 −1
  798. fs/bcachefs/journal.c +0 −31
  799. fs/bcachefs/journal.h +0 −98
  800. fs/bcachefs/journal_io.c +7 −0
  801. fs/bcachefs/journal_reclaim.c +15 −27
  802. fs/bcachefs/journal_types.h +0 −26
  803. fs/bcachefs/six.c +5 −2
  804. fs/bcachefs/subvolume_types.h +1 −1
  805. fs/bcachefs/trace.h +2 −9
  806. fs/bcachefs/xattr.c +9 −0
  807. fs/btrfs/ctree.c +1 −1
  808. fs/btrfs/delayed-ref.c +2 −2
  809. fs/btrfs/extent-tree.c +17 −8
  810. fs/btrfs/extent-tree.h +2 −1
  811. fs/btrfs/inode.c +7 −0
  812. fs/btrfs/ioctl.c +5 −5
  813. fs/btrfs/qgroup.c +8 −2
  814. fs/btrfs/raid-stripe-tree.c +1 −1
  815. fs/btrfs/scrub.c +7 −3
  816. fs/btrfs/volumes.c +3 −3
  817. fs/btrfs/zoned.c +0 −7
  818. fs/ecryptfs/inode.c +10 −2
  819. fs/erofs/Kconfig +1 −1
  820. fs/erofs/data.c +3 −2
  821. fs/erofs/inode.c +35 −63
  822. fs/inode.c +2 −0
  823. fs/libfs.c +11 −3
  824. fs/nfsd/cache.h +2 −2
  825. fs/nfsd/nfs4state.c +1 −1
  826. fs/nfsd/nfscache.c +51 −36
  827. fs/nfsd/nfssvc.c +12 −2
  828. fs/overlayfs/inode.c +5 −5
  829. fs/overlayfs/overlayfs.h +8 −0
  830. fs/overlayfs/params.c +5 −6
  831. fs/overlayfs/util.c +1 −1
  832. fs/smb/client/cifs_spnego.c +2 −2
  833. fs/smb/client/cifsglob.h +11 −3
  834. fs/smb/client/cifspdu.h +2 −2
  835. fs/smb/client/cifsproto.h +13 −1
  836. fs/smb/client/cifssmb.c +77 −116
  837. fs/smb/client/connect.c +6 −0
  838. fs/smb/client/inode.c +60 −14
  839. fs/smb/client/readdir.c +5 −1
  840. fs/smb/client/sess.c +14 −10
  841. fs/smb/client/smb1ops.c +32 −121
  842. fs/smb/client/smb2inode.c +1 −1
  843. fs/smb/client/smb2ops.c +112 −115
  844. fs/smb/client/smb2transport.c +2 −3
  845. fs/stat.c +5 −1
  846. fs/tracefs/event_inode.c +26 −39
  847. fs/tracefs/inode.c +4 −9
  848. fs/xfs/Kconfig +1 −1
  849. fs/xfs/libxfs/xfs_alloc.c +24 −3
  850. fs/xfs/libxfs/xfs_defer.c +18 −10
  851. fs/xfs/libxfs/xfs_defer.h +1 −1
  852. fs/xfs/libxfs/xfs_inode_buf.c +3 −0
  853. fs/xfs/xfs_dquot.c +3 −2
  854. fs/xfs/xfs_dquot_item_recover.c +18 −3
  855. fs/xfs/xfs_inode.h +8 −0
  856. fs/xfs/xfs_inode_item_recover.c +30 −16
  857. fs/xfs/xfs_ioctl.c +20 −10
  858. fs/xfs/xfs_iops.c +7 −0
  859. fs/xfs/xfs_log.c +12 −11
  860. fs/xfs/xfs_log_recover.c +1 −1
  861. fs/xfs/xfs_reflink.c +1 −0
  862. include/acpi/acpi_bus.h +1 −0
  863. include/asm-generic/qspinlock.h +1 −1
  864. include/drm/bridge/aux-bridge.h +37 −0
  865. include/drm/display/drm_dp.h +28 −0
  866. include/drm/display/drm_dp_helper.h +32 −0
  867. include/drm/display/drm_dp_mst_helper.h +12 −4
  868. include/drm/drm_atomic_helper.h +2 −3
  869. include/drm/drm_auth.h +0 −22
  870. include/drm/drm_bridge.h +1 −3
  871. include/drm/drm_color_mgmt.h +8 −11
  872. include/drm/drm_device.h +2 −69
  873. include/drm/drm_drv.h +9 −19
  874. include/drm/drm_edid.h +0 −153
  875. include/drm/drm_eld.h +164 −0
  876. include/drm/drm_encoder.h +15 −1
  877. include/drm/drm_file.h +12 −5
  878. include/drm/drm_flip_work.h +3 −17
  879. include/drm/drm_format_helper.h +68 −13
  880. include/drm/drm_framebuffer.h +0 −12
  881. include/drm/drm_gem.h +16 −16
  882. include/drm/drm_gem_atomic_helper.h +10 −0
  883. include/drm/drm_gpuvm.h +527 −5
  884. include/drm/drm_ioctl.h +0 −11
  885. include/drm/drm_legacy.h +0 −331
  886. include/drm/drm_mipi_dbi.h +3 −1
  887. include/drm/drm_mipi_dsi.h +2 −0
  888. include/drm/drm_modeset_helper_vtables.h +10 −0
  889. include/drm/drm_plane.h +24 −0
  890. include/drm/drm_plane_helper.h +0 −2
  891. include/drm/drm_print.h +1 −1
  892. include/drm/gpu_scheduler.h +41 −15
  893. include/linux/blk-pm.h +0 −1
  894. include/linux/bpf.h +7 −3
  895. include/linux/bpf_verifier.h +16 −0
  896. include/linux/cpuhotplug.h +1 −0
  897. include/linux/dma-buf.h +7 −4
  898. include/linux/export-internal.h +1 −3
  899. include/linux/fb.h +14 −2
  900. include/linux/hid.h +3 −0
  901. include/linux/hrtimer.h +2 −2
  902. include/linux/iosys-map.h +22 −22
  903. include/linux/mdio.h +1 −1
  904. include/linux/netdevice.h +26 −4
  905. include/linux/pagemap.h +17 −0
  906. include/linux/perf_event.h +8 −5
  907. include/linux/sizes.h +9 −0
  908. include/linux/stackleak.h +6 −0
  909. include/linux/usb/phy.h +0 −13
  910. include/linux/virtio_pci_modern.h +0 −7
  911. include/net/netfilter/nf_tables.h +2 −2
  912. include/net/netkit.h +6 −0
  913. include/net/tc_act/tc_ct.h +9 −0
  914. include/trace/events/rxrpc.h +1 −1
  915. include/uapi/drm/drm.h +71 −1
  916. include/uapi/drm/drm_mode.h +19 −0
  917. include/uapi/drm/ivpu_accel.h +1 −1
  918. include/uapi/drm/pvr_drm.h +1295 −0
  919. include/uapi/drm/qaic_accel.h +3 −2
  920. include/uapi/drm/v3d_drm.h +244 −1
  921. include/uapi/drm/virtgpu_drm.h +2 −0
  922. include/uapi/linux/btrfs_tree.h +16 −8
  923. include/uapi/linux/fcntl.h +3 −0
  924. include/uapi/linux/sync_file.h +22 −0
  925. include/uapi/linux/virtio_pci.h +11 −0
  926. include/xen/events.h +2 −6
  927. io_uring/fdinfo.c +2 −7
  928. io_uring/fs.c +1 −1
  929. io_uring/rsrc.c +1 −1
  930. io_uring/sqpoll.c +10 −2
  931. kernel/audit_watch.c +1 −1
  932. kernel/bpf/core.c +3 −5
  933. kernel/bpf/verifier.c +329 −160
  934. kernel/cgroup/cgroup.c +0 −12
  935. kernel/cpu.c +7 −1
  936. kernel/events/core.c +17 −0
  937. kernel/futex/core.c +6 −3
  938. kernel/locking/lockdep.c +2 −1
  939. kernel/sched/fair.c +135 −26
  940. kernel/sys.c +4 −0
  941. kernel/time/hrtimer.c +12 −21
  942. lib/errname.c +0 −6
  943. lib/iov_iter.c +1 −1
  944. lib/zstd/common/fse_decompress.c +1 −1
  945. mm/damon/core.c +1 −1
  946. mm/damon/sysfs-schemes.c +5 −0
  947. mm/damon/sysfs.c +4 −2
  948. mm/filemap.c +1 −1
  949. mm/huge_memory.c +9 −7
  950. mm/ksm.c +1 −1
  951. mm/memcontrol.c +2 −1
  952. mm/page-writeback.c +1 −1
  953. mm/userfaultfd.c +1 −1
  954. mm/util.c +10 −0
  955. net/bridge/netfilter/nf_conntrack_bridge.c +1 −1
  956. net/core/dev.c +59 −2
  957. net/core/filter.c +14 −5
  958. net/core/gso_test.c +5 −9
  959. net/ipv4/inet_diag.c +1 −0
  960. net/ipv4/inet_hashtables.c +1 −1
  961. net/ipv4/raw_diag.c +1 −0
  962. net/ipv4/route.c +1 −1
  963. net/ipv4/tcp_diag.c +1 −0
  964. net/ipv4/udp_diag.c +1 −0
  965. net/mptcp/mptcp_diag.c +1 −0
  966. net/mptcp/pm_netlink.c +3 −2
  967. net/mptcp/protocol.c +8 −3
  968. net/mptcp/sockopt.c +3 −0
  969. net/ncsi/ncsi-aen.c +0 −5
  970. net/netfilter/ipset/ip_set_core.c +7 −7
  971. net/netfilter/nf_tables_api.c +33 −27
  972. net/netfilter/nft_byteorder.c +3 −2
  973. net/netfilter/nft_meta.c +1 −1
  974. net/netfilter/nft_set_rbtree.c +0 −2
  975. net/packet/diag.c +1 −0
  976. net/rxrpc/conn_client.c +4 −3
  977. net/rxrpc/input.c +29 −32
  978. net/sched/act_ct.c +3 −0
  979. net/sctp/diag.c +1 −0
  980. net/smc/af_smc.c +6 −2
  981. net/smc/smc_diag.c +1 −0
  982. net/tipc/diag.c +1 −0
  983. net/tipc/netlink_compat.c +1 −0
  984. net/tls/tls_sw.c +3 −0
  985. net/unix/af_unix.c +5 −4
  986. net/unix/diag.c +1 −0
  987. net/vmw_vsock/diag.c +1 −0
  988. net/xdp/xsk_diag.c +1 −0
  989. scripts/Makefile.lib +2 −2
  990. scripts/checkstack.pl +1 −2
  991. scripts/gcc-plugins/latent_entropy_plugin.c +2 −2
  992. scripts/gcc-plugins/randomize_layout_plugin.c +0 −10
  993. scripts/kconfig/symbol.c +6 −8
  994. scripts/mod/modpost.c +4 −2
  995. sound/core/pcm_drm_eld.c +1 −0
  996. sound/pci/hda/cs35l56_hda_i2c.c +4 −0
  997. sound/pci/hda/hda_intel.c +3 −0
  998. sound/pci/hda/patch_realtek.c +13 −16
  999. sound/soc/codecs/hdac_hdmi.c +1 −0
  1000. sound/soc/codecs/hdmi-codec.c +1 −0
  1001. sound/x86/intel_hdmi_audio.c +1 −0
  1002. tools/arch/parisc/include/uapi/asm/errno.h +0 −2
  1003. tools/hv/hv_kvp_daemon.c +12 −8
  1004. tools/hv/hv_set_ifconfig.sh +2 −2
  1005. tools/net/ynl/Makefile.deps +1 −1
  1006. tools/net/ynl/generated/devlink-user.c +1 −1
  1007. tools/net/ynl/ynl-gen-c.py +6 −0
  1008. tools/power/pm-graph/sleepgraph.py +1 −1
  1009. tools/power/x86/turbostat/turbostat.c +1537 −1537
  1010. tools/testing/selftests/arm64/fp/za-fork.c +1 −1
  1011. tools/testing/selftests/bpf/prog_tests/tc_redirect.c +190 −127
  1012. tools/testing/selftests/bpf/prog_tests/verifier.c +2 −0
  1013. tools/testing/selftests/bpf/progs/bpf_loop_bench.c +8 −5
  1014. tools/testing/selftests/bpf/progs/cb_refs.c +1 −0
  1015. tools/testing/selftests/bpf/progs/exceptions_fail.c +2 −0
  1016. tools/testing/selftests/bpf/progs/strobemeta.h +48 −30
  1017. tools/testing/selftests/bpf/progs/verifier_cfg.c +62 −0
  1018. tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c +242 −0
  1019. tools/testing/selftests/bpf/progs/verifier_loops1.c +6 −3
  1020. tools/testing/selftests/bpf/progs/verifier_precision.c +40 −0
  1021. tools/testing/selftests/bpf/progs/verifier_subprog_precision.c +72 −14
  1022. tools/testing/selftests/bpf/progs/xdp_synproxy_kern.c +52 −32
  1023. tools/testing/selftests/bpf/verifier/calls.c +3 −3
  1024. tools/testing/selftests/bpf/verifier/ld_imm64.c +4 −4
  1025. tools/testing/selftests/bpf/xskxceiver.c +12 −7
  1026. tools/testing/selftests/mm/.gitignore +1 −0
  1027. tools/testing/selftests/mm/pagemap_ioctl.c +12 −11
  1028. tools/testing/selftests/mm/run_vmtests.sh +3 −0
  1029. tools/testing/selftests/net/mptcp/mptcp_join.sh +1 −1
  1030. tools/testing/selftests/net/rtnetlink.sh +1 −1
  1031. tools/testing/vsock/vsock_test.c +13 −6
Documentation/accel/qaic/aic100.rst+8−3
@@ -36,8 +36,9 @@ AIC100 DID (0xa100). · 35 unmodified lines
3636
3737 AIC100 does not implement FLR (function level reset).
3838
39−AIC100 implements MSI but does not implement MSI-X. AIC100 requires 17 MSIs to
40−operate (1 for MHI, 16 for the DMA Bridge).
39+AIC100 implements MSI but does not implement MSI-X. AIC100 prefers 17 MSIs to
40+operate (1 for MHI, 16 for the DMA Bridge). Falling back to 1 MSI is possible in
41+scenarios where reserving 32 MSIs isn't feasible.
4142
4243 As a PCIe device, AIC100 utilizes BARs to provide host interfaces to the device
4344 hardware. AIC100 provides 3, 64-bit BARs.
@@ -220,10 +221,14 @@ of the defined channels, and their uses. · 176 unmodified lines
220221 +----------------+---------+----------+----------------------------------------+
221222 | QAIC_DEBUG | 18 & 19 | AMSS | Not used. |
222223 +----------------+---------+----------+----------------------------------------+
223−| QAIC_TIMESYNC | 20 & 21 | SBL/AMSS | Used to synchronize timestamps in the |
224+| QAIC_TIMESYNC | 20 & 21 | SBL | Used to synchronize timestamps in the |
224225 | | | | device side logs with the host time |
225226 | | | | source. |
226227 +----------------+---------+----------+----------------------------------------+
228+| QAIC_TIMESYNC | 22 & 23 | AMSS | Used to periodically synchronize |
229+| _PERIODIC | | | timestamps in the device side logs with|
230+| | | | the host time source. |
231++----------------+---------+----------+----------------------------------------+
227232
228233 DMA Bridge
229234 ==========
Documentation/accel/qaic/qaic.rst+36−1
@@ -10,6 +10,9 @@ accelerator products. · 9 unmodified lines
1010 Interrupts
1111 ==========
1212
13+IRQ Storm Mitigation
14+--------------------
15+
1316 While the AIC100 DMA Bridge hardware implements an IRQ storm mitigation
1417 mechanism, it is still possible for an IRQ storm to occur. A storm can happen
1518 if the workload is particularly quick, and the host is responsive. If the host
@@ -35,6 +38,26 @@ generates 100k IRQs per second (per /proc/interrupts) is reduced to roughly 64 · 19 unmodified lines
3538 IRQs over 5 minutes while keeping the host system stable, and having the same
3639 workload throughput performance (within run to run noise variation).
3740
41+Single MSI Mode
42+---------------
43+
44+MultiMSI is not well supported on all systems; virtualized ones even less so
45+(circa 2023). Between hypervisors masking the PCIe MSI capability structure to
46+large memory requirements for vIOMMUs (required for supporting MultiMSI), it is
47+useful to be able to fall back to a single MSI when needed.
48+
49+To support this fallback, we allow the case where only one MSI is able to be
50+allocated, and share that one MSI between MHI and the DBCs. The device detects
51+when only one MSI has been configured and directs the interrupts for the DBCs
52+to the interrupt normally used for MHI. Unfortunately this means that the
53+interrupt handlers for every DBC and MHI wake up for every interrupt that
54+arrives; however, the DBC threaded irq handlers only are started when work to be
55+done is detected (MHI will always start its threaded handler).
56+
57+If the DBC is configured to force MSI interrupts, this can circumvent the
58+software IRQ storm mitigation mentioned above. Since the MSI is shared it is
59+never disabled, allowing each new entry to the FIFO to trigger a new interrupt.
60+
3861
3962 Neural Network Control (NNC) Protocol
4063 =====================================
@@ -70,8 +93,15 @@ commands (does not impact QAIC). · 29 unmodified lines
7093 uAPI
7194 ====
7295
96+QAIC creates an accel device per phsyical PCIe device. This accel device exists
97+for as long as the PCIe device is known to Linux.
98+
99+The PCIe device may not be in the state to accept requests from userspace at
100+all times. QAIC will trigger KOBJ_ONLINE/OFFLINE uevents to advertise when the
101+device can accept requests (ONLINE) and when the device is no longer accepting
102+requests (OFFLINE) because of a reset or other state transition.
103+
73104 QAIC defines a number of driver specific IOCTLs as part of the userspace API.
74−This section describes those APIs.
75105
76106 DRM_IOCTL_QAIC_MANAGE
77107 This IOCTL allows userspace to send a NNC request to the QSM. The call will
@@ -178,3 +208,8 @@ overrides this for that call. Default is 5000 (5 seconds). · 100 unmodified lines
178208
179209 Sets the polling interval in microseconds (us) when datapath polling is active.
180210 Takes effect at the next polling interval. Default is 100 (100 us).
211+
212+**timesync_delay_ms (unsigned int)**
213+
214+Sets the time interval in milliseconds (ms) between two consecutive timesync
215+operations. Default is 1000 (1000 ms).
Documentation/arch/loongarch/introduction.rst+2−2
@@ -375,9 +375,9 @@ Developer web site of Loongson and LoongArch (Software and Documentation): · 374 unmodified lines
375375
376376 Documentation of LoongArch ISA:
377377
378− https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-CN.pdf (in Chinese)
378+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-CN.pdf (in Chinese)
379379
380− https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-EN.pdf (in English)
380+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-EN.pdf (in English)
381381
382382 Documentation of LoongArch ELF psABI:
383383
Documentation/arch/x86/boot.rst+1−1
@@ -77,7 +77,7 @@ Protocol 2.14 BURNT BY INCORRECT COMMIT · 76 unmodified lines
7777 Protocol 2.15 (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max.
7878 ============= ============================================================
7979
80−.. note::
80+ .. note::
8181 The protocol version number should be changed only if the setup header
8282 is changed. There is no need to update the version number if boot_params
8383 or kernel_info are changed. Additionally, it is recommended to use
Documentation/core-api/pin_user_pages.rst+2−0
@@ -153,6 +153,8 @@ NOTE: Some pages, such as DAX pages, cannot be pinned with longterm pins. That's · 152 unmodified lines
153153 because DAX pages do not have a separate page cache, and so "pinning" implies
154154 locking down file system blocks, which is not (yet) supported in that way.
155155
156+.. _mmu-notifier-registration-case:
157+
156158 CASE 3: MMU notifier registration, with or without page faulting hardware
157159 -------------------------------------------------------------------------
158160 Device drivers can pin pages via get_user_pages*(), and register for mmu
Documentation/devicetree/bindings/display/bridge/lontium,lt8912b.yaml+21−0
@@ -55,6 +55,27 @@ properties: · 54 unmodified lines
5555 - port@0
5656 - port@1
5757
58+ vcchdmipll-supply:
59+ description: A 1.8V supply that powers the HDMI PLL.
60+
61+ vcchdmitx-supply:
62+ description: A 1.8V supply that powers the HDMI TX part.
63+
64+ vcclvdspll-supply:
65+ description: A 1.8V supply that powers the LVDS PLL.
66+
67+ vcclvdstx-supply:
68+ description: A 1.8V supply that powers the LVDS TX part.
69+
70+ vccmipirx-supply:
71+ description: A 1.8V supply that powers the MIPI RX part.
72+
73+ vccsysclk-supply:
74+ description: A 1.8V supply that powers the SYSCLK.
75+
76+ vdd-supply:
77+ description: A 1.8V supply that powers the digital part.
78+
5879 required:
5980 - compatible
6081 - reg
Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml+3−0
@@ -23,6 +23,7 @@ properties: · 22 unmodified lines
2323 items:
2424 - enum:
2525 - hannstar,hsd060bhw4
26+ - powkiddy,x55-panel
2627 - const: himax,hx8394
2728
2829 reg: true
@@ -31,6 +32,8 @@ properties: · 2 unmodified lines
3132
3233 backlight: true
3334
35+ rotation: true
36+
3437 port: true
3538
3639 vcc-supply:
Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml+1−0
@@ -16,6 +16,7 @@ properties: · 15 unmodified lines
1616 compatible:
1717 items:
1818 - enum:
19+ - ampire,am8001280g
1920 - bananapi,lhr050h41
2021 - feixin,k101-im2byl02
2122 - tdo,tl050hdv35
Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml+1−1
@@ -21,7 +21,7 @@ properties: · 20 unmodified lines
2121 - enum:
2222 - anbernic,rg351v-panel
2323 - anbernic,rg353p-panel
24− - anbernic,rg353v-panel
24+ - powkiddy,rk2023-panel
2525 - const: newvision,nv3051d
2626
2727 reg: true
Documentation/devicetree/bindings/display/panel/panel-simple.yaml+4−0
@@ -73,6 +73,8 @@ properties: · 72 unmodified lines
7373 - auo,t215hvn01
7474 # Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
7575 - avic,tm070ddh03
76+ # BOE BP101WX1-100 10.1" WXGA (1280x800) LVDS panel
77+ - boe,bp101wx1-100
7678 # BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel
7779 - boe,ev121wxm-n10-1850
7880 # BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
@@ -144,6 +146,8 @@ properties: · 65 unmodified lines
144146 - edt,etmv570g2dhu
145147 # E Ink VB3300-KCA
146148 - eink,vb3300-kca
149+ # Evervision Electronics Co. Ltd. VGG644804 5.7" VGA TFT LCD Panel
150+ - evervision,vgg644804
147151 # Evervision Electronics Co. Ltd. VGG804821 5.0" WVGA TFT LCD Panel
148152 - evervision,vgg804821
149153 # Foxlink Group 5" WVGA TFT LCD panel
Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml+14−0
@@ -23,6 +23,7 @@ properties: · 22 unmodified lines
2323 compatible:
2424 enum:
2525 - ti,am625-dss
26+ - ti,am62a7,dss
2627 - ti,am65x-dss
2728
2829 reg:
@@ -87,6 +88,7 @@ properties: · 58 unmodified lines
8788 For AM65x DSS, the OLDI output port node from video port 1.
8889 For AM625 DSS, the internal DPI output port node from video
8990 port 1.
91+ For AM62A7 DSS, the port is tied off inside the SoC.
9092
9193 port@1:
9294 $ref: /schemas/graph.yaml#/properties/port
@@ -108,6 +110,18 @@ properties: · 15 unmodified lines
108110 Input memory (from main memory to dispc) bandwidth limit in
109111 bytes per second
110112
113+allOf:
114+ - if:
115+ properties:
116+ compatible:
117+ contains:
118+ const: ti,am62a7-dss
119+ then:
120+ properties:
121+ ports:
122+ properties:
123+ port@0: false
124+
111125 required:
112126 - compatible
113127 - reg
Documentation/devicetree/bindings/gpu/arm,mali-utgard.yaml+1−0
@@ -29,6 +29,7 @@ properties: · 28 unmodified lines
2929 - allwinner,sun50i-a64-mali
3030 - rockchip,rk3036-mali
3131 - rockchip,rk3066-mali
32+ - rockchip,rk3128-mali
3233 - rockchip,rk3188-mali
3334 - rockchip,rk3228-mali
3435 - samsung,exynos4210-mali
Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml+1−0
@@ -17,6 +17,7 @@ properties: · 16 unmodified lines
1717 compatible:
1818 enum:
1919 - brcm,2711-v3d
20+ - brcm,2712-v3d
2021 - brcm,7268-v3d
2122 - brcm,7278-v3d
2223
Documentation/devicetree/bindings/gpu/img,powervr.yaml+73−0
@@ -0,0 +1,73 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+# Copyright (c) 2023 Imagination Technologies Ltd.
3+%YAML 1.2
4+---
5+$id: http://devicetree.org/schemas/gpu/img,powervr.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
7+
8+title: Imagination Technologies PowerVR and IMG GPU
9+
10+maintainers:
11+ - Frank Binns <frank.binns@imgtec.com>
12+
13+properties:
14+ compatible:
15+ items:
16+ - enum:
17+ - ti,am62-gpu
18+ - const: img,img-axe # IMG AXE GPU model/revision is fully discoverable
19+
20+ reg:
21+ maxItems: 1
22+
23+ clocks:
24+ minItems: 1
25+ maxItems: 3
26+
27+ clock-names:
28+ items:
29+ - const: core
30+ - const: mem
31+ - const: sys
32+ minItems: 1
33+
34+ interrupts:
35+ maxItems: 1
36+
37+ power-domains:
38+ maxItems: 1
39+
40+required:
41+ - compatible
42+ - reg
43+ - clocks
44+ - clock-names
45+ - interrupts
46+
47+additionalProperties: false
48+
49+allOf:
50+ - if:
51+ properties:
52+ compatible:
53+ contains:
54+ const: ti,am62-gpu
55+ then:
56+ properties:
57+ clocks:
58+ maxItems: 1
59+
60+examples:
61+ - |
62+ #include <dt-bindings/interrupt-controller/irq.h>
63+ #include <dt-bindings/interrupt-controller/arm-gic.h>
64+ #include <dt-bindings/soc/ti,sci_pm_domain.h>
65+
66+ gpu@fd00000 {
67+ compatible = "ti,am62-gpu", "img,img-axe";
68+ reg = <0x0fd00000 0x20000>;
69+ clocks = <&k3_clks 187 0>;
70+ clock-names = "core";
71+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
72+ power-domains = <&k3_pds 187 TI_SCI_PD_EXCLUSIVE>;
73+ };
Documentation/devicetree/bindings/net/ethernet-controller.yaml+2−2
@@ -275,12 +275,12 @@ allOf: · 274 unmodified lines
275275 properties:
276276 rx-internal-delay-ps:
277277 description:
278− RGMII Receive Clock Delay defined in pico seconds.This is used for
278+ RGMII Receive Clock Delay defined in pico seconds. This is used for
279279 controllers that have configurable RX internal delays. If this
280280 property is present then the MAC applies the RX delay.
281281 tx-internal-delay-ps:
282282 description:
283− RGMII Transmit Clock Delay defined in pico seconds.This is used for
283+ RGMII Transmit Clock Delay defined in pico seconds. This is used for
284284 controllers that have configurable TX internal delays. If this
285285 property is present then the MAC applies the TX delay.
286286
Documentation/devicetree/bindings/ufs/qcom,ufs.yaml+2−0
@@ -36,6 +36,7 @@ properties: · 35 unmodified lines
3636 - qcom,sm8350-ufshc
3737 - qcom,sm8450-ufshc
3838 - qcom,sm8550-ufshc
39+ - qcom,sm8650-ufshc
3940 - const: qcom,ufshc
4041 - const: jedec,ufs-2.0
4142
@@ -122,6 +123,7 @@ allOf: · 80 unmodified lines
122123 - qcom,sm8350-ufshc
123124 - qcom,sm8450-ufshc
124125 - qcom,sm8550-ufshc
126+ - qcom,sm8650-ufshc
125127 then:
126128 properties:
127129 clocks:
Documentation/devicetree/bindings/usb/microchip,usb5744.yaml+6−1
@@ -36,7 +36,11 @@ properties: · 35 unmodified lines
3636
3737 vdd-supply:
3838 description:
39− VDD power supply to the hub
39+ 3V3 power supply to the hub
40+
41+ vdd2-supply:
42+ description:
43+ 1V2 power supply to the hub
4044
4145 peer-hub:
4246 $ref: /schemas/types.yaml#/definitions/phandle
@@ -62,6 +66,7 @@ allOf: · 19 unmodified lines
6266 properties:
6367 reset-gpios: false
6468 vdd-supply: false
69+ vdd2-supply: false
6570 peer-hub: false
6671 i2c-bus: false
6772 else:
Documentation/devicetree/bindings/usb/qcom,dwc3.yaml+2−2
@@ -521,8 +521,8 @@ examples: · 520 unmodified lines
521521
522522 interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
523523 <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
524− <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
525− <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
524+ <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
525+ <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
526526 interrupt-names = "hs_phy_irq", "ss_phy_irq",
527527 "dm_hs_phy_irq", "dp_hs_phy_irq";
528528
Documentation/devicetree/bindings/usb/usb-hcd.yaml+1−1
@@ -41,7 +41,7 @@ examples: · 40 unmodified lines
4141 - |
4242 usb {
4343 phys = <&usb2_phy1>, <&usb3_phy1>;
44− phy-names = "usb";
44+ phy-names = "usb2", "usb3";
4545 #address-cells = <1>;
4646 #size-cells = <0>;
4747
Documentation/filesystems/erofs.rst+4−0
@@ -91,6 +91,10 @@ compatibility checking tool (fsck.erofs), and a debugging tool (dump.erofs): · 90 unmodified lines
9191
9292 - git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
9393
94+For more information, please also refer to the documentation site:
95+
96+- https://erofs.docs.kernel.org
97+
9498 Bugs and patches are welcome, please kindly help us and send to the following
9599 linux-erofs mailing list:
96100
Documentation/gpu/drivers.rst+2−0
@@ -3,9 +3,11 @@ GPU Driver Documentation · 2 unmodified lines
33 ========================
44
55 .. toctree::
6+ :maxdepth: 3
67
78 amdgpu/index
89 i915
10+ imagination/index
911 mcde
1012 meson
1113 pl111
Documentation/gpu/drm-kms-helpers.rst+6−0
@@ -363,6 +363,12 @@ EDID Helper Functions Reference · 362 unmodified lines
363363 .. kernel-doc:: drivers/gpu/drm/drm_edid.c
364364 :export:
365365
366+.. kernel-doc:: include/drm/drm_eld.h
367+ :internal:
368+
369+.. kernel-doc:: drivers/gpu/drm/drm_eld.c
370+ :export:
371+
366372 SCDC Helper Functions Reference
367373 ===============================
368374
Documentation/gpu/drm-kms.rst+8−0
@@ -548,6 +548,8 @@ Plane Composition Properties · 547 unmodified lines
548548 .. kernel-doc:: drivers/gpu/drm/drm_blend.c
549549 :doc: overview
550550
551+.. _damage_tracking_properties:
552+
551553 Damage Tracking Properties
552554 --------------------------
553555
@@ -579,6 +581,12 @@ Variable Refresh Properties · 25 unmodified lines
579581 .. kernel-doc:: drivers/gpu/drm/drm_connector.c
580582 :doc: Variable refresh properties
581583
584+Cursor Hotspot Properties
585+---------------------------
586+
587+.. kernel-doc:: drivers/gpu/drm/drm_plane.c
588+ :doc: hotspot properties
589+
582590 Existing KMS Properties
583591 -----------------------
584592
Documentation/gpu/drm-mm.rst+10−0
@@ -466,6 +466,8 @@ DRM MM Range Allocator Function References · 465 unmodified lines
466466 .. kernel-doc:: drivers/gpu/drm/drm_mm.c
467467 :export:
468468
469+.. _drm_gpuvm:
470+
469471 DRM GPUVM
470472 =========
471473
@@ -481,6 +483,8 @@ Split and Merge · 9 unmodified lines
481483 .. kernel-doc:: drivers/gpu/drm/drm_gpuvm.c
482484 :doc: Split and Merge
483485
486+.. _drm_gpuvm_locking:
487+
484488 Locking
485489 -------
486490
@@ -552,6 +556,12 @@ Overview · 65 unmodified lines
552556 .. kernel-doc:: drivers/gpu/drm/scheduler/sched_main.c
553557 :doc: Overview
554558
559+Flow Control
560+------------
561+
562+.. kernel-doc:: drivers/gpu/drm/scheduler/sched_main.c
563+ :doc: Flow Control
564+
555565 Scheduler Function References
556566 -----------------------------
557567
Documentation/gpu/drm-vm-bind-locking.rst+582−0
@@ -0,0 +1,582 @@
1+.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2+
3+===============
4+VM_BIND locking
5+===============
6+
7+This document attempts to describe what's needed to get VM_BIND locking right,
8+including the userptr mmu_notifier locking. It also discusses some
9+optimizations to get rid of the looping through of all userptr mappings and
10+external / shared object mappings that is needed in the simplest
11+implementation. In addition, there is a section describing the VM_BIND locking
12+required for implementing recoverable pagefaults.
13+
14+The DRM GPUVM set of helpers
15+============================
16+
17+There is a set of helpers for drivers implementing VM_BIND, and this
18+set of helpers implements much, but not all of the locking described
19+in this document. In particular, it is currently lacking a userptr
20+implementation. This document does not intend to describe the DRM GPUVM
21+implementation in detail, but it is covered in :ref:`its own
22+documentation <drm_gpuvm>`. It is highly recommended for any driver
23+implementing VM_BIND to use the DRM GPUVM helpers and to extend it if
24+common functionality is missing.
25+
26+Nomenclature
27+============
28+
29+* ``gpu_vm``: Abstraction of a virtual GPU address space with
30+ meta-data. Typically one per client (DRM file-private), or one per
31+ execution context.
32+* ``gpu_vma``: Abstraction of a GPU address range within a gpu_vm with
33+ associated meta-data. The backing storage of a gpu_vma can either be
34+ a GEM object or anonymous or page-cache pages mapped also into the CPU
35+ address space for the process.
36+* ``gpu_vm_bo``: Abstracts the association of a GEM object and
37+ a VM. The GEM object maintains a list of gpu_vm_bos, where each gpu_vm_bo
38+ maintains a list of gpu_vmas.
39+* ``userptr gpu_vma or just userptr``: A gpu_vma, whose backing store
40+ is anonymous or page-cache pages as described above.
41+* ``revalidating``: Revalidating a gpu_vma means making the latest version
42+ of the backing store resident and making sure the gpu_vma's
43+ page-table entries point to that backing store.
44+* ``dma_fence``: A struct dma_fence that is similar to a struct completion
45+ and which tracks GPU activity. When the GPU activity is finished,
46+ the dma_fence signals. Please refer to the ``DMA Fences`` section of
47+ the :doc:`dma-buf doc </driver-api/dma-buf>`.
48+* ``dma_resv``: A struct dma_resv (a.k.a reservation object) that is used
49+ to track GPU activity in the form of multiple dma_fences on a
50+ gpu_vm or a GEM object. The dma_resv contains an array / list
51+ of dma_fences and a lock that needs to be held when adding
52+ additional dma_fences to the dma_resv. The lock is of a type that
53+ allows deadlock-safe locking of multiple dma_resvs in arbitrary
54+ order. Please refer to the ``Reservation Objects`` section of the
55+ :doc:`dma-buf doc </driver-api/dma-buf>`.
56+* ``exec function``: An exec function is a function that revalidates all
57+ affected gpu_vmas, submits a GPU command batch and registers the
58+ dma_fence representing the GPU command's activity with all affected
59+ dma_resvs. For completeness, although not covered by this document,
60+ it's worth mentioning that an exec function may also be the
61+ revalidation worker that is used by some drivers in compute /
62+ long-running mode.
63+* ``local object``: A GEM object which is only mapped within a
64+ single VM. Local GEM objects share the gpu_vm's dma_resv.
65+* ``external object``: a.k.a shared object: A GEM object which may be shared
66+ by multiple gpu_vms and whose backing storage may be shared with
67+ other drivers.
68+
69+Locks and locking order
70+=======================
71+
72+One of the benefits of VM_BIND is that local GEM objects share the gpu_vm's
73+dma_resv object and hence the dma_resv lock. So, even with a huge
74+number of local GEM objects, only one lock is needed to make the exec
75+sequence atomic.
76+
77+The following locks and locking orders are used:
78+
79+* The ``gpu_vm->lock`` (optionally an rwsem). Protects the gpu_vm's
80+ data structure keeping track of gpu_vmas. It can also protect the
81+ gpu_vm's list of userptr gpu_vmas. With a CPU mm analogy this would
82+ correspond to the mmap_lock. An rwsem allows several readers to walk
83+ the VM tree concurrently, but the benefit of that concurrency most
84+ likely varies from driver to driver.
85+* The ``userptr_seqlock``. This lock is taken in read mode for each
86+ userptr gpu_vma on the gpu_vm's userptr list, and in write mode during mmu
87+ notifier invalidation. This is not a real seqlock but described in
88+ ``mm/mmu_notifier.c`` as a "Collision-retry read-side/write-side
89+ 'lock' a lot like a seqcount. However this allows multiple
90+ write-sides to hold it at once...". The read side critical section
91+ is enclosed by ``mmu_interval_read_begin() /
92+ mmu_interval_read_retry()`` with ``mmu_interval_read_begin()``
93+ sleeping if the write side is held.
94+ The write side is held by the core mm while calling mmu interval
95+ invalidation notifiers.
96+* The ``gpu_vm->resv`` lock. Protects the gpu_vm's list of gpu_vmas needing
97+ rebinding, as well as the residency state of all the gpu_vm's local
98+ GEM objects.
99+ Furthermore, it typically protects the gpu_vm's list of evicted and
100+ external GEM objects.
101+* The ``gpu_vm->userptr_notifier_lock``. This is an rwsem that is
102+ taken in read mode during exec and write mode during a mmu notifier
103+ invalidation. The userptr notifier lock is per gpu_vm.
104+* The ``gem_object->gpuva_lock`` This lock protects the GEM object's
105+ list of gpu_vm_bos. This is usually the same lock as the GEM
106+ object's dma_resv, but some drivers protects this list differently,
107+ see below.
108+* The ``gpu_vm list spinlocks``. With some implementations they are needed
109+ to be able to update the gpu_vm evicted- and external object
110+ list. For those implementations, the spinlocks are grabbed when the
111+ lists are manipulated. However, to avoid locking order violations
112+ with the dma_resv locks, a special scheme is needed when iterating
113+ over the lists.
114+
115+.. _gpu_vma lifetime:
116+
117+Protection and lifetime of gpu_vm_bos and gpu_vmas
118+==================================================
119+
120+The GEM object's list of gpu_vm_bos, and the gpu_vm_bo's list of gpu_vmas
121+is protected by the ``gem_object->gpuva_lock``, which is typically the
122+same as the GEM object's dma_resv, but if the driver
123+needs to access these lists from within a dma_fence signalling
124+critical section, it can instead choose to protect it with a
125+separate lock, which can be locked from within the dma_fence signalling
126+critical section. Such drivers then need to pay additional attention
127+to what locks need to be taken from within the loop when iterating
128+over the gpu_vm_bo and gpu_vma lists to avoid locking-order violations.
129+
130+The DRM GPUVM set of helpers provide lockdep asserts that this lock is
131+held in relevant situations and also provides a means of making itself
132+aware of which lock is actually used: :c:func:`drm_gem_gpuva_set_lock`.
133+
134+Each gpu_vm_bo holds a reference counted pointer to the underlying GEM
135+object, and each gpu_vma holds a reference counted pointer to the
136+gpu_vm_bo. When iterating over the GEM object's list of gpu_vm_bos and
137+over the gpu_vm_bo's list of gpu_vmas, the ``gem_object->gpuva_lock`` must
138+not be dropped, otherwise, gpu_vmas attached to a gpu_vm_bo may
139+disappear without notice since those are not reference-counted. A
140+driver may implement its own scheme to allow this at the expense of
141+additional complexity, but this is outside the scope of this document.
142+
143+In the DRM GPUVM implementation, each gpu_vm_bo and each gpu_vma
144+holds a reference count on the gpu_vm itself. Due to this, and to avoid circular
145+reference counting, cleanup of the gpu_vm's gpu_vmas must not be done from the
146+gpu_vm's destructor. Drivers typically implements a gpu_vm close
147+function for this cleanup. The gpu_vm close function will abort gpu
148+execution using this VM, unmap all gpu_vmas and release page-table memory.
149+
150+Revalidation and eviction of local objects
151+==========================================
152+
153+Note that in all the code examples given below we use simplified
154+pseudo-code. In particular, the dma_resv deadlock avoidance algorithm
155+as well as reserving memory for dma_resv fences is left out.
156+
157+Revalidation
158+____________
159+With VM_BIND, all local objects need to be resident when the gpu is
160+executing using the gpu_vm, and the objects need to have valid
161+gpu_vmas set up pointing to them. Typically, each gpu command buffer
162+submission is therefore preceded with a re-validation section:
163+
164+.. code-block:: C
165+
166+ dma_resv_lock(gpu_vm->resv);
167+
168+ // Validation section starts here.
169+ for_each_gpu_vm_bo_on_evict_list(&gpu_vm->evict_list, &gpu_vm_bo) {
170+ validate_gem_bo(&gpu_vm_bo->gem_bo);
171+
172+ // The following list iteration needs the Gem object's
173+ // dma_resv to be held (it protects the gpu_vm_bo's list of
174+ // gpu_vmas, but since local gem objects share the gpu_vm's
175+ // dma_resv, it is already held at this point.
176+ for_each_gpu_vma_of_gpu_vm_bo(&gpu_vm_bo, &gpu_vma)
177+ move_gpu_vma_to_rebind_list(&gpu_vma, &gpu_vm->rebind_list);
178+ }
179+
180+ for_each_gpu_vma_on_rebind_list(&gpu vm->rebind_list, &gpu_vma) {
181+ rebind_gpu_vma(&gpu_vma);
182+ remove_gpu_vma_from_rebind_list(&gpu_vma);
183+ }
184+ // Validation section ends here, and job submission starts.
185+
186+ add_dependencies(&gpu_job, &gpu_vm->resv);
187+ job_dma_fence = gpu_submit(&gpu_job));
188+
189+ add_dma_fence(job_dma_fence, &gpu_vm->resv);
190+ dma_resv_unlock(gpu_vm->resv);
191+
192+The reason for having a separate gpu_vm rebind list is that there
193+might be userptr gpu_vmas that are not mapping a buffer object that
194+also need rebinding.
195+
196+Eviction
197+________
198+
199+Eviction of one of these local objects will then look similar to the
200+following:
201+
202+.. code-block:: C
203+
204+ obj = get_object_from_lru();
205+
206+ dma_resv_lock(obj->resv);
207+ for_each_gpu_vm_bo_of_obj(obj, &gpu_vm_bo);
208+ add_gpu_vm_bo_to_evict_list(&gpu_vm_bo, &gpu_vm->evict_list);
209+
210+ add_dependencies(&eviction_job, &obj->resv);
211+ job_dma_fence = gpu_submit(&eviction_job);
212+ add_dma_fence(&obj->resv, job_dma_fence);
213+
214+ dma_resv_unlock(&obj->resv);
215+ put_object(obj);
216+
217+Note that since the object is local to the gpu_vm, it will share the gpu_vm's
218+dma_resv lock such that ``obj->resv == gpu_vm->resv``.
219+The gpu_vm_bos marked for eviction are put on the gpu_vm's evict list,
220+which is protected by ``gpu_vm->resv``. During eviction all local
221+objects have their dma_resv locked and, due to the above equality, also
222+the gpu_vm's dma_resv protecting the gpu_vm's evict list is locked.
223+
224+With VM_BIND, gpu_vmas don't need to be unbound before eviction,
225+since the driver must ensure that the eviction blit or copy will wait
226+for GPU idle or depend on all previous GPU activity. Furthermore, any
227+subsequent attempt by the GPU to access freed memory through the
228+gpu_vma will be preceded by a new exec function, with a revalidation
229+section which will make sure all gpu_vmas are rebound. The eviction
230+code holding the object's dma_resv while revalidating will ensure a
231+new exec function may not race with the eviction.
232+
233+A driver can be implemented in such a way that, on each exec function,
234+only a subset of vmas are selected for rebind. In this case, all vmas that are
235+*not* selected for rebind must be unbound before the exec
236+function workload is submitted.
237+
238+Locking with external buffer objects
239+====================================
240+
241+Since external buffer objects may be shared by multiple gpu_vm's they
242+can't share their reservation object with a single gpu_vm. Instead
243+they need to have a reservation object of their own. The external
244+objects bound to a gpu_vm using one or many gpu_vmas are therefore put on a
245+per-gpu_vm list which is protected by the gpu_vm's dma_resv lock or
246+one of the :ref:`gpu_vm list spinlocks <Spinlock iteration>`. Once
247+the gpu_vm's reservation object is locked, it is safe to traverse the
248+external object list and lock the dma_resvs of all external
249+objects. However, if instead a list spinlock is used, a more elaborate
250+iteration scheme needs to be used.
251+
252+At eviction time, the gpu_vm_bos of *all* the gpu_vms an external
253+object is bound to need to be put on their gpu_vm's evict list.
254+However, when evicting an external object, the dma_resvs of the
255+gpu_vms the object is bound to are typically not held. Only
256+the object's private dma_resv can be guaranteed to be held. If there
257+is a ww_acquire context at hand at eviction time we could grab those
258+dma_resvs but that could cause expensive ww_mutex rollbacks. A simple
259+option is to just mark the gpu_vm_bos of the evicted gem object with
260+an ``evicted`` bool that is inspected before the next time the
261+corresponding gpu_vm evicted list needs to be traversed. For example, when
262+traversing the list of external objects and locking them. At that time,
263+both the gpu_vm's dma_resv and the object's dma_resv is held, and the
264+gpu_vm_bo marked evicted, can then be added to the gpu_vm's list of
265+evicted gpu_vm_bos. The ``evicted`` bool is formally protected by the
266+object's dma_resv.
267+
268+The exec function becomes
269+
270+.. code-block:: C
271+
272+ dma_resv_lock(gpu_vm->resv);
273+
274+ // External object list is protected by the gpu_vm->resv lock.
275+ for_each_gpu_vm_bo_on_extobj_list(gpu_vm, &gpu_vm_bo) {
276+ dma_resv_lock(gpu_vm_bo.gem_obj->resv);
277+ if (gpu_vm_bo_marked_evicted(&gpu_vm_bo))
278+ add_gpu_vm_bo_to_evict_list(&gpu_vm_bo, &gpu_vm->evict_list);
279+ }
280+
281+ for_each_gpu_vm_bo_on_evict_list(&gpu_vm->evict_list, &gpu_vm_bo) {
282+ validate_gem_bo(&gpu_vm_bo->gem_bo);
283+
284+ for_each_gpu_vma_of_gpu_vm_bo(&gpu_vm_bo, &gpu_vma)
285+ move_gpu_vma_to_rebind_list(&gpu_vma, &gpu_vm->rebind_list);
286+ }
287+
288+ for_each_gpu_vma_on_rebind_list(&gpu vm->rebind_list, &gpu_vma) {
289+ rebind_gpu_vma(&gpu_vma);
290+ remove_gpu_vma_from_rebind_list(&gpu_vma);
291+ }
292+
293+ add_dependencies(&gpu_job, &gpu_vm->resv);
294+ job_dma_fence = gpu_submit(&gpu_job));
295+
296+ add_dma_fence(job_dma_fence, &gpu_vm->resv);
297+ for_each_external_obj(gpu_vm, &obj)
298+ add_dma_fence(job_dma_fence, &obj->resv);
299+ dma_resv_unlock_all_resv_locks();
300+
301+And the corresponding shared-object aware eviction would look like:
302+
303+.. code-block:: C
304+
305+ obj = get_object_from_lru();
306+
307+ dma_resv_lock(obj->resv);
308+ for_each_gpu_vm_bo_of_obj(obj, &gpu_vm_bo)
309+ if (object_is_vm_local(obj))
310+ add_gpu_vm_bo_to_evict_list(&gpu_vm_bo, &gpu_vm->evict_list);
311+ else
312+ mark_gpu_vm_bo_evicted(&gpu_vm_bo);
313+
314+ add_dependencies(&eviction_job, &obj->resv);
315+ job_dma_fence = gpu_submit(&eviction_job);
316+ add_dma_fence(&obj->resv, job_dma_fence);
317+
318+ dma_resv_unlock(&obj->resv);
319+ put_object(obj);
320+
321+.. _Spinlock iteration:
322+
323+Accessing the gpu_vm's lists without the dma_resv lock held
324+===========================================================
325+
326+Some drivers will hold the gpu_vm's dma_resv lock when accessing the
327+gpu_vm's evict list and external objects lists. However, there are
328+drivers that need to access these lists without the dma_resv lock
329+held, for example due to asynchronous state updates from within the
330+dma_fence signalling critical path. In such cases, a spinlock can be
331+used to protect manipulation of the lists. However, since higher level
332+sleeping locks need to be taken for each list item while iterating
333+over the lists, the items already iterated over need to be
334+temporarily moved to a private list and the spinlock released
335+while processing each item:
336+
337+.. code block:: C
338+
339+ struct list_head still_in_list;
340+
341+ INIT_LIST_HEAD(&still_in_list);
342+
343+ spin_lock(&gpu_vm->list_lock);
344+ do {
345+ struct list_head *entry = list_first_entry_or_null(&gpu_vm->list, head);
346+
347+ if (!entry)
348+ break;
349+
350+ list_move_tail(&entry->head, &still_in_list);
351+ list_entry_get_unless_zero(entry);
352+ spin_unlock(&gpu_vm->list_lock);
353+
354+ process(entry);
355+
356+ spin_lock(&gpu_vm->list_lock);
357+ list_entry_put(entry);
358+ } while (true);
359+
360+ list_splice_tail(&still_in_list, &gpu_vm->list);
361+ spin_unlock(&gpu_vm->list_lock);
362+
363+Due to the additional locking and atomic operations, drivers that *can*
364+avoid accessing the gpu_vm's list outside of the dma_resv lock
365+might want to avoid also this iteration scheme. Particularly, if the
366+driver anticipates a large number of list items. For lists where the
367+anticipated number of list items is small, where list iteration doesn't
368+happen very often or if there is a significant additional cost
369+associated with each iteration, the atomic operation overhead
370+associated with this type of iteration is, most likely, negligible. Note that
371+if this scheme is used, it is necessary to make sure this list
372+iteration is protected by an outer level lock or semaphore, since list
373+items are temporarily pulled off the list while iterating, and it is
374+also worth mentioning that the local list ``still_in_list`` should
375+also be considered protected by the ``gpu_vm->list_lock``, and it is
376+thus possible that items can be removed also from the local list
377+concurrently with list iteration.
378+
379+Please refer to the :ref:`DRM GPUVM locking section
380+<drm_gpuvm_locking>` and its internal
381+:c:func:`get_next_vm_bo_from_list` function.
382+
383+
384+userptr gpu_vmas
385+================
386+
387+A userptr gpu_vma is a gpu_vma that, instead of mapping a buffer object to a
388+GPU virtual address range, directly maps a CPU mm range of anonymous-
389+or file page-cache pages.
390+A very simple approach would be to just pin the pages using
391+pin_user_pages() at bind time and unpin them at unbind time, but this
392+creates a Denial-Of-Service vector since a single user-space process
393+would be able to pin down all of system memory, which is not
394+desirable. (For special use-cases and assuming proper accounting pinning might
395+still be a desirable feature, though). What we need to do in the
396+general case is to obtain a reference to the desired pages, make sure
397+we are notified using a MMU notifier just before the CPU mm unmaps the
398+pages, dirty them if they are not mapped read-only to the GPU, and
399+then drop the reference.
400+When we are notified by the MMU notifier that CPU mm is about to drop the
401+pages, we need to stop GPU access to the pages by waiting for VM idle
402+in the MMU notifier and make sure that before the next time the GPU
403+tries to access whatever is now present in the CPU mm range, we unmap
404+the old pages from the GPU page tables and repeat the process of
405+obtaining new page references. (See the :ref:`notifier example
406+<Invalidation example>` below). Note that when the core mm decides to
407+laundry pages, we get such an unmap MMU notification and can mark the
408+pages dirty again before the next GPU access. We also get similar MMU
409+notifications for NUMA accounting which the GPU driver doesn't really
410+need to care about, but so far it has proven difficult to exclude
411+certain notifications.
412+
413+Using a MMU notifier for device DMA (and other methods) is described in
414+:ref:`the pin_user_pages() documentation <mmu-notifier-registration-case>`.
415+
416+Now, the method of obtaining struct page references using
417+get_user_pages() unfortunately can't be used under a dma_resv lock
418+since that would violate the locking order of the dma_resv lock vs the
419+mmap_lock that is grabbed when resolving a CPU pagefault. This means
420+the gpu_vm's list of userptr gpu_vmas needs to be protected by an
421+outer lock, which in our example below is the ``gpu_vm->lock``.
422+
423+The MMU interval seqlock for a userptr gpu_vma is used in the following
424+way:
425+
426+.. code-block:: C
427+
428+ // Exclusive locking mode here is strictly needed only if there are
429+ // invalidated userptr gpu_vmas present, to avoid concurrent userptr
430+ // revalidations of the same userptr gpu_vma.
431+ down_write(&gpu_vm->lock);
432+ retry:
433+
434+ // Note: mmu_interval_read_begin() blocks until there is no
435+ // invalidation notifier running anymore.
436+ seq = mmu_interval_read_begin(&gpu_vma->userptr_interval);
437+ if (seq != gpu_vma->saved_seq) {
438+ obtain_new_page_pointers(&gpu_vma);
439+ dma_resv_lock(&gpu_vm->resv);
440+ add_gpu_vma_to_revalidate_list(&gpu_vma, &gpu_vm);
441+ dma_resv_unlock(&gpu_vm->resv);
442+ gpu_vma->saved_seq = seq;
443+ }
444+
445+ // The usual revalidation goes here.
446+
447+ // Final userptr sequence validation may not happen before the
448+ // submission dma_fence is added to the gpu_vm's resv, from the POW
449+ // of the MMU invalidation notifier. Hence the
450+ // userptr_notifier_lock that will make them appear atomic.
451+
452+ add_dependencies(&gpu_job, &gpu_vm->resv);
453+ down_read(&gpu_vm->userptr_notifier_lock);
454+ if (mmu_interval_read_retry(&gpu_vma->userptr_interval, gpu_vma->saved_seq)) {
455+ up_read(&gpu_vm->userptr_notifier_lock);
456+ goto retry;
457+ }
458+
459+ job_dma_fence = gpu_submit(&gpu_job));
460+
461+ add_dma_fence(job_dma_fence, &gpu_vm->resv);
462+
463+ for_each_external_obj(gpu_vm, &obj)
464+ add_dma_fence(job_dma_fence, &obj->resv);
465+
466+ dma_resv_unlock_all_resv_locks();
467+ up_read(&gpu_vm->userptr_notifier_lock);
468+ up_write(&gpu_vm->lock);
469+
470+The code between ``mmu_interval_read_begin()`` and the
471+``mmu_interval_read_retry()`` marks the read side critical section of
472+what we call the ``userptr_seqlock``. In reality, the gpu_vm's userptr
473+gpu_vma list is looped through, and the check is done for *all* of its
474+userptr gpu_vmas, although we only show a single one here.
475+
476+The userptr gpu_vma MMU invalidation notifier might be called from
477+reclaim context and, again, to avoid locking order violations, we can't
478+take any dma_resv lock nor the gpu_vm->lock from within it.
479+
480+.. _Invalidation example:
481+.. code-block:: C
482+
483+ bool gpu_vma_userptr_invalidate(userptr_interval, cur_seq)
484+ {
485+ // Make sure the exec function either sees the new sequence
486+ // and backs off or we wait for the dma-fence:
487+
488+ down_write(&gpu_vm->userptr_notifier_lock);
489+ mmu_interval_set_seq(userptr_interval, cur_seq);
490+ up_write(&gpu_vm->userptr_notifier_lock);
491+
492+ // At this point, the exec function can't succeed in
493+ // submitting a new job, because cur_seq is an invalid
494+ // sequence number and will always cause a retry. When all
495+ // invalidation callbacks, the mmu notifier core will flip
496+ // the sequence number to a valid one. However we need to
497+ // stop gpu access to the old pages here.
498+
499+ dma_resv_wait_timeout(&gpu_vm->resv, DMA_RESV_USAGE_BOOKKEEP,
500+ false, MAX_SCHEDULE_TIMEOUT);
501+ return true;
502+ }
503+
504+When this invalidation notifier returns, the GPU can no longer be
505+accessing the old pages of the userptr gpu_vma and needs to redo the
506+page-binding before a new GPU submission can succeed.
507+
508+Efficient userptr gpu_vma exec_function iteration
509+_________________________________________________
510+
511+If the gpu_vm's list of userptr gpu_vmas becomes large, it's
512+inefficient to iterate through the complete lists of userptrs on each
513+exec function to check whether each userptr gpu_vma's saved
514+sequence number is stale. A solution to this is to put all
515+*invalidated* userptr gpu_vmas on a separate gpu_vm list and
516+only check the gpu_vmas present on this list on each exec
517+function. This list will then lend itself very-well to the spinlock
518+locking scheme that is
519+:ref:`described in the spinlock iteration section <Spinlock iteration>`, since
520+in the mmu notifier, where we add the invalidated gpu_vmas to the
521+list, it's not possible to take any outer locks like the
522+``gpu_vm->lock`` or the ``gpu_vm->resv`` lock. Note that the
523+``gpu_vm->lock`` still needs to be taken while iterating to ensure the list is
524+complete, as also mentioned in that section.
525+
526+If using an invalidated userptr list like this, the retry check in the
527+exec function trivially becomes a check for invalidated list empty.
528+
529+Locking at bind and unbind time
530+===============================
531+
532+At bind time, assuming a GEM object backed gpu_vma, each
533+gpu_vma needs to be associated with a gpu_vm_bo and that
534+gpu_vm_bo in turn needs to be added to the GEM object's
535+gpu_vm_bo list, and possibly to the gpu_vm's external object
536+list. This is referred to as *linking* the gpu_vma, and typically
537+requires that the ``gpu_vm->lock`` and the ``gem_object->gpuva_lock``
538+are held. When unlinking a gpu_vma the same locks should be held,
539+and that ensures that when iterating over ``gpu_vmas`, either under
540+the ``gpu_vm->resv`` or the GEM object's dma_resv, that the gpu_vmas
541+stay alive as long as the lock under which we iterate is not released. For
542+userptr gpu_vmas it's similarly required that during vma destroy, the
543+outer ``gpu_vm->lock`` is held, since otherwise when iterating over
544+the invalidated userptr list as described in the previous section,
545+there is nothing keeping those userptr gpu_vmas alive.
546+
547+Locking for recoverable page-fault page-table updates
548+=====================================================
549+
550+There are two important things we need to ensure with locking for
551+recoverable page-faults:
552+
553+* At the time we return pages back to the system / allocator for
554+ reuse, there should be no remaining GPU mappings and any GPU TLB
555+ must have been flushed.
556+* The unmapping and mapping of a gpu_vma must not race.
557+
558+Since the unmapping (or zapping) of GPU ptes is typically taking place
559+where it is hard or even impossible to take any outer level locks we
560+must either introduce a new lock that is held at both mapping and
561+unmapping time, or look at the locks we do hold at unmapping time and
562+make sure that they are held also at mapping time. For userptr
563+gpu_vmas, the ``userptr_seqlock`` is held in write mode in the mmu
564+invalidation notifier where zapping happens. Hence, if the
565+``userptr_seqlock`` as well as the ``gpu_vm->userptr_notifier_lock``
566+is held in read mode during mapping, it will not race with the
567+zapping. For GEM object backed gpu_vmas, zapping will take place under
568+the GEM object's dma_resv and ensuring that the dma_resv is held also
569+when populating the page-tables for any gpu_vma pointing to the GEM
570+object, will similarly ensure we are race-free.
571+
572+If any part of the mapping is performed asynchronously
573+under a dma-fence with these locks released, the zapping will need to
574+wait for that dma-fence to signal under the relevant lock before
575+starting to modify the page-table.
576+
577+Since modifying the
578+page-table structure in a way that frees up page-table memory
579+might also require outer level locks, the zapping of GPU ptes
580+typically focuses only on zeroing page-table or page-directory entries
581+and flushing TLB, whereas freeing of page-table memory is deferred to
582+unbind or rebind time.
Documentation/gpu/imagination/index.rst+13−0
@@ -0,0 +1,13 @@
1+=======================================
2+drm/imagination PowerVR Graphics Driver
3+=======================================
4+
5+.. kernel-doc:: drivers/gpu/drm/imagination/pvr_drv.c
6+ :doc: PowerVR (Series 6 and later) and IMG Graphics Driver
7+
8+Contents
9+========
10+.. toctree::
11+ :maxdepth: 2
12+
13+ uapi
Documentation/gpu/imagination/uapi.rst+171−0
@@ -0,0 +1,171 @@
1+====
2+UAPI
3+====
4+The sources associated with this section can be found in ``pvr_drm.h``.
5+
6+.. kernel-doc:: include/uapi/drm/pvr_drm.h
7+ :doc: PowerVR UAPI
8+
9+OBJECT ARRAYS
10+=============
11+.. kernel-doc:: include/uapi/drm/pvr_drm.h
12+ :identifiers: drm_pvr_obj_array
13+
14+.. kernel-doc:: include/uapi/drm/pvr_drm.h
15+ :identifiers: DRM_PVR_OBJ_ARRAY
16+
17+IOCTLS
18+======
19+.. kernel-doc:: include/uapi/drm/pvr_drm.h
20+ :doc: PowerVR IOCTL interface
21+
22+.. kernel-doc:: include/uapi/drm/pvr_drm.h
23+ :identifiers: PVR_IOCTL
24+
25+DEV_QUERY
26+---------
27+.. kernel-doc:: include/uapi/drm/pvr_drm.h
28+ :doc: PowerVR IOCTL DEV_QUERY interface
29+
30+.. kernel-doc:: include/uapi/drm/pvr_drm.h
31+ :identifiers: drm_pvr_dev_query
32+
33+.. kernel-doc:: include/uapi/drm/pvr_drm.h
34+ :identifiers: drm_pvr_ioctl_dev_query_args
35+
36+.. kernel-doc:: include/uapi/drm/pvr_drm.h
37+ :identifiers: drm_pvr_dev_query_gpu_info
38+ drm_pvr_dev_query_runtime_info
39+ drm_pvr_dev_query_hwrt_info
40+ drm_pvr_dev_query_quirks
41+ drm_pvr_dev_query_enhancements
42+
43+.. kernel-doc:: include/uapi/drm/pvr_drm.h
44+ :identifiers: drm_pvr_heap_id
45+ drm_pvr_heap
46+ drm_pvr_dev_query_heap_info
47+
48+.. kernel-doc:: include/uapi/drm/pvr_drm.h
49+ :identifiers: drm_pvr_static_data_area_usage
50+ drm_pvr_static_data_area
51+ drm_pvr_dev_query_static_data_areas
52+
53+CREATE_BO
54+---------
55+.. kernel-doc:: include/uapi/drm/pvr_drm.h
56+ :doc: PowerVR IOCTL CREATE_BO interface
57+
58+.. kernel-doc:: include/uapi/drm/pvr_drm.h
59+ :identifiers: drm_pvr_ioctl_create_bo_args
60+
61+.. kernel-doc:: include/uapi/drm/pvr_drm.h
62+ :doc: Flags for CREATE_BO
63+
64+GET_BO_MMAP_OFFSET
65+------------------
66+.. kernel-doc:: include/uapi/drm/pvr_drm.h
67+ :doc: PowerVR IOCTL GET_BO_MMAP_OFFSET interface
68+
69+.. kernel-doc:: include/uapi/drm/pvr_drm.h
70+ :identifiers: drm_pvr_ioctl_get_bo_mmap_offset_args
71+
72+CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT
73+----------------------------------------
74+.. kernel-doc:: include/uapi/drm/pvr_drm.h
75+ :doc: PowerVR IOCTL CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT interfaces
76+
77+.. kernel-doc:: include/uapi/drm/pvr_drm.h
78+ :identifiers: drm_pvr_ioctl_create_vm_context_args
79+ drm_pvr_ioctl_destroy_vm_context_args
80+
81+VM_MAP and VM_UNMAP
82+-------------------
83+.. kernel-doc:: include/uapi/drm/pvr_drm.h
84+ :doc: PowerVR IOCTL VM_MAP and VM_UNMAP interfaces
85+
86+.. kernel-doc:: include/uapi/drm/pvr_drm.h
87+ :identifiers: drm_pvr_ioctl_vm_map_args
88+ drm_pvr_ioctl_vm_unmap_args
89+
90+CREATE_CONTEXT and DESTROY_CONTEXT
91+----------------------------------
92+.. kernel-doc:: include/uapi/drm/pvr_drm.h
93+ :doc: PowerVR IOCTL CREATE_CONTEXT and DESTROY_CONTEXT interfaces
94+
95+.. kernel-doc:: include/uapi/drm/pvr_drm.h
96+ :identifiers: drm_pvr_ioctl_create_context_args
97+
98+.. kernel-doc:: include/uapi/drm/pvr_drm.h
99+ :identifiers: drm_pvr_ctx_priority
100+ drm_pvr_ctx_type
101+ drm_pvr_static_render_context_state
102+ drm_pvr_static_render_context_state_format
103+ drm_pvr_reset_framework
104+ drm_pvr_reset_framework_format
105+
106+.. kernel-doc:: include/uapi/drm/pvr_drm.h
107+ :identifiers: drm_pvr_ioctl_destroy_context_args
108+
109+CREATE_FREE_LIST and DESTROY_FREE_LIST
110+--------------------------------------
111+.. kernel-doc:: include/uapi/drm/pvr_drm.h
112+ :doc: PowerVR IOCTL CREATE_FREE_LIST and DESTROY_FREE_LIST interfaces
113+
114+.. kernel-doc:: include/uapi/drm/pvr_drm.h
115+ :identifiers: drm_pvr_ioctl_create_free_list_args
116+
117+.. kernel-doc:: include/uapi/drm/pvr_drm.h
118+ :identifiers: drm_pvr_ioctl_destroy_free_list_args
119+
120+CREATE_HWRT_DATASET and DESTROY_HWRT_DATASET
121+--------------------------------------------
122+.. kernel-doc:: include/uapi/drm/pvr_drm.h
123+ :doc: PowerVR IOCTL CREATE_HWRT_DATASET and DESTROY_HWRT_DATASET interfaces
124+
125+.. kernel-doc:: include/uapi/drm/pvr_drm.h
126+ :identifiers: drm_pvr_ioctl_create_hwrt_dataset_args
127+
128+.. kernel-doc:: include/uapi/drm/pvr_drm.h
129+ :identifiers: drm_pvr_create_hwrt_geom_data_args
130+ drm_pvr_create_hwrt_rt_data_args
131+
132+.. kernel-doc:: include/uapi/drm/pvr_drm.h
133+ :identifiers: drm_pvr_ioctl_destroy_hwrt_dataset_args
134+
135+SUBMIT_JOBS
136+-----------
137+.. kernel-doc:: include/uapi/drm/pvr_drm.h
138+ :doc: PowerVR IOCTL SUBMIT_JOBS interface
139+
140+.. kernel-doc:: include/uapi/drm/pvr_drm.h
141+ :doc: Flags for the drm_pvr_sync_op object.
142+
143+.. kernel-doc:: include/uapi/drm/pvr_drm.h
144+ :identifiers: drm_pvr_ioctl_submit_jobs_args
145+
146+.. kernel-doc:: include/uapi/drm/pvr_drm.h
147+ :doc: Flags for SUBMIT_JOB ioctl geometry command.
148+
149+.. kernel-doc:: include/uapi/drm/pvr_drm.h
150+ :doc: Flags for SUBMIT_JOB ioctl fragment command.
151+
152+.. kernel-doc:: include/uapi/drm/pvr_drm.h
153+ :doc: Flags for SUBMIT_JOB ioctl compute command.
154+
155+.. kernel-doc:: include/uapi/drm/pvr_drm.h
156+ :doc: Flags for SUBMIT_JOB ioctl transfer command.
157+
158+.. kernel-doc:: include/uapi/drm/pvr_drm.h
159+ :identifiers: drm_pvr_sync_op
160+ drm_pvr_job_type
161+ drm_pvr_hwrt_data_ref
162+ drm_pvr_job
163+
164+Internal notes
165+==============
166+.. kernel-doc:: drivers/gpu/drm/imagination/pvr_device.h
167+ :doc: IOCTL validation helpers
168+
169+.. kernel-doc:: drivers/gpu/drm/imagination/pvr_device.h
170+ :identifiers: PVR_STATIC_ASSERT_64BIT_ALIGNED PVR_IOCTL_UNION_PADDING_CHECK
171+ pvr_ioctl_union_padding_check
Documentation/gpu/implementation_guidelines.rst+1−0
@@ -7,3 +7,4 @@ Misc DRM driver uAPI- and feature implementation guidelines · 6 unmodified lines
77 .. toctree::
88
99 drm-vm-bind-async
10+ drm-vm-bind-locking
Documentation/gpu/rfc/xe.rst+67−65
@@ -70,35 +70,42 @@ When the time comes for Xe, the protection will be lifted on Xe and kept in i915 · 69 unmodified lines
7070 Xe – Pre-Merge Goals - Work-in-Progress
7171 =======================================
7272
73−Drm_scheduler
74−-------------
75−Xe primarily uses Firmware based scheduling (GuC FW). However, it will use
76−drm_scheduler as the scheduler ‘frontend’ for userspace submission in order to
77−resolve syncobj and dma-buf implicit sync dependencies. However, drm_scheduler is
78−not yet prepared to handle the 1-to-1 relationship between drm_gpu_scheduler and
79−drm_sched_entity.
73+Display integration with i915
74+-----------------------------
75+In order to share the display code with the i915 driver so that there is maximum
76+reuse, the i915/display/ code is built twice, once for i915.ko and then for
77+xe.ko. Currently, the i915/display code in Xe tree is polluted with many 'ifdefs'
78+depending on the build target. The goal is to refactor both Xe and i915/display
79+code simultaneously in order to get a clean result before they land upstream, so
80+that display can already be part of the initial pull request towards drm-next.
8081
81−Deeper changes to drm_scheduler should *not* be required to get Xe accepted, but
82−some consensus needs to be reached between Xe and other community drivers that
83−could also benefit from this work, for coupling FW based/assisted submission such
84−as the ARM’s new Mali GPU driver, and others.
82+However, display code should not gate the acceptance of Xe in upstream. Xe
83+patches will be refactored in a way that display code can be removed, if needed,
84+from the first pull request of Xe towards drm-next. The expectation is that when
85+both drivers are part of the drm-tip, the introduction of cleaner patches will be
86+easier and speed up.
8587
86−As a key measurable result, the patch series introducing Xe itself shall not
87−depend on any other patch touching drm_scheduler itself that was not yet merged
88−through drm-misc. This, by itself, already includes the reach of an agreement for
89−uniform 1 to 1 relationship implementation / usage across drivers.
88+Xe – uAPI high level overview
89+=============================
9090
91−ASYNC VM_BIND
92−-------------
93−Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
94−Xe merged, it is mandatory to have a consensus with other drivers and Mesa.
95−It needs to be clear how to handle async VM_BIND and interactions with userspace
96−memory fences. Ideally with helper support so people don't get it wrong in all
97−possible ways.
91+...Warning: To be done in follow up patches after/when/where the main consensus in various items are individually reached.
9892
99−As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of
100−various flavors, error handling and sample API suggestions are documented in
101−:doc:`The ASYNC VM_BIND document </gpu/drm-vm-bind-async>`.
93+Xe – Pre-Merge Goals - Completed
94+================================
95+
96+Drm_exec
97+--------
98+Helper to make dma_resv locking for a big number of buffers is getting removed in
99+the drm_exec series proposed in https://patchwork.freedesktop.org/patch/524376/
100+If that happens, Xe needs to change and incorporate the changes in the driver.
101+The goal is to engage with the Community to understand if the best approach is to
102+move that to the drivers that are using it or if we should keep the helpers in
103+place waiting for Xe to get merged.
104+
105+This item ties into the GPUVA, VM_BIND, and even long-running compute support.
106+
107+As a key measurable result, we need to have a community consensus documented in
108+this document and the Xe driver prepared for the changes, if necessary.
102109
103110 Userptr integration and vm_bind
104111 -------------------------------
@@ -123,10 +130,45 @@ Documentation should include: · 18 unmodified lines
123130
124131 * O(1) complexity under VM_BIND.
125132
133+The document is now included in the drm documentation :doc:`here </gpu/drm-vm-bind-async>`.
134+
126135 Some parts of userptr like mmu_notifiers should become GPUVA or DRM helpers when
127136 the second driver supporting VM_BIND+userptr appears. Details to be defined when
128137 the time comes.
129138
139+The DRM GPUVM helpers do not yet include the userptr parts, but discussions
140+about implementing them are ongoing.
141+
142+ASYNC VM_BIND
143+-------------
144+Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
145+Xe merged, it is mandatory to have a consensus with other drivers and Mesa.
146+It needs to be clear how to handle async VM_BIND and interactions with userspace
147+memory fences. Ideally with helper support so people don't get it wrong in all
148+possible ways.
149+
150+As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of
151+various flavors, error handling and sample API suggestions are documented in
152+:doc:`The ASYNC VM_BIND document </gpu/drm-vm-bind-async>`.
153+
154+Drm_scheduler
155+-------------
156+Xe primarily uses Firmware based scheduling (GuC FW). However, it will use
157+drm_scheduler as the scheduler ‘frontend’ for userspace submission in order to
158+resolve syncobj and dma-buf implicit sync dependencies. However, drm_scheduler is
159+not yet prepared to handle the 1-to-1 relationship between drm_gpu_scheduler and
160+drm_sched_entity.
161+
162+Deeper changes to drm_scheduler should *not* be required to get Xe accepted, but
163+some consensus needs to be reached between Xe and other community drivers that
164+could also benefit from this work, for coupling FW based/assisted submission such
165+as the ARM’s new Mali GPU driver, and others.
166+
167+As a key measurable result, the patch series introducing Xe itself shall not
168+depend on any other patch touching drm_scheduler itself that was not yet merged
169+through drm-misc. This, by itself, already includes the reach of an agreement for
170+uniform 1 to 1 relationship implementation / usage across drivers.
171+
130172 Long running compute: minimal data structure/scaffolding
131173 --------------------------------------------------------
132174 The generic scheduler code needs to include the handling of endless compute
@@ -139,46 +181,6 @@ this minimal drm/scheduler work, if needed, merged to drm-misc in a way that any · 6 unmodified lines
139181 drm driver, including Xe, could re-use and add their own individual needs on top
140182 in a next stage. However, this should not block the initial merge.
141183
142−This is a non-blocker item since the driver without the support for the long
143−running compute enabled is not a showstopper.
144−
145−Display integration with i915
146−-----------------------------
147−In order to share the display code with the i915 driver so that there is maximum
148−reuse, the i915/display/ code is built twice, once for i915.ko and then for
149−xe.ko. Currently, the i915/display code in Xe tree is polluted with many 'ifdefs'
150−depending on the build target. The goal is to refactor both Xe and i915/display
151−code simultaneously in order to get a clean result before they land upstream, so
152−that display can already be part of the initial pull request towards drm-next.
153−
154−However, display code should not gate the acceptance of Xe in upstream. Xe
155−patches will be refactored in a way that display code can be removed, if needed,
156−from the first pull request of Xe towards drm-next. The expectation is that when
157−both drivers are part of the drm-tip, the introduction of cleaner patches will be
158−easier and speed up.
159−
160−Drm_exec
161−--------
162−Helper to make dma_resv locking for a big number of buffers is getting removed in
163−the drm_exec series proposed in https://patchwork.freedesktop.org/patch/524376/
164−If that happens, Xe needs to change and incorporate the changes in the driver.
165−The goal is to engage with the Community to understand if the best approach is to
166−move that to the drivers that are using it or if we should keep the helpers in
167−place waiting for Xe to get merged.
168−
169−This item ties into the GPUVA, VM_BIND, and even long-running compute support.
170−
171−As a key measurable result, we need to have a community consensus documented in
172−this document and the Xe driver prepared for the changes, if necessary.
173−
174−Xe – uAPI high level overview
175−=============================
176−
177−...Warning: To be done in follow up patches after/when/where the main consensus in various items are individually reached.
178−
179−Xe – Pre-Merge Goals - Completed
180−================================
181−
182184 Dev_coredump
183185 ------------
184186
Documentation/gpu/todo.rst+43−4
@@ -337,8 +337,8 @@ connector register/unregister fixes · 336 unmodified lines
337337
338338 Level: Intermediate
339339
340−Remove load/unload callbacks from all non-DRIVER_LEGACY drivers
341−---------------------------------------------------------------
340+Remove load/unload callbacks
341+----------------------------
342342
343343 The load/unload callbacks in struct &drm_driver are very much midlayers, plus
344344 for historical reasons they get the ordering wrong (and we can't fix that)
@@ -347,8 +347,7 @@ between setting up the &drm_driver structure and calling drm_dev_register(). · 2 unmodified lines
347347 - Rework drivers to no longer use the load/unload callbacks, directly coding the
348348 load/unload sequence into the driver's probe function.
349349
350−- Once all non-DRIVER_LEGACY drivers are converted, disallow the load/unload
351− callbacks for all modern drivers.
350+- Once all drivers are converted, remove the load/unload callbacks.
352351
353352 Contact: Daniel Vetter
354353
@@ -621,6 +620,23 @@ Contact: Javier Martinez Canillas <javierm@redhat.com> · 266 unmodified lines
621620
622621 Level: Intermediate
623622
623+Clean up and document former selftests suites
624+---------------------------------------------
625+
626+Some KUnit test suites (drm_buddy, drm_cmdline_parser, drm_damage_helper,
627+drm_format, drm_framebuffer, drm_dp_mst_helper, drm_mm, drm_plane_helper and
628+drm_rect) are former selftests suites that have been converted over when KUnit
629+was first introduced.
630+
631+These suites were fairly undocumented, and with different goals than what unit
632+tests can be. Trying to identify what each test in these suites actually test
633+for, whether that makes sense for a unit test, and either remove it if it
634+doesn't or document it if it does would be of great help.
635+
636+Contact: Maxime Ripard <mripard@kernel.org>
637+
638+Level: Intermediate
639+
624640 Enable trinity for DRM
625641 ----------------------
626642
@@ -765,6 +781,29 @@ Contact: Hans de Goede · 138 unmodified lines
765781
766782 Level: Advanced
767783
784+Buffer age or other damage accumulation algorithm for buffer damage
785+===================================================================
786+
787+Drivers that do per-buffer uploads, need a buffer damage handling (rather than
788+frame damage like drivers that do per-plane or per-CRTC uploads), but there is
789+no support to get the buffer age or any other damage accumulation algorithm.
790+
791+For this reason, the damage helpers just fallback to a full plane update if the
792+framebuffer attached to a plane has changed since the last page-flip. Drivers
793+set &drm_plane_state.ignore_damage_clips to true as indication to
794+drm_atomic_helper_damage_iter_init() and drm_atomic_helper_damage_iter_next()
795+helpers that the damage clips should be ignored.
796+
797+This should be improved to get damage tracking properly working on drivers that
798+do per-buffer uploads.
799+
800+More information about damage tracking and references to learning materials can
801+be found in :ref:`damage_tracking_properties`.
802+
803+Contact: Javier Martinez Canillas <javierm@redhat.com>
804+
805+Level: Advanced
806+
768807 Outside DRM
769808 ===========
770809
Documentation/process/maintainer-netdev.rst+17−3
@@ -193,9 +193,23 @@ Review timelines · 192 unmodified lines
193193 Generally speaking, the patches get triaged quickly (in less than
194194 48h). But be patient, if your patch is active in patchwork (i.e. it's
195195 listed on the project's patch list) the chances it was missed are close to zero.
196−Asking the maintainer for status updates on your
197−patch is a good way to ensure your patch is ignored or pushed to the
198−bottom of the priority list.
196+
197+The high volume of development on netdev makes reviewers move on
198+from discussions relatively quickly. New comments and replies
199+are very unlikely to arrive after a week of silence. If a patch
200+is no longer active in patchwork and the thread went idle for more
201+than a week - clarify the next steps and/or post the next version.
202+
203+For RFC postings specifically, if nobody responded in a week - reviewers
204+either missed the posting or have no strong opinions. If the code is ready,
205+repost as a PATCH.
206+
207+Emails saying just "ping" or "bump" are considered rude. If you can't figure
208+out the status of the patch from patchwork or where the discussion has
209+landed - describe your best guess and ask if it's correct. For example::
210+
211+ I don't understand what the next steps are. Person X seems to be unhappy
212+ with A, should I do B and repost the patches?
199213
200214 .. _Changes requested:
201215
Documentation/translations/zh_CN/arch/loongarch/introduction.rst+2−2
@@ -338,9 +338,9 @@ Loongson与LoongArch的开发者网站(软件与文档资源): · 337 unmodified lines
338338
339339 LoongArch指令集架构的文档:
340340
341− https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-CN.pdf (中文版)
341+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-CN.pdf (中文版)
342342
343− https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-EN.pdf (英文版)
343+ https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-EN.pdf (英文版)
344344
345345 LoongArch的ELF psABI文档:
346346
MAINTAINERS+48−16
@@ -6503,8 +6503,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc · 6502 unmodified lines
65036503 F: drivers/gpu/drm/sun4i/sun8i*
65046504
65056505 DRM DRIVER FOR ARM PL111 CLCD
6506−M: Emma Anholt <emma@anholt.net>
6507−S: Supported
6506+S: Orphan
65086507 T: git git://anongit.freedesktop.org/drm/drm-misc
65096508 F: drivers/gpu/drm/pl111/
65106509
@@ -6619,8 +6618,7 @@ F: Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml · 108 unmodified lines
66196618 F: drivers/gpu/drm/panel/panel-himax-hx8394.c
66206619
66216620 DRM DRIVER FOR HX8357D PANELS
6622−M: Emma Anholt <emma@anholt.net>
6623−S: Maintained
6621+S: Orphan
66246622 T: git git://anongit.freedesktop.org/drm/drm-misc
66256623 F: Documentation/devicetree/bindings/display/himax,hx8357d.txt
66266624 F: drivers/gpu/drm/tiny/hx8357d.c
@@ -7213,8 +7211,8 @@ F: Documentation/devicetree/bindings/display/ti/ · 586 unmodified lines
72137211 F: drivers/gpu/drm/omapdrm/
72147212
72157213 DRM DRIVERS FOR V3D
7216−M: Emma Anholt <emma@anholt.net>
72177214 M: Melissa Wen <mwen@igalia.com>
7215+M: Maíra Canal <mcanal@igalia.com>
72187216 S: Supported
72197217 T: git git://anongit.freedesktop.org/drm/drm-misc
72207218 F: Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
@@ -7222,7 +7220,6 @@ F: drivers/gpu/drm/v3d/ · 1 unmodified line
72227220 F: include/uapi/drm/v3d_drm.h
72237221
72247222 DRM DRIVERS FOR VC4
7225−M: Emma Anholt <emma@anholt.net>
72267223 M: Maxime Ripard <mripard@kernel.org>
72277224 S: Supported
72287225 T: git git://github.com/anholt/linux
@@ -7855,6 +7852,7 @@ R: Yue Hu <huyue2@coolpad.com> · 626 unmodified lines
78557852 R: Jeffle Xu <jefflexu@linux.alibaba.com>
78567853 L: linux-erofs@lists.ozlabs.org
78577854 S: Maintained
7855+W: https://erofs.docs.kernel.org
78587856 T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
78597857 F: Documentation/ABI/testing/sysfs-fs-erofs
78607858 F: Documentation/filesystems/erofs.rst
@@ -8950,7 +8948,6 @@ S: Maintained · 1089 unmodified lines
89508948 F: scripts/get_maintainer.pl
89518949
89528950 GFS2 FILE SYSTEM
8953−M: Bob Peterson <rpeterso@redhat.com>
89548951 M: Andreas Gruenbacher <agruenba@redhat.com>
89558952 L: gfs2@lists.linux.dev
89568953 S: Supported
@@ -10395,6 +10392,17 @@ IMGTEC IR DECODER DRIVER · 1438 unmodified lines
1039510392 S: Orphan
1039610393 F: drivers/media/rc/img-ir/
1039710394
10395+IMGTEC POWERVR DRM DRIVER
10396+M: Frank Binns <frank.binns@imgtec.com>
10397+M: Donald Robson <donald.robson@imgtec.com>
10398+M: Matt Coster <matt.coster@imgtec.com>
10399+S: Supported
10400+T: git git://anongit.freedesktop.org/drm/drm-misc
10401+F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
10402+F: Documentation/gpu/imagination/
10403+F: drivers/gpu/drm/imagination/
10404+F: include/uapi/drm/pvr_drm.h
10405+
1039810406 IMON SOUNDGRAPH USB IR RECEIVER
1039910407 M: Sean Young <sean@mess.org>
1040010408 L: linux-media@vger.kernel.org
@@ -10639,9 +10647,9 @@ M: Rodrigo Vivi <rodrigo.vivi@intel.com> · 238 unmodified lines
1063910647 M: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
1064010648 L: intel-gfx@lists.freedesktop.org
1064110649 S: Supported
10642−W: https://01.org/linuxgraphics/
10650+W: https://drm.pages.freedesktop.org/intel-docs/
1064310651 Q: http://patchwork.freedesktop.org/project/intel-gfx/
10644−B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs
10652+B: https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html
1064510653 C: irc://irc.oftc.net/intel-gfx
1064610654 T: git git://anongit.freedesktop.org/drm-intel
1064710655 F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
@@ -11025,7 +11033,6 @@ F: drivers/net/wireless/intel/iwlwifi/ · 377 unmodified lines
1102511033
1102611034 INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER
1102711035 M: Jithu Joseph <jithu.joseph@intel.com>
11028−R: Maurice Ma <maurice.ma@intel.com>
1102911036 S: Maintained
1103011037 W: https://slimbootloader.github.io/security/firmware-update.html
1103111038 F: drivers/platform/x86/intel/wmi/sbl-fw-update.c
@@ -13779,7 +13786,6 @@ F: drivers/net/ethernet/mellanox/mlxfw/ · 2747 unmodified lines
1377913786 MELLANOX HARDWARE PLATFORM SUPPORT
1378013787 M: Hans de Goede <hdegoede@redhat.com>
1378113788 M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
13782−M: Mark Gross <markgross@kernel.org>
1378313789 M: Vadim Pasternak <vadimp@nvidia.com>
1378413790 L: platform-driver-x86@vger.kernel.org
1378513791 S: Supported
@@ -14388,7 +14394,6 @@ F: drivers/platform/surface/surface_gpe.c · 602 unmodified lines
1438814394 MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT
1438914395 M: Hans de Goede <hdegoede@redhat.com>
1439014396 M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
14391−M: Mark Gross <markgross@kernel.org>
1439214397 M: Maximilian Luz <luzmaximilian@gmail.com>
1439314398 L: platform-driver-x86@vger.kernel.org
1439414399 S: Maintained
@@ -14995,6 +15000,7 @@ M: Jakub Kicinski <kuba@kernel.org> · 600 unmodified lines
1499515000 M: Paolo Abeni <pabeni@redhat.com>
1499615001 L: netdev@vger.kernel.org
1499715002 S: Maintained
15003+P: Documentation/process/maintainer-netdev.rst
1499815004 Q: https://patchwork.kernel.org/project/netdevbpf/list/
1499915005 T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
1500015006 T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
@@ -15046,6 +15052,7 @@ M: Jakub Kicinski <kuba@kernel.org> · 45 unmodified lines
1504615052 M: Paolo Abeni <pabeni@redhat.com>
1504715053 L: netdev@vger.kernel.org
1504815054 S: Maintained
15055+P: Documentation/process/maintainer-netdev.rst
1504915056 Q: https://patchwork.kernel.org/project/netdevbpf/list/
1505015057 B: mailto:netdev@vger.kernel.org
1505115058 T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
@@ -15056,6 +15063,7 @@ F: Documentation/networking/ · 4 unmodified lines
1505615063 F: Documentation/process/maintainer-netdev.rst
1505715064 F: Documentation/userspace-api/netlink/
1505815065 F: include/linux/in.h
15066+F: include/linux/indirect_call_wrapper.h
1505915067 F: include/linux/net.h
1506015068 F: include/linux/netdevice.h
1506115069 F: include/net/
@@ -21769,7 +21777,9 @@ F: Documentation/devicetree/bindings/counter/ti-eqep.yaml · 6707 unmodified lines
2176921777 F: drivers/counter/ti-eqep.c
2177021778
2177121779 TI ETHERNET SWITCH DRIVER (CPSW)
21772−R: Grygorii Strashko <grygorii.strashko@ti.com>
21780+R: Siddharth Vadapalli <s-vadapalli@ti.com>
21781+R: Ravi Gunasekaran <r-gunasekaran@ti.com>
21782+R: Roger Quadros <rogerq@kernel.org>
2177321783 L: linux-omap@vger.kernel.org
2177421784 L: netdev@vger.kernel.org
2177521785 S: Maintained
@@ -21793,6 +21803,15 @@ F: Documentation/devicetree/bindings/media/i2c/ti,ds90* · 17 unmodified lines
2179321803 F: drivers/media/i2c/ds90*
2179421804 F: include/media/i2c/ds90*
2179521805
21806+TI ICSSG ETHERNET DRIVER (ICSSG)
21807+R: MD Danish Anwar <danishanwar@ti.com>
21808+R: Roger Quadros <rogerq@kernel.org>
21809+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
21810+L: netdev@vger.kernel.org
21811+S: Maintained
21812+F: Documentation/devicetree/bindings/net/ti,icss*.yaml
21813+F: drivers/net/ethernet/ti/icssg/*
21814+
2179621815 TI J721E CSI2RX DRIVER
2179721816 M: Jai Luthra <j-luthra@ti.com>
2179821817 L: linux-media@vger.kernel.org
@@ -22068,6 +22087,7 @@ F: drivers/watchdog/tqmx86_wdt.c · 269 unmodified lines
2206822087 TRACING
2206922088 M: Steven Rostedt <rostedt@goodmis.org>
2207022089 M: Masami Hiramatsu <mhiramat@kernel.org>
22090+R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2207122091 L: linux-kernel@vger.kernel.org
2207222092 L: linux-trace-kernel@vger.kernel.org
2207322093 S: Maintained
@@ -23654,7 +23674,6 @@ F: drivers/platform/x86/x86-android-tablets/ · 1580 unmodified lines
2365423674 X86 PLATFORM DRIVERS
2365523675 M: Hans de Goede <hdegoede@redhat.com>
2365623676 M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
23657−M: Mark Gross <markgross@kernel.org>
2365823677 L: platform-driver-x86@vger.kernel.org
2365923678 S: Maintained
2366023679 Q: https://patchwork.kernel.org/project/platform-driver-x86/list/
@@ -23692,6 +23711,20 @@ F: arch/x86/kernel/dumpstack.c · 31 unmodified lines
2369223711 F: arch/x86/kernel/stacktrace.c
2369323712 F: arch/x86/kernel/unwind_*.c
2369423713
23714+X86 TRUST DOMAIN EXTENSIONS (TDX)
23715+M: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
23716+R: Dave Hansen <dave.hansen@linux.intel.com>
23717+L: x86@kernel.org
23718+L: linux-coco@lists.linux.dev
23719+S: Supported
23720+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/tdx
23721+F: arch/x86/boot/compressed/tdx*
23722+F: arch/x86/coco/tdx/
23723+F: arch/x86/include/asm/shared/tdx.h
23724+F: arch/x86/include/asm/tdx.h
23725+F: arch/x86/virt/vmx/tdx/
23726+F: drivers/virt/coco/tdx-guest
23727+
2369523728 X86 VDSO
2369623729 M: Andy Lutomirski <luto@kernel.org>
2369723730 L: linux-kernel@vger.kernel.org
@@ -23872,8 +23905,7 @@ T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git · 174 unmodified lines
2387223905 P: Documentation/filesystems/xfs-maintainer-entry-profile.rst
2387323906 F: Documentation/ABI/testing/sysfs-fs-xfs
2387423907 F: Documentation/admin-guide/xfs.rst
23875−F: Documentation/filesystems/xfs-delayed-logging-design.rst
23876−F: Documentation/filesystems/xfs-self-describing-metadata.rst
23908+F: Documentation/filesystems/xfs-*
2387723909 F: fs/xfs/
2387823910 F: include/uapi/linux/dqblk_xfs.h
2387923911 F: include/uapi/linux/fsmap.h
Makefile+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22 VERSION = 6
33 PATCHLEVEL = 7
44 SUBLEVEL = 0
5−EXTRAVERSION = -rc1
5+EXTRAVERSION = -rc3
66 NAME = Hurr durr I'ma ninja sloth
77
88 # *DOCUMENTATION*
arch/arm/xen/enlighten.c+2−1
@@ -484,7 +484,8 @@ static int __init xen_guest_init(void) · 483 unmodified lines
484484 * for secondary CPUs as they are brought up.
485485 * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
486486 */
487− xen_vcpu_info = alloc_percpu(struct vcpu_info);
487+ xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
488+ 1 << fls(sizeof(struct vcpu_info) - 1));
488489 if (xen_vcpu_info == NULL)
489490 return -ENOMEM;
490491
arch/arm64/Makefile+1−1
@@ -158,7 +158,7 @@ endif · 157 unmodified lines
158158
159159 all: $(notdir $(KBUILD_IMAGE))
160160
161−
161+vmlinuz.efi: Image
162162 Image vmlinuz.efi: vmlinux
163163 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
164164
arch/arm64/include/asm/setup.h+15−2
@@ -21,9 +21,22 @@ static inline bool arch_parse_debug_rodata(char *arg) · 20 unmodified lines
2121 extern bool rodata_enabled;
2222 extern bool rodata_full;
2323
24− if (arg && !strcmp(arg, "full")) {
24+ if (!arg)
25+ return false;
26+
27+ if (!strcmp(arg, "full")) {
28+ rodata_enabled = rodata_full = true;
29+ return true;
30+ }
31+
32+ if (!strcmp(arg, "off")) {
33+ rodata_enabled = rodata_full = false;
34+ return true;
35+ }
36+
37+ if (!strcmp(arg, "on")) {
2538 rodata_enabled = true;
26− rodata_full = true;
39+ rodata_full = false;
2740 return true;
2841 }
2942
arch/arm64/mm/pageattr.c+3−4
@@ -29,8 +29,8 @@ bool can_set_direct_map(void) · 28 unmodified lines
2929 *
3030 * KFENCE pool requires page-granular mapping if initialized late.
3131 */
32− return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() ||
33− arm64_kfence_can_set_direct_map();
32+ return rodata_full || debug_pagealloc_enabled() ||
33+ arm64_kfence_can_set_direct_map();
3434 }
3535
3636 static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
@@ -105,8 +105,7 @@ static int change_memory_common(unsigned long addr, int numpages, · 68 unmodified lines
105105 * If we are manipulating read-only permissions, apply the same
106106 * change to the linear mapping of the pages that back this VM area.
107107 */
108− if (rodata_enabled &&
109− rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
108+ if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
110109 pgprot_val(clear_mask) == PTE_RDONLY)) {
111110 for (i = 0; i < area->nr_pages; i++) {
112111 __change_memory_common((u64)page_address(area->pages[i]),
arch/loongarch/Makefile+3−0
@@ -68,6 +68,7 @@ LDFLAGS_vmlinux += -static -n -nostdlib · 67 unmodified lines
6868 ifdef CONFIG_AS_HAS_EXPLICIT_RELOCS
6969 cflags-y += $(call cc-option,-mexplicit-relocs)
7070 KBUILD_CFLAGS_KERNEL += $(call cc-option,-mdirect-extern-access)
71+KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdirect-access-external-data)
7172 KBUILD_AFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
7273 KBUILD_CFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
7374 KBUILD_AFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
@@ -142,6 +143,8 @@ vdso-install-y += arch/loongarch/vdso/vdso.so.dbg · 68 unmodified lines
142143
143144 all: $(notdir $(KBUILD_IMAGE))
144145
146+vmlinuz.efi: vmlinux.efi
147+
145148 vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux
146149 $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@
147150
arch/loongarch/include/asm/asmmacro.h+1−2
@@ -609,8 +609,7 @@ · 608 unmodified lines
609609 lu32i.d \reg, 0
610610 lu52i.d \reg, \reg, 0
611611 .pushsection ".la_abs", "aw", %progbits
612− 768:
613− .dword 768b-766b
612+ .dword 766b
614613 .dword \sym
615614 .popsection
616615 #endif
arch/loongarch/include/asm/percpu.h+5−6
@@ -40,13 +40,13 @@ static __always_inline unsigned long __percpu_##op(void *ptr, \ · 39 unmodified lines
4040 switch (size) { \
4141 case 4: \
4242 __asm__ __volatile__( \
43− "am"#asm_op".w" " %[ret], %[val], %[ptr] \n" \
43+ "am"#asm_op".w" " %[ret], %[val], %[ptr] \n" \
4444 : [ret] "=&r" (ret), [ptr] "+ZB"(*(u32 *)ptr) \
4545 : [val] "r" (val)); \
4646 break; \
4747 case 8: \
4848 __asm__ __volatile__( \
49− "am"#asm_op".d" " %[ret], %[val], %[ptr] \n" \
49+ "am"#asm_op".d" " %[ret], %[val], %[ptr] \n" \
5050 : [ret] "=&r" (ret), [ptr] "+ZB"(*(u64 *)ptr) \
5151 : [val] "r" (val)); \
5252 break; \
@@ -63,7 +63,7 @@ PERCPU_OP(and, and, &) · 10 unmodified lines
6363 PERCPU_OP(or, or, |)
6464 #undef PERCPU_OP
6565
66−static __always_inline unsigned long __percpu_read(void *ptr, int size)
66+static __always_inline unsigned long __percpu_read(void __percpu *ptr, int size)
6767 {
6868 unsigned long ret;
6969
@@ -100,7 +100,7 @@ static __always_inline unsigned long __percpu_read(void *ptr, int size) · 30 unmodified lines
100100 return ret;
101101 }
102102
103−static __always_inline void __percpu_write(void *ptr, unsigned long val, int size)
103+static __always_inline void __percpu_write(void __percpu *ptr, unsigned long val, int size)
104104 {
105105 switch (size) {
106106 case 1:
@@ -132,8 +132,7 @@ static __always_inline void __percpu_write(void *ptr, unsigned long val, int siz · 25 unmodified lines
132132 }
133133 }
134134
135−static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val,
136− int size)
135+static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val, int size)
137136 {
138137 switch (size) {
139138 case 1:
arch/loongarch/include/asm/setup.h+1−1
@@ -25,7 +25,7 @@ extern void set_merr_handler(unsigned long offset, void *addr, unsigned long len · 24 unmodified lines
2525 #ifdef CONFIG_RELOCATABLE
2626
2727 struct rela_la_abs {
28− long offset;
28+ long pc;
2929 long symvalue;
3030 };
3131
arch/loongarch/kernel/relocate.c+9−1
@@ -52,7 +52,7 @@ static inline void __init relocate_absolute(long random_offset) · 51 unmodified lines
5252 for (p = begin; (void *)p < end; p++) {
5353 long v = p->symvalue;
5454 uint32_t lu12iw, ori, lu32id, lu52id;
55− union loongarch_instruction *insn = (void *)p - p->offset;
55+ union loongarch_instruction *insn = (void *)p->pc;
5656
5757 lu12iw = (v >> 12) & 0xfffff;
5858 ori = v & 0xfff;
@@ -102,6 +102,14 @@ static inline __init unsigned long get_random_boot(void) · 43 unmodified lines
102102 return hash;
103103 }
104104
105+static int __init nokaslr(char *p)
106+{
107+ pr_info("KASLR is disabled.\n");
108+
109+ return 0; /* Print a notice and silence the boot warning */
110+}
111+early_param("nokaslr", nokaslr);
112+
105113 static inline __init bool kaslr_disabled(void)
106114 {
107115 char *str;
arch/loongarch/kernel/time.c+9−14
@@ -58,14 +58,16 @@ static int constant_set_state_oneshot(struct clock_event_device *evt) · 57 unmodified lines
5858 return 0;
5959 }
6060
61−static int constant_set_state_oneshot_stopped(struct clock_event_device *evt)
61+static int constant_set_state_periodic(struct clock_event_device *evt)
6262 {
63+ unsigned long period;
6364 unsigned long timer_config;
6465
6566 raw_spin_lock(&state_lock);
6667
67− timer_config = csr_read64(LOONGARCH_CSR_TCFG);
68− timer_config &= ~CSR_TCFG_EN;
68+ period = const_clock_freq / HZ;
69+ timer_config = period & CSR_TCFG_VAL;
70+ timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
6971 csr_write64(timer_config, LOONGARCH_CSR_TCFG);
7072
7173 raw_spin_unlock(&state_lock);
@@ -73,16 +75,14 @@ static int constant_set_state_oneshot_stopped(struct clock_event_device *evt) · 1 unmodified line
7375 return 0;
7476 }
7577
76−static int constant_set_state_periodic(struct clock_event_device *evt)
78+static int constant_set_state_shutdown(struct clock_event_device *evt)
7779 {
78− unsigned long period;
7980 unsigned long timer_config;
8081
8182 raw_spin_lock(&state_lock);
8283
83− period = const_clock_freq / HZ;
84− timer_config = period & CSR_TCFG_VAL;
85− timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
84+ timer_config = csr_read64(LOONGARCH_CSR_TCFG);
85+ timer_config &= ~CSR_TCFG_EN;
8686 csr_write64(timer_config, LOONGARCH_CSR_TCFG);
8787
8888 raw_spin_unlock(&state_lock);
@@ -90,11 +90,6 @@ static int constant_set_state_periodic(struct clock_event_device *evt) · 1 unmodified line
9090 return 0;
9191 }
9292
93−static int constant_set_state_shutdown(struct clock_event_device *evt)
94−{
95− return 0;
96−}
97−
9893 static int constant_timer_next_event(unsigned long delta, struct clock_event_device *evt)
9994 {
10095 unsigned long timer_config;
@@ -161,7 +156,7 @@ int constant_clockevent_init(void) · 60 unmodified lines
161156 cd->rating = 320;
162157 cd->cpumask = cpumask_of(cpu);
163158 cd->set_state_oneshot = constant_set_state_oneshot;
164− cd->set_state_oneshot_stopped = constant_set_state_oneshot_stopped;
159+ cd->set_state_oneshot_stopped = constant_set_state_shutdown;
165160 cd->set_state_periodic = constant_set_state_periodic;
166161 cd->set_state_shutdown = constant_set_state_shutdown;
167162 cd->set_next_event = constant_timer_next_event;
arch/loongarch/mm/pgtable.c+2−2
@@ -13,13 +13,13 @@ struct page *dmw_virt_to_page(unsigned long kaddr) · 12 unmodified lines
1313 {
1414 return pfn_to_page(virt_to_pfn(kaddr));
1515 }
16−EXPORT_SYMBOL_GPL(dmw_virt_to_page);
16+EXPORT_SYMBOL(dmw_virt_to_page);
1717
1818 struct page *tlb_virt_to_page(unsigned long kaddr)
1919 {
2020 return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr)));
2121 }
22−EXPORT_SYMBOL_GPL(tlb_virt_to_page);
22+EXPORT_SYMBOL(tlb_virt_to_page);
2323
2424 pgd_t *pgd_alloc(struct mm_struct *mm)
2525 {
arch/parisc/Kconfig+8−5
@@ -115,9 +115,12 @@ config ARCH_HAS_ILOG2_U64 · 114 unmodified lines
115115 default n
116116
117117 config GENERIC_BUG
118− bool
119− default y
118+ def_bool y
120119 depends on BUG
120+ select GENERIC_BUG_RELATIVE_POINTERS if 64BIT
121+
122+config GENERIC_BUG_RELATIVE_POINTERS
123+ bool
121124
122125 config GENERIC_HWEIGHT
123126 bool
@@ -140,11 +143,11 @@ config ARCH_MMAP_RND_COMPAT_BITS_MIN · 16 unmodified lines
140143 default 8
141144
142145 config ARCH_MMAP_RND_BITS_MAX
143− default 24 if 64BIT
144− default 17
146+ default 18 if 64BIT
147+ default 13
145148
146149 config ARCH_MMAP_RND_COMPAT_BITS_MAX
147− default 17
150+ default 13
148151
149152 # unless you want to implement ACPI on PA-RISC ... ;-)
150153 config PM
arch/parisc/include/asm/alternative.h+6−3
@@ -34,7 +34,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, · 33 unmodified lines
3434
3535 /* Alternative SMP implementation. */
3636 #define ALTERNATIVE(cond, replacement) "!0:" \
37− ".section .altinstructions, \"aw\" !" \
37+ ".section .altinstructions, \"a\" !" \
38+ ".align 4 !" \
3839 ".word (0b-4-.) !" \
3940 ".hword 1, " __stringify(cond) " !" \
4041 ".word " __stringify(replacement) " !" \
@@ -44,7 +45,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, · 3 unmodified lines
4445
4546 /* to replace one single instructions by a new instruction */
4647 #define ALTERNATIVE(from, to, cond, replacement)\
47− .section .altinstructions, "aw" ! \
48+ .section .altinstructions, "a" ! \
49+ .align 4 ! \
4850 .word (from - .) ! \
4951 .hword (to - from)/4, cond ! \
5052 .word replacement ! \
@@ -52,7 +54,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, · 1 unmodified line
5254
5355 /* to replace multiple instructions by new code */
5456 #define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\
55− .section .altinstructions, "aw" ! \
57+ .section .altinstructions, "a" ! \
58+ .align 4 ! \
5659 .word (from - .) ! \
5760 .hword -num_instructions, cond ! \
5861 .word (new_instr_ptr - .) ! \
arch/parisc/include/asm/assembly.h+1−0
@@ -574,6 +574,7 @@ · 573 unmodified lines
574574 */
575575 #define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \
576576 .section __ex_table,"aw" ! \
577+ .align 4 ! \
577578 .word (fault_addr - .), (except_addr - .) ! \
578579 .previous
579580
arch/parisc/include/asm/bug.h+22−16
@@ -17,24 +17,27 @@ · 16 unmodified lines
1717 #define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff"
1818 #define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */
1919
20−#if defined(CONFIG_64BIT)
21−#define ASM_WORD_INSN ".dword\t"
20+#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
21+# define __BUG_REL(val) ".word " __stringify(val) " - ."
2222 #else
23−#define ASM_WORD_INSN ".word\t"
23+# define __BUG_REL(val) ".word " __stringify(val)
2424 #endif
2525
26+
2627 #ifdef CONFIG_DEBUG_BUGVERBOSE
2728 #define BUG() \
2829 do { \
2930 asm volatile("\n" \
3031 "1:\t" PARISC_BUG_BREAK_ASM "\n" \
31− "\t.pushsection __bug_table,\"aw\"\n" \
32− "2:\t" ASM_WORD_INSN "1b, %c0\n" \
33− "\t.short %c1, %c2\n" \
34− "\t.org 2b+%c3\n" \
32+ "\t.pushsection __bug_table,\"a\"\n" \
33+ "\t.align 4\n" \
34+ "2:\t" __BUG_REL(1b) "\n" \
35+ "\t" __BUG_REL(%c0) "\n" \
36+ "\t.short %1, %2\n" \
37+ "\t.blockz %3-2*4-2*2\n" \
3538 "\t.popsection" \
3639 : : "i" (__FILE__), "i" (__LINE__), \
37− "i" (0), "i" (sizeof(struct bug_entry)) ); \
40+ "i" (0), "i" (sizeof(struct bug_entry)) ); \
3841 unreachable(); \
3942 } while(0)
4043
@@ -51,10 +54,12 @@ · 10 unmodified lines
5154 do { \
5255 asm volatile("\n" \
5356 "1:\t" PARISC_BUG_BREAK_ASM "\n" \
54− "\t.pushsection __bug_table,\"aw\"\n" \
55− "2:\t" ASM_WORD_INSN "1b, %c0\n" \
56− "\t.short %c1, %c2\n" \
57− "\t.org 2b+%c3\n" \
57+ "\t.pushsection __bug_table,\"a\"\n" \
58+ "\t.align 4\n" \
59+ "2:\t" __BUG_REL(1b) "\n" \
60+ "\t" __BUG_REL(%c0) "\n" \
61+ "\t.short %1, %2\n" \
62+ "\t.blockz %3-2*4-2*2\n" \
5863 "\t.popsection" \
5964 : : "i" (__FILE__), "i" (__LINE__), \
6065 "i" (BUGFLAG_WARNING|(flags)), \
@@ -65,10 +70,11 @@ · 4 unmodified lines
6570 do { \
6671 asm volatile("\n" \
6772 "1:\t" PARISC_BUG_BREAK_ASM "\n" \
68− "\t.pushsection __bug_table,\"aw\"\n" \
69− "2:\t" ASM_WORD_INSN "1b\n" \
70− "\t.short %c0\n" \
71− "\t.org 2b+%c1\n" \
73+ "\t.pushsection __bug_table,\"a\"\n" \
74+ "\t.align %2\n" \
75+ "2:\t" __BUG_REL(1b) "\n" \
76+ "\t.short %0\n" \
77+ "\t.blockz %1-4-2\n" \
7278 "\t.popsection" \
7379 : : "i" (BUGFLAG_WARNING|(flags)), \
7480 "i" (sizeof(struct bug_entry)) ); \
arch/parisc/include/asm/elf.h+1−9
@@ -349,15 +349,7 @@ struct pt_regs; /* forward declaration... */ · 348 unmodified lines
349349
350350 #define ELF_HWCAP 0
351351
352−/* Masks for stack and mmap randomization */
353−#define BRK_RND_MASK (is_32bit_task() ? 0x07ffUL : 0x3ffffUL)
354−#define MMAP_RND_MASK (is_32bit_task() ? 0x1fffUL : 0x3ffffUL)
355−#define STACK_RND_MASK MMAP_RND_MASK
356−
357−struct mm_struct;
358−extern unsigned long arch_randomize_brk(struct mm_struct *);
359−#define arch_randomize_brk arch_randomize_brk
360−
352+#define STACK_RND_MASK 0x7ff /* 8MB of VA */
361353
362354 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
363355 struct linux_binprm;
arch/parisc/include/asm/jump_label.h+6−2
@@ -15,10 +15,12 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran · 14 unmodified lines
1515 asm_volatile_goto("1:\n\t"
1616 "nop\n\t"
1717 ".pushsection __jump_table, \"aw\"\n\t"
18+ ".align %1\n\t"
1819 ".word 1b - ., %l[l_yes] - .\n\t"
1920 __stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
2021 ".popsection\n\t"
21− : : "i" (&((char *)key)[branch]) : : l_yes);
22+ : : "i" (&((char *)key)[branch]), "i" (sizeof(long))
23+ : : l_yes);
2224
2325 return false;
2426 l_yes:
@@ -30,10 +32,12 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool · 5 unmodified lines
3032 asm_volatile_goto("1:\n\t"
3133 "b,n %l[l_yes]\n\t"
3234 ".pushsection __jump_table, \"aw\"\n\t"
35+ ".align %1\n\t"
3336 ".word 1b - ., %l[l_yes] - .\n\t"
3437 __stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
3538 ".popsection\n\t"
36− : : "i" (&((char *)key)[branch]) : : l_yes);
39+ : : "i" (&((char *)key)[branch]), "i" (sizeof(long))
40+ : : l_yes);
3741
3842 return false;
3943 l_yes:
arch/parisc/include/asm/ldcw.h+1−1
@@ -55,7 +55,7 @@ · 54 unmodified lines
5555 })
5656
5757 #ifdef CONFIG_SMP
58−# define __lock_aligned __section(".data..lock_aligned")
58+# define __lock_aligned __section(".data..lock_aligned") __aligned(16)
5959 #endif
6060
6161 #endif /* __PARISC_LDCW_H */
arch/parisc/include/asm/processor.h+2−0
@@ -47,6 +47,8 @@ · 46 unmodified lines
4747
4848 #ifndef __ASSEMBLY__
4949
50+struct rlimit;
51+unsigned long mmap_upper_limit(struct rlimit *rlim_stack);
5052 unsigned long calc_max_stack_size(unsigned long stack_max);
5153
5254 /*
arch/parisc/include/asm/uaccess.h+1−0
@@ -41,6 +41,7 @@ struct exception_table_entry { · 40 unmodified lines
4141
4242 #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\
4343 ".section __ex_table,\"aw\"\n" \
44+ ".align 4\n" \
4445 ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \
4546 ".previous\n"
4647
arch/parisc/include/uapi/asm/errno.h+0−2
@@ -75,7 +75,6 @@ · 74 unmodified lines
7575
7676 /* We now return you to your regularly scheduled HPUX. */
7777
78−#define ENOSYM 215 /* symbol does not exist in executable */
7978 #define ENOTSOCK 216 /* Socket operation on non-socket */
8079 #define EDESTADDRREQ 217 /* Destination address required */
8180 #define EMSGSIZE 218 /* Message too long */
@@ -101,7 +100,6 @@ · 19 unmodified lines
101100 #define ETIMEDOUT 238 /* Connection timed out */
102101 #define ECONNREFUSED 239 /* Connection refused */
103102 #define EREFUSED ECONNREFUSED /* for HP's NFS apparently */
104−#define EREMOTERELEASE 240 /* Remote peer released connection */
105103 #define EHOSTDOWN 241 /* Host is down */
106104 #define EHOSTUNREACH 242 /* No route to host */
107105
arch/parisc/kernel/processor.c+1−1
@@ -383,7 +383,7 @@ show_cpuinfo (struct seq_file *m, void *v) · 382 unmodified lines
383383 char cpu_name[60], *p;
384384
385385 /* strip PA path from CPU name to not confuse lscpu */
386− strlcpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name));
386+ strscpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name));
387387 p = strrchr(cpu_name, '[');
388388 if (p)
389389 *(--p) = 0;
arch/parisc/kernel/sys_parisc.c+1−1
@@ -77,7 +77,7 @@ unsigned long calc_max_stack_size(unsigned long stack_max) · 76 unmodified lines
7777 * indicating that "current" should be used instead of a passed-in
7878 * value from the exec bprm as done with arch_pick_mmap_layout().
7979 */
80−static unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
80+unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
8181 {
8282 unsigned long stack_base;
8383
arch/parisc/kernel/vmlinux.lds.S+1−0
@@ -130,6 +130,7 @@ SECTIONS · 129 unmodified lines
130130 RO_DATA(8)
131131
132132 /* unwind info */
133+ . = ALIGN(4);
133134 .PARISC.unwind : {
134135 __start___unwind = .;
135136 *(.PARISC.unwind)
arch/s390/include/asm/processor.h+0−1
@@ -228,7 +228,6 @@ typedef struct thread_struct thread_struct; · 227 unmodified lines
228228 execve_tail(); \
229229 } while (0)
230230
231−/* Forward declaration, a strange C thing */
232231 struct task_struct;
233232 struct mm_struct;
234233 struct seq_file;
arch/s390/kernel/ipl.c+1−0
@@ -666,6 +666,7 @@ static int __init ipl_init(void) · 665 unmodified lines
666666 &ipl_ccw_attr_group_lpar);
667667 break;
668668 case IPL_TYPE_ECKD:
669+ case IPL_TYPE_ECKD_DUMP:
669670 rc = sysfs_create_group(&ipl_kset->kobj, &ipl_eckd_attr_group);
670671 break;
671672 case IPL_TYPE_FCP:
arch/s390/kernel/perf_pai_crypto.c+5−6
@@ -279,12 +279,6 @@ static int paicrypt_event_init(struct perf_event *event) · 278 unmodified lines
279279 if (IS_ERR(cpump))
280280 return PTR_ERR(cpump);
281281
282− /* Event initialization sets last_tag to 0. When later on the events
283− * are deleted and re-added, do not reset the event count value to zero.
284− * Events are added, deleted and re-added when 2 or more events
285− * are active at the same time.
286− */
287− event->hw.last_tag = 0;
288282 event->destroy = paicrypt_event_destroy;
289283
290284 if (a->sample_period) {
@@ -318,6 +312,11 @@ static void paicrypt_start(struct perf_event *event, int flags) · 27 unmodified lines
318312 {
319313 u64 sum;
320314
315+ /* Event initialization sets last_tag to 0. When later on the events
316+ * are deleted and re-added, do not reset the event count value to zero.
317+ * Events are added, deleted and re-added when 2 or more events
318+ * are active at the same time.
319+ */
321320 if (!event->hw.last_tag) {
322321 event->hw.last_tag = 1;
323322 sum = paicrypt_getall(event); /* Get current value */
arch/s390/kernel/perf_pai_ext.c+0−1
@@ -260,7 +260,6 @@ static int paiext_event_init(struct perf_event *event) · 259 unmodified lines
260260 rc = paiext_alloc(a, event);
261261 if (rc)
262262 return rc;
263− event->hw.last_tag = 0;
264263 event->destroy = paiext_event_destroy;
265264
266265 if (a->sample_period) {
arch/x86/events/intel/core.c+1−1
@@ -4660,7 +4660,7 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu) · 4659 unmodified lines
46604660 if (pmu->intel_cap.pebs_output_pt_available)
46614661 pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
46624662 else
4663− pmu->pmu.capabilities |= ~PERF_PMU_CAP_AUX_OUTPUT;
4663+ pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT;
46644664
46654665 intel_pmu_check_event_constraints(pmu->event_constraints,
46664666 pmu->num_counters,
arch/x86/hyperv/hv_init.c+21−4
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <linux/io.h>
1616 #include <asm/apic.h>
1717 #include <asm/desc.h>
18+#include <asm/e820/api.h>
1819 #include <asm/sev.h>
1920 #include <asm/ibt.h>
2021 #include <asm/hypervisor.h>
@@ -286,15 +287,31 @@ static int hv_cpu_die(unsigned int cpu) · 265 unmodified lines
286287
287288 static int __init hv_pci_init(void)
288289 {
289− int gen2vm = efi_enabled(EFI_BOOT);
290+ bool gen2vm = efi_enabled(EFI_BOOT);
290291
291292 /*
292− * For Generation-2 VM, we exit from pci_arch_init() by returning 0.
293− * The purpose is to suppress the harmless warning:
293+ * A Generation-2 VM doesn't support legacy PCI/PCIe, so both
294+ * raw_pci_ops and raw_pci_ext_ops are NULL, and pci_subsys_init() ->
295+ * pcibios_init() doesn't call pcibios_resource_survey() ->
296+ * e820__reserve_resources_late(); as a result, any emulated persistent
297+ * memory of E820_TYPE_PRAM (12) via the kernel parameter
298+ * memmap=nn[KMG]!ss is not added into iomem_resource and hence can't be
299+ * detected by register_e820_pmem(). Fix this by directly calling
300+ * e820__reserve_resources_late() here: e820__reserve_resources_late()
301+ * depends on e820__reserve_resources(), which has been called earlier
302+ * from setup_arch(). Note: e820__reserve_resources_late() also adds
303+ * any memory of E820_TYPE_PMEM (7) into iomem_resource, and
304+ * acpi_nfit_register_region() -> acpi_nfit_insert_resource() ->
305+ * region_intersects() returns REGION_INTERSECTS, so the memory of
306+ * E820_TYPE_PMEM won't get added twice.
307+ *
308+ * We return 0 here so that pci_arch_init() won't print the warning:
294309 * "PCI: Fatal: No config space access function found"
295310 */
296− if (gen2vm)
311+ if (gen2vm) {
312+ e820__reserve_resources_late();
297313 return 0;
314+ }
298315
299316 /* For Generation-1 VM, we'll proceed in pci_arch_init(). */
300317 return 1;
arch/x86/include/asm/acpi.h+14−0
@@ -16,6 +16,9 @@ · 15 unmodified lines
1616 #include <asm/x86_init.h>
1717 #include <asm/cpufeature.h>
1818 #include <asm/irq_vectors.h>
19+#include <asm/xen/hypervisor.h>
20+
21+#include <xen/xen.h>
1922
2023 #ifdef CONFIG_ACPI_APEI
2124 # include <asm/pgtable_types.h>
@@ -127,6 +130,17 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap) · 105 unmodified lines
127130 if (!cpu_has(c, X86_FEATURE_MWAIT) ||
128131 boot_option_idle_override == IDLE_NOMWAIT)
129132 *cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH);
133+
134+ if (xen_initial_domain()) {
135+ /*
136+ * When Linux is running as Xen dom0, the hypervisor is the
137+ * entity in charge of the processor power management, and so
138+ * Xen needs to check the OS capabilities reported in the
139+ * processor capabilities buffer matches what the hypervisor
140+ * driver supports.
141+ */
142+ xen_sanitize_proc_cap_bits(cap);
143+ }
130144 }
131145
132146 static inline bool acpi_has_cpu_in_madt(void)
arch/x86/include/asm/xen/hypervisor.h+9−0
@@ -100,4 +100,13 @@ static inline void leave_lazy(enum xen_lazy_mode mode) · 99 unmodified lines
100100
101101 enum xen_lazy_mode xen_get_lazy_mode(void);
102102
103+#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI)
104+void xen_sanitize_proc_cap_bits(uint32_t *buf);
105+#else
106+static inline void xen_sanitize_proc_cap_bits(uint32_t *buf)
107+{
108+ BUG();
109+}
110+#endif
111+
103112 #endif /* _ASM_X86_XEN_HYPERVISOR_H */
arch/x86/kernel/acpi/boot.c+15−19
@@ -63,6 +63,7 @@ int acpi_fix_pin2_polarity __initdata; · 62 unmodified lines
6363
6464 #ifdef CONFIG_X86_LOCAL_APIC
6565 static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
66+static bool has_lapic_cpus __initdata;
6667 static bool acpi_support_online_capable;
6768 #endif
6869
@@ -232,6 +233,14 @@ acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end) · 163 unmodified lines
232233 if (!acpi_is_processor_usable(processor->lapic_flags))
233234 return 0;
234235
236+ /*
237+ * According to https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#processor-local-x2apic-structure
238+ * when MADT provides both valid LAPIC and x2APIC entries, the APIC ID
239+ * in x2APIC must be equal or greater than 0xff.
240+ */
241+ if (has_lapic_cpus && apic_id < 0xff)
242+ return 0;
243+
235244 /*
236245 * We need to register disabled CPU as well to permit
237246 * counting disabled CPUs. This allows us to size
@@ -1114,10 +1123,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void) · 876 unmodified lines
11141123
11151124 static int __init acpi_parse_madt_lapic_entries(void)
11161125 {
1117− int count;
1118− int x2count = 0;
1119− int ret;
1120− struct acpi_subtable_proc madt_proc[2];
1126+ int count, x2count = 0;
11211127
11221128 if (!boot_cpu_has(X86_FEATURE_APIC))
11231129 return -ENODEV;
@@ -1126,21 +1132,11 @@ static int __init acpi_parse_madt_lapic_entries(void) · 2 unmodified lines
11261132 acpi_parse_sapic, MAX_LOCAL_APIC);
11271133
11281134 if (!count) {
1129− memset(madt_proc, 0, sizeof(madt_proc));
1130− madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
1131− madt_proc[0].handler = acpi_parse_lapic;
1132− madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
1133− madt_proc[1].handler = acpi_parse_x2apic;
1134− ret = acpi_table_parse_entries_array(ACPI_SIG_MADT,
1135− sizeof(struct acpi_table_madt),
1136− madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
1137− if (ret < 0) {
1138− pr_err("Error parsing LAPIC/X2APIC entries\n");
1139− return ret;
1140− }
1141−
1142− count = madt_proc[0].count;
1143− x2count = madt_proc[1].count;
1135+ count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
1136+ acpi_parse_lapic, MAX_LOCAL_APIC);
1137+ has_lapic_cpus = count > 0;
1138+ x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
1139+ acpi_parse_x2apic, MAX_LOCAL_APIC);
11441140 }
11451141 if (!count && !x2count) {
11461142 pr_err("No LAPIC entries present\n");
arch/x86/kernel/cpu/microcode/amd.c+11−28
@@ -104,8 +104,6 @@ struct cont_desc { · 103 unmodified lines
104104 size_t size;
105105 };
106106
107−static u32 ucode_new_rev;
108−
109107 /*
110108 * Microcode patch container file is prepended to the initrd in cpio
111109 * format. See Documentation/arch/x86/microcode.rst
@@ -442,12 +440,11 @@ static int __apply_microcode_amd(struct microcode_amd *mc) · 330 unmodified lines
442440 *
443441 * Returns true if container found (sets @desc), false otherwise.
444442 */
445−static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
443+static bool early_apply_microcode(u32 cpuid_1_eax, u32 old_rev, void *ucode, size_t size)
446444 {
447445 struct cont_desc desc = { 0 };
448446 struct microcode_amd *mc;
449447 bool ret = false;
450− u32 rev, dummy;
451448
452449 desc.cpuid_1_eax = cpuid_1_eax;
453450
@@ -457,22 +454,15 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size) · 3 unmodified lines
457454 if (!mc)
458455 return ret;
459456
460− native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
461−
462457 /*
463458 * Allow application of the same revision to pick up SMT-specific
464459 * changes even if the revision of the other SMT thread is already
465460 * up-to-date.
466461 */
467− if (rev > mc->hdr.patch_id)
462+ if (old_rev > mc->hdr.patch_id)
468463 return ret;
469464
470− if (!__apply_microcode_amd(mc)) {
471− ucode_new_rev = mc->hdr.patch_id;
472− ret = true;
473− }
474−
475− return ret;
465+ return !__apply_microcode_amd(mc);
476466 }
477467
478468 static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
@@ -506,9 +496,12 @@ static void __init find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpi · 27 unmodified lines
506496 *ret = cp;
507497 }
508498
509−void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
499+void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_eax)
510500 {
511501 struct cpio_data cp = { };
502+ u32 dummy;
503+
504+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->old_rev, dummy);
512505
513506 /* Needed in load_microcode_amd() */
514507 ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax;
@@ -517,7 +510,8 @@ void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax) · 2 unmodified lines
517510 if (!(cp.data && cp.size))
518511 return;
519512
520− early_apply_microcode(cpuid_1_eax, cp.data, cp.size);
513+ if (early_apply_microcode(cpuid_1_eax, ed->old_rev, cp.data, cp.size))
514+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy);
521515 }
522516
523517 static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
@@ -625,10 +619,8 @@ void reload_ucode_amd(unsigned int cpu) · 101 unmodified lines
625619 rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
626620
627621 if (rev < mc->hdr.patch_id) {
628− if (!__apply_microcode_amd(mc)) {
629− ucode_new_rev = mc->hdr.patch_id;
630− pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
631− }
622+ if (!__apply_microcode_amd(mc))
623+ pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id);
632624 }
633625 }
634626
@@ -649,8 +641,6 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) · 14 unmodified lines
649641 if (p && (p->patch_id == csig->rev))
650642 uci->mc = p->data;
651643
652− pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
653−
654644 return 0;
655645 }
656646
@@ -691,8 +681,6 @@ static enum ucode_state apply_microcode_amd(int cpu) · 34 unmodified lines
691681 rev = mc_amd->hdr.patch_id;
692682 ret = UCODE_UPDATED;
693683
694− pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev);
695−
696684 out:
697685 uci->cpu_sig.rev = rev;
698686 c->microcode = rev;
@@ -935,11 +923,6 @@ struct microcode_ops * __init init_amd_microcode(void) · 236 unmodified lines
935923 pr_warn("AMD CPU family 0x%x not supported\n", c->x86);
936924 return NULL;
937925 }
938−
939− if (ucode_new_rev)
940− pr_info_once("microcode updated early to new patch_level=0x%08x\n",
941− ucode_new_rev);
942−
943926 return &microcode_amd_ops;
944927 }
945928
arch/x86/kernel/cpu/microcode/core.c+9−6
@@ -41,8 +41,6 @@ · 40 unmodified lines
4141
4242 #include "internal.h"
4343
44−#define DRIVER_VERSION "2.2"
45−
4644 static struct microcode_ops *microcode_ops;
4745 bool dis_ucode_ldr = true;
4846
@@ -77,6 +75,8 @@ static u32 final_levels[] = { · 28 unmodified lines
7775 0, /* T-101 terminator */
7876 };
7977
78+struct early_load_data early_data;
79+
8080 /*
8181 * Check the current patch level on this CPU.
8282 *
@@ -155,9 +155,9 @@ void __init load_ucode_bsp(void) · 72 unmodified lines
155155 return;
156156
157157 if (intel)
158− load_ucode_intel_bsp();
158+ load_ucode_intel_bsp(&early_data);
159159 else
160− load_ucode_amd_bsp(cpuid_1_eax);
160+ load_ucode_amd_bsp(&early_data, cpuid_1_eax);
161161 }
162162
163163 void load_ucode_ap(void)
@@ -828,6 +828,11 @@ static int __init microcode_init(void) · 664 unmodified lines
828828 if (!microcode_ops)
829829 return -ENODEV;
830830
831+ pr_info_once("Current revision: 0x%08x\n", (early_data.new_rev ?: early_data.old_rev));
832+
833+ if (early_data.new_rev)
834+ pr_info_once("Updated early from: 0x%08x\n", early_data.old_rev);
835+
831836 microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0);
832837 if (IS_ERR(microcode_pdev))
833838 return PTR_ERR(microcode_pdev);
@@ -846,8 +851,6 @@ static int __init microcode_init(void) · 12 unmodified lines
846851 cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
847852 mc_cpu_online, mc_cpu_down_prep);
848853
849− pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION);
850−
851854 return 0;
852855
853856 out_pdev:
arch/x86/kernel/cpu/microcode/intel.c+7−10
@@ -339,16 +339,9 @@ static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci, · 338 unmodified lines
339339 static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
340340 {
341341 struct microcode_intel *mc = uci->mc;
342− enum ucode_state ret;
343− u32 cur_rev, date;
342+ u32 cur_rev;
344343
345− ret = __apply_microcode(uci, mc, &cur_rev);
346− if (ret == UCODE_UPDATED) {
347− date = mc->hdr.date;
348− pr_info_once("updated early: 0x%x -> 0x%x, date = %04x-%02x-%02x\n",
349− cur_rev, mc->hdr.rev, date & 0xffff, date >> 24, (date >> 16) & 0xff);
350− }
351− return ret;
344+ return __apply_microcode(uci, mc, &cur_rev);
352345 }
353346
354347 static __init bool load_builtin_intel_microcode(struct cpio_data *cp)
@@ -413,13 +406,17 @@ static int __init save_builtin_microcode(void) · 58 unmodified lines
413406 early_initcall(save_builtin_microcode);
414407
415408 /* Load microcode on BSP from initrd or builtin blobs */
416−void __init load_ucode_intel_bsp(void)
409+void __init load_ucode_intel_bsp(struct early_load_data *ed)
417410 {
418411 struct ucode_cpu_info uci;
419412
413+ ed->old_rev = intel_get_microcode_revision();
414+
420415 uci.mc = get_microcode_blob(&uci, false);
421416 if (uci.mc && apply_microcode_early(&uci) == UCODE_UPDATED)
422417 ucode_patch_va = UCODE_BSP_LOADED;
418+
419+ ed->new_rev = uci.cpu_sig.rev;
423420 }
424421
425422 void load_ucode_intel_ap(void)
arch/x86/kernel/cpu/microcode/internal.h+10−4
@@ -37,6 +37,12 @@ struct microcode_ops { · 36 unmodified lines
3737 use_nmi : 1;
3838 };
3939
40+struct early_load_data {
41+ u32 old_rev;
42+ u32 new_rev;
43+};
44+
45+extern struct early_load_data early_data;
4046 extern struct ucode_cpu_info ucode_cpu_info[];
4147 struct cpio_data find_microcode_in_initrd(const char *path);
4248
@@ -92,14 +98,14 @@ extern bool dis_ucode_ldr; · 49 unmodified lines
9298 extern bool force_minrev;
9399
94100 #ifdef CONFIG_CPU_SUP_AMD
95−void load_ucode_amd_bsp(unsigned int family);
101+void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family);
96102 void load_ucode_amd_ap(unsigned int family);
97103 int save_microcode_in_initrd_amd(unsigned int family);
98104 void reload_ucode_amd(unsigned int cpu);
99105 struct microcode_ops *init_amd_microcode(void);
100106 void exit_amd_microcode(void);
101107 #else /* CONFIG_CPU_SUP_AMD */
102−static inline void load_ucode_amd_bsp(unsigned int family) { }
108+static inline void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family) { }
103109 static inline void load_ucode_amd_ap(unsigned int family) { }
104110 static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
105111 static inline void reload_ucode_amd(unsigned int cpu) { }
@@ -108,12 +114,12 @@ static inline void exit_amd_microcode(void) { } · 2 unmodified lines
108114 #endif /* !CONFIG_CPU_SUP_AMD */
109115
110116 #ifdef CONFIG_CPU_SUP_INTEL
111−void load_ucode_intel_bsp(void);
117+void load_ucode_intel_bsp(struct early_load_data *ed);
112118 void load_ucode_intel_ap(void);
113119 void reload_ucode_intel(void);
114120 struct microcode_ops *init_intel_microcode(void);
115121 #else /* CONFIG_CPU_SUP_INTEL */
116−static inline void load_ucode_intel_bsp(void) { }
122+static inline void load_ucode_intel_bsp(struct early_load_data *ed) { }
117123 static inline void load_ucode_intel_ap(void) { }
118124 static inline void reload_ucode_intel(void) { }
119125 static inline struct microcode_ops *init_intel_microcode(void) { return NULL; }
arch/x86/kernel/cpu/mshyperv.c+4−1
@@ -262,11 +262,14 @@ static uint32_t __init ms_hyperv_platform(void) · 261 unmodified lines
262262 static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
263263 {
264264 static atomic_t nmi_cpu = ATOMIC_INIT(-1);
265+ unsigned int old_cpu, this_cpu;
265266
266267 if (!unknown_nmi_panic)
267268 return NMI_DONE;
268269
269− if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1)
270+ old_cpu = -1;
271+ this_cpu = raw_smp_processor_id();
272+ if (!atomic_try_cmpxchg(&nmi_cpu, &old_cpu, this_cpu))
270273 return NMI_HANDLED;
271274
272275 return NMI_DONE;
arch/x86/kernel/signal_64.c+3−3
@@ -175,9 +175,6 @@ int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) · 174 unmodified lines
175175 frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp);
176176 uc_flags = frame_uc_flags(regs);
177177
178− if (setup_signal_shadow_stack(ksig))
179− return -EFAULT;
180−
181178 if (!user_access_begin(frame, sizeof(*frame)))
182179 return -EFAULT;
183180
@@ -198,6 +195,9 @@ int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) · 14 unmodified lines
198195 return -EFAULT;
199196 }
200197
198+ if (setup_signal_shadow_stack(ksig))
199+ return -EFAULT;
200+
201201 /* Set up registers for signal handler */
202202 regs->di = ksig->sig;
203203 /* In case the signal handler was declared without prototypes */
block/bdev.c+2−0
@@ -425,6 +425,8 @@ void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors) · 424 unmodified lines
425425
426426 void bdev_add(struct block_device *bdev, dev_t dev)
427427 {
428+ if (bdev_stable_writes(bdev))
429+ mapping_set_stable_writes(bdev->bd_inode->i_mapping);
428430 bdev->bd_dev = dev;
429431 bdev->bd_inode->i_rdev = dev;
430432 bdev->bd_inode->i_ino = dev;
block/blk-cgroup.c+13−0
@@ -577,6 +577,7 @@ static void blkg_destroy_all(struct gendisk *disk) · 576 unmodified lines
577577 struct request_queue *q = disk->queue;
578578 struct blkcg_gq *blkg, *n;
579579 int count = BLKG_DESTROY_BATCH_SIZE;
580+ int i;
580581
581582 restart:
582583 spin_lock_irq(&q->queue_lock);
@@ -602,6 +603,18 @@ restart: · 19 unmodified lines
602603 }
603604 }
604605
606+ /*
607+ * Mark policy deactivated since policy offline has been done, and
608+ * the free is scheduled, so future blkcg_deactivate_policy() can
609+ * be bypassed
610+ */
611+ for (i = 0; i < BLKCG_MAX_POLS; i++) {
612+ struct blkcg_policy *pol = blkcg_policy[i];
613+
614+ if (pol)
615+ __clear_bit(pol->plid, q->blkcg_pols);
616+ }
617+
605618 q->root_blkg = NULL;
606619 spin_unlock_irq(&q->queue_lock);
607620 }
block/blk-cgroup.h+0−2
@@ -249,8 +249,6 @@ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, · 248 unmodified lines
249249 {
250250 struct blkcg_gq *blkg;
251251
252− WARN_ON_ONCE(!rcu_read_lock_held());
253−
254252 if (blkcg == &blkcg_root)
255253 return q->root_blkg;
256254
block/blk-mq.c+38−37
@@ -2858,11 +2858,8 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, · 2857 unmodified lines
28582858 };
28592859 struct request *rq;
28602860
2861− if (unlikely(bio_queue_enter(bio)))
2862− return NULL;
2863−
28642861 if (blk_mq_attempt_bio_merge(q, bio, nsegs))
2865− goto queue_exit;
2862+ return NULL;
28662863
28672864 rq_qos_throttle(q, bio);
28682865
@@ -2878,35 +2875,23 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, · 9 unmodified lines
28782875 rq_qos_cleanup(q, bio);
28792876 if (bio->bi_opf & REQ_NOWAIT)
28802877 bio_wouldblock_error(bio);
2881−queue_exit:
2882− blk_queue_exit(q);
28832878 return NULL;
28842879 }
28852880
2886−static inline struct request *blk_mq_get_cached_request(struct request_queue *q,
2887− struct blk_plug *plug, struct bio **bio, unsigned int nsegs)
2881+/* return true if this @rq can be used for @bio */
2882+static bool blk_mq_can_use_cached_rq(struct request *rq, struct blk_plug *plug,
2883+ struct bio *bio)
28882884 {
2889− struct request *rq;
2890− enum hctx_type type, hctx_type;
2885+ enum hctx_type type = blk_mq_get_hctx_type(bio->bi_opf);
2886+ enum hctx_type hctx_type = rq->mq_hctx->type;
28912887
2892− if (!plug)
2893− return NULL;
2894− rq = rq_list_peek(&plug->cached_rq);
2895− if (!rq || rq->q != q)
2896− return NULL;
2888+ WARN_ON_ONCE(rq_list_peek(&plug->cached_rq) != rq);
28972889
2898− if (blk_mq_attempt_bio_merge(q, *bio, nsegs)) {
2899− *bio = NULL;
2900− return NULL;
2901− }
2902−
2903− type = blk_mq_get_hctx_type((*bio)->bi_opf);
2904− hctx_type = rq->mq_hctx->type;
29052890 if (type != hctx_type &&
29062891 !(type == HCTX_TYPE_READ && hctx_type == HCTX_TYPE_DEFAULT))
2907− return NULL;
2908− if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf))
2909− return NULL;
2892+ return false;
2893+ if (op_is_flush(rq->cmd_flags) != op_is_flush(bio->bi_opf))
2894+ return false;
29102895
29112896 /*
29122897 * If any qos ->throttle() end up blocking, we will have flushed the
@@ -2914,12 +2899,12 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q, · 1 unmodified line
29142899 * before we throttle.
29152900 */
29162901 plug->cached_rq = rq_list_next(rq);
2917− rq_qos_throttle(q, *bio);
2902+ rq_qos_throttle(rq->q, bio);
29182903
29192904 blk_mq_rq_time_init(rq, 0);
2920− rq->cmd_flags = (*bio)->bi_opf;
2905+ rq->cmd_flags = bio->bi_opf;
29212906 INIT_LIST_HEAD(&rq->queuelist);
2922− return rq;
2907+ return true;
29232908 }
29242909
29252910 static void bio_set_ioprio(struct bio *bio)
@@ -2949,7 +2934,7 @@ void blk_mq_submit_bio(struct bio *bio) · 23 unmodified lines
29492934 struct blk_plug *plug = blk_mq_plug(bio);
29502935 const int is_sync = op_is_sync(bio->bi_opf);
29512936 struct blk_mq_hw_ctx *hctx;
2952− struct request *rq;
2937+ struct request *rq = NULL;
29532938 unsigned int nr_segs = 1;
29542939 blk_status_t ret;
29552940
@@ -2960,20 +2945,36 @@ void blk_mq_submit_bio(struct bio *bio) · 4 unmodified lines
29602945 return;
29612946 }
29622947
2963− if (!bio_integrity_prep(bio))
2964− return;
2965−
29662948 bio_set_ioprio(bio);
29672949
2968− rq = blk_mq_get_cached_request(q, plug, &bio, nr_segs);
2969− if (!rq) {
2970− if (!bio)
2950+ if (plug) {
2951+ rq = rq_list_peek(&plug->cached_rq);
2952+ if (rq && rq->q != q)
2953+ rq = NULL;
2954+ }
2955+ if (rq) {
2956+ if (!bio_integrity_prep(bio))
29712957 return;
2972− rq = blk_mq_get_new_requests(q, plug, bio, nr_segs);
2973− if (unlikely(!rq))
2958+ if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
29742959 return;
2960+ if (blk_mq_can_use_cached_rq(rq, plug, bio))
2961+ goto done;
2962+ percpu_ref_get(&q->q_usage_counter);
2963+ } else {
2964+ if (unlikely(bio_queue_enter(bio)))
2965+ return;
2966+ if (!bio_integrity_prep(bio))
2967+ goto fail;
2968+ }
2969+
2970+ rq = blk_mq_get_new_requests(q, plug, bio, nr_segs);
2971+ if (unlikely(!rq)) {
2972+fail:
2973+ blk_queue_exit(q);
2974+ return;
29752975 }
29762976
2977+done:
29772978 trace_block_getrq(bio);
29782979
29792980 rq_qos_track(q, rq, bio);
block/blk-pm.c+5−28
@@ -163,38 +163,15 @@ EXPORT_SYMBOL(blk_pre_runtime_resume); · 162 unmodified lines
163163 * @q: the queue of the device
164164 *
165165 * Description:
166− * For historical reasons, this routine merely calls blk_set_runtime_active()
167− * to do the real work of restarting the queue. It does this regardless of
168− * whether the device's runtime-resume succeeded; even if it failed the
166+ * Restart the queue of a runtime suspended device. It does this regardless
167+ * of whether the device's runtime-resume succeeded; even if it failed the
169168 * driver or error handler will need to communicate with the device.
170169 *
171170 * This function should be called near the end of the device's
172− * runtime_resume callback.
171+ * runtime_resume callback to correct queue runtime PM status and re-enable
172+ * peeking requests from the queue.
173173 */
174174 void blk_post_runtime_resume(struct request_queue *q)
175−{
176− blk_set_runtime_active(q);
177−}
178−EXPORT_SYMBOL(blk_post_runtime_resume);
179−
180−/**
181− * blk_set_runtime_active - Force runtime status of the queue to be active
182− * @q: the queue of the device
183− *
184− * If the device is left runtime suspended during system suspend the resume
185− * hook typically resumes the device and corrects runtime status
186− * accordingly. However, that does not affect the queue runtime PM status
187− * which is still "suspended". This prevents processing requests from the
188− * queue.
189− *
190− * This function can be used in driver's resume hook to correct queue
191− * runtime PM status and re-enable peeking requests from the queue. It
192− * should be called before first request is added to the queue.
193− *
194− * This function is also called by blk_post_runtime_resume() for
195− * runtime resumes. It does everything necessary to restart the queue.
196− */
197−void blk_set_runtime_active(struct request_queue *q)
198175 {
199176 int old_status;
200177
@@ -211,4 +188,4 @@ void blk_set_runtime_active(struct request_queue *q) · 10 unmodified lines
211188 if (old_status != RPM_ACTIVE)
212189 blk_clear_pm_only(q);
213190 }
214−EXPORT_SYMBOL(blk_set_runtime_active);
191+EXPORT_SYMBOL(blk_post_runtime_resume);
block/blk-throttle.c+2−0
@@ -1320,6 +1320,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) · 1319 unmodified lines
13201320 tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE),
13211321 tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE));
13221322
1323+ rcu_read_lock();
13231324 /*
13241325 * Update has_rules[] flags for the updated tg's subtree. A tg is
13251326 * considered to have rules if either the tg itself or any of its
@@ -1347,6 +1348,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) · 21 unmodified lines
13471348 this_tg->latency_target = max(this_tg->latency_target,
13481349 parent_tg->latency_target);
13491350 }
1351+ rcu_read_unlock();
13501352
13511353 /*
13521354 * We're already holding queue_lock and know @tg is valid. Let's
drivers/accel/drm_accel.c+1−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <linux/idr.h>
1212
1313 #include <drm/drm_accel.h>
14+#include <drm/drm_auth.h>
1415 #include <drm/drm_debugfs.h>
1516 #include <drm/drm_drv.h>
1617 #include <drm/drm_file.h>
drivers/accel/ivpu/Kconfig+6−5
@@ -1,16 +1,17 @@
11 # SPDX-License-Identifier: GPL-2.0-only
22
33 config DRM_ACCEL_IVPU
4− tristate "Intel VPU for Meteor Lake and newer"
4+ tristate "Intel NPU (Neural Processing Unit)"
55 depends on DRM_ACCEL
66 depends on X86_64 && !UML
77 depends on PCI && PCI_MSI
88 select FW_LOADER
9− select SHMEM
9+ select DRM_GEM_SHMEM_HELPER
1010 select GENERIC_ALLOCATOR
1111 help
12− Choose this option if you have a system that has an 14th generation Intel CPU
13− or newer. VPU stands for Versatile Processing Unit and it's a CPU-integrated
14− inference accelerator for Computer Vision and Deep Learning applications.
12+ Choose this option if you have a system with an 14th generation
13+ Intel CPU (Meteor Lake) or newer. Intel NPU (formerly called Intel VPU)
14+ is a CPU-integrated inference accelerator for Computer Vision
15+ and Deep Learning applications.
1516
1617 If "M" is selected, the module will be called intel_vpu.
drivers/accel/ivpu/ivpu_debugfs.c+57−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include "ivpu_fw.h"
1515 #include "ivpu_fw_log.h"
1616 #include "ivpu_gem.h"
17+#include "ivpu_hw.h"
1718 #include "ivpu_jsm_msg.h"
1819 #include "ivpu_pm.h"
1920
@@ -115,6 +116,31 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { · 95 unmodified lines
115116 {"reset_pending", reset_pending_show, 0},
116117 };
117118
119+static ssize_t
120+dvfs_mode_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
121+{
122+ struct ivpu_device *vdev = file->private_data;
123+ struct ivpu_fw_info *fw = vdev->fw;
124+ u32 dvfs_mode;
125+ int ret;
126+
127+ ret = kstrtou32_from_user(user_buf, size, 0, &dvfs_mode);
128+ if (ret < 0)
129+ return ret;
130+
131+ fw->dvfs_mode = dvfs_mode;
132+
133+ ivpu_pm_schedule_recovery(vdev);
134+
135+ return size;
136+}
137+
138+static const struct file_operations dvfs_mode_fops = {
139+ .owner = THIS_MODULE,
140+ .open = simple_open,
141+ .write = dvfs_mode_fops_write,
142+};
143+
118144 static int fw_log_show(struct seq_file *s, void *v)
119145 {
120146 struct ivpu_device *vdev = s->private;
@@ -151,6 +177,30 @@ static const struct file_operations fw_log_fops = { · 30 unmodified lines
151177 .release = single_release,
152178 };
153179
180+static ssize_t
181+fw_profiling_freq_fops_write(struct file *file, const char __user *user_buf,
182+ size_t size, loff_t *pos)
183+{
184+ struct ivpu_device *vdev = file->private_data;
185+ bool enable;
186+ int ret;
187+
188+ ret = kstrtobool_from_user(user_buf, size, &enable);
189+ if (ret < 0)
190+ return ret;
191+
192+ ivpu_hw_profiling_freq_drive(vdev, enable);
193+ ivpu_pm_schedule_recovery(vdev);
194+
195+ return size;
196+}
197+
198+static const struct file_operations fw_profiling_freq_fops = {
199+ .owner = THIS_MODULE,
200+ .open = simple_open,
201+ .write = fw_profiling_freq_fops_write,
202+};
203+
154204 static ssize_t
155205 fw_trace_destination_mask_fops_write(struct file *file, const char __user *user_buf,
156206 size_t size, loff_t *pos)
@@ -280,6 +330,9 @@ void ivpu_debugfs_init(struct ivpu_device *vdev) · 123 unmodified lines
280330 debugfs_create_file("force_recovery", 0200, debugfs_root, vdev,
281331 &ivpu_force_recovery_fops);
282332
333+ debugfs_create_file("dvfs_mode", 0200, debugfs_root, vdev,
334+ &dvfs_mode_fops);
335+
283336 debugfs_create_file("fw_log", 0644, debugfs_root, vdev,
284337 &fw_log_fops);
285338 debugfs_create_file("fw_trace_destination_mask", 0200, debugfs_root, vdev,
@@ -291,4 +344,8 @@ void ivpu_debugfs_init(struct ivpu_device *vdev) · 5 unmodified lines
291344
292345 debugfs_create_file("reset_engine", 0200, debugfs_root, vdev,
293346 &ivpu_reset_engine_fops);
347+
348+ if (ivpu_hw_gen(vdev) >= IVPU_HW_40XX)
349+ debugfs_create_file("fw_profiling_freq_drive", 0200,
350+ debugfs_root, vdev, &fw_profiling_freq_fops);
294351 }
drivers/accel/ivpu/ivpu_drv.c+27−22
@@ -31,8 +31,6 @@ · 30 unmodified lines
3131 __stringify(DRM_IVPU_DRIVER_MINOR) "."
3232 #endif
3333
34−static const struct drm_driver driver;
35−
3634 static struct lock_class_key submitted_jobs_xa_lock_class_key;
3735
3836 int ivpu_dbg_mask;
@@ -41,7 +39,7 @@ MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros."); · 2 unmodified lines
4139
4240 int ivpu_test_mode;
4341 module_param_named_unsafe(test_mode, ivpu_test_mode, int, 0644);
44−MODULE_PARM_DESC(test_mode, "Test mode: 0 - normal operation, 1 - fw unit test, 2 - null hw");
42+MODULE_PARM_DESC(test_mode, "Test mode mask. See IVPU_TEST_MODE_* macros.");
4543
4644 u8 ivpu_pll_min_ratio;
4745 module_param_named(pll_min_ratio, ivpu_pll_min_ratio, byte, 0644);
@@ -93,8 +91,8 @@ static void file_priv_release(struct kref *ref) · 45 unmodified lines
9391 ivpu_dbg(vdev, FILE, "file_priv release: ctx %u\n", file_priv->ctx.id);
9492
9593 ivpu_cmdq_release_all(file_priv);
96− ivpu_bo_remove_all_bos_from_context(&file_priv->ctx);
9794 ivpu_jsm_context_release(vdev, file_priv->ctx.id);
95+ ivpu_bo_remove_all_bos_from_context(vdev, &file_priv->ctx);
9896 ivpu_mmu_user_context_fini(vdev, &file_priv->ctx);
9997 drm_WARN_ON(&vdev->drm, xa_erase_irq(&vdev->context_xa, file_priv->ctx.id) != file_priv);
10098 mutex_destroy(&file_priv->lock);
@@ -317,16 +315,14 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev) · 216 unmodified lines
317315 unsigned long timeout;
318316 int ret;
319317
320− if (ivpu_test_mode == IVPU_TEST_MODE_FW_TEST)
318+ if (ivpu_test_mode & IVPU_TEST_MODE_FW_TEST)
321319 return 0;
322320
323− ivpu_ipc_consumer_add(vdev, &cons, IVPU_IPC_CHAN_BOOT_MSG);
321+ ivpu_ipc_consumer_add(vdev, &cons, IVPU_IPC_CHAN_BOOT_MSG, NULL);
324322
325323 timeout = jiffies + msecs_to_jiffies(vdev->timeout.boot);
326324 while (1) {
327− ret = ivpu_ipc_irq_handler(vdev);
328− if (ret)
329− break;
325+ ivpu_ipc_irq_handler(vdev, NULL);
330326 ret = ivpu_ipc_receive(vdev, &cons, &ipc_hdr, NULL, 0);
331327 if (ret != -ETIMEDOUT || time_after_eq(jiffies, timeout))
332328 break;
@@ -362,7 +358,7 @@ int ivpu_boot(struct ivpu_device *vdev) · 29 unmodified lines
362358 int ret;
363359
364360 /* Update boot params located at first 4KB of FW memory */
365− ivpu_fw_boot_params_setup(vdev, vdev->fw->mem->kvaddr);
361+ ivpu_fw_boot_params_setup(vdev, ivpu_bo_vaddr(vdev->fw->mem));
366362
367363 ret = ivpu_hw_boot_fw(vdev);
368364 if (ret) {
@@ -414,7 +410,9 @@ static const struct drm_driver driver = { · 45 unmodified lines
414410
415411 .open = ivpu_open,
416412 .postclose = ivpu_postclose,
417− .gem_prime_import = ivpu_gem_prime_import,
413+
414+ .gem_create_object = ivpu_gem_create_object,
415+ .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
418416
419417 .ioctls = ivpu_drm_ioctls,
420418 .num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),
@@ -427,6 +425,13 @@ static const struct drm_driver driver = { · 6 unmodified lines
427425 .minor = DRM_IVPU_DRIVER_MINOR,
428426 };
429427
428+static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
429+{
430+ struct ivpu_device *vdev = arg;
431+
432+ return ivpu_ipc_irq_thread_handler(vdev);
433+}
434+
430435 static int ivpu_irq_init(struct ivpu_device *vdev)
431436 {
432437 struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
@@ -440,8 +445,8 @@ static int ivpu_irq_init(struct ivpu_device *vdev) · 7 unmodified lines
440445
441446 vdev->irq = pci_irq_vector(pdev, 0);
442447
443− ret = devm_request_irq(vdev->drm.dev, vdev->irq, vdev->hw->ops->irq_handler,
444− IRQF_NO_AUTOEN, DRIVER_NAME, vdev);
448+ ret = devm_request_threaded_irq(vdev->drm.dev, vdev->irq, vdev->hw->ops->irq_handler,
449+ ivpu_irq_thread_handler, IRQF_NO_AUTOEN, DRIVER_NAME, vdev);
445450 if (ret)
446451 ivpu_err(vdev, "Failed to request an IRQ %d\n", ret);
447452
@@ -533,6 +538,11 @@ static int ivpu_dev_init(struct ivpu_device *vdev) · 85 unmodified lines
533538 xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC);
534539 xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
535540 lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key);
541+ INIT_LIST_HEAD(&vdev->bo_list);
542+
543+ ret = drmm_mutex_init(&vdev->drm, &vdev->bo_list_lock);
544+ if (ret)
545+ goto err_xa_destroy;
536546
537547 ret = ivpu_pci_init(vdev);
538548 if (ret)
@@ -550,7 +560,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev) · 11 unmodified lines
550560 /* Power up early so the rest of init code can access VPU registers */
551561 ret = ivpu_hw_power_up(vdev);
552562 if (ret)
553− goto err_xa_destroy;
563+ goto err_power_down;
554564
555565 ret = ivpu_mmu_global_context_init(vdev);
556566 if (ret)
@@ -574,20 +584,15 @@ static int ivpu_dev_init(struct ivpu_device *vdev) · 17 unmodified lines
574584
575585 ivpu_pm_init(vdev);
576586
577− ret = ivpu_job_done_thread_init(vdev);
578− if (ret)
579− goto err_ipc_fini;
580−
581587 ret = ivpu_boot(vdev);
582588 if (ret)
583− goto err_job_done_thread_fini;
589+ goto err_ipc_fini;
584590
591+ ivpu_job_done_consumer_init(vdev);
585592 ivpu_pm_enable(vdev);
586593
587594 return 0;
588595
589−err_job_done_thread_fini:
590− ivpu_job_done_thread_fini(vdev);
591596 err_ipc_fini:
592597 ivpu_ipc_fini(vdev);
593598 err_fw_fini:
@@ -612,7 +617,7 @@ static void ivpu_dev_fini(struct ivpu_device *vdev) · 18 unmodified lines
612617 ivpu_shutdown(vdev);
613618 if (IVPU_WA(d3hot_after_power_off))
614619 pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
615− ivpu_job_done_thread_fini(vdev);
620+ ivpu_job_done_consumer_fini(vdev);
616621 ivpu_pm_cancel_recovery(vdev);
617622
618623 ivpu_ipc_fini(vdev);
drivers/accel/ivpu/ivpu_drv.h+13−5
@@ -17,9 +17,10 @@ · 16 unmodified lines
1717 #include <uapi/drm/ivpu_accel.h>
1818
1919 #include "ivpu_mmu_context.h"
20+#include "ivpu_ipc.h"
2021
2122 #define DRIVER_NAME "intel_vpu"
22−#define DRIVER_DESC "Driver for Intel Versatile Processing Unit (VPU)"
23+#define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)"
2324 #define DRIVER_DATE "20230117"
2425
2526 #define PCI_DEVICE_ID_MTL 0x7d1d
@@ -88,6 +89,7 @@ struct ivpu_wa_table { · 62 unmodified lines
8889 bool d3hot_after_power_off;
8990 bool interrupt_clear_with_0;
9091 bool disable_clock_relinquish;
92+ bool disable_d0i3_msg;
9193 };
9294
9395 struct ivpu_hw_info;
@@ -115,8 +117,11 @@ struct ivpu_device { · 21 unmodified lines
115117 struct xarray context_xa;
116118 struct xa_limit context_xa_limit;
117119
120+ struct mutex bo_list_lock; /* Protects bo_list */
121+ struct list_head bo_list;
122+
118123 struct xarray submitted_jobs_xa;
119− struct task_struct *job_done_thread;
124+ struct ivpu_ipc_consumer job_done_consumer;
120125
121126 atomic64_t unique_id_counter;
122127
@@ -126,6 +131,7 @@ struct ivpu_device { · 3 unmodified lines
126131 int tdr;
127132 int reschedule_suspend;
128133 int autosuspend;
134+ int d0i3_entry_msg;
129135 } timeout;
130136 };
131137
@@ -148,9 +154,11 @@ extern u8 ivpu_pll_min_ratio; · 16 unmodified lines
148154 extern u8 ivpu_pll_max_ratio;
149155 extern bool ivpu_disable_mmu_cont_pages;
150156
151−#define IVPU_TEST_MODE_DISABLED 0
152−#define IVPU_TEST_MODE_FW_TEST 1
153−#define IVPU_TEST_MODE_NULL_HW 2
157+#define IVPU_TEST_MODE_FW_TEST BIT(0)
158+#define IVPU_TEST_MODE_NULL_HW BIT(1)
159+#define IVPU_TEST_MODE_NULL_SUBMISSION BIT(2)
160+#define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4)
161+#define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5)
154162 extern int ivpu_test_mode;
155163
156164 struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);
drivers/accel/ivpu/ivpu_fw.c+74−5
@@ -33,12 +33,17 @@ · 32 unmodified lines
3333
3434 #define ADDR_TO_L2_CACHE_CFG(addr) ((addr) >> 31)
3535
36−#define IVPU_FW_CHECK_API(vdev, fw_hdr, name, min_major) \
36+/* Check if FW API is compatible with the driver */
37+#define IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, name, min_major) \
3738 ivpu_fw_check_api(vdev, fw_hdr, #name, \
3839 VPU_##name##_API_VER_INDEX, \
3940 VPU_##name##_API_VER_MAJOR, \
4041 VPU_##name##_API_VER_MINOR, min_major)
4142
43+/* Check if API version is lower that the given version */
44+#define IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, name, major, minor) \
45+ ivpu_fw_check_api_ver_lt(vdev, fw_hdr, #name, VPU_##name##_API_VER_INDEX, major, minor)
46+
4247 static char *ivpu_firmware;
4348 module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644);
4449 MODULE_PARM_DESC(firmware, "VPU firmware binary in /lib/firmware/..");
@@ -105,6 +110,19 @@ ivpu_fw_check_api(struct ivpu_device *vdev, const struct vpu_firmware_header *fw · 60 unmodified lines
105110 return 0;
106111 }
107112
113+static bool
114+ivpu_fw_check_api_ver_lt(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr,
115+ const char *str, int index, u16 major, u16 minor)
116+{
117+ u16 fw_major = (u16)(fw_hdr->api_version[index] >> 16);
118+ u16 fw_minor = (u16)(fw_hdr->api_version[index]);
119+
120+ if (fw_major < major || (fw_major == major && fw_minor < minor))
121+ return true;
122+
123+ return false;
124+}
125+
108126 static int ivpu_fw_parse(struct ivpu_device *vdev)
109127 {
110128 struct ivpu_fw_info *fw = vdev->fw;
@@ -164,9 +182,9 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) · 53 unmodified lines
164182 ivpu_info(vdev, "Firmware: %s, version: %s", fw->name,
165183 (const char *)fw_hdr + VPU_FW_HEADER_SIZE);
166184
167− if (IVPU_FW_CHECK_API(vdev, fw_hdr, BOOT, 3))
185+ if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, BOOT, 3))
168186 return -EINVAL;
169− if (IVPU_FW_CHECK_API(vdev, fw_hdr, JSM, 3))
187+ if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, JSM, 3))
170188 return -EINVAL;
171189
172190 fw->runtime_addr = runtime_addr;
@@ -182,6 +200,8 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) · 9 unmodified lines
182200 fw->trace_destination_mask = VPU_TRACE_DESTINATION_VERBOSE_TRACING;
183201 fw->trace_hw_component_mask = -1;
184202
203+ fw->dvfs_mode = 0;
204+
185205 ivpu_dbg(vdev, FW_BOOT, "Size: file %lu image %u runtime %u shavenn %u\n",
186206 fw->file->size, fw->image_size, fw->runtime_size, fw->shave_nn_size);
187207 ivpu_dbg(vdev, FW_BOOT, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n",
@@ -195,6 +215,24 @@ static void ivpu_fw_release(struct ivpu_device *vdev) · 7 unmodified lines
195215 release_firmware(vdev->fw->file);
196216 }
197217
218+/* Initialize workarounds that depend on FW version */
219+static void
220+ivpu_fw_init_wa(struct ivpu_device *vdev)
221+{
222+ const struct vpu_firmware_header *fw_hdr = (const void *)vdev->fw->file->data;
223+
224+ if (IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, BOOT, 3, 17) ||
225+ (ivpu_hw_gen(vdev) > IVPU_HW_37XX) ||
226+ (ivpu_test_mode & IVPU_TEST_MODE_D0I3_MSG_DISABLE))
227+ vdev->wa.disable_d0i3_msg = true;
228+
229+ /* Force enable the feature for testing purposes */
230+ if (ivpu_test_mode & IVPU_TEST_MODE_D0I3_MSG_ENABLE)
231+ vdev->wa.disable_d0i3_msg = false;
232+
233+ IVPU_PRINT_WA(disable_d0i3_msg);
234+}
235+
198236 static int ivpu_fw_update_global_range(struct ivpu_device *vdev)
199237 {
200238 struct ivpu_fw_info *fw = vdev->fw;
@@ -248,7 +286,7 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) · 47 unmodified lines
248286
249287 if (fw->shave_nn_size) {
250288 fw->mem_shave_nn = ivpu_bo_alloc_internal(vdev, vdev->hw->ranges.shave.start,
251− fw->shave_nn_size, DRM_IVPU_BO_UNCACHED);
289+ fw->shave_nn_size, DRM_IVPU_BO_WC);
252290 if (!fw->mem_shave_nn) {
253291 ivpu_err(vdev, "Failed to allocate shavenn buffer\n");
254292 ret = -ENOMEM;
@@ -297,6 +335,8 @@ int ivpu_fw_init(struct ivpu_device *vdev) · 42 unmodified lines
297335 if (ret)
298336 goto err_fw_release;
299337
338+ ivpu_fw_init_wa(vdev);
339+
300340 ret = ivpu_fw_mem_init(vdev);
301341 if (ret)
302342 goto err_fw_release;
@@ -422,14 +462,31 @@ static void ivpu_fw_boot_params_print(struct ivpu_device *vdev, struct vpu_boot_ · 119 unmodified lines
422462 boot_params->punit_telemetry_sram_size);
423463 ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_telemetry_enable = 0x%x\n",
424464 boot_params->vpu_telemetry_enable);
465+ ivpu_dbg(vdev, FW_BOOT, "boot_params.dvfs_mode = %u\n",
466+ boot_params->dvfs_mode);
467+ ivpu_dbg(vdev, FW_BOOT, "boot_params.d0i3_delayed_entry = %d\n",
468+ boot_params->d0i3_delayed_entry);
469+ ivpu_dbg(vdev, FW_BOOT, "boot_params.d0i3_residency_time_us = %lld\n",
470+ boot_params->d0i3_residency_time_us);
471+ ivpu_dbg(vdev, FW_BOOT, "boot_params.d0i3_entry_vpu_ts = %llu\n",
472+ boot_params->d0i3_entry_vpu_ts);
425473 }
426474
427475 void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params)
428476 {
429477 struct ivpu_bo *ipc_mem_rx = vdev->ipc->mem_rx;
430478
431− /* In case of warm boot we only have to reset the entrypoint addr */
479+ /* In case of warm boot only update variable params */
432480 if (!ivpu_fw_is_cold_boot(vdev)) {
481+ boot_params->d0i3_residency_time_us =
482+ ktime_us_delta(ktime_get_boottime(), vdev->hw->d0i3_entry_host_ts);
483+ boot_params->d0i3_entry_vpu_ts = vdev->hw->d0i3_entry_vpu_ts;
484+
485+ ivpu_dbg(vdev, FW_BOOT, "boot_params.d0i3_residency_time_us = %lld\n",
486+ boot_params->d0i3_residency_time_us);
487+ ivpu_dbg(vdev, FW_BOOT, "boot_params.d0i3_entry_vpu_ts = %llu\n",
488+ boot_params->d0i3_entry_vpu_ts);
489+
433490 boot_params->save_restore_ret_address = 0;
434491 vdev->pm->is_warmboot = true;
435492 wmb(); /* Flush WC buffers after writing save_restore_ret_address */
@@ -442,6 +499,13 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 6 unmodified lines
442499 boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number;
443500 boot_params->frequency = ivpu_hw_reg_pll_freq_get(vdev);
444501
502+ /*
503+ * This param is a debug firmware feature. It switches default clock
504+ * to higher resolution one for fine-grained and more accurate firmware
505+ * task profiling.
506+ */
507+ boot_params->perf_clk_frequency = ivpu_hw_profiling_freq_get(vdev);
508+
445509 /*
446510 * Uncached region of VPU address space, covers IPC buffers, job queues
447511 * and log buffers, programmable to L2$ Uncached by VPU MTRR
@@ -493,6 +557,11 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 45 unmodified lines
493557 boot_params->punit_telemetry_sram_base = ivpu_hw_reg_telemetry_offset_get(vdev);
494558 boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev);
495559 boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev);
560+ boot_params->dvfs_mode = vdev->fw->dvfs_mode;
561+ if (!IVPU_WA(disable_d0i3_msg))
562+ boot_params->d0i3_delayed_entry = 1;
563+ boot_params->d0i3_residency_time_us = 0;
564+ boot_params->d0i3_entry_vpu_ts = 0;
496565
497566 wmb(); /* Flush WC buffers after writing bootparams */
498567
drivers/accel/ivpu/ivpu_fw.h+1−0
@@ -27,6 +27,7 @@ struct ivpu_fw_info { · 26 unmodified lines
2727 u32 trace_level;
2828 u32 trace_destination_mask;
2929 u64 trace_hw_component_mask;
30+ u32 dvfs_mode;
3031 };
3132
3233 int ivpu_fw_init(struct ivpu_device *vdev);
drivers/accel/ivpu/ivpu_gem.c+199−479
@@ -20,215 +20,18 @@ · 19 unmodified lines
2020 #include "ivpu_mmu.h"
2121 #include "ivpu_mmu_context.h"
2222
23−MODULE_IMPORT_NS(DMA_BUF);
24−
2523 static const struct drm_gem_object_funcs ivpu_gem_funcs;
2624
27−static struct lock_class_key prime_bo_lock_class_key;
28−
29−static int __must_check prime_alloc_pages_locked(struct ivpu_bo *bo)
30−{
31− /* Pages are managed by the underlying dma-buf */
32− return 0;
33−}
34−
35−static void prime_free_pages_locked(struct ivpu_bo *bo)
36−{
37− /* Pages are managed by the underlying dma-buf */
38−}
39−
40−static int prime_map_pages_locked(struct ivpu_bo *bo)
41−{
42− struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
43− struct sg_table *sgt;
44−
45− sgt = dma_buf_map_attachment_unlocked(bo->base.import_attach, DMA_BIDIRECTIONAL);
46− if (IS_ERR(sgt)) {
47− ivpu_err(vdev, "Failed to map attachment: %ld\n", PTR_ERR(sgt));
48− return PTR_ERR(sgt);
49− }
50−
51− bo->sgt = sgt;
52− return 0;
53−}
54−
55−static void prime_unmap_pages_locked(struct ivpu_bo *bo)
56−{
57− dma_buf_unmap_attachment_unlocked(bo->base.import_attach, bo->sgt, DMA_BIDIRECTIONAL);
58− bo->sgt = NULL;
59−}
60−
61−static const struct ivpu_bo_ops prime_ops = {
62− .type = IVPU_BO_TYPE_PRIME,
63− .name = "prime",
64− .alloc_pages = prime_alloc_pages_locked,
65− .free_pages = prime_free_pages_locked,
66− .map_pages = prime_map_pages_locked,
67− .unmap_pages = prime_unmap_pages_locked,
68−};
69−
70−static int __must_check shmem_alloc_pages_locked(struct ivpu_bo *bo)
71−{
72− int npages = ivpu_bo_size(bo) >> PAGE_SHIFT;
73− struct page **pages;
74−
75− pages = drm_gem_get_pages(&bo->base);
76− if (IS_ERR(pages))
77− return PTR_ERR(pages);
78−
79− if (bo->flags & DRM_IVPU_BO_WC)
80− set_pages_array_wc(pages, npages);
81− else if (bo->flags & DRM_IVPU_BO_UNCACHED)
82− set_pages_array_uc(pages, npages);
83−
84− bo->pages = pages;
85− return 0;
86−}
87−
88−static void shmem_free_pages_locked(struct ivpu_bo *bo)
89−{
90− if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED)
91− set_pages_array_wb(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT);
92−
93− drm_gem_put_pages(&bo->base, bo->pages, true, false);
94− bo->pages = NULL;
95−}
96−
97−static int ivpu_bo_map_pages_locked(struct ivpu_bo *bo)
98−{
99− int npages = ivpu_bo_size(bo) >> PAGE_SHIFT;
100− struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
101− struct sg_table *sgt;
102− int ret;
103−
104− sgt = drm_prime_pages_to_sg(&vdev->drm, bo->pages, npages);
105− if (IS_ERR(sgt)) {
106− ivpu_err(vdev, "Failed to allocate sgtable\n");
107− return PTR_ERR(sgt);
108− }
109−
110− ret = dma_map_sgtable(vdev->drm.dev, sgt, DMA_BIDIRECTIONAL, 0);
111− if (ret) {
112− ivpu_err(vdev, "Failed to map BO in IOMMU: %d\n", ret);
113− goto err_free_sgt;
114− }
115−
116− bo->sgt = sgt;
117− return 0;
118−
119−err_free_sgt:
120− kfree(sgt);
121− return ret;
122−}
123−
124−static void ivpu_bo_unmap_pages_locked(struct ivpu_bo *bo)
125−{
126− struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
127−
128− dma_unmap_sgtable(vdev->drm.dev, bo->sgt, DMA_BIDIRECTIONAL, 0);
129− sg_free_table(bo->sgt);
130− kfree(bo->sgt);
131− bo->sgt = NULL;
132−}
133−
134−static const struct ivpu_bo_ops shmem_ops = {
135− .type = IVPU_BO_TYPE_SHMEM,
136− .name = "shmem",
137− .alloc_pages = shmem_alloc_pages_locked,
138− .free_pages = shmem_free_pages_locked,
139− .map_pages = ivpu_bo_map_pages_locked,
140− .unmap_pages = ivpu_bo_unmap_pages_locked,
141−};
142−
143−static int __must_check internal_alloc_pages_locked(struct ivpu_bo *bo)
144−{
145− unsigned int i, npages = ivpu_bo_size(bo) >> PAGE_SHIFT;
146− struct page **pages;
147− int ret;
148−
149− pages = kvmalloc_array(npages, sizeof(*bo->pages), GFP_KERNEL);
150− if (!pages)
151− return -ENOMEM;
152−
153− for (i = 0; i < npages; i++) {
154− pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
155− if (!pages[i]) {
156− ret = -ENOMEM;
157− goto err_free_pages;
158− }
159− cond_resched();
160− }
161−
162− bo->pages = pages;
163− return 0;
164−
165−err_free_pages:
166− while (i--)
167− put_page(pages[i]);
168− kvfree(pages);
169− return ret;
170−}
171−
172−static void internal_free_pages_locked(struct ivpu_bo *bo)
173−{
174− unsigned int i, npages = ivpu_bo_size(bo) >> PAGE_SHIFT;
175−
176− if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED)
177− set_pages_array_wb(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT);
178−
179− for (i = 0; i < npages; i++)
180− put_page(bo->pages[i]);
181−
182− kvfree(bo->pages);
183− bo->pages = NULL;
184−}
185−
186−static const struct ivpu_bo_ops internal_ops = {
187− .type = IVPU_BO_TYPE_INTERNAL,
188− .name = "internal",
189− .alloc_pages = internal_alloc_pages_locked,
190− .free_pages = internal_free_pages_locked,
191− .map_pages = ivpu_bo_map_pages_locked,
192− .unmap_pages = ivpu_bo_unmap_pages_locked,
193−};
194−
195−static int __must_check ivpu_bo_alloc_and_map_pages_locked(struct ivpu_bo *bo)
196−{
197− struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
198− int ret;
199−
200− lockdep_assert_held(&bo->lock);
201− drm_WARN_ON(&vdev->drm, bo->sgt);
202−
203− ret = bo->ops->alloc_pages(bo);
204− if (ret) {
205− ivpu_err(vdev, "Failed to allocate pages for BO: %d", ret);
206− return ret;
207− }
208−
209− ret = bo->ops->map_pages(bo);
210− if (ret) {
211− ivpu_err(vdev, "Failed to map pages for BO: %d", ret);
212− goto err_free_pages;
213− }
214− return ret;
215−
216−err_free_pages:
217− bo->ops->free_pages(bo);
218− return ret;
219−}
220−
221−static void ivpu_bo_unmap_and_free_pages(struct ivpu_bo *bo)
25+static inline void ivpu_dbg_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, const char *action)
22226 {
223− mutex_lock(&bo->lock);
224−
225− WARN_ON(!bo->sgt);
226− bo->ops->unmap_pages(bo);
227− WARN_ON(bo->sgt);
228− bo->ops->free_pages(bo);
229− WARN_ON(bo->pages);
230−
231− mutex_unlock(&bo->lock);
27+ if (bo->ctx)
28+ ivpu_dbg(vdev, BO, "%6s: size %zu has_pages %d dma_mapped %d handle %u ctx %d vpu_addr 0x%llx mmu_mapped %d\n",
29+ action, ivpu_bo_size(bo), (bool)bo->base.pages, (bool)bo->base.sgt,
30+ bo->handle, bo->ctx->id, bo->vpu_addr, bo->mmu_mapped);
31+ else
32+ ivpu_dbg(vdev, BO, "%6s: size %zu has_pages %d dma_mapped %d handle %u (not added to context)\n",
33+ action, ivpu_bo_size(bo), (bool)bo->base.pages, (bool)bo->base.sgt,
34+ bo->handle);
23235 }
23336
23437 /*
@@ -245,21 +48,24 @@ int __must_check ivpu_bo_pin(struct ivpu_bo *bo) · 10 unmodified lines
24548
24649 mutex_lock(&bo->lock);
24750
248− if (!bo->vpu_addr) {
249− ivpu_err(vdev, "vpu_addr not set for BO ctx_id: %d handle: %d\n",
250− bo->ctx->id, bo->handle);
51+ ivpu_dbg_bo(vdev, bo, "pin");
52+
53+ if (!bo->ctx) {
54+ ivpu_err(vdev, "vpu_addr not allocated for BO %d\n", bo->handle);
25155 ret = -EINVAL;
25256 goto unlock;
25357 }
25458
255− if (!bo->sgt) {
256− ret = ivpu_bo_alloc_and_map_pages_locked(bo);
257− if (ret)
59+ if (!bo->mmu_mapped) {
60+ struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(&bo->base);
61+
62+ if (IS_ERR(sgt)) {
63+ ret = PTR_ERR(sgt);
64+ ivpu_err(vdev, "Failed to map BO in IOMMU: %d\n", ret);
25865 goto unlock;
259− }
66+ }
26067
261− if (!bo->mmu_mapped) {
262− ret = ivpu_mmu_context_map_sgt(vdev, bo->ctx, bo->vpu_addr, bo->sgt,
68+ ret = ivpu_mmu_context_map_sgt(vdev, bo->ctx, bo->vpu_addr, sgt,
26369 ivpu_bo_is_snooped(bo));
26470 if (ret) {
26571 ivpu_err(vdev, "Failed to map BO in MMU: %d\n", ret);
@@ -281,248 +87,213 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, · 15 unmodified lines
28187 struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
28288 int ret;
28389
284− if (!range) {
285− if (bo->flags & DRM_IVPU_BO_SHAVE_MEM)
286− range = &vdev->hw->ranges.shave;
287− else if (bo->flags & DRM_IVPU_BO_DMA_MEM)
288− range = &vdev->hw->ranges.dma;
289− else
290− range = &vdev->hw->ranges.user;
291− }
90+ mutex_lock(&bo->lock);
29291
293− mutex_lock(&ctx->lock);
294− ret = ivpu_mmu_context_insert_node_locked(ctx, range, ivpu_bo_size(bo), &bo->mm_node);
92+ ret = ivpu_mmu_context_insert_node(ctx, range, ivpu_bo_size(bo), &bo->mm_node);
29593 if (!ret) {
29694 bo->ctx = ctx;
29795 bo->vpu_addr = bo->mm_node.start;
298− list_add_tail(&bo->ctx_node, &ctx->bo_list);
96+ } else {
97+ ivpu_err(vdev, "Failed to add BO to context %u: %d\n", ctx->id, ret);
29998 }
300− mutex_unlock(&ctx->lock);
99+
100+ ivpu_dbg_bo(vdev, bo, "alloc");
101+
102+ mutex_unlock(&bo->lock);
301103
302104 return ret;
303105 }
304106
305−static void ivpu_bo_free_vpu_addr(struct ivpu_bo *bo)
107+static void ivpu_bo_unbind_locked(struct ivpu_bo *bo)
306108 {
307109 struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
308− struct ivpu_mmu_context *ctx = bo->ctx;
309110
310− ivpu_dbg(vdev, BO, "remove from ctx: ctx %d vpu_addr 0x%llx allocated %d mmu_mapped %d\n",
311− ctx->id, bo->vpu_addr, (bool)bo->sgt, bo->mmu_mapped);
111+ lockdep_assert_held(&bo->lock);
312112
313− mutex_lock(&bo->lock);
113+ ivpu_dbg_bo(vdev, bo, "unbind");
114+
115+ /* TODO: dma_unmap */
314116
315117 if (bo->mmu_mapped) {
316− drm_WARN_ON(&vdev->drm, !bo->sgt);
317− ivpu_mmu_context_unmap_sgt(vdev, ctx, bo->vpu_addr, bo->sgt);
118+ drm_WARN_ON(&vdev->drm, !bo->ctx);
119+ drm_WARN_ON(&vdev->drm, !bo->vpu_addr);
120+ drm_WARN_ON(&vdev->drm, !bo->base.sgt);
121+ ivpu_mmu_context_unmap_sgt(vdev, bo->ctx, bo->vpu_addr, bo->base.sgt);
318122 bo->mmu_mapped = false;
319123 }
320124
321− mutex_lock(&ctx->lock);
322− list_del(&bo->ctx_node);
323− bo->vpu_addr = 0;
324− bo->ctx = NULL;
325− ivpu_mmu_context_remove_node_locked(ctx, &bo->mm_node);
326− mutex_unlock(&ctx->lock);
125+ if (bo->ctx) {
126+ ivpu_mmu_context_remove_node(bo->ctx, &bo->mm_node);
127+ bo->vpu_addr = 0;
128+ bo->ctx = NULL;
129+ }
130+}
327131
132+static void ivpu_bo_unbind(struct ivpu_bo *bo)
133+{
134+ mutex_lock(&bo->lock);
135+ ivpu_bo_unbind_locked(bo);
328136 mutex_unlock(&bo->lock);
329137 }
330138
331−void ivpu_bo_remove_all_bos_from_context(struct ivpu_mmu_context *ctx)
139+void ivpu_bo_remove_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx)
332140 {
333− struct ivpu_bo *bo, *tmp;
141+ struct ivpu_bo *bo;
142+
143+ if (drm_WARN_ON(&vdev->drm, !ctx))
144+ return;
334145
335− list_for_each_entry_safe(bo, tmp, &ctx->bo_list, ctx_node)
336− ivpu_bo_free_vpu_addr(bo);
146+ mutex_lock(&vdev->bo_list_lock);
147+ list_for_each_entry(bo, &vdev->bo_list, bo_list_node) {
148+ mutex_lock(&bo->lock);
149+ if (bo->ctx == ctx)
150+ ivpu_bo_unbind_locked(bo);
151+ mutex_unlock(&bo->lock);
152+ }
153+ mutex_unlock(&vdev->bo_list_lock);
337154 }
338155
339−static struct ivpu_bo *
340−ivpu_bo_alloc(struct ivpu_device *vdev, struct ivpu_mmu_context *mmu_context,
341− u64 size, u32 flags, const struct ivpu_bo_ops *ops,
342− const struct ivpu_addr_range *range, u64 user_ptr)
156+struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size)
343157 {
344158 struct ivpu_bo *bo;
345− int ret = 0;
346−
347− if (drm_WARN_ON(&vdev->drm, size == 0 || !PAGE_ALIGNED(size)))
348− return ERR_PTR(-EINVAL);
349159
350− switch (flags & DRM_IVPU_BO_CACHE_MASK) {
351− case DRM_IVPU_BO_CACHED:
352− case DRM_IVPU_BO_UNCACHED:
353− case DRM_IVPU_BO_WC:
354− break;
355− default:
160+ if (size == 0 || !PAGE_ALIGNED(size))
356161 return ERR_PTR(-EINVAL);
357− }
358162
359163 bo = kzalloc(sizeof(*bo), GFP_KERNEL);
360164 if (!bo)
361165 return ERR_PTR(-ENOMEM);
362166
363− mutex_init(&bo->lock);
364− bo->base.funcs = &ivpu_gem_funcs;
365− bo->flags = flags;
366− bo->ops = ops;
367− bo->user_ptr = user_ptr;
368−
369− if (ops->type == IVPU_BO_TYPE_SHMEM)
370− ret = drm_gem_object_init(&vdev->drm, &bo->base, size);
371− else
372− drm_gem_private_object_init(&vdev->drm, &bo->base, size);
373−
374− if (ret) {
375− ivpu_err(vdev, "Failed to initialize drm object\n");
376− goto err_free;
377− }
378−
379− if (flags & DRM_IVPU_BO_MAPPABLE) {
380− ret = drm_gem_create_mmap_offset(&bo->base);
381− if (ret) {
382− ivpu_err(vdev, "Failed to allocate mmap offset\n");
383− goto err_release;
384− }
385− }
386−
387− if (mmu_context) {
388− ret = ivpu_bo_alloc_vpu_addr(bo, mmu_context, range);
389− if (ret) {
390− ivpu_err(vdev, "Failed to add BO to context: %d\n", ret);
391− goto err_release;
392− }
393− }
167+ bo->base.base.funcs = &ivpu_gem_funcs;
168+ bo->base.pages_mark_dirty_on_put = true; /* VPU can dirty a BO anytime */
394169
395− return bo;
170+ INIT_LIST_HEAD(&bo->bo_list_node);
171+ mutex_init(&bo->lock);
396172
397−err_release:
398− drm_gem_object_release(&bo->base);
399−err_free:
400− kfree(bo);
401− return ERR_PTR(ret);
173+ return &bo->base.base;
402174 }
403175
404−static void ivpu_bo_free(struct drm_gem_object *obj)
176+static struct ivpu_bo *
177+ivpu_bo_create(struct ivpu_device *vdev, u64 size, u32 flags)
405178 {
406− struct ivpu_bo *bo = to_ivpu_bo(obj);
407− struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
408−
409− if (bo->ctx)
410− ivpu_dbg(vdev, BO, "free: ctx %d vpu_addr 0x%llx allocated %d mmu_mapped %d\n",
411− bo->ctx->id, bo->vpu_addr, (bool)bo->sgt, bo->mmu_mapped);
412− else
413− ivpu_dbg(vdev, BO, "free: ctx (released) allocated %d mmu_mapped %d\n",
414− (bool)bo->sgt, bo->mmu_mapped);
415−
416− drm_WARN_ON(&vdev->drm, !dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ));
179+ struct drm_gem_shmem_object *shmem;
180+ struct ivpu_bo *bo;
417181
418− vunmap(bo->kvaddr);
182+ switch (flags & DRM_IVPU_BO_CACHE_MASK) {
183+ case DRM_IVPU_BO_CACHED:
184+ case DRM_IVPU_BO_WC:
185+ break;
186+ default:
187+ return ERR_PTR(-EINVAL);
188+ }
419189
420− if (bo->ctx)
421− ivpu_bo_free_vpu_addr(bo);
190+ shmem = drm_gem_shmem_create(&vdev->drm, size);
191+ if (IS_ERR(shmem))
192+ return ERR_CAST(shmem);
422193
423− if (bo->sgt)
424− ivpu_bo_unmap_and_free_pages(bo);
194+ bo = to_ivpu_bo(&shmem->base);
195+ bo->base.map_wc = flags & DRM_IVPU_BO_WC;
196+ bo->flags = flags;
425197
426− if (bo->base.import_attach)
427− drm_prime_gem_destroy(&bo->base, bo->sgt);
198+ mutex_lock(&vdev->bo_list_lock);
199+ list_add_tail(&bo->bo_list_node, &vdev->bo_list);
200+ mutex_unlock(&vdev->bo_list_lock);
428201
429− drm_gem_object_release(&bo->base);
202+ ivpu_dbg(vdev, BO, "create: vpu_addr 0x%llx size %zu flags 0x%x\n",
203+ bo->vpu_addr, bo->base.base.size, flags);
430204
431− mutex_destroy(&bo->lock);
432− kfree(bo);
205+ return bo;
433206 }
434207
435−static int ivpu_bo_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
208+static int ivpu_bo_open(struct drm_gem_object *obj, struct drm_file *file)
436209 {
210+ struct ivpu_file_priv *file_priv = file->driver_priv;
211+ struct ivpu_device *vdev = file_priv->vdev;
437212 struct ivpu_bo *bo = to_ivpu_bo(obj);
438− struct ivpu_device *vdev = ivpu_bo_to_vdev(bo);
439−
440− ivpu_dbg(vdev, BO, "mmap: ctx %u handle %u vpu_addr 0x%llx size %zu type %s",
441− bo->ctx->id, bo->handle, bo->vpu_addr, ivpu_bo_size(bo), bo->ops->name);
213+ struct ivpu_addr_range *range;
442214
443− if (obj->import_attach) {
444− /* Drop the reference drm_gem_mmap_obj() acquired.*/
445− drm_gem_object_put(obj);
446− vma->vm_private_data = NULL;
447− return dma_buf_mmap(obj->dma_buf, vma, 0);
448− }
449−
450− vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND);
451− vma->vm_page_prot = ivpu_bo_pgprot(bo, vm_get_page_prot(vma->vm_flags));
215+ if (bo->flags & DRM_IVPU_BO_SHAVE_MEM)
216+ range = &vdev->hw->ranges.shave;
217+ else if (bo->flags & DRM_IVPU_BO_DMA_MEM)
218+ range = &vdev->hw->ranges.dma;
219+ else
220+ range = &vdev->hw->ranges.user;
452221
453− return 0;
222+ return ivpu_bo_alloc_vpu_addr(bo, &file_priv->ctx, range);
454223 }
455224
456−static struct sg_table *ivpu_bo_get_sg_table(struct drm_gem_object *obj)
225+static void ivpu_bo_free(struct drm_gem_object *obj)
457226 {
227+ struct ivpu_device *vdev = to_ivpu_device(obj->dev);
458228 struct ivpu_bo *bo = to_ivpu_bo(obj);
459− loff_t npages = obj->size >> PAGE_SHIFT;
460− int ret = 0;
461229
462− mutex_lock(&bo->lock);
230+ mutex_lock(&vdev->bo_list_lock);
231+ list_del(&bo->bo_list_node);
232+ mutex_unlock(&vdev->bo_list_lock);
463233
464− if (!bo->sgt)
465− ret = ivpu_bo_alloc_and_map_pages_locked(bo);
234+ drm_WARN_ON(&vdev->drm, !dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ));
466235
467− mutex_unlock(&bo->lock);
236+ ivpu_dbg_bo(vdev, bo, "free");
468237
469− if (ret)
470− return ERR_PTR(ret);
238+ ivpu_bo_unbind(bo);
239+ mutex_destroy(&bo->lock);
471240
472− return drm_prime_pages_to_sg(obj->dev, bo->pages, npages);
241+ drm_WARN_ON(obj->dev, bo->base.pages_use_count > 1);
242+ drm_gem_shmem_free(&bo->base);
473243 }
474244
475−static vm_fault_t ivpu_vm_fault(struct vm_fault *vmf)
476−{
477− struct vm_area_struct *vma = vmf->vma;
478− struct drm_gem_object *obj = vma->vm_private_data;
479− struct ivpu_bo *bo = to_ivpu_bo(obj);
480− loff_t npages = obj->size >> PAGE_SHIFT;
481− pgoff_t page_offset;
482− struct page *page;
483− vm_fault_t ret;
484− int err;
485−
486− mutex_lock(&bo->lock);
487−
488− if (!bo->sgt) {
489− err = ivpu_bo_alloc_and_map_pages_locked(bo);
490− if (err) {
491− ret = vmf_error(err);
492− goto unlock;
493− }
494− }
495−
496− /* We don't use vmf->pgoff since that has the fake offset */
497− page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
498− if (page_offset >= npages) {
499− ret = VM_FAULT_SIGBUS;
500− } else {
501− page = bo->pages[page_offset];
502− ret = vmf_insert_pfn(vma, vmf->address, page_to_pfn(page));
503− }
504−
505−unlock:
506− mutex_unlock(&bo->lock);
245+static const struct dma_buf_ops ivpu_bo_dmabuf_ops = {
246+ .cache_sgt_mapping = true,
247+ .attach = drm_gem_map_attach,
248+ .detach = drm_gem_map_detach,
249+ .map_dma_buf = drm_gem_map_dma_buf,
250+ .unmap_dma_buf = drm_gem_unmap_dma_buf,
251+ .release = drm_gem_dmabuf_release,
252+ .mmap = drm_gem_dmabuf_mmap,
253+ .vmap = drm_gem_dmabuf_vmap,
254+ .vunmap = drm_gem_dmabuf_vunmap,
255+};
507256
508− return ret;
257+static struct dma_buf *ivpu_bo_export(struct drm_gem_object *obj, int flags)
258+{
259+ struct drm_device *dev = obj->dev;
260+ struct dma_buf_export_info exp_info = {
261+ .exp_name = KBUILD_MODNAME,
262+ .owner = dev->driver->fops->owner,
263+ .ops = &ivpu_bo_dmabuf_ops,
264+ .size = obj->size,
265+ .flags = flags,
266+ .priv = obj,
267+ .resv = obj->resv,
268+ };
269+ void *sgt;
270+
271+ /*
272+ * Make sure that pages are allocated and dma-mapped before exporting the bo.
273+ * DMA-mapping is required if the bo will be imported to the same device.
274+ */
275+ sgt = drm_gem_shmem_get_pages_sgt(to_drm_gem_shmem_obj(obj));
276+ if (IS_ERR(sgt))
277+ return sgt;
278+
279+ return drm_gem_dmabuf_export(dev, &exp_info);
509280 }
510281
511−static const struct vm_operations_struct ivpu_vm_ops = {
512− .fault = ivpu_vm_fault,
513− .open = drm_gem_vm_open,
514− .close = drm_gem_vm_close,
515−};
516−
517282 static const struct drm_gem_object_funcs ivpu_gem_funcs = {
518283 .free = ivpu_bo_free,
519− .mmap = ivpu_bo_mmap,
520− .vm_ops = &ivpu_vm_ops,
521− .get_sg_table = ivpu_bo_get_sg_table,
284+ .open = ivpu_bo_open,
285+ .export = ivpu_bo_export,
286+ .print_info = drm_gem_shmem_object_print_info,
287+ .pin = drm_gem_shmem_object_pin,
288+ .unpin = drm_gem_shmem_object_unpin,
289+ .get_sg_table = drm_gem_shmem_object_get_sg_table,
290+ .vmap = drm_gem_shmem_object_vmap,
291+ .vunmap = drm_gem_shmem_object_vunmap,
292+ .mmap = drm_gem_shmem_object_mmap,
293+ .vm_ops = &drm_gem_shmem_vm_ops,
522294 };
523295
524−int
525−ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
296+int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
526297 {
527298 struct ivpu_file_priv *file_priv = file->driver_priv;
528299 struct ivpu_device *vdev = file_priv->vdev;
@@ -537,23 +308,20 @@ ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 8 unmodified lines
537308 if (size == 0)
538309 return -EINVAL;
539310
540− bo = ivpu_bo_alloc(vdev, &file_priv->ctx, size, args->flags, &shmem_ops, NULL, 0);
311+ bo = ivpu_bo_create(vdev, size, args->flags);
541312 if (IS_ERR(bo)) {
542313 ivpu_err(vdev, "Failed to create BO: %pe (ctx %u size %llu flags 0x%x)",
543314 bo, file_priv->ctx.id, args->size, args->flags);
544315 return PTR_ERR(bo);
545316 }
546317
547− ret = drm_gem_handle_create(file, &bo->base, &bo->handle);
318+ ret = drm_gem_handle_create(file, &bo->base.base, &bo->handle);
548319 if (!ret) {
549320 args->vpu_addr = bo->vpu_addr;
550321 args->handle = bo->handle;
551322 }
552323
553− drm_gem_object_put(&bo->base);
554−
555− ivpu_dbg(vdev, BO, "alloc shmem: ctx %u vpu_addr 0x%llx size %zu flags 0x%x\n",
556− file_priv->ctx.id, bo->vpu_addr, ivpu_bo_size(bo), bo->flags);
324+ drm_gem_object_put(&bo->base.base);
557325
558326 return ret;
559327 }
@@ -563,8 +331,8 @@ ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 fla · 3 unmodified lines
563331 {
564332 const struct ivpu_addr_range *range;
565333 struct ivpu_addr_range fixed_range;
334+ struct iosys_map map;
566335 struct ivpu_bo *bo;
567− pgprot_t prot;
568336 int ret;
569337
570338 drm_WARN_ON(&vdev->drm, !PAGE_ALIGNED(vpu_addr));
@@ -578,81 +346,42 @@ ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 fla · 7 unmodified lines
578346 range = &vdev->hw->ranges.global;
579347 }
580348
581− bo = ivpu_bo_alloc(vdev, &vdev->gctx, size, flags, &internal_ops, range, 0);
349+ bo = ivpu_bo_create(vdev, size, flags);
582350 if (IS_ERR(bo)) {
583351 ivpu_err(vdev, "Failed to create BO: %pe (vpu_addr 0x%llx size %llu flags 0x%x)",
584352 bo, vpu_addr, size, flags);
585353 return NULL;
586354 }
587355
588− ret = ivpu_bo_pin(bo);
356+ ret = ivpu_bo_alloc_vpu_addr(bo, &vdev->gctx, range);
589357 if (ret)
590358 goto err_put;
591359
592− if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED)
593− drm_clflush_pages(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT);
594−
595− if (bo->flags & DRM_IVPU_BO_WC)
596− set_pages_array_wc(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT);
597− else if (bo->flags & DRM_IVPU_BO_UNCACHED)
598− set_pages_array_uc(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT);
599−
600− prot = ivpu_bo_pgprot(bo, PAGE_KERNEL);
601− bo->kvaddr = vmap(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT, VM_MAP, prot);
602− if (!bo->kvaddr) {
603− ivpu_err(vdev, "Failed to map BO into kernel virtual memory\n");
360+ ret = ivpu_bo_pin(bo);
361+ if (ret)
604362 goto err_put;
605− }
606363
607− ivpu_dbg(vdev, BO, "alloc internal: ctx 0 vpu_addr 0x%llx size %zu flags 0x%x\n",
608− bo->vpu_addr, ivpu_bo_size(bo), flags);
364+ ret = drm_gem_shmem_vmap(&bo->base, &map);
365+ if (ret)
366+ goto err_put;
609367
610368 return bo;
611369
612370 err_put:
613− drm_gem_object_put(&bo->base);
371+ drm_gem_object_put(&bo->base.base);
614372 return NULL;
615373 }
616374
617375 void ivpu_bo_free_internal(struct ivpu_bo *bo)
618376 {
619− drm_gem_object_put(&bo->base);
620−}
621−
622−struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
623−{
624− struct ivpu_device *vdev = to_ivpu_device(dev);
625− struct dma_buf_attachment *attach;
626− struct ivpu_bo *bo;
627−
628− attach = dma_buf_attach(buf, dev->dev);
629− if (IS_ERR(attach))
630− return ERR_CAST(attach);
631−
632− get_dma_buf(buf);
377+ struct iosys_map map = IOSYS_MAP_INIT_VADDR(bo->base.vaddr);
633378
634− bo = ivpu_bo_alloc(vdev, NULL, buf->size, DRM_IVPU_BO_MAPPABLE, &prime_ops, NULL, 0);
635− if (IS_ERR(bo)) {
636− ivpu_err(vdev, "Failed to import BO: %pe (size %lu)", bo, buf->size);
637− goto err_detach;
638− }
639−
640− lockdep_set_class(&bo->lock, &prime_bo_lock_class_key);
641−
642− bo->base.import_attach = attach;
643−
644− return &bo->base;
645−
646−err_detach:
647− dma_buf_detach(buf, attach);
648− dma_buf_put(buf);
649− return ERR_CAST(bo);
379+ drm_gem_shmem_vunmap(&bo->base, &map);
380+ drm_gem_object_put(&bo->base.base);
650381 }
651382
652383 int ivpu_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
653384 {
654− struct ivpu_file_priv *file_priv = file->driver_priv;
655− struct ivpu_device *vdev = to_ivpu_device(dev);
656385 struct drm_ivpu_bo_info *args = data;
657386 struct drm_gem_object *obj;
658387 struct ivpu_bo *bo;
@@ -665,21 +394,12 @@ int ivpu_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file · 6 unmodified lines
665394 bo = to_ivpu_bo(obj);
666395
667396 mutex_lock(&bo->lock);
668−
669− if (!bo->ctx) {
670− ret = ivpu_bo_alloc_vpu_addr(bo, &file_priv->ctx, NULL);
671− if (ret) {
672− ivpu_err(vdev, "Failed to allocate vpu_addr: %d\n", ret);
673− goto unlock;
674− }
675− }
676−
677397 args->flags = bo->flags;
678398 args->mmap_offset = drm_vma_node_offset_addr(&obj->vma_node);
679399 args->vpu_addr = bo->vpu_addr;
680400 args->size = obj->size;
681−unlock:
682401 mutex_unlock(&bo->lock);
402+
683403 drm_gem_object_put(obj);
684404 return ret;
685405 }
@@ -714,41 +434,41 @@ static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) · 28 unmodified lines
714434 {
715435 unsigned long dma_refcount = 0;
716436
717− if (bo->base.dma_buf && bo->base.dma_buf->file)
718− dma_refcount = atomic_long_read(&bo->base.dma_buf->file->f_count);
437+ mutex_lock(&bo->lock);
438+
439+ if (bo->base.base.dma_buf && bo->base.base.dma_buf->file)
440+ dma_refcount = atomic_long_read(&bo->base.base.dma_buf->file->f_count);
441+
442+ drm_printf(p, "%-3u %-6d 0x%-12llx %-10lu 0x%-8x %-4u %-8lu",
443+ bo->ctx->id, bo->handle, bo->vpu_addr, bo->base.base.size,
444+ bo->flags, kref_read(&bo->base.base.refcount), dma_refcount);
445+
446+ if (bo->base.base.import_attach)
447+ drm_printf(p, " imported");
448+
449+ if (bo->base.pages)
450+ drm_printf(p, " has_pages");
719451
720− drm_printf(p, "%5u %6d %16llx %10lu %10u %12lu %14s\n",
721− bo->ctx->id, bo->handle, bo->vpu_addr, ivpu_bo_size(bo),
722− kref_read(&bo->base.refcount), dma_refcount, bo->ops->name);
452+ if (bo->mmu_mapped)
453+ drm_printf(p, " mmu_mapped");
454+
455+ drm_printf(p, "\n");
456+
457+ mutex_unlock(&bo->lock);
723458 }
724459
725460 void ivpu_bo_list(struct drm_device *dev, struct drm_printer *p)
726461 {
727462 struct ivpu_device *vdev = to_ivpu_device(dev);
728− struct ivpu_file_priv *file_priv;
729− unsigned long ctx_id;
730463 struct ivpu_bo *bo;
731464
732− drm_printf(p, "%5s %6s %16s %10s %10s %12s %14s\n",
733− "ctx", "handle", "vpu_addr", "size", "refcount", "dma_refcount", "type");
465+ drm_printf(p, "%-3s %-6s %-14s %-10s %-10s %-4s %-8s %s\n",
466+ "ctx", "handle", "vpu_addr", "size", "flags", "refs", "dma_refs", "attribs");
734467
735− mutex_lock(&vdev->gctx.lock);
736− list_for_each_entry(bo, &vdev->gctx.bo_list, ctx_node)
468+ mutex_lock(&vdev->bo_list_lock);
469+ list_for_each_entry(bo, &vdev->bo_list, bo_list_node)
737470 ivpu_bo_print_info(bo, p);
738− mutex_unlock(&vdev->gctx.lock);
739−
740− xa_for_each(&vdev->context_xa, ctx_id, file_priv) {
741− file_priv = ivpu_file_priv_get_by_ctx_id(vdev, ctx_id);
742− if (!file_priv)
743− continue;
744−
745− mutex_lock(&file_priv->ctx.lock);
746− list_for_each_entry(bo, &file_priv->ctx.bo_list, ctx_node)
747− ivpu_bo_print_info(bo, p);
748− mutex_unlock(&file_priv->ctx.lock);
749−
750− ivpu_file_priv_put(&file_priv);
751− }
471+ mutex_unlock(&vdev->bo_list_lock);
752472 }
753473
754474 void ivpu_bo_list_print(struct drm_device *dev)
drivers/accel/ivpu/ivpu_gem.h+16−59
@@ -6,84 +6,52 @@ · 5 unmodified lines
66 #define __IVPU_GEM_H__
77
88 #include <drm/drm_gem.h>
9+#include <drm/drm_gem_shmem_helper.h>
910 #include <drm/drm_mm.h>
1011
11−struct dma_buf;
12−struct ivpu_bo_ops;
1312 struct ivpu_file_priv;
1413
1514 struct ivpu_bo {
16− struct drm_gem_object base;
17− const struct ivpu_bo_ops *ops;
18−
15+ struct drm_gem_shmem_object base;
1916 struct ivpu_mmu_context *ctx;
20− struct list_head ctx_node;
17+ struct list_head bo_list_node;
2118 struct drm_mm_node mm_node;
2219
23− struct mutex lock; /* Protects: pages, sgt, mmu_mapped */
24− struct sg_table *sgt;
25− struct page **pages;
26− bool mmu_mapped;
27−
28− void *kvaddr;
20+ struct mutex lock; /* Protects: ctx, mmu_mapped, vpu_addr */
2921 u64 vpu_addr;
3022 u32 handle;
3123 u32 flags;
32− uintptr_t user_ptr;
33− u32 job_status;
34−};
35−
36−enum ivpu_bo_type {
37− IVPU_BO_TYPE_SHMEM = 1,
38− IVPU_BO_TYPE_INTERNAL,
39− IVPU_BO_TYPE_PRIME,
40−};
41−
42−struct ivpu_bo_ops {
43− enum ivpu_bo_type type;
44− const char *name;
45− int (*alloc_pages)(struct ivpu_bo *bo);
46− void (*free_pages)(struct ivpu_bo *bo);
47− int (*map_pages)(struct ivpu_bo *bo);
48− void (*unmap_pages)(struct ivpu_bo *bo);
24+ u32 job_status; /* Valid only for command buffer */
25+ bool mmu_mapped;
4926 };
5027
5128 int ivpu_bo_pin(struct ivpu_bo *bo);
52−void ivpu_bo_remove_all_bos_from_context(struct ivpu_mmu_context *ctx);
53−void ivpu_bo_list(struct drm_device *dev, struct drm_printer *p);
54−void ivpu_bo_list_print(struct drm_device *dev);
29+void ivpu_bo_remove_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx);
5530
56−struct ivpu_bo *
57−ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 flags);
31+struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size);
32+struct ivpu_bo *ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 flags);
5833 void ivpu_bo_free_internal(struct ivpu_bo *bo);
59−struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf);
60−void ivpu_bo_unmap_sgt_and_remove_from_context(struct ivpu_bo *bo);
6134
6235 int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
6336 int ivpu_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
6437 int ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
6538
39+void ivpu_bo_list(struct drm_device *dev, struct drm_printer *p);
40+void ivpu_bo_list_print(struct drm_device *dev);
41+
6642 static inline struct ivpu_bo *to_ivpu_bo(struct drm_gem_object *obj)
6743 {
68− return container_of(obj, struct ivpu_bo, base);
44+ return container_of(obj, struct ivpu_bo, base.base);
6945 }
7046
7147 static inline void *ivpu_bo_vaddr(struct ivpu_bo *bo)
7248 {
73− return bo->kvaddr;
49+ return bo->base.vaddr;
7450 }
7551
7652 static inline size_t ivpu_bo_size(struct ivpu_bo *bo)
7753 {
78− return bo->base.size;
79−}
80−
81−static inline struct page *ivpu_bo_get_page(struct ivpu_bo *bo, u64 offset)
82−{
83− if (offset > ivpu_bo_size(bo) || !bo->pages)
84− return NULL;
85−
86− return bo->pages[offset / PAGE_SIZE];
54+ return bo->base.base.size;
8755 }
8856
8957 static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
@@ -96,20 +64,9 @@ static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) · 6 unmodified lines
9664 return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
9765 }
9866
99−static inline pgprot_t ivpu_bo_pgprot(struct ivpu_bo *bo, pgprot_t prot)
100−{
101− if (bo->flags & DRM_IVPU_BO_WC)
102− return pgprot_writecombine(prot);
103−
104− if (bo->flags & DRM_IVPU_BO_UNCACHED)
105− return pgprot_noncached(prot);
106−
107− return prot;
108−}
109−
11067 static inline struct ivpu_device *ivpu_bo_to_vdev(struct ivpu_bo *bo)
11168 {
112− return to_ivpu_device(bo->base.dev);
69+ return to_ivpu_device(bo->base.base.dev);
11370 }
11471
11572 static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
drivers/accel/ivpu/ivpu_hw.h+20−0
@@ -15,8 +15,11 @@ struct ivpu_hw_ops { · 14 unmodified lines
1515 int (*power_down)(struct ivpu_device *vdev);
1616 int (*reset)(struct ivpu_device *vdev);
1717 bool (*is_idle)(struct ivpu_device *vdev);
18+ int (*wait_for_idle)(struct ivpu_device *vdev);
1819 void (*wdt_disable)(struct ivpu_device *vdev);
1920 void (*diagnose_failure)(struct ivpu_device *vdev);
21+ u32 (*profiling_freq_get)(struct ivpu_device *vdev);
22+ void (*profiling_freq_drive)(struct ivpu_device *vdev, bool enable);
2023 u32 (*reg_pll_freq_get)(struct ivpu_device *vdev);
2124 u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev);
2225 u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev);
@@ -58,6 +61,8 @@ struct ivpu_hw_info { · 35 unmodified lines
5861 u32 sku;
5962 u16 config;
6063 int dma_bits;
64+ ktime_t d0i3_entry_host_ts;
65+ u64 d0i3_entry_vpu_ts;
6166 };
6267
6368 extern const struct ivpu_hw_ops ivpu_hw_37xx_ops;
@@ -85,6 +90,11 @@ static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev) · 21 unmodified lines
8590 return vdev->hw->ops->is_idle(vdev);
8691 };
8792
93+static inline int ivpu_hw_wait_for_idle(struct ivpu_device *vdev)
94+{
95+ return vdev->hw->ops->wait_for_idle(vdev);
96+};
97+
8898 static inline int ivpu_hw_power_down(struct ivpu_device *vdev)
8999 {
90100 ivpu_dbg(vdev, PM, "HW power down\n");
@@ -104,6 +114,16 @@ static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev) · 13 unmodified lines
104114 vdev->hw->ops->wdt_disable(vdev);
105115 };
106116
117+static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
118+{
119+ return vdev->hw->ops->profiling_freq_get(vdev);
120+};
121+
122+static inline void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
123+{
124+ return vdev->hw->ops->profiling_freq_drive(vdev, enable);
125+};
126+
107127 /* Register indirect accesses */
108128 static inline u32 ivpu_hw_reg_pll_freq_get(struct ivpu_device *vdev)
109129 {
drivers/accel/ivpu/ivpu_hw_37xx.c+69−36
@@ -29,6 +29,7 @@ · 28 unmodified lines
2929
3030 #define PLL_REF_CLK_FREQ (50 * 1000000)
3131 #define PLL_SIMULATION_FREQ (10 * 1000000)
32+#define PLL_PROF_CLK_FREQ (38400 * 1000)
3233 #define PLL_DEFAULT_EPP_VALUE 0x80
3334
3435 #define TIM_SAFE_ENABLE 0xf1d0dead
@@ -37,7 +38,7 @@ · 2 unmodified lines
3738 #define TIMEOUT_US (150 * USEC_PER_MSEC)
3839 #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
3940 #define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
40−#define IDLE_TIMEOUT_US (500 * USEC_PER_MSEC)
41+#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
4142
4243 #define ICB_0_IRQ_MASK ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
4344 (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
@@ -90,6 +91,7 @@ static void ivpu_hw_timeouts_init(struct ivpu_device *vdev) · 46 unmodified lines
9091 vdev->timeout.tdr = 2000;
9192 vdev->timeout.reschedule_suspend = 10;
9293 vdev->timeout.autosuspend = 10;
94+ vdev->timeout.d0i3_entry_msg = 5;
9395 }
9496
9597 static int ivpu_pll_wait_for_cmd_send(struct ivpu_device *vdev)
@@ -502,6 +504,16 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev) · 406 unmodified lines
502504 return ret;
503505 }
504506
507+static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
508+{
509+ ivpu_boot_dpu_active_drive(vdev, false);
510+ ivpu_boot_pwr_island_isolation_drive(vdev, true);
511+ ivpu_boot_pwr_island_trickle_drive(vdev, false);
512+ ivpu_boot_pwr_island_drive(vdev, false);
513+
514+ return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
515+}
516+
505517 static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
506518 {
507519 u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
@@ -600,25 +612,17 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev) · 92 unmodified lines
600612
601613 static int ivpu_hw_37xx_reset(struct ivpu_device *vdev)
602614 {
603− int ret;
604− u32 val;
605−
606− if (IVPU_WA(punit_disabled))
607− return 0;
615+ int ret = 0;
608616
609− ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
610− if (ret) {
611− ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
612− return ret;
617+ if (ivpu_boot_pwr_domain_disable(vdev)) {
618+ ivpu_err(vdev, "Failed to disable power domain\n");
619+ ret = -EIO;
613620 }
614621
615− val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_IP_RESET);
616− val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, val);
617− REGB_WR32(VPU_37XX_BUTTRESS_VPU_IP_RESET, val);
618−
619− ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
620− if (ret)
621− ivpu_err(vdev, "Timed out waiting for RESET completion\n");
622+ if (ivpu_pll_disable(vdev)) {
623+ ivpu_err(vdev, "Failed to disable PLL\n");
624+ ret = -EIO;
625+ }
622626
623627 return ret;
624628 }
@@ -651,10 +655,6 @@ static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev) · 26 unmodified lines
651655 {
652656 int ret;
653657
654− ret = ivpu_hw_37xx_reset(vdev);
655− if (ret)
656− ivpu_warn(vdev, "Failed to reset HW: %d\n", ret);
657−
658658 ret = ivpu_hw_37xx_d0i3_disable(vdev);
659659 if (ret)
660660 ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
@@ -718,15 +718,28 @@ static bool ivpu_hw_37xx_is_idle(struct ivpu_device *vdev) · 57 unmodified lines
718718 REG_TEST_FLD(VPU_37XX_BUTTRESS_VPU_STATUS, IDLE, val);
719719 }
720720
721+static int ivpu_hw_37xx_wait_for_idle(struct ivpu_device *vdev)
722+{
723+ return REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
724+}
725+
726+static void ivpu_hw_37xx_save_d0i3_entry_timestamp(struct ivpu_device *vdev)
727+{
728+ vdev->hw->d0i3_entry_host_ts = ktime_get_boottime();
729+ vdev->hw->d0i3_entry_vpu_ts = REGV_RD64(VPU_37XX_CPU_SS_TIM_PERF_FREE_CNT);
730+}
731+
721732 static int ivpu_hw_37xx_power_down(struct ivpu_device *vdev)
722733 {
723734 int ret = 0;
724735
725− if (!ivpu_hw_37xx_is_idle(vdev) && ivpu_hw_37xx_reset(vdev))
726− ivpu_err(vdev, "Failed to reset the VPU\n");
736+ ivpu_hw_37xx_save_d0i3_entry_timestamp(vdev);
727737
728− if (ivpu_pll_disable(vdev)) {
729− ivpu_err(vdev, "Failed to disable PLL\n");
738+ if (!ivpu_hw_37xx_is_idle(vdev))
739+ ivpu_warn(vdev, "VPU not idle during power down\n");
740+
741+ if (ivpu_hw_37xx_reset(vdev)) {
742+ ivpu_err(vdev, "Failed to reset VPU\n");
730743 ret = -EIO;
731744 }
732745
@@ -756,6 +769,16 @@ static void ivpu_hw_37xx_wdt_disable(struct ivpu_device *vdev) · 23 unmodified lines
756769 REGV_WR32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, val);
757770 }
758771
772+static u32 ivpu_hw_37xx_profiling_freq_get(struct ivpu_device *vdev)
773+{
774+ return PLL_PROF_CLK_FREQ;
775+}
776+
777+static void ivpu_hw_37xx_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
778+{
779+ /* Profiling freq - is a debug feature. Unavailable on VPU 37XX. */
780+}
781+
759782 static u32 ivpu_hw_37xx_pll_to_freq(u32 ratio, u32 config)
760783 {
761784 u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
@@ -867,17 +890,20 @@ static void ivpu_hw_37xx_irq_noc_firewall_handler(struct ivpu_device *vdev) · 105 unmodified lines
867890 }
868891
869892 /* Handler for IRQs from VPU core (irqV) */
870−static u32 ivpu_hw_37xx_irqv_handler(struct ivpu_device *vdev, int irq)
893+static bool ivpu_hw_37xx_irqv_handler(struct ivpu_device *vdev, int irq, bool *wake_thread)
871894 {
872895 u32 status = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
873896
897+ if (!status)
898+ return false;
899+
874900 REGV_WR32(VPU_37XX_HOST_SS_ICB_CLEAR_0, status);
875901
876902 if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
877903 ivpu_mmu_irq_evtq_handler(vdev);
878904
879905 if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
880− ivpu_ipc_irq_handler(vdev);
906+ ivpu_ipc_irq_handler(vdev, wake_thread);
881907
882908 if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
883909 ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
@@ -894,17 +920,17 @@ static u32 ivpu_hw_37xx_irqv_handler(struct ivpu_device *vdev, int irq) · 10 unmodified lines
894920 if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
895921 ivpu_hw_37xx_irq_noc_firewall_handler(vdev);
896922
897− return status;
923+ return true;
898924 }
899925
900926 /* Handler for IRQs from Buttress core (irqB) */
901−static u32 ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq)
927+static bool ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq)
902928 {
903929 u32 status = REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
904930 bool schedule_recovery = false;
905931
906− if (status == 0)
907− return 0;
932+ if (!status)
933+ return false;
908934
909935 if (REG_TEST_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
910936 ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x",
@@ -940,23 +966,27 @@ static u32 ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq) · 29 unmodified lines
940966 if (schedule_recovery)
941967 ivpu_pm_schedule_recovery(vdev);
942968
943− return status;
969+ return true;
944970 }
945971
946972 static irqreturn_t ivpu_hw_37xx_irq_handler(int irq, void *ptr)
947973 {
948974 struct ivpu_device *vdev = ptr;
949− u32 ret_irqv, ret_irqb;
975+ bool irqv_handled, irqb_handled, wake_thread = false;
950976
951977 REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
952978
953− ret_irqv = ivpu_hw_37xx_irqv_handler(vdev, irq);
954− ret_irqb = ivpu_hw_37xx_irqb_handler(vdev, irq);
979+ irqv_handled = ivpu_hw_37xx_irqv_handler(vdev, irq, &wake_thread);
980+ irqb_handled = ivpu_hw_37xx_irqb_handler(vdev, irq);
955981
956982 /* Re-enable global interrupts to re-trigger MSI for pending interrupts */
957983 REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
958984
959− return IRQ_RETVAL(ret_irqb | ret_irqv);
985+ if (wake_thread)
986+ return IRQ_WAKE_THREAD;
987+ if (irqv_handled || irqb_handled)
988+ return IRQ_HANDLED;
989+ return IRQ_NONE;
960990 }
961991
962992 static void ivpu_hw_37xx_diagnose_failure(struct ivpu_device *vdev)
@@ -993,11 +1023,14 @@ const struct ivpu_hw_ops ivpu_hw_37xx_ops = { · 30 unmodified lines
9931023 .info_init = ivpu_hw_37xx_info_init,
9941024 .power_up = ivpu_hw_37xx_power_up,
9951025 .is_idle = ivpu_hw_37xx_is_idle,
1026+ .wait_for_idle = ivpu_hw_37xx_wait_for_idle,
9961027 .power_down = ivpu_hw_37xx_power_down,
9971028 .reset = ivpu_hw_37xx_reset,
9981029 .boot_fw = ivpu_hw_37xx_boot_fw,
9991030 .wdt_disable = ivpu_hw_37xx_wdt_disable,
10001031 .diagnose_failure = ivpu_hw_37xx_diagnose_failure,
1032+ .profiling_freq_get = ivpu_hw_37xx_profiling_freq_get,
1033+ .profiling_freq_drive = ivpu_hw_37xx_profiling_freq_drive,
10011034 .reg_pll_freq_get = ivpu_hw_37xx_reg_pll_freq_get,
10021035 .reg_telemetry_offset_get = ivpu_hw_37xx_reg_telemetry_offset_get,
10031036 .reg_telemetry_size_get = ivpu_hw_37xx_reg_telemetry_size_get,
drivers/accel/ivpu/ivpu_hw_37xx_reg.h+2−0
@@ -240,6 +240,8 @@ · 239 unmodified lines
240240 #define VPU_37XX_CPU_SS_TIM_GEN_CONFIG 0x06021008u
241241 #define VPU_37XX_CPU_SS_TIM_GEN_CONFIG_WDOG_TO_INT_CLR_MASK BIT_MASK(9)
242242
243+#define VPU_37XX_CPU_SS_TIM_PERF_FREE_CNT 0x06029000u
244+
243245 #define VPU_37XX_CPU_SS_DOORBELL_0 0x06300000u
244246 #define VPU_37XX_CPU_SS_DOORBELL_0_SET_MASK BIT_MASK(0)
245247
drivers/accel/ivpu/ivpu_hw_40xx.c+48−21
@@ -39,6 +39,7 @@ · 38 unmodified lines
3939 #define TIMEOUT_US (150 * USEC_PER_MSEC)
4040 #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
4141 #define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
42+#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
4243
4344 #define WEIGHTS_DEFAULT 0xf711f711u
4445 #define WEIGHTS_ATS_DEFAULT 0x0000f711u
@@ -139,18 +140,21 @@ static void ivpu_hw_timeouts_init(struct ivpu_device *vdev) · 94 unmodified lines
139140 vdev->timeout.tdr = 2000000;
140141 vdev->timeout.reschedule_suspend = 1000;
141142 vdev->timeout.autosuspend = -1;
143+ vdev->timeout.d0i3_entry_msg = 500;
142144 } else if (ivpu_is_simics(vdev)) {
143145 vdev->timeout.boot = 50;
144146 vdev->timeout.jsm = 500;
145147 vdev->timeout.tdr = 10000;
146148 vdev->timeout.reschedule_suspend = 10;
147149 vdev->timeout.autosuspend = -1;
150+ vdev->timeout.d0i3_entry_msg = 100;
148151 } else {
149152 vdev->timeout.boot = 1000;
150153 vdev->timeout.jsm = 500;
151154 vdev->timeout.tdr = 2000;
152155 vdev->timeout.reschedule_suspend = 10;
153156 vdev->timeout.autosuspend = 10;
157+ vdev->timeout.d0i3_entry_msg = 5;
154158 }
155159 }
156160
@@ -824,12 +828,6 @@ static int ivpu_hw_40xx_power_up(struct ivpu_device *vdev) · 667 unmodified lines
824828 {
825829 int ret;
826830
827− ret = ivpu_hw_40xx_reset(vdev);
828− if (ret) {
829− ivpu_err(vdev, "Failed to reset HW: %d\n", ret);
830− return ret;
831− }
832−
833831 ret = ivpu_hw_40xx_d0i3_disable(vdev);
834832 if (ret)
835833 ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
@@ -898,10 +896,23 @@ static bool ivpu_hw_40xx_is_idle(struct ivpu_device *vdev) · 62 unmodified lines
898896 REG_TEST_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, IDLE, val);
899897 }
900898
899+static int ivpu_hw_40xx_wait_for_idle(struct ivpu_device *vdev)
900+{
901+ return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
902+}
903+
904+static void ivpu_hw_40xx_save_d0i3_entry_timestamp(struct ivpu_device *vdev)
905+{
906+ vdev->hw->d0i3_entry_host_ts = ktime_get_boottime();
907+ vdev->hw->d0i3_entry_vpu_ts = REGV_RD64(VPU_40XX_CPU_SS_TIM_PERF_EXT_FREE_CNT);
908+}
909+
901910 static int ivpu_hw_40xx_power_down(struct ivpu_device *vdev)
902911 {
903912 int ret = 0;
904913
914+ ivpu_hw_40xx_save_d0i3_entry_timestamp(vdev);
915+
905916 if (!ivpu_hw_40xx_is_idle(vdev) && ivpu_hw_40xx_reset(vdev))
906917 ivpu_warn(vdev, "Failed to reset the VPU\n");
907918
@@ -933,6 +944,19 @@ static void ivpu_hw_40xx_wdt_disable(struct ivpu_device *vdev) · 25 unmodified lines
933944 REGV_WR32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, val);
934945 }
935946
947+static u32 ivpu_hw_40xx_profiling_freq_get(struct ivpu_device *vdev)
948+{
949+ return vdev->hw->pll.profiling_freq;
950+}
951+
952+static void ivpu_hw_40xx_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
953+{
954+ if (enable)
955+ vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_HIGH;
956+ else
957+ vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
958+}
959+
936960 /* Register indirect accesses */
937961 static u32 ivpu_hw_40xx_reg_pll_freq_get(struct ivpu_device *vdev)
938962 {
@@ -1023,13 +1047,12 @@ static void ivpu_hw_40xx_irq_noc_firewall_handler(struct ivpu_device *vdev) · 84 unmodified lines
10231047 }
10241048
10251049 /* Handler for IRQs from VPU core (irqV) */
1026−static irqreturn_t ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq)
1050+static bool ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq, bool *wake_thread)
10271051 {
10281052 u32 status = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
1029− irqreturn_t ret = IRQ_NONE;
10301053
10311054 if (!status)
1032− return IRQ_NONE;
1055+ return false;
10331056
10341057 REGV_WR32(VPU_40XX_HOST_SS_ICB_CLEAR_0, status);
10351058
@@ -1037,7 +1060,7 @@ static irqreturn_t ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq) · 1 unmodified line
10371060 ivpu_mmu_irq_evtq_handler(vdev);
10381061
10391062 if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
1040− ret |= ivpu_ipc_irq_handler(vdev);
1063+ ivpu_ipc_irq_handler(vdev, wake_thread);
10411064
10421065 if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
10431066 ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
@@ -1054,17 +1077,17 @@ static irqreturn_t ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq) · 10 unmodified lines
10541077 if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
10551078 ivpu_hw_40xx_irq_noc_firewall_handler(vdev);
10561079
1057− return ret;
1080+ return true;
10581081 }
10591082
10601083 /* Handler for IRQs from Buttress core (irqB) */
1061−static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
1084+static bool ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
10621085 {
10631086 bool schedule_recovery = false;
10641087 u32 status = REGB_RD32(VPU_40XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
10651088
1066− if (status == 0)
1067− return IRQ_NONE;
1089+ if (!status)
1090+ return false;
10681091
10691092 if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
10701093 ivpu_dbg(vdev, IRQ, "FREQ_CHANGE");
@@ -1116,26 +1139,27 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq) · 45 unmodified lines
11161139 if (schedule_recovery)
11171140 ivpu_pm_schedule_recovery(vdev);
11181141
1119− return IRQ_HANDLED;
1142+ return true;
11201143 }
11211144
11221145 static irqreturn_t ivpu_hw_40xx_irq_handler(int irq, void *ptr)
11231146 {
1147+ bool irqv_handled, irqb_handled, wake_thread = false;
11241148 struct ivpu_device *vdev = ptr;
1125− irqreturn_t ret = IRQ_NONE;
11261149
11271150 REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
11281151
1129− ret |= ivpu_hw_40xx_irqv_handler(vdev, irq);
1130− ret |= ivpu_hw_40xx_irqb_handler(vdev, irq);
1152+ irqv_handled = ivpu_hw_40xx_irqv_handler(vdev, irq, &wake_thread);
1153+ irqb_handled = ivpu_hw_40xx_irqb_handler(vdev, irq);
11311154
11321155 /* Re-enable global interrupts to re-trigger MSI for pending interrupts */
11331156 REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
11341157
1135− if (ret & IRQ_WAKE_THREAD)
1158+ if (wake_thread)
11361159 return IRQ_WAKE_THREAD;
1137−
1138− return ret;
1160+ if (irqv_handled || irqb_handled)
1161+ return IRQ_HANDLED;
1162+ return IRQ_NONE;
11391163 }
11401164
11411165 static void ivpu_hw_40xx_diagnose_failure(struct ivpu_device *vdev)
@@ -1185,11 +1209,14 @@ const struct ivpu_hw_ops ivpu_hw_40xx_ops = { · 43 unmodified lines
11851209 .info_init = ivpu_hw_40xx_info_init,
11861210 .power_up = ivpu_hw_40xx_power_up,
11871211 .is_idle = ivpu_hw_40xx_is_idle,
1212+ .wait_for_idle = ivpu_hw_40xx_wait_for_idle,
11881213 .power_down = ivpu_hw_40xx_power_down,
11891214 .reset = ivpu_hw_40xx_reset,
11901215 .boot_fw = ivpu_hw_40xx_boot_fw,
11911216 .wdt_disable = ivpu_hw_40xx_wdt_disable,
11921217 .diagnose_failure = ivpu_hw_40xx_diagnose_failure,
1218+ .profiling_freq_get = ivpu_hw_40xx_profiling_freq_get,
1219+ .profiling_freq_drive = ivpu_hw_40xx_profiling_freq_drive,
11931220 .reg_pll_freq_get = ivpu_hw_40xx_reg_pll_freq_get,
11941221 .reg_telemetry_offset_get = ivpu_hw_40xx_reg_telemetry_offset_get,
11951222 .reg_telemetry_size_get = ivpu_hw_40xx_reg_telemetry_size_get,
drivers/accel/ivpu/ivpu_ipc.c+157−94
@@ -5,7 +5,7 @@ · 4 unmodified lines
55
66 #include <linux/genalloc.h>
77 #include <linux/highmem.h>
8−#include <linux/kthread.h>
8+#include <linux/pm_runtime.h>
99 #include <linux/wait.h>
1010
1111 #include "ivpu_drv.h"
@@ -17,19 +17,12 @@ · 5 unmodified lines
1717 #include "ivpu_pm.h"
1818
1919 #define IPC_MAX_RX_MSG 128
20−#define IS_KTHREAD() (get_current()->flags & PF_KTHREAD)
2120
2221 struct ivpu_ipc_tx_buf {
2322 struct ivpu_ipc_hdr ipc;
2423 struct vpu_jsm_msg jsm;
2524 };
2625
27−struct ivpu_ipc_rx_msg {
28− struct list_head link;
29− struct ivpu_ipc_hdr *ipc_hdr;
30− struct vpu_jsm_msg *jsm_msg;
31−};
32−
3326 static void ivpu_ipc_msg_dump(struct ivpu_device *vdev, char *c,
3427 struct ivpu_ipc_hdr *ipc_hdr, u32 vpu_addr)
3528 {
@@ -139,8 +132,49 @@ static void ivpu_ipc_tx(struct ivpu_device *vdev, u32 vpu_addr) · 103 unmodified lines
139132 ivpu_hw_reg_ipc_tx_set(vdev, vpu_addr);
140133 }
141134
142−void
143−ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, u32 channel)
135+static void
136+ivpu_ipc_rx_msg_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
137+ struct ivpu_ipc_hdr *ipc_hdr, struct vpu_jsm_msg *jsm_msg)
138+{
139+ struct ivpu_ipc_info *ipc = vdev->ipc;
140+ struct ivpu_ipc_rx_msg *rx_msg;
141+
142+ lockdep_assert_held(&ipc->cons_lock);
143+ lockdep_assert_irqs_disabled();
144+
145+ rx_msg = kzalloc(sizeof(*rx_msg), GFP_ATOMIC);
146+ if (!rx_msg) {
147+ ivpu_ipc_rx_mark_free(vdev, ipc_hdr, jsm_msg);
148+ return;
149+ }
150+
151+ atomic_inc(&ipc->rx_msg_count);
152+
153+ rx_msg->ipc_hdr = ipc_hdr;
154+ rx_msg->jsm_msg = jsm_msg;
155+ rx_msg->callback = cons->rx_callback;
156+
157+ if (rx_msg->callback) {
158+ list_add_tail(&rx_msg->link, &ipc->cb_msg_list);
159+ } else {
160+ spin_lock(&cons->rx_lock);
161+ list_add_tail(&rx_msg->link, &cons->rx_msg_list);
162+ spin_unlock(&cons->rx_lock);
163+ wake_up(&cons->rx_msg_wq);
164+ }
165+}
166+
167+static void
168+ivpu_ipc_rx_msg_del(struct ivpu_device *vdev, struct ivpu_ipc_rx_msg *rx_msg)
169+{
170+ list_del(&rx_msg->link);
171+ ivpu_ipc_rx_mark_free(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
172+ atomic_dec(&vdev->ipc->rx_msg_count);
173+ kfree(rx_msg);
174+}
175+
176+void ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
177+ u32 channel, ivpu_ipc_rx_callback_t rx_callback)
144178 {
145179 struct ivpu_ipc_info *ipc = vdev->ipc;
146180
@@ -148,13 +182,15 @@ ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, · 1 unmodified line
148182 cons->channel = channel;
149183 cons->tx_vpu_addr = 0;
150184 cons->request_id = 0;
151− spin_lock_init(&cons->rx_msg_lock);
185+ cons->aborted = false;
186+ cons->rx_callback = rx_callback;
187+ spin_lock_init(&cons->rx_lock);
152188 INIT_LIST_HEAD(&cons->rx_msg_list);
153189 init_waitqueue_head(&cons->rx_msg_wq);
154190
155− spin_lock_irq(&ipc->cons_list_lock);
191+ spin_lock_irq(&ipc->cons_lock);
156192 list_add_tail(&cons->link, &ipc->cons_list);
157− spin_unlock_irq(&ipc->cons_list_lock);
193+ spin_unlock_irq(&ipc->cons_lock);
158194 }
159195
160196 void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons)
@@ -162,18 +198,14 @@ void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *c · 1 unmodified line
162198 struct ivpu_ipc_info *ipc = vdev->ipc;
163199 struct ivpu_ipc_rx_msg *rx_msg, *r;
164200
165− spin_lock_irq(&ipc->cons_list_lock);
201+ spin_lock_irq(&ipc->cons_lock);
166202 list_del(&cons->link);
167− spin_unlock_irq(&ipc->cons_list_lock);
168−
169− spin_lock_irq(&cons->rx_msg_lock);
170− list_for_each_entry_safe(rx_msg, r, &cons->rx_msg_list, link) {
171− list_del(&rx_msg->link);
172− ivpu_ipc_rx_mark_free(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
173− atomic_dec(&ipc->rx_msg_count);
174− kfree(rx_msg);
175− }
176− spin_unlock_irq(&cons->rx_msg_lock);
203+ spin_unlock_irq(&ipc->cons_lock);
204+
205+ spin_lock_irq(&cons->rx_lock);
206+ list_for_each_entry_safe(rx_msg, r, &cons->rx_msg_list, link)
207+ ivpu_ipc_rx_msg_del(vdev, rx_msg);
208+ spin_unlock_irq(&cons->rx_lock);
177209
178210 ivpu_ipc_tx_release(vdev, cons->tx_vpu_addr);
179211 }
@@ -202,52 +234,61 @@ unlock: · 22 unmodified lines
202234 return ret;
203235 }
204236
237+static bool ivpu_ipc_rx_need_wakeup(struct ivpu_ipc_consumer *cons)
238+{
239+ bool ret;
240+
241+ spin_lock_irq(&cons->rx_lock);
242+ ret = !list_empty(&cons->rx_msg_list) || cons->aborted;
243+ spin_unlock_irq(&cons->rx_lock);
244+
245+ return ret;
246+}
247+
205248 int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
206249 struct ivpu_ipc_hdr *ipc_buf,
207− struct vpu_jsm_msg *ipc_payload, unsigned long timeout_ms)
250+ struct vpu_jsm_msg *jsm_msg, unsigned long timeout_ms)
208251 {
209− struct ivpu_ipc_info *ipc = vdev->ipc;
210252 struct ivpu_ipc_rx_msg *rx_msg;
211253 int wait_ret, ret = 0;
212254
255+ if (drm_WARN_ONCE(&vdev->drm, cons->rx_callback, "Consumer works only in async mode\n"))
256+ return -EINVAL;
257+
213258 wait_ret = wait_event_timeout(cons->rx_msg_wq,
214− (IS_KTHREAD() && kthread_should_stop()) ||
215− !list_empty(&cons->rx_msg_list),
259+ ivpu_ipc_rx_need_wakeup(cons),
216260 msecs_to_jiffies(timeout_ms));
217261
218− if (IS_KTHREAD() && kthread_should_stop())
219− return -EINTR;
220−
221262 if (wait_ret == 0)
222263 return -ETIMEDOUT;
223264
224− spin_lock_irq(&cons->rx_msg_lock);
265+ spin_lock_irq(&cons->rx_lock);
266+ if (cons->aborted) {
267+ spin_unlock_irq(&cons->rx_lock);
268+ return -ECANCELED;
269+ }
225270 rx_msg = list_first_entry_or_null(&cons->rx_msg_list, struct ivpu_ipc_rx_msg, link);
226271 if (!rx_msg) {
227− spin_unlock_irq(&cons->rx_msg_lock);
272+ spin_unlock_irq(&cons->rx_lock);
228273 return -EAGAIN;
229274 }
230− list_del(&rx_msg->link);
231− spin_unlock_irq(&cons->rx_msg_lock);
232275
233276 if (ipc_buf)
234277 memcpy(ipc_buf, rx_msg->ipc_hdr, sizeof(*ipc_buf));
235278 if (rx_msg->jsm_msg) {
236− u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*ipc_payload));
279+ u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg));
237280
238281 if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) {
239282 ivpu_dbg(vdev, IPC, "IPC resp result error: %d\n", rx_msg->jsm_msg->result);
240283 ret = -EBADMSG;
241284 }
242285
243− if (ipc_payload)
244− memcpy(ipc_payload, rx_msg->jsm_msg, size);
286+ if (jsm_msg)
287+ memcpy(jsm_msg, rx_msg->jsm_msg, size);
245288 }
246289
247− ivpu_ipc_rx_mark_free(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
248− atomic_dec(&ipc->rx_msg_count);
249− kfree(rx_msg);
250−
290+ ivpu_ipc_rx_msg_del(vdev, rx_msg);
291+ spin_unlock_irq(&cons->rx_lock);
251292 return ret;
252293 }
253294
@@ -260,7 +301,7 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req · 6 unmodified lines
260301 struct ivpu_ipc_consumer cons;
261302 int ret;
262303
263− ivpu_ipc_consumer_add(vdev, &cons, channel);
304+ ivpu_ipc_consumer_add(vdev, &cons, channel, NULL);
264305
265306 ret = ivpu_ipc_send(vdev, &cons, req);
266307 if (ret) {
@@ -285,23 +326,19 @@ consumer_del: · 18 unmodified lines
285326 return ret;
286327 }
287328
288−int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
289− enum vpu_ipc_msg_type expected_resp_type,
290− struct vpu_jsm_msg *resp, u32 channel,
291− unsigned long timeout_ms)
329+int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
330+ enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
331+ u32 channel, unsigned long timeout_ms)
292332 {
293333 struct vpu_jsm_msg hb_req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB };
294334 struct vpu_jsm_msg hb_resp;
295335 int ret, hb_ret;
296336
297− ret = ivpu_rpm_get(vdev);
298− if (ret < 0)
299− return ret;
337+ drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev));
300338
301− ret = ivpu_ipc_send_receive_internal(vdev, req, expected_resp_type, resp,
302− channel, timeout_ms);
339+ ret = ivpu_ipc_send_receive_internal(vdev, req, expected_resp, resp, channel, timeout_ms);
303340 if (ret != -ETIMEDOUT)
304− goto rpm_put;
341+ return ret;
305342
306343 hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE,
307344 &hb_resp, VPU_IPC_CHAN_ASYNC_CMD,
@@ -311,7 +348,21 @@ int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, · 3 unmodified lines
311348 ivpu_pm_schedule_recovery(vdev);
312349 }
313350
314−rpm_put:
351+ return ret;
352+}
353+
354+int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
355+ enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
356+ u32 channel, unsigned long timeout_ms)
357+{
358+ int ret;
359+
360+ ret = ivpu_rpm_get(vdev);
361+ if (ret < 0)
362+ return ret;
363+
364+ ret = ivpu_ipc_send_receive_active(vdev, req, expected_resp, resp, channel, timeout_ms);
365+
315366 ivpu_rpm_put(vdev);
316367 return ret;
317368 }
@@ -329,35 +380,7 @@ ivpu_ipc_match_consumer(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons · 11 unmodified lines
329380 return false;
330381 }
331382
332−static void
333−ivpu_ipc_dispatch(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
334− struct ivpu_ipc_hdr *ipc_hdr, struct vpu_jsm_msg *jsm_msg)
335−{
336− struct ivpu_ipc_info *ipc = vdev->ipc;
337− struct ivpu_ipc_rx_msg *rx_msg;
338− unsigned long flags;
339−
340− lockdep_assert_held(&ipc->cons_list_lock);
341−
342− rx_msg = kzalloc(sizeof(*rx_msg), GFP_ATOMIC);
343− if (!rx_msg) {
344− ivpu_ipc_rx_mark_free(vdev, ipc_hdr, jsm_msg);
345− return;
346− }
347−
348− atomic_inc(&ipc->rx_msg_count);
349−
350− rx_msg->ipc_hdr = ipc_hdr;
351− rx_msg->jsm_msg = jsm_msg;
352−
353− spin_lock_irqsave(&cons->rx_msg_lock, flags);
354− list_add_tail(&rx_msg->link, &cons->rx_msg_list);
355− spin_unlock_irqrestore(&cons->rx_msg_lock, flags);
356−
357− wake_up(&cons->rx_msg_wq);
358−}
359−
360−int ivpu_ipc_irq_handler(struct ivpu_device *vdev)
383+void ivpu_ipc_irq_handler(struct ivpu_device *vdev, bool *wake_thread)
361384 {
362385 struct ivpu_ipc_info *ipc = vdev->ipc;
363386 struct ivpu_ipc_consumer *cons;
@@ -375,7 +398,7 @@ int ivpu_ipc_irq_handler(struct ivpu_device *vdev) · 11 unmodified lines
375398 vpu_addr = ivpu_hw_reg_ipc_rx_addr_get(vdev);
376399 if (vpu_addr == REG_IO_ERROR) {
377400 ivpu_err_ratelimited(vdev, "Failed to read IPC rx addr register\n");
378− return -EIO;
401+ return;
379402 }
380403
381404 ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr);
@@ -405,15 +428,15 @@ int ivpu_ipc_irq_handler(struct ivpu_device *vdev) · 23 unmodified lines
405428 }
406429
407430 dispatched = false;
408− spin_lock_irqsave(&ipc->cons_list_lock, flags);
431+ spin_lock_irqsave(&ipc->cons_lock, flags);
409432 list_for_each_entry(cons, &ipc->cons_list, link) {
410433 if (ivpu_ipc_match_consumer(vdev, cons, ipc_hdr, jsm_msg)) {
411− ivpu_ipc_dispatch(vdev, cons, ipc_hdr, jsm_msg);
434+ ivpu_ipc_rx_msg_add(vdev, cons, ipc_hdr, jsm_msg);
412435 dispatched = true;
413436 break;
414437 }
415438 }
416− spin_unlock_irqrestore(&ipc->cons_list_lock, flags);
439+ spin_unlock_irqrestore(&ipc->cons_lock, flags);
417440
418441 if (!dispatched) {
419442 ivpu_dbg(vdev, IPC, "IPC RX msg 0x%x dropped (no consumer)\n", vpu_addr);
@@ -421,7 +444,28 @@ int ivpu_ipc_irq_handler(struct ivpu_device *vdev) · 1 unmodified line
421444 }
422445 }
423446
424− return 0;
447+ if (wake_thread)
448+ *wake_thread = !list_empty(&ipc->cb_msg_list);
449+}
450+
451+irqreturn_t ivpu_ipc_irq_thread_handler(struct ivpu_device *vdev)
452+{
453+ struct ivpu_ipc_info *ipc = vdev->ipc;
454+ struct ivpu_ipc_rx_msg *rx_msg, *r;
455+ struct list_head cb_msg_list;
456+
457+ INIT_LIST_HEAD(&cb_msg_list);
458+
459+ spin_lock_irq(&ipc->cons_lock);
460+ list_splice_tail_init(&ipc->cb_msg_list, &cb_msg_list);
461+ spin_unlock_irq(&ipc->cons_lock);
462+
463+ list_for_each_entry_safe(rx_msg, r, &cb_msg_list, link) {
464+ rx_msg->callback(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
465+ ivpu_ipc_rx_msg_del(vdev, rx_msg);
466+ }
467+
468+ return IRQ_HANDLED;
425469 }
426470
427471 int ivpu_ipc_init(struct ivpu_device *vdev)
@@ -456,10 +500,10 @@ int ivpu_ipc_init(struct ivpu_device *vdev) · 28 unmodified lines
456500 goto err_free_rx;
457501 }
458502
503+ spin_lock_init(&ipc->cons_lock);
459504 INIT_LIST_HEAD(&ipc->cons_list);
460− spin_lock_init(&ipc->cons_list_lock);
505+ INIT_LIST_HEAD(&ipc->cb_msg_list);
461506 drmm_mutex_init(&vdev->drm, &ipc->lock);
462−
463507 ivpu_ipc_reset(vdev);
464508 return 0;
465509
@@ -472,6 +516,13 @@ err_free_tx: · 6 unmodified lines
472516
473517 void ivpu_ipc_fini(struct ivpu_device *vdev)
474518 {
519+ struct ivpu_ipc_info *ipc = vdev->ipc;
520+
521+ drm_WARN_ON(&vdev->drm, ipc->on);
522+ drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cons_list));
523+ drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cb_msg_list));
524+ drm_WARN_ON(&vdev->drm, atomic_read(&ipc->rx_msg_count) > 0);
525+
475526 ivpu_ipc_mem_fini(vdev);
476527 }
477528
@@ -488,16 +539,27 @@ void ivpu_ipc_disable(struct ivpu_device *vdev) · 10 unmodified lines
488539 {
489540 struct ivpu_ipc_info *ipc = vdev->ipc;
490541 struct ivpu_ipc_consumer *cons, *c;
491− unsigned long flags;
542+ struct ivpu_ipc_rx_msg *rx_msg, *r;
543+
544+ drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cb_msg_list));
492545
493546 mutex_lock(&ipc->lock);
494547 ipc->on = false;
495548 mutex_unlock(&ipc->lock);
496549
497− spin_lock_irqsave(&ipc->cons_list_lock, flags);
498− list_for_each_entry_safe(cons, c, &ipc->cons_list, link)
550+ spin_lock_irq(&ipc->cons_lock);
551+ list_for_each_entry_safe(cons, c, &ipc->cons_list, link) {
552+ spin_lock(&cons->rx_lock);
553+ if (!cons->rx_callback)
554+ cons->aborted = true;
555+ list_for_each_entry_safe(rx_msg, r, &cons->rx_msg_list, link)
556+ ivpu_ipc_rx_msg_del(vdev, rx_msg);
557+ spin_unlock(&cons->rx_lock);
499558 wake_up(&cons->rx_msg_wq);
500− spin_unlock_irqrestore(&ipc->cons_list_lock, flags);
559+ }
560+ spin_unlock_irq(&ipc->cons_lock);
561+
562+ drm_WARN_ON(&vdev->drm, atomic_read(&ipc->rx_msg_count) > 0);
501563 }
502564
503565 void ivpu_ipc_reset(struct ivpu_device *vdev)
@@ -505,6 +567,7 @@ void ivpu_ipc_reset(struct ivpu_device *vdev) · 1 unmodified line
505567 struct ivpu_ipc_info *ipc = vdev->ipc;
506568
507569 mutex_lock(&ipc->lock);
570+ drm_WARN_ON(&vdev->drm, ipc->on);
508571
509572 memset(ivpu_bo_vaddr(ipc->mem_tx), 0, ivpu_bo_size(ipc->mem_tx));
510573 memset(ivpu_bo_vaddr(ipc->mem_rx), 0, ivpu_bo_size(ipc->mem_rx));
drivers/accel/ivpu/ivpu_ipc.h+25−8
@@ -42,13 +42,26 @@ struct ivpu_ipc_hdr { · 41 unmodified lines
4242 u8 status;
4343 } __packed __aligned(IVPU_IPC_ALIGNMENT);
4444
45+typedef void (*ivpu_ipc_rx_callback_t)(struct ivpu_device *vdev,
46+ struct ivpu_ipc_hdr *ipc_hdr,
47+ struct vpu_jsm_msg *jsm_msg);
48+
49+struct ivpu_ipc_rx_msg {
50+ struct list_head link;
51+ struct ivpu_ipc_hdr *ipc_hdr;
52+ struct vpu_jsm_msg *jsm_msg;
53+ ivpu_ipc_rx_callback_t callback;
54+};
55+
4556 struct ivpu_ipc_consumer {
4657 struct list_head link;
4758 u32 channel;
4859 u32 tx_vpu_addr;
4960 u32 request_id;
61+ bool aborted;
62+ ivpu_ipc_rx_callback_t rx_callback;
5063
51− spinlock_t rx_msg_lock; /* Protects rx_msg_list */
64+ spinlock_t rx_lock; /* Protects rx_msg_list and aborted */
5265 struct list_head rx_msg_list;
5366 wait_queue_head_t rx_msg_wq;
5467 };
@@ -60,8 +73,9 @@ struct ivpu_ipc_info { · 5 unmodified lines
6073
6174 atomic_t rx_msg_count;
6275
63− spinlock_t cons_list_lock; /* Protects cons_list */
76+ spinlock_t cons_lock; /* Protects cons_list and cb_msg_list */
6477 struct list_head cons_list;
78+ struct list_head cb_msg_list;
6579
6680 atomic_t request_id;
6781 struct mutex lock; /* Lock on status */
@@ -75,19 +89,22 @@ void ivpu_ipc_enable(struct ivpu_device *vdev); · 7 unmodified lines
7589 void ivpu_ipc_disable(struct ivpu_device *vdev);
7690 void ivpu_ipc_reset(struct ivpu_device *vdev);
7791
78−int ivpu_ipc_irq_handler(struct ivpu_device *vdev);
92+void ivpu_ipc_irq_handler(struct ivpu_device *vdev, bool *wake_thread);
93+irqreturn_t ivpu_ipc_irq_thread_handler(struct ivpu_device *vdev);
7994
8095 void ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
81− u32 channel);
96+ u32 channel, ivpu_ipc_rx_callback_t callback);
8297 void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons);
8398
8499 int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
85− struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *ipc_payload,
100+ struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg,
86101 unsigned long timeout_ms);
87102
103+int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
104+ enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
105+ u32 channel, unsigned long timeout_ms);
88106 int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
89− enum vpu_ipc_msg_type expected_resp_type,
90− struct vpu_jsm_msg *resp, u32 channel,
91− unsigned long timeout_ms);
107+ enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
108+ u32 channel, unsigned long timeout_ms);
92109
93110 #endif /* __IVPU_IPC_H__ */
drivers/accel/ivpu/ivpu_job.c+31−68
@@ -7,7 +7,6 @@ · 6 unmodified lines
77
88 #include <linux/bitfield.h>
99 #include <linux/highmem.h>
10−#include <linux/kthread.h>
1110 #include <linux/pci.h>
1211 #include <linux/module.h>
1312 #include <uapi/drm/ivpu_accel.h>
@@ -24,10 +23,6 @@ · 10 unmodified lines
2423 #define JOB_ID_CONTEXT_MASK GENMASK(31, 8)
2524 #define JOB_MAX_BUFFER_COUNT 65535
2625
27−static unsigned int ivpu_tdr_timeout_ms;
28−module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, uint, 0644);
29−MODULE_PARM_DESC(tdr_timeout_ms, "Timeout for device hang detection, in milliseconds, 0 - default");
30−
3126 static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq)
3227 {
3328 ivpu_hw_reg_db_set(vdev, cmdq->db_id);
@@ -196,6 +191,8 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) · 162 unmodified lines
196191 entry->batch_buf_addr = job->cmd_buf_vpu_addr;
197192 entry->job_id = job->job_id;
198193 entry->flags = 0;
194+ if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION))
195+ entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK;
199196 wmb(); /* Ensure that tail is updated after filling entry */
200197 header->tail = next_entry;
201198 wmb(); /* Flush WC buffer for jobq header */
@@ -264,7 +261,7 @@ static void job_release(struct kref *ref) · 62 unmodified lines
264261
265262 for (i = 0; i < job->bo_count; i++)
266263 if (job->bos[i])
267− drm_gem_object_put(&job->bos[i]->base);
264+ drm_gem_object_put(&job->bos[i]->base.base);
268265
269266 dma_fence_put(job->done_fence);
270267 ivpu_file_priv_put(&job->file_priv);
@@ -340,23 +337,12 @@ static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status) · 69 unmodified lines
340337 ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n",
341338 job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status);
342339
340+ ivpu_stop_job_timeout_detection(vdev);
341+
343342 job_put(job);
344343 return 0;
345344 }
346345
347−static void ivpu_job_done_message(struct ivpu_device *vdev, void *msg)
348−{
349− struct vpu_ipc_msg_payload_job_done *payload;
350− struct vpu_jsm_msg *job_ret_msg = msg;
351− int ret;
352−
353− payload = (struct vpu_ipc_msg_payload_job_done *)&job_ret_msg->payload;
354−
355− ret = ivpu_job_done(vdev, payload->job_id, payload->job_status);
356− if (ret)
357− ivpu_err(vdev, "Failed to finish job %d: %d\n", payload->job_id, ret);
358−}
359−
360346 void ivpu_jobs_abort_all(struct ivpu_device *vdev)
361347 {
362348 struct ivpu_job *job;
@@ -398,11 +384,13 @@ static int ivpu_direct_job_submission(struct ivpu_job *job) · 35 unmodified lines
398384 if (ret)
399385 goto err_xa_erase;
400386
387+ ivpu_start_job_timeout_detection(vdev);
388+
401389 ivpu_dbg(vdev, JOB, "Job submitted: id %3u addr 0x%llx ctx %2d engine %d next %d\n",
402390 job->job_id, job->cmd_buf_vpu_addr, file_priv->ctx.id,
403391 job->engine_idx, cmdq->jobq->header.tail);
404392
405− if (ivpu_test_mode == IVPU_TEST_MODE_NULL_HW) {
393+ if (ivpu_test_mode & IVPU_TEST_MODE_NULL_HW) {
406394 ivpu_job_done(vdev, job->job_id, VPU_JSM_STATUS_SUCCESS);
407395 cmdq->jobq->header.head = cmdq->jobq->header.tail;
408396 wmb(); /* Flush WC buffer for jobq header */
@@ -448,7 +436,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 · 39 unmodified lines
448436 }
449437
450438 bo = job->bos[CMD_BUF_IDX];
451− if (!dma_resv_test_signaled(bo->base.resv, DMA_RESV_USAGE_READ)) {
439+ if (!dma_resv_test_signaled(bo->base.base.resv, DMA_RESV_USAGE_READ)) {
452440 ivpu_warn(vdev, "Buffer is already in use\n");
453441 return -EBUSY;
454442 }
@@ -468,7 +456,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 · 13 unmodified lines
468456 }
469457
470458 for (i = 0; i < buf_count; i++) {
471− ret = dma_resv_reserve_fences(job->bos[i]->base.resv, 1);
459+ ret = dma_resv_reserve_fences(job->bos[i]->base.base.resv, 1);
472460 if (ret) {
473461 ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret);
474462 goto unlock_reservations;
@@ -477,7 +465,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 · 2 unmodified lines
477465
478466 for (i = 0; i < buf_count; i++) {
479467 usage = (i == CMD_BUF_IDX) ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_BOOKKEEP;
480− dma_resv_add_fence(job->bos[i]->base.resv, job->done_fence, usage);
468+ dma_resv_add_fence(job->bos[i]->base.base.resv, job->done_fence, usage);
481469 }
482470
483471 unlock_reservations:
@@ -562,61 +550,36 @@ free_handles: · 78 unmodified lines
562550 return ret;
563551 }
564552
565−static int ivpu_job_done_thread(void *arg)
553+static void
554+ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr,
555+ struct vpu_jsm_msg *jsm_msg)
566556 {
567− struct ivpu_device *vdev = (struct ivpu_device *)arg;
568− struct ivpu_ipc_consumer cons;
569− struct vpu_jsm_msg jsm_msg;
570− bool jobs_submitted;
571− unsigned int timeout;
557+ struct vpu_ipc_msg_payload_job_done *payload;
572558 int ret;
573559
574− ivpu_dbg(vdev, JOB, "Started %s\n", __func__);
575−
576− ivpu_ipc_consumer_add(vdev, &cons, VPU_IPC_CHAN_JOB_RET);
577−
578− while (!kthread_should_stop()) {
579− timeout = ivpu_tdr_timeout_ms ? ivpu_tdr_timeout_ms : vdev->timeout.tdr;
580− jobs_submitted = !xa_empty(&vdev->submitted_jobs_xa);
581− ret = ivpu_ipc_receive(vdev, &cons, NULL, &jsm_msg, timeout);
582− if (!ret) {
583− ivpu_job_done_message(vdev, &jsm_msg);
584− } else if (ret == -ETIMEDOUT) {
585− if (jobs_submitted && !xa_empty(&vdev->submitted_jobs_xa)) {
586− ivpu_err(vdev, "TDR detected, timeout %d ms", timeout);
587− ivpu_hw_diagnose_failure(vdev);
588− ivpu_pm_schedule_recovery(vdev);
589− }
590− }
560+ if (!jsm_msg) {
561+ ivpu_err(vdev, "IPC message has no JSM payload\n");
562+ return;
591563 }
592564
593− ivpu_ipc_consumer_del(vdev, &cons);
594−
595− ivpu_jobs_abort_all(vdev);
565+ if (jsm_msg->result != VPU_JSM_STATUS_SUCCESS) {
566+ ivpu_err(vdev, "Invalid JSM message result: %d\n", jsm_msg->result);
567+ return;
568+ }
596569
597− ivpu_dbg(vdev, JOB, "Stopped %s\n", __func__);
598− return 0;
570+ payload = (struct vpu_ipc_msg_payload_job_done *)&jsm_msg->payload;
571+ ret = ivpu_job_done(vdev, payload->job_id, payload->job_status);
572+ if (!ret && !xa_empty(&vdev->submitted_jobs_xa))
573+ ivpu_start_job_timeout_detection(vdev);
599574 }
600575
601−int ivpu_job_done_thread_init(struct ivpu_device *vdev)
576+void ivpu_job_done_consumer_init(struct ivpu_device *vdev)
602577 {
603− struct task_struct *thread;
604−
605− thread = kthread_run(&ivpu_job_done_thread, (void *)vdev, "ivpu_job_done_thread");
606− if (IS_ERR(thread)) {
607− ivpu_err(vdev, "Failed to start job completion thread\n");
608− return -EIO;
609− }
610−
611− get_task_struct(thread);
612− wake_up_process(thread);
613−
614− vdev->job_done_thread = thread;
615−
616− return 0;
578+ ivpu_ipc_consumer_add(vdev, &vdev->job_done_consumer,
579+ VPU_IPC_CHAN_JOB_RET, ivpu_job_done_callback);
617580 }
618581
619−void ivpu_job_done_thread_fini(struct ivpu_device *vdev)
582+void ivpu_job_done_consumer_fini(struct ivpu_device *vdev)
620583 {
621− kthread_stop_put(vdev->job_done_thread);
584+ ivpu_ipc_consumer_del(vdev, &vdev->job_done_consumer);
622585 }
drivers/accel/ivpu/ivpu_job.h+2−2
@@ -59,8 +59,8 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 58 unmodified lines
5959 void ivpu_cmdq_release_all(struct ivpu_file_priv *file_priv);
6060 void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev);
6161
62−int ivpu_job_done_thread_init(struct ivpu_device *vdev);
63−void ivpu_job_done_thread_fini(struct ivpu_device *vdev);
62+void ivpu_job_done_consumer_init(struct ivpu_device *vdev);
63+void ivpu_job_done_consumer_fini(struct ivpu_device *vdev);
6464
6565 void ivpu_jobs_abort_all(struct ivpu_device *vdev);
6666
drivers/accel/ivpu/ivpu_jsm_msg.c+38−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 */
55
66 #include "ivpu_drv.h"
7+#include "ivpu_hw.h"
78 #include "ivpu_ipc.h"
89 #include "ivpu_jsm_msg.h"
910
@@ -36,6 +37,17 @@ const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type) · 26 unmodified lines
3637 IVPU_CASE_TO_STR(VPU_JSM_MSG_DESTROY_CMD_QUEUE);
3738 IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES);
3839 IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_REGISTER_DB);
40+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_CMDQ);
41+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_SUSPEND_CMDQ);
42+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_CMDQ_RSP);
43+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_SUSPEND_CMDQ_DONE);
44+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG);
45+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP);
46+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION);
47+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_ENGINE_RESUME);
48+ IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE);
49+ IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP);
50+ IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP_RSP);
3951 IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT);
4052 IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL);
4153 IVPU_CASE_TO_STR(VPU_JSM_MSG_JOB_DONE);
@@ -65,6 +77,12 @@ const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type) · 23 unmodified lines
6577 IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES_RSP);
6678 IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT_DONE);
6779 IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL_RSP);
80+ IVPU_CASE_TO_STR(VPU_JSM_MSG_PWR_D0I3_ENTER);
81+ IVPU_CASE_TO_STR(VPU_JSM_MSG_PWR_D0I3_ENTER_DONE);
82+ IVPU_CASE_TO_STR(VPU_JSM_MSG_DCT_ENABLE);
83+ IVPU_CASE_TO_STR(VPU_JSM_MSG_DCT_ENABLE_DONE);
84+ IVPU_CASE_TO_STR(VPU_JSM_MSG_DCT_DISABLE);
85+ IVPU_CASE_TO_STR(VPU_JSM_MSG_DCT_DISABLE_DONE);
6886 }
6987 #undef IVPU_CASE_TO_STR
7088
@@ -243,3 +261,23 @@ int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid) · 172 unmodified lines
243261 return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
244262 VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
245263 }
264+
265+int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev)
266+{
267+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_PWR_D0I3_ENTER };
268+ struct vpu_jsm_msg resp;
269+ int ret;
270+
271+ if (IVPU_WA(disable_d0i3_msg))
272+ return 0;
273+
274+ req.payload.pwr_d0i3_enter.send_response = 1;
275+
276+ ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE,
277+ &resp, VPU_IPC_CHAN_GEN_CMD,
278+ vdev->timeout.d0i3_entry_msg);
279+ if (ret)
280+ return ret;
281+
282+ return ivpu_hw_wait_for_idle(vdev);
283+}
drivers/accel/ivpu/ivpu_jsm_msg.h+1−0
@@ -22,4 +22,5 @@ int ivpu_jsm_trace_get_capability(struct ivpu_device *vdev, u32 *trace_destinati · 21 unmodified lines
2222 int ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 trace_destination_mask,
2323 u64 trace_hw_component_mask);
2424 int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid);
25+int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev);
2526 #endif
drivers/accel/ivpu/ivpu_mmu.c+36−8
@@ -230,7 +230,12 @@ · 229 unmodified lines
230230 (REG_FLD(IVPU_MMU_REG_GERROR, MSI_PRIQ_ABT)) | \
231231 (REG_FLD(IVPU_MMU_REG_GERROR, MSI_ABT)))
232232
233−static char *ivpu_mmu_event_to_str(u32 cmd)
233+#define IVPU_MMU_CERROR_NONE 0x0
234+#define IVPU_MMU_CERROR_ILL 0x1
235+#define IVPU_MMU_CERROR_ABT 0x2
236+#define IVPU_MMU_CERROR_ATC_INV_SYNC 0x3
237+
238+static const char *ivpu_mmu_event_to_str(u32 cmd)
234239 {
235240 switch (cmd) {
236241 case IVPU_MMU_EVT_F_UUT:
@@ -276,6 +281,22 @@ static char *ivpu_mmu_event_to_str(u32 cmd) · 39 unmodified lines
276281 }
277282 }
278283
284+static const char *ivpu_mmu_cmdq_err_to_str(u32 err)
285+{
286+ switch (err) {
287+ case IVPU_MMU_CERROR_NONE:
288+ return "No CMDQ Error";
289+ case IVPU_MMU_CERROR_ILL:
290+ return "Illegal command";
291+ case IVPU_MMU_CERROR_ABT:
292+ return "External abort on CMDQ read";
293+ case IVPU_MMU_CERROR_ATC_INV_SYNC:
294+ return "Sync failed to complete ATS invalidation";
295+ default:
296+ return "Unknown CMDQ Error";
297+ }
298+}
299+
279300 static void ivpu_mmu_config_check(struct ivpu_device *vdev)
280301 {
281302 u32 val_ref;
@@ -479,10 +500,7 @@ static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev) · 197 unmodified lines
479500 u64 val;
480501 int ret;
481502
482− val = FIELD_PREP(IVPU_MMU_CMD_OPCODE, CMD_SYNC) |
483− FIELD_PREP(IVPU_MMU_CMD_SYNC_0_CS, 0x2) |
484− FIELD_PREP(IVPU_MMU_CMD_SYNC_0_MSH, 0x3) |
485− FIELD_PREP(IVPU_MMU_CMD_SYNC_0_MSI_ATTR, 0xf);
503+ val = FIELD_PREP(IVPU_MMU_CMD_OPCODE, CMD_SYNC);
486504
487505 ret = ivpu_mmu_cmdq_cmd_write(vdev, "SYNC", val, 0);
488506 if (ret)
@@ -492,8 +510,15 @@ static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev) · 3 unmodified lines
492510 REGV_WR32(IVPU_MMU_REG_CMDQ_PROD, q->prod);
493511
494512 ret = ivpu_mmu_cmdq_wait_for_cons(vdev);
495− if (ret)
496− ivpu_err(vdev, "Timed out waiting for consumer: %d\n", ret);
513+ if (ret) {
514+ u32 err;
515+
516+ val = REGV_RD32(IVPU_MMU_REG_CMDQ_CONS);
517+ err = REG_GET_FLD(IVPU_MMU_REG_CMDQ_CONS, ERR, val);
518+
519+ ivpu_err(vdev, "Timed out waiting for MMU consumer: %d, error: %s\n", ret,
520+ ivpu_mmu_cmdq_err_to_str(err));
521+ }
497522
498523 return ret;
499524 }
@@ -750,9 +775,12 @@ int ivpu_mmu_init(struct ivpu_device *vdev) · 250 unmodified lines
750775
751776 ivpu_dbg(vdev, MMU, "Init..\n");
752777
753− drmm_mutex_init(&vdev->drm, &mmu->lock);
754778 ivpu_mmu_config_check(vdev);
755779
780+ ret = drmm_mutex_init(&vdev->drm, &mmu->lock);
781+ if (ret)
782+ return ret;
783+
756784 ret = ivpu_mmu_structs_alloc(vdev);
757785 if (ret)
758786 return ret;
drivers/accel/ivpu/ivpu_mmu_context.c+86−67
@@ -5,6 +5,9 @@ · 4 unmodified lines
55
66 #include <linux/bitfield.h>
77 #include <linux/highmem.h>
8+#include <linux/set_memory.h>
9+
10+#include <drm/drm_cache.h>
811
912 #include "ivpu_drv.h"
1013 #include "ivpu_hw.h"
@@ -39,12 +42,57 @@ · 28 unmodified lines
3942 #define IVPU_MMU_ENTRY_MAPPED (IVPU_MMU_ENTRY_FLAG_AF | IVPU_MMU_ENTRY_FLAG_USER | \
4043 IVPU_MMU_ENTRY_FLAG_NG | IVPU_MMU_ENTRY_VALID)
4144
45+static void *ivpu_pgtable_alloc_page(struct ivpu_device *vdev, dma_addr_t *dma)
46+{
47+ dma_addr_t dma_addr;
48+ struct page *page;
49+ void *cpu;
50+
51+ page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
52+ if (!page)
53+ return NULL;
54+
55+ set_pages_array_wc(&page, 1);
56+
57+ dma_addr = dma_map_page(vdev->drm.dev, page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
58+ if (dma_mapping_error(vdev->drm.dev, dma_addr))
59+ goto err_free_page;
60+
61+ cpu = vmap(&page, 1, VM_MAP, pgprot_writecombine(PAGE_KERNEL));
62+ if (!cpu)
63+ goto err_dma_unmap_page;
64+
65+
66+ *dma = dma_addr;
67+ return cpu;
68+
69+err_dma_unmap_page:
70+ dma_unmap_page(vdev->drm.dev, dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
71+
72+err_free_page:
73+ put_page(page);
74+ return NULL;
75+}
76+
77+static void ivpu_pgtable_free_page(struct ivpu_device *vdev, u64 *cpu_addr, dma_addr_t dma_addr)
78+{
79+ struct page *page;
80+
81+ if (cpu_addr) {
82+ page = vmalloc_to_page(cpu_addr);
83+ vunmap(cpu_addr);
84+ dma_unmap_page(vdev->drm.dev, dma_addr & ~IVPU_MMU_ENTRY_FLAGS_MASK, PAGE_SIZE,
85+ DMA_BIDIRECTIONAL);
86+ set_pages_array_wb(&page, 1);
87+ put_page(page);
88+ }
89+}
90+
4291 static int ivpu_mmu_pgtable_init(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable)
4392 {
4493 dma_addr_t pgd_dma;
4594
46− pgtable->pgd_dma_ptr = dma_alloc_coherent(vdev->drm.dev, IVPU_MMU_PGTABLE_SIZE, &pgd_dma,
47− GFP_KERNEL);
95+ pgtable->pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma);
4896 if (!pgtable->pgd_dma_ptr)
4997 return -ENOMEM;
5098
@@ -53,13 +101,6 @@ static int ivpu_mmu_pgtable_init(struct ivpu_device *vdev, struct ivpu_mmu_pgtab · 2 unmodified lines
53101 return 0;
54102 }
55103
56−static void ivpu_mmu_pgtable_free(struct ivpu_device *vdev, u64 *cpu_addr, dma_addr_t dma_addr)
57−{
58− if (cpu_addr)
59− dma_free_coherent(vdev->drm.dev, IVPU_MMU_PGTABLE_SIZE, cpu_addr,
60− dma_addr & ~IVPU_MMU_ENTRY_FLAGS_MASK);
61−}
62−
63104 static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable)
64105 {
65106 int pgd_idx, pud_idx, pmd_idx;
@@ -84,19 +125,19 @@ static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgt · 18 unmodified lines
84125 pte_dma_ptr = pgtable->pte_ptrs[pgd_idx][pud_idx][pmd_idx];
85126 pte_dma = pgtable->pmd_ptrs[pgd_idx][pud_idx][pmd_idx];
86127
87− ivpu_mmu_pgtable_free(vdev, pte_dma_ptr, pte_dma);
128+ ivpu_pgtable_free_page(vdev, pte_dma_ptr, pte_dma);
88129 }
89130
90131 kfree(pgtable->pte_ptrs[pgd_idx][pud_idx]);
91− ivpu_mmu_pgtable_free(vdev, pmd_dma_ptr, pmd_dma);
132+ ivpu_pgtable_free_page(vdev, pmd_dma_ptr, pmd_dma);
92133 }
93134
94135 kfree(pgtable->pmd_ptrs[pgd_idx]);
95136 kfree(pgtable->pte_ptrs[pgd_idx]);
96− ivpu_mmu_pgtable_free(vdev, pud_dma_ptr, pud_dma);
137+ ivpu_pgtable_free_page(vdev, pud_dma_ptr, pud_dma);
97138 }
98139
99− ivpu_mmu_pgtable_free(vdev, pgtable->pgd_dma_ptr, pgtable->pgd_dma);
140+ ivpu_pgtable_free_page(vdev, pgtable->pgd_dma_ptr, pgtable->pgd_dma);
100141 }
101142
102143 static u64*
@@ -108,7 +149,7 @@ ivpu_mmu_ensure_pud(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable, · 5 unmodified lines
108149 if (pud_dma_ptr)
109150 return pud_dma_ptr;
110151
111− pud_dma_ptr = dma_alloc_wc(vdev->drm.dev, IVPU_MMU_PGTABLE_SIZE, &pud_dma, GFP_KERNEL);
152+ pud_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pud_dma);
112153 if (!pud_dma_ptr)
113154 return NULL;
114155
@@ -131,7 +172,7 @@ err_free_pmd_ptrs: · 16 unmodified lines
131172 kfree(pgtable->pmd_ptrs[pgd_idx]);
132173
133174 err_free_pud_dma_ptr:
134− ivpu_mmu_pgtable_free(vdev, pud_dma_ptr, pud_dma);
175+ ivpu_pgtable_free_page(vdev, pud_dma_ptr, pud_dma);
135176 return NULL;
136177 }
137178
@@ -145,7 +186,7 @@ ivpu_mmu_ensure_pmd(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable, · 7 unmodified lines
145186 if (pmd_dma_ptr)
146187 return pmd_dma_ptr;
147188
148− pmd_dma_ptr = dma_alloc_wc(vdev->drm.dev, IVPU_MMU_PGTABLE_SIZE, &pmd_dma, GFP_KERNEL);
189+ pmd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pmd_dma);
149190 if (!pmd_dma_ptr)
150191 return NULL;
151192
@@ -160,7 +201,7 @@ ivpu_mmu_ensure_pmd(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable, · 8 unmodified lines
160201 return pmd_dma_ptr;
161202
162203 err_free_pmd_dma_ptr:
163− ivpu_mmu_pgtable_free(vdev, pmd_dma_ptr, pmd_dma);
204+ ivpu_pgtable_free_page(vdev, pmd_dma_ptr, pmd_dma);
164205 return NULL;
165206 }
166207
@@ -174,7 +215,7 @@ ivpu_mmu_ensure_pte(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable, · 7 unmodified lines
174215 if (pte_dma_ptr)
175216 return pte_dma_ptr;
176217
177− pte_dma_ptr = dma_alloc_wc(vdev->drm.dev, IVPU_MMU_PGTABLE_SIZE, &pte_dma, GFP_KERNEL);
218+ pte_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pte_dma);
178219 if (!pte_dma_ptr)
179220 return NULL;
180221
@@ -249,38 +290,6 @@ static void ivpu_mmu_context_unmap_page(struct ivpu_mmu_context *ctx, u64 vpu_ad · 68 unmodified lines
249290 ctx->pgtable.pte_ptrs[pgd_idx][pud_idx][pmd_idx][pte_idx] = IVPU_MMU_ENTRY_INVALID;
250291 }
251292
252−static void
253−ivpu_mmu_context_flush_page_tables(struct ivpu_mmu_context *ctx, u64 vpu_addr, size_t size)
254−{
255− struct ivpu_mmu_pgtable *pgtable = &ctx->pgtable;
256− u64 end_addr = vpu_addr + size;
257−
258− /* Align to PMD entry (2 MB) */
259− vpu_addr &= ~(IVPU_MMU_PTE_MAP_SIZE - 1);
260−
261− while (vpu_addr < end_addr) {
262− int pgd_idx = FIELD_GET(IVPU_MMU_PGD_INDEX_MASK, vpu_addr);
263− u64 pud_end = (pgd_idx + 1) * (u64)IVPU_MMU_PUD_MAP_SIZE;
264−
265− while (vpu_addr < end_addr && vpu_addr < pud_end) {
266− int pud_idx = FIELD_GET(IVPU_MMU_PUD_INDEX_MASK, vpu_addr);
267− u64 pmd_end = (pud_idx + 1) * (u64)IVPU_MMU_PMD_MAP_SIZE;
268−
269− while (vpu_addr < end_addr && vpu_addr < pmd_end) {
270− int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr);
271−
272− clflush_cache_range(pgtable->pte_ptrs[pgd_idx][pud_idx][pmd_idx],
273− IVPU_MMU_PGTABLE_SIZE);
274− vpu_addr += IVPU_MMU_PTE_MAP_SIZE;
275− }
276− clflush_cache_range(pgtable->pmd_ptrs[pgd_idx][pud_idx],
277− IVPU_MMU_PGTABLE_SIZE);
278− }
279− clflush_cache_range(pgtable->pud_ptrs[pgd_idx], IVPU_MMU_PGTABLE_SIZE);
280− }
281− clflush_cache_range(pgtable->pgd_dma_ptr, IVPU_MMU_PGTABLE_SIZE);
282−}
283−
284293 static int
285294 ivpu_mmu_context_map_pages(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
286295 u64 vpu_addr, dma_addr_t dma_addr, size_t size, u64 prot)
@@ -327,6 +336,9 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, · 40 unmodified lines
327336 u64 prot;
328337 u64 i;
329338
339+ if (drm_WARN_ON(&vdev->drm, !ctx))
340+ return -EINVAL;
341+
330342 if (!IS_ALIGNED(vpu_addr, IVPU_MMU_PAGE_SIZE))
331343 return -EINVAL;
332344
@@ -349,10 +361,11 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, · 16 unmodified lines
349361 mutex_unlock(&ctx->lock);
350362 return ret;
351363 }
352− ivpu_mmu_context_flush_page_tables(ctx, vpu_addr, size);
353364 vpu_addr += size;
354365 }
355366
367+ /* Ensure page table modifications are flushed from wc buffers to memory */
368+ wmb();
356369 mutex_unlock(&ctx->lock);
357370
358371 ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id);
@@ -369,8 +382,8 @@ ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ct · 10 unmodified lines
369382 int ret;
370383 u64 i;
371384
372− if (!IS_ALIGNED(vpu_addr, IVPU_MMU_PAGE_SIZE))
373− ivpu_warn(vdev, "Unaligned vpu_addr: 0x%llx\n", vpu_addr);
385+ if (drm_WARN_ON(&vdev->drm, !ctx))
386+ return;
374387
375388 mutex_lock(&ctx->lock);
376389
@@ -378,10 +391,11 @@ ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ct · 1 unmodified line
378391 size_t size = sg_dma_len(sg) + sg->offset;
379392
380393 ivpu_mmu_context_unmap_pages(ctx, vpu_addr, size);
381− ivpu_mmu_context_flush_page_tables(ctx, vpu_addr, size);
382394 vpu_addr += size;
383395 }
384396
397+ /* Ensure page table modifications are flushed from wc buffers to memory */
398+ wmb();
385399 mutex_unlock(&ctx->lock);
386400
387401 ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id);
@@ -390,28 +404,34 @@ ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ct · 2 unmodified lines
390404 }
391405
392406 int
393−ivpu_mmu_context_insert_node_locked(struct ivpu_mmu_context *ctx,
394− const struct ivpu_addr_range *range,
395− u64 size, struct drm_mm_node *node)
407+ivpu_mmu_context_insert_node(struct ivpu_mmu_context *ctx, const struct ivpu_addr_range *range,
408+ u64 size, struct drm_mm_node *node)
396409 {
397− lockdep_assert_held(&ctx->lock);
410+ int ret;
411+
412+ WARN_ON(!range);
398413
414+ mutex_lock(&ctx->lock);
399415 if (!ivpu_disable_mmu_cont_pages && size >= IVPU_MMU_CONT_PAGES_SIZE) {
400− if (!drm_mm_insert_node_in_range(&ctx->mm, node, size, IVPU_MMU_CONT_PAGES_SIZE, 0,
401− range->start, range->end, DRM_MM_INSERT_BEST))
402− return 0;
416+ ret = drm_mm_insert_node_in_range(&ctx->mm, node, size, IVPU_MMU_CONT_PAGES_SIZE, 0,
417+ range->start, range->end, DRM_MM_INSERT_BEST);
418+ if (!ret)
419+ goto unlock;
403420 }
404421
405− return drm_mm_insert_node_in_range(&ctx->mm, node, size, IVPU_MMU_PAGE_SIZE, 0,
406− range->start, range->end, DRM_MM_INSERT_BEST);
422+ ret = drm_mm_insert_node_in_range(&ctx->mm, node, size, IVPU_MMU_PAGE_SIZE, 0,
423+ range->start, range->end, DRM_MM_INSERT_BEST);
424+unlock:
425+ mutex_unlock(&ctx->lock);
426+ return ret;
407427 }
408428
409429 void
410−ivpu_mmu_context_remove_node_locked(struct ivpu_mmu_context *ctx, struct drm_mm_node *node)
430+ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx, struct drm_mm_node *node)
411431 {
412− lockdep_assert_held(&ctx->lock);
413−
432+ mutex_lock(&ctx->lock);
414433 drm_mm_remove_node(node);
434+ mutex_unlock(&ctx->lock);
415435 }
416436
417437 static int
@@ -421,7 +441,6 @@ ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u3 · 3 unmodified lines
421441 int ret;
422442
423443 mutex_init(&ctx->lock);
424− INIT_LIST_HEAD(&ctx->bo_list);
425444
426445 ret = ivpu_mmu_pgtable_init(vdev, &ctx->pgtable);
427446 if (ret) {
drivers/accel/ivpu/ivpu_mmu_context.h+4−7
@@ -23,10 +23,9 @@ struct ivpu_mmu_pgtable { · 22 unmodified lines
2323 };
2424
2525 struct ivpu_mmu_context {
26− struct mutex lock; /* protects: mm, pgtable, bo_list */
26+ struct mutex lock; /* Protects: mm, pgtable */
2727 struct drm_mm mm;
2828 struct ivpu_mmu_pgtable pgtable;
29− struct list_head bo_list;
3029 u32 id;
3130 };
3231
@@ -39,11 +38,9 @@ int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context · 6 unmodified lines
3938 void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx);
4039 void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid);
4140
42−int ivpu_mmu_context_insert_node_locked(struct ivpu_mmu_context *ctx,
43− const struct ivpu_addr_range *range,
44− u64 size, struct drm_mm_node *node);
45−void ivpu_mmu_context_remove_node_locked(struct ivpu_mmu_context *ctx,
46− struct drm_mm_node *node);
41+int ivpu_mmu_context_insert_node(struct ivpu_mmu_context *ctx, const struct ivpu_addr_range *range,
42+ u64 size, struct drm_mm_node *node);
43+void ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx, struct drm_mm_node *node);
4744
4845 int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
4946 u64 vpu_addr, struct sg_table *sgt, bool llc_coherent);
drivers/accel/ivpu/ivpu_pm.c+58−17
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include "ivpu_fw.h"
1616 #include "ivpu_ipc.h"
1717 #include "ivpu_job.h"
18+#include "ivpu_jsm_msg.h"
1819 #include "ivpu_mmu.h"
1920 #include "ivpu_pm.h"
2021
@@ -22,6 +23,10 @@ static bool ivpu_disable_recovery; · 1 unmodified line
2223 module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644);
2324 MODULE_PARM_DESC(disable_recovery, "Disables recovery when VPU hang is detected");
2425
26+static unsigned long ivpu_tdr_timeout_ms;
27+module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, ulong, 0644);
28+MODULE_PARM_DESC(tdr_timeout_ms, "Timeout for device hang detection, in milliseconds, 0 - default");
29+
2530 #define PM_RESCHEDULE_LIMIT 5
2631
2732 static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev)
@@ -69,27 +74,31 @@ retry: · 41 unmodified lines
6974 ret = ivpu_hw_power_up(vdev);
7075 if (ret) {
7176 ivpu_err(vdev, "Failed to power up HW: %d\n", ret);
72− return ret;
77+ goto err_power_down;
7378 }
7479
7580 ret = ivpu_mmu_enable(vdev);
7681 if (ret) {
7782 ivpu_err(vdev, "Failed to resume MMU: %d\n", ret);
78− ivpu_hw_power_down(vdev);
79− return ret;
83+ goto err_power_down;
8084 }
8185
8286 ret = ivpu_boot(vdev);
83− if (ret) {
84− ivpu_mmu_disable(vdev);
85− ivpu_hw_power_down(vdev);
86− if (!ivpu_fw_is_cold_boot(vdev)) {
87− ivpu_warn(vdev, "Failed to resume the FW: %d. Retrying cold boot..\n", ret);
88− ivpu_pm_prepare_cold_boot(vdev);
89− goto retry;
90− } else {
91− ivpu_err(vdev, "Failed to resume the FW: %d\n", ret);
92− }
87+ if (ret)
88+ goto err_mmu_disable;
89+
90+ return 0;
91+
92+err_mmu_disable:
93+ ivpu_mmu_disable(vdev);
94+err_power_down:
95+ ivpu_hw_power_down(vdev);
96+
97+ if (!ivpu_fw_is_cold_boot(vdev)) {
98+ ivpu_pm_prepare_cold_boot(vdev);
99+ goto retry;
100+ } else {
101+ ivpu_err(vdev, "Failed to resume the FW: %d\n", ret);
93102 }
94103
95104 return ret;
@@ -136,6 +145,31 @@ void ivpu_pm_schedule_recovery(struct ivpu_device *vdev) · 40 unmodified lines
136145 }
137146 }
138147
148+static void ivpu_job_timeout_work(struct work_struct *work)
149+{
150+ struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, job_timeout_work.work);
151+ struct ivpu_device *vdev = pm->vdev;
152+ unsigned long timeout_ms = ivpu_tdr_timeout_ms ? ivpu_tdr_timeout_ms : vdev->timeout.tdr;
153+
154+ ivpu_err(vdev, "TDR detected, timeout %lu ms", timeout_ms);
155+ ivpu_hw_diagnose_failure(vdev);
156+
157+ ivpu_pm_schedule_recovery(vdev);
158+}
159+
160+void ivpu_start_job_timeout_detection(struct ivpu_device *vdev)
161+{
162+ unsigned long timeout_ms = ivpu_tdr_timeout_ms ? ivpu_tdr_timeout_ms : vdev->timeout.tdr;
163+
164+ /* No-op if already queued */
165+ queue_delayed_work(system_wq, &vdev->pm->job_timeout_work, msecs_to_jiffies(timeout_ms));
166+}
167+
168+void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev)
169+{
170+ cancel_delayed_work_sync(&vdev->pm->job_timeout_work);
171+}
172+
139173 int ivpu_pm_suspend_cb(struct device *dev)
140174 {
141175 struct drm_device *drm = dev_get_drvdata(dev);
@@ -153,6 +187,8 @@ int ivpu_pm_suspend_cb(struct device *dev) · 11 unmodified lines
153187 }
154188 }
155189
190+ ivpu_jsm_pwr_d0i3_enter(vdev);
191+
156192 ivpu_suspend(vdev);
157193 ivpu_pm_prepare_warm_boot(vdev);
158194
@@ -188,6 +224,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) · 29 unmodified lines
188224 {
189225 struct drm_device *drm = dev_get_drvdata(dev);
190226 struct ivpu_device *vdev = to_ivpu_device(drm);
227+ bool hw_is_idle = true;
191228 int ret;
192229
193230 ivpu_dbg(vdev, PM, "Runtime suspend..\n");
@@ -200,11 +237,16 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) · 6 unmodified lines
200237 return -EAGAIN;
201238 }
202239
240+ if (!vdev->pm->suspend_reschedule_counter)
241+ hw_is_idle = false;
242+ else if (ivpu_jsm_pwr_d0i3_enter(vdev))
243+ hw_is_idle = false;
244+
203245 ret = ivpu_suspend(vdev);
204246 if (ret)
205247 ivpu_err(vdev, "Failed to set suspend VPU: %d\n", ret);
206248
207− if (!vdev->pm->suspend_reschedule_counter) {
249+ if (!hw_is_idle) {
208250 ivpu_warn(vdev, "VPU failed to enter idle, force suspended.\n");
209251 ivpu_pm_prepare_cold_boot(vdev);
210252 } else {
@@ -250,9 +292,6 @@ int ivpu_rpm_get_if_active(struct ivpu_device *vdev) · 39 unmodified lines
250292 {
251293 int ret;
252294
253− ivpu_dbg(vdev, RPM, "rpm_get_if_active count %d\n",
254− atomic_read(&vdev->drm.dev->power.usage_count));
255−
256295 ret = pm_runtime_get_if_active(vdev->drm.dev, false);
257296 drm_WARN_ON(&vdev->drm, ret < 0);
258297
@@ -307,6 +346,7 @@ void ivpu_pm_init(struct ivpu_device *vdev) · 48 unmodified lines
307346
308347 atomic_set(&pm->in_reset, 0);
309348 INIT_WORK(&pm->recovery_work, ivpu_pm_recovery_work);
349+ INIT_DELAYED_WORK(&pm->job_timeout_work, ivpu_job_timeout_work);
310350
311351 if (ivpu_disable_recovery)
312352 delay = -1;
@@ -321,6 +361,7 @@ void ivpu_pm_init(struct ivpu_device *vdev) · 8 unmodified lines
321361
322362 void ivpu_pm_cancel_recovery(struct ivpu_device *vdev)
323363 {
364+ drm_WARN_ON(&vdev->drm, delayed_work_pending(&vdev->pm->job_timeout_work));
324365 cancel_work_sync(&vdev->pm->recovery_work);
325366 }
326367
drivers/accel/ivpu/ivpu_pm.h+3−0
@@ -12,6 +12,7 @@ struct ivpu_device; · 11 unmodified lines
1212
1313 struct ivpu_pm_info {
1414 struct ivpu_device *vdev;
15+ struct delayed_work job_timeout_work;
1516 struct work_struct recovery_work;
1617 atomic_t in_reset;
1718 atomic_t reset_counter;
@@ -37,5 +38,7 @@ int __must_check ivpu_rpm_get_if_active(struct ivpu_device *vdev); · 19 unmodified lines
3738 void ivpu_rpm_put(struct ivpu_device *vdev);
3839
3940 void ivpu_pm_schedule_recovery(struct ivpu_device *vdev);
41+void ivpu_start_job_timeout_detection(struct ivpu_device *vdev);
42+void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev);
4043
4144 #endif /* __IVPU_PM_H__ */
drivers/accel/ivpu/vpu_boot_api.h+81−9
@@ -11,7 +11,10 @@ · 10 unmodified lines
1111 * The bellow values will be used to construct the version info this way:
1212 * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) |
1313 * VPU_BOOT_API_VER_MINOR;
14− * VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes.
14+ * VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes
15+ * This information is collected by using vpuip_2/application/vpuFirmware/make_std_fw_image.py
16+ * If a header is missing this info we ignore the header, if a header is missing or contains
17+ * partial info a build error will be generated.
1518 */
1619
1720 /*
@@ -24,12 +27,12 @@ · 6 unmodified lines
2427 * Minor version changes when API backward compatibility is preserved.
2528 * Resets to 0 if Major version is incremented.
2629 */
27−#define VPU_BOOT_API_VER_MINOR 12
30+#define VPU_BOOT_API_VER_MINOR 20
2831
2932 /*
3033 * API header changed (field names, documentation, formatting) but API itself has not been changed
3134 */
32−#define VPU_BOOT_API_VER_PATCH 2
35+#define VPU_BOOT_API_VER_PATCH 4
3336
3437 /*
3538 * Index in the API version table
@@ -63,6 +66,12 @@ struct vpu_firmware_header { · 27 unmodified lines
6366 /* Size of memory require for firmware execution */
6467 u32 runtime_size;
6568 u32 shave_nn_fw_size;
69+ /* Size of primary preemption buffer. */
70+ u32 preemption_buffer_1_size;
71+ /* Size of secondary preemption buffer. */
72+ u32 preemption_buffer_2_size;
73+ /* Space reserved for future preemption-related fields. */
74+ u32 preemption_reserved[6];
6675 };
6776
6877 /*
@@ -89,6 +98,14 @@ enum VPU_BOOT_L2_CACHE_CFG_TYPE { · 20 unmodified lines
8998 VPU_BOOT_L2_CACHE_CFG_NUM = 2
9099 };
91100
101+/** VPU MCA ECC signalling mode. By default, no signalling is used */
102+enum VPU_BOOT_MCA_ECC_SIGNAL_TYPE {
103+ VPU_BOOT_MCA_ECC_NONE = 0,
104+ VPU_BOOT_MCA_ECC_CORR = 1,
105+ VPU_BOOT_MCA_ECC_FATAL = 2,
106+ VPU_BOOT_MCA_ECC_BOTH = 3
107+};
108+
92109 /**
93110 * Logging destinations.
94111 *
@@ -131,9 +148,11 @@ enum vpu_trace_destination { · 36 unmodified lines
131148 #define VPU_TRACE_PROC_BIT_ACT_SHV_3 22
132149 #define VPU_TRACE_PROC_NO_OF_HW_DEVS 23
133150
134−/* KMB HW component IDs are sequential, so define first and last IDs. */
135−#define VPU_TRACE_PROC_BIT_KMB_FIRST VPU_TRACE_PROC_BIT_LRT
136−#define VPU_TRACE_PROC_BIT_KMB_LAST VPU_TRACE_PROC_BIT_SHV_15
151+/* VPU 30xx HW component IDs are sequential, so define first and last IDs. */
152+#define VPU_TRACE_PROC_BIT_30XX_FIRST VPU_TRACE_PROC_BIT_LRT
153+#define VPU_TRACE_PROC_BIT_30XX_LAST VPU_TRACE_PROC_BIT_SHV_15
154+#define VPU_TRACE_PROC_BIT_KMB_FIRST VPU_TRACE_PROC_BIT_30XX_FIRST
155+#define VPU_TRACE_PROC_BIT_KMB_LAST VPU_TRACE_PROC_BIT_30XX_LAST
137156
138157 struct vpu_boot_l2_cache_config {
139158 u8 use;
@@ -148,6 +167,25 @@ struct vpu_warm_boot_section { · 8 unmodified lines
148167 u32 is_clear_op;
149168 };
150169
170+/*
171+ * When HW scheduling mode is enabled, a present period is defined.
172+ * It will be used by VPU to swap between normal and focus priorities
173+ * to prevent starving of normal priority band (when implemented).
174+ * Host must provide a valid value at boot time in
175+ * `vpu_focus_present_timer_ms`. If the value provided by the host is not within the
176+ * defined range a default value will be used. Here we define the min. and max.
177+ * allowed values and the and default value of the present period. Units are milliseconds.
178+ */
179+#define VPU_PRESENT_CALL_PERIOD_MS_DEFAULT 50
180+#define VPU_PRESENT_CALL_PERIOD_MS_MIN 16
181+#define VPU_PRESENT_CALL_PERIOD_MS_MAX 10000
182+
183+/**
184+ * Macros to enable various operation modes within the VPU.
185+ * To be defined as part of 32 bit mask.
186+ */
187+#define VPU_OP_MODE_SURVIVABILITY 0x1
188+
151189 struct vpu_boot_params {
152190 u32 magic;
153191 u32 vpu_id;
@@ -218,6 +256,7 @@ struct vpu_boot_params { · 64 unmodified lines
218256 * the threshold will not be logged); applies to every enabled logging
219257 * destination and loggable HW component. See 'mvLog_t' enum for acceptable
220258 * values.
259+ * TODO: EISW-33556: Move log level definition (mvLog_t) to this file.
221260 */
222261 u32 default_trace_level;
223262 u32 boot_type;
@@ -249,7 +288,36 @@ struct vpu_boot_params { · 25 unmodified lines
249288 u32 temp_sensor_period_ms;
250289 /** PLL ratio for efficient clock frequency */
251290 u32 pn_freq_pll_ratio;
252− u32 pad4[28];
291+ /** DVFS Mode: Default: 0, Max Performance: 1, On Demand: 2, Power Save: 3 */
292+ u32 dvfs_mode;
293+ /**
294+ * Depending on DVFS Mode:
295+ * On-demand: Default if 0.
296+ * Bit 0-7 - uint8_t: Highest residency percent
297+ * Bit 8-15 - uint8_t: High residency percent
298+ * Bit 16-23 - uint8_t: Low residency percent
299+ * Bit 24-31 - uint8_t: Lowest residency percent
300+ * Bit 32-35 - unsigned 4b: PLL Ratio increase amount on highest residency
301+ * Bit 36-39 - unsigned 4b: PLL Ratio increase amount on high residency
302+ * Bit 40-43 - unsigned 4b: PLL Ratio decrease amount on low residency
303+ * Bit 44-47 - unsigned 4b: PLL Ratio decrease amount on lowest frequency
304+ * Bit 48-55 - uint8_t: Period (ms) for residency decisions
305+ * Bit 56-63 - uint8_t: Averaging windows (as multiples of period. Max: 30 decimal)
306+ * Power Save/Max Performance: Unused
307+ */
308+ u64 dvfs_param;
309+ /**
310+ * D0i3 delayed entry
311+ * Bit0: Disable CPU state save on D0i2 entry flow.
312+ * 0: Every D0i2 entry saves state. Save state IPC message ignored.
313+ * 1: IPC message required to save state on D0i3 entry flow.
314+ */
315+ u32 d0i3_delayed_entry;
316+ /* Time spent by VPU in D0i3 state */
317+ u64 d0i3_residency_time_us;
318+ /* Value of VPU perf counter at the time of entering D0i3 state . */
319+ u64 d0i3_entry_vpu_ts;
320+ u32 pad4[20];
253321 /* Warm boot information: 0x400 - 0x43F */
254322 u32 warm_boot_sections_count;
255323 u32 warm_boot_start_address_reference;
@@ -274,8 +342,12 @@ struct vpu_boot_params { · 18 unmodified lines
274342 u32 vpu_scheduling_mode;
275343 /* Present call period in milliseconds. */
276344 u32 vpu_focus_present_timer_ms;
277− /* Unused/reserved: 0x478 - 0xFFF */
278− u32 pad6[738];
345+ /* VPU ECC Signaling */
346+ u32 vpu_uses_ecc_mca_signal;
347+ /* Values defined by VPU_OP_MODE* macros */
348+ u32 vpu_operation_mode;
349+ /* Unused/reserved: 0x480 - 0xFFF */
350+ u32 pad6[736];
279351 };
280352
281353 /*
drivers/accel/ivpu/vpu_jsm_api.h+294−15
@@ -22,12 +22,12 @@ · 21 unmodified lines
2222 /*
2323 * Minor version changes when API backward compatibility is preserved.
2424 */
25−#define VPU_JSM_API_VER_MINOR 0
25+#define VPU_JSM_API_VER_MINOR 15
2626
2727 /*
2828 * API header changed (field names, documentation, formatting) but API itself has not been changed
2929 */
30−#define VPU_JSM_API_VER_PATCH 1
30+#define VPU_JSM_API_VER_PATCH 0
3131
3232 /*
3333 * Index in the API version table
@@ -84,11 +84,13 @@ · 50 unmodified lines
8484 * Job flags bit masks.
8585 */
8686 #define VPU_JOB_FLAGS_NULL_SUBMISSION_MASK 0x00000001
87+#define VPU_JOB_FLAGS_PRIVATE_DATA_MASK 0xFF000000
8788
8889 /*
8990 * Sizes of the reserved areas in jobs, in bytes.
9091 */
91−#define VPU_JOB_RESERVED_BYTES 16
92+#define VPU_JOB_RESERVED_BYTES 8
93+
9294 /*
9395 * Sizes of the reserved areas in job queues, in bytes.
9496 */
@@ -108,6 +110,20 @@ · 13 unmodified lines
108110 */
109111 #define VPU_DYNDBG_CMD_MAX_LEN 96
110112
113+/*
114+ * For HWS command queue scheduling, we can prioritise command queues inside the
115+ * same process with a relative in-process priority. Valid values for relative
116+ * priority are given below - max and min.
117+ */
118+#define VPU_HWS_COMMAND_QUEUE_MAX_IN_PROCESS_PRIORITY 7
119+#define VPU_HWS_COMMAND_QUEUE_MIN_IN_PROCESS_PRIORITY -7
120+
121+/*
122+ * For HWS priority scheduling, we can have multiple realtime priority bands.
123+ * They are numbered 0 to a MAX.
124+ */
125+#define VPU_HWS_MAX_REALTIME_PRIORITY_LEVEL 31U
126+
111127 /*
112128 * Job format.
113129 */
@@ -117,8 +133,14 @@ struct vpu_job_queue_entry { · 3 unmodified lines
117133 u32 flags; /**< Flags bit field, see VPU_JOB_FLAGS_* above */
118134 u64 root_page_table_addr; /**< Address of root page table to use for this job */
119135 u64 root_page_table_update_counter; /**< Page tables update events counter */
120− u64 preemption_buffer_address; /**< Address of the preemption buffer to use for this job */
121− u64 preemption_buffer_size; /**< Size of the preemption buffer to use for this job */
136+ u64 primary_preempt_buf_addr;
137+ /**< Address of the primary preemption buffer to use for this job */
138+ u32 primary_preempt_buf_size;
139+ /**< Size of the primary preemption buffer to use for this job */
140+ u32 secondary_preempt_buf_size;
141+ /**< Size of secondary preemption buffer to use for this job */
142+ u64 secondary_preempt_buf_addr;
143+ /**< Address of secondary preemption buffer to use for this job */
122144 u8 reserved_0[VPU_JOB_RESERVED_BYTES];
123145 };
124146
@@ -152,6 +174,46 @@ enum vpu_trace_entity_type { · 27 unmodified lines
152174 VPU_TRACE_ENTITY_TYPE_HW_COMPONENT = 2,
153175 };
154176
177+/*
178+ * HWS specific log buffer header details.
179+ * Total size is 32 bytes.
180+ */
181+struct vpu_hws_log_buffer_header {
182+ /* Written by VPU after adding a log entry. Initialised by host to 0. */
183+ u32 first_free_entry_index;
184+ /* Incremented by VPU every time the VPU overwrites the 0th entry;
185+ * initialised by host to 0.
186+ */
187+ u32 wraparound_count;
188+ /*
189+ * This is the number of buffers that can be stored in the log buffer provided by the host.
190+ * It is written by host before passing buffer to VPU. VPU should consider it read-only.
191+ */
192+ u64 num_of_entries;
193+ u64 reserved[2];
194+};
195+
196+/*
197+ * HWS specific log buffer entry details.
198+ * Total size is 32 bytes.
199+ */
200+struct vpu_hws_log_buffer_entry {
201+ /* VPU timestamp must be an invariant timer tick (not impacted by DVFS) */
202+ u64 vpu_timestamp;
203+ /*
204+ * Operation type:
205+ * 0 - context state change
206+ * 1 - queue new work
207+ * 2 - queue unwait sync object
208+ * 3 - queue no more work
209+ * 4 - queue wait sync object
210+ */
211+ u32 operation_type;
212+ u32 reserved;
213+ /* Operation data depends on operation type */
214+ u64 operation_data[2];
215+};
216+
155217 /*
156218 * Host <-> VPU IPC messages types.
157219 */
@@ -228,6 +290,23 @@ enum vpu_ipc_msg_type { · 70 unmodified lines
228290 * deallocated or reassigned to another context.
229291 */
230292 VPU_JSM_MSG_HWS_REGISTER_DB = 0x1117,
293+ /** Control command: Log buffer setting */
294+ VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG = 0x1118,
295+ /* Control command: Suspend command queue. */
296+ VPU_JSM_MSG_HWS_SUSPEND_CMDQ = 0x1119,
297+ /* Control command: Resume command queue */
298+ VPU_JSM_MSG_HWS_RESUME_CMDQ = 0x111a,
299+ /* Control command: Resume engine after reset */
300+ VPU_JSM_MSG_HWS_ENGINE_RESUME = 0x111b,
301+ /* Control command: Enable survivability/DCT mode */
302+ VPU_JSM_MSG_DCT_ENABLE = 0x111c,
303+ /* Control command: Disable survivability/DCT mode */
304+ VPU_JSM_MSG_DCT_DISABLE = 0x111d,
305+ /**
306+ * Dump VPU state. To be used for debug purposes only.
307+ * NOTE: Please introduce new ASYNC commands before this one. *
308+ */
309+ VPU_JSM_MSG_STATE_DUMP = 0x11FF,
231310 /* IPC Host -> Device, General commands */
232311 VPU_JSM_MSG_GENERAL_CMD = 0x1200,
233312 VPU_JSM_MSG_BLOB_DEINIT = VPU_JSM_MSG_GENERAL_CMD,
@@ -236,6 +315,10 @@ enum vpu_ipc_msg_type { · 2 unmodified lines
236315 * Linux command: `echo '<dyndbg_cmd>' > <debugfs>/dynamic_debug/control`.
237316 */
238317 VPU_JSM_MSG_DYNDBG_CONTROL = 0x1201,
318+ /**
319+ * Perform the save procedure for the D0i3 entry
320+ */
321+ VPU_JSM_MSG_PWR_D0I3_ENTER = 0x1202,
239322 /* IPC Device -> Host, Job completion */
240323 VPU_JSM_MSG_JOB_DONE = 0x2100,
241324 /* IPC Device -> Host, Async command completion */
@@ -304,11 +387,35 @@ enum vpu_ipc_msg_type { · 62 unmodified lines
304387 VPU_JSM_MSG_DESTROY_CMD_QUEUE_RSP = 0x2216,
305388 /** Response to control command: Set context scheduling properties */
306389 VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES_RSP = 0x2217,
390+ /** Response to control command: Log buffer setting */
391+ VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP = 0x2218,
392+ /* IPC Device -> Host, HWS notify index entry of log buffer written */
393+ VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION = 0x2219,
394+ /* IPC Device -> Host, HWS completion of a context suspend request */
395+ VPU_JSM_MSG_HWS_SUSPEND_CMDQ_DONE = 0x221a,
396+ /* Response to control command: Resume command queue */
397+ VPU_JSM_MSG_HWS_RESUME_CMDQ_RSP = 0x221b,
398+ /* Response to control command: Resume engine command response */
399+ VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE = 0x221c,
400+ /* Response to control command: Enable survivability/DCT mode */
401+ VPU_JSM_MSG_DCT_ENABLE_DONE = 0x221d,
402+ /* Response to control command: Disable survivability/DCT mode */
403+ VPU_JSM_MSG_DCT_DISABLE_DONE = 0x221e,
404+ /**
405+ * Response to state dump control command.
406+ * NOTE: Please introduce new ASYNC responses before this one. *
407+ */
408+ VPU_JSM_MSG_STATE_DUMP_RSP = 0x22FF,
307409 /* IPC Device -> Host, General command completion */
308410 VPU_JSM_MSG_GENERAL_CMD_DONE = 0x2300,
309411 VPU_JSM_MSG_BLOB_DEINIT_DONE = VPU_JSM_MSG_GENERAL_CMD_DONE,
310412 /** Response to VPU_JSM_MSG_DYNDBG_CONTROL. */
311413 VPU_JSM_MSG_DYNDBG_CONTROL_RSP = 0x2301,
414+ /**
415+ * Acknowledgment of completion of the save procedure initiated by
416+ * VPU_JSM_MSG_PWR_D0I3_ENTER
417+ */
418+ VPU_JSM_MSG_PWR_D0I3_ENTER_DONE = 0x2302,
312419 };
313420
314421 enum vpu_ipc_msg_status { VPU_JSM_MSG_FREE, VPU_JSM_MSG_ALLOCATED };
@@ -593,12 +700,12 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { · 278 unmodified lines
593700 * Default quantum in 100ns units for scheduling across processes
594701 * within a priority band
595702 */
596− u64 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS];
703+ u32 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS];
597704 /*
598705 * Default grace period in 100ns units for processes that preempt each
599706 * other within a priority band
600707 */
601− u64 process_grace_period[VPU_HWS_NUM_PRIORITY_BANDS];
708+ u32 process_grace_period[VPU_HWS_NUM_PRIORITY_BANDS];
602709 /*
603710 * For normal priority band, specifies the target VPU percentage
604711 * in situations when it's starved by the focus band.
@@ -608,32 +715,51 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { · 3 unmodified lines
608715 u32 reserved_0;
609716 };
610717
611−/* HWS create command queue request */
718+/*
719+ * @brief HWS create command queue request.
720+ * Host will create a command queue via this command.
721+ * Note: Cmdq group is a handle of an object which
722+ * may contain one or more command queues.
723+ * @see VPU_JSM_MSG_CREATE_CMD_QUEUE
724+ * @see VPU_JSM_MSG_CREATE_CMD_QUEUE_RSP
725+ */
612726 struct vpu_ipc_msg_payload_hws_create_cmdq {
613727 /* Process id */
614728 u64 process_id;
615729 /* Host SSID */
616730 u32 host_ssid;
617− /* Zero Padding */
618− u32 reserved;
731+ /* Engine for which queue is being created */
732+ u32 engine_idx;
733+ /*
734+ * Cmdq group may be set to 0 or equal to
735+ * cmdq_id while each priority band contains
736+ * only single engine instances.
737+ */
738+ u64 cmdq_group;
619739 /* Command queue id */
620740 u64 cmdq_id;
621741 /* Command queue base */
622742 u64 cmdq_base;
623743 /* Command queue size */
624744 u32 cmdq_size;
625− /* Reserved */
745+ /* Zero padding */
626746 u32 reserved_0;
627747 };
628748
629−/* HWS create command queue response */
749+/*
750+ * @brief HWS create command queue response.
751+ * @see VPU_JSM_MSG_CREATE_CMD_QUEUE
752+ * @see VPU_JSM_MSG_CREATE_CMD_QUEUE_RSP
753+ */
630754 struct vpu_ipc_msg_payload_hws_create_cmdq_rsp {
631755 /* Process id */
632756 u64 process_id;
633757 /* Host SSID */
634758 u32 host_ssid;
635− /* Zero Padding */
636− u32 reserved;
759+ /* Engine for which queue is being created */
760+ u32 engine_idx;
761+ /* Command queue group */
762+ u64 cmdq_group;
637763 /* Command queue id */
638764 u64 cmdq_id;
639765 };
@@ -661,7 +787,7 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { · 21 unmodified lines
661787 /* Inside realtime band assigns a further priority */
662788 u32 realtime_priority_level;
663789 /* Priority relative to other contexts in the same process */
664− u32 in_process_priority;
790+ s32 in_process_priority;
665791 /* Zero padding / Reserved */
666792 u32 reserved_1;
667793 /* Context quantum relative to other contexts of same priority in the same process */
@@ -694,6 +820,123 @@ struct vpu_jsm_hws_register_db { · 26 unmodified lines
694820 u64 cmdq_size;
695821 };
696822
823+/*
824+ * @brief Structure to set another buffer to be used for scheduling-related logging.
825+ * The size of the logging buffer and the number of entries is defined as part of the
826+ * buffer itself as described next.
827+ * The log buffer received from the host is made up of;
828+ * - header: 32 bytes in size, as shown in 'struct vpu_hws_log_buffer_header'.
829+ * The header contains the number of log entries in the buffer.
830+ * - log entry: 0 to n-1, each log entry is 32 bytes in size, as shown in
831+ * 'struct vpu_hws_log_buffer_entry'.
832+ * The entry contains the VPU timestamp, operation type and data.
833+ * The host should provide the notify index value of log buffer to VPU. This is a
834+ * value defined within the log buffer and when written to will generate the
835+ * scheduling log notification.
836+ * The host should set engine_idx and vpu_log_buffer_va to 0 to disable logging
837+ * for a particular engine.
838+ * VPU will handle one log buffer for each of supported engines.
839+ * VPU should allow the logging to consume one host_ssid.
840+ * @see VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG
841+ * @see VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP
842+ * @see VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION
843+ */
844+struct vpu_ipc_msg_payload_hws_set_scheduling_log {
845+ /* Engine ordinal */
846+ u32 engine_idx;
847+ /* Host SSID */
848+ u32 host_ssid;
849+ /*
850+ * VPU log buffer virtual address.
851+ * Set to 0 to disable logging for this engine.
852+ */
853+ u64 vpu_log_buffer_va;
854+ /*
855+ * Notify index of log buffer. VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION
856+ * is generated when an event log is written to this index.
857+ */
858+ u64 notify_index;
859+};
860+
861+/*
862+ * @brief The scheduling log notification is generated by VPU when it writes
863+ * an event into the log buffer at the notify_index. VPU notifies host with
864+ * VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION. This is an asynchronous
865+ * message from VPU to host.
866+ * @see VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION
867+ * @see VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG
868+ */
869+struct vpu_ipc_msg_payload_hws_scheduling_log_notification {
870+ /* Engine ordinal */
871+ u32 engine_idx;
872+ /* Zero Padding */
873+ u32 reserved_0;
874+};
875+
876+/*
877+ * @brief HWS suspend command queue request and done structure.
878+ * Host will request the suspend of contexts and VPU will;
879+ * - Suspend all work on this context
880+ * - Preempt any running work
881+ * - Asynchronously perform the above and return success immediately once
882+ * all items above are started successfully
883+ * - Notify the host of completion of these operations via
884+ * VPU_JSM_MSG_HWS_SUSPEND_CMDQ_DONE
885+ * - Reject any other context operations on a context with an in-flight
886+ * suspend request running
887+ * Same structure used when VPU notifies host of completion of a context suspend
888+ * request. The ids and suspend fence value reported in this command will match
889+ * the one in the request from the host to suspend the context. Once suspend is
890+ * complete, VPU will not access any data relating to this command queue until
891+ * it is resumed.
892+ * @see VPU_JSM_MSG_HWS_SUSPEND_CMDQ
893+ * @see VPU_JSM_MSG_HWS_SUSPEND_CMDQ_DONE
894+ */
895+struct vpu_ipc_msg_payload_hws_suspend_cmdq {
896+ /* Host SSID */
897+ u32 host_ssid;
898+ /* Zero Padding */
899+ u32 reserved_0;
900+ /* Command queue id */
901+ u64 cmdq_id;
902+ /*
903+ * Suspend fence value - reported by the VPU suspend context
904+ * completed once suspend is complete.
905+ */
906+ u64 suspend_fence_value;
907+};
908+
909+/*
910+ * @brief HWS Resume command queue request / response structure.
911+ * Host will request the resume of a context;
912+ * - VPU will resume all work on this context
913+ * - Scheduler will allow this context to be scheduled
914+ * @see VPU_JSM_MSG_HWS_RESUME_CMDQ
915+ * @see VPU_JSM_MSG_HWS_RESUME_CMDQ_RSP
916+ */
917+struct vpu_ipc_msg_payload_hws_resume_cmdq {
918+ /* Host SSID */
919+ u32 host_ssid;
920+ /* Zero Padding */
921+ u32 reserved_0;
922+ /* Command queue id */
923+ u64 cmdq_id;
924+};
925+
926+/*
927+ * @brief HWS Resume engine request / response structure.
928+ * After a HWS engine reset, all scheduling is stopped on VPU until a engine resume.
929+ * Host shall send this command to resume scheduling of any valid queue.
930+ * @see VPU_JSM_MSG_HWS_RESUME_ENGINE
931+ * @see VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE
932+ */
933+struct vpu_ipc_msg_payload_hws_resume_engine {
934+ /* Engine to be resumed */
935+ u32 engine_idx;
936+ /* Reserved */
937+ u32 reserved_0;
938+};
939+
697940 /**
698941 * Payload for VPU_JSM_MSG_TRACE_SET_CONFIG[_RSP] and
699942 * VPU_JSM_MSG_TRACE_GET_CONFIG_RSP messages.
@@ -938,6 +1181,35 @@ struct vpu_ipc_msg_payload_dyndbg_control { · 238 unmodified lines
9381181 char dyndbg_cmd[VPU_DYNDBG_CMD_MAX_LEN];
9391182 };
9401183
1184+/**
1185+ * Payload for VPU_JSM_MSG_PWR_D0I3_ENTER
1186+ *
1187+ * This is a bi-directional payload.
1188+ */
1189+struct vpu_ipc_msg_payload_pwr_d0i3_enter {
1190+ /**
1191+ * 0: VPU_JSM_MSG_PWR_D0I3_ENTER_DONE is not sent to the host driver
1192+ * The driver will poll for D0i2 Idle state transitions.
1193+ * 1: VPU_JSM_MSG_PWR_D0I3_ENTER_DONE is sent after VPU state save is complete
1194+ */
1195+ u32 send_response;
1196+ u32 reserved_0;
1197+};
1198+
1199+/**
1200+ * Payload for VPU_JSM_MSG_DCT_ENABLE message.
1201+ *
1202+ * Default values for DCT active/inactive times are 5.3ms and 30ms respectively,
1203+ * corresponding to a 85% duty cycle. This payload allows the host to tune these
1204+ * values according to application requirements.
1205+ */
1206+struct vpu_ipc_msg_payload_pwr_dct_control {
1207+ /** Duty cycle active time in microseconds */
1208+ u32 dct_active_us;
1209+ /** Duty cycle inactive time in microseconds */
1210+ u32 dct_inactive_us;
1211+};
1212+
9411213 /*
9421214 * Payloads union, used to define complete message format.
9431215 */
@@ -974,6 +1246,13 @@ union vpu_ipc_msg_payload { · 30 unmodified lines
9741246 struct vpu_ipc_msg_payload_hws_destroy_cmdq hws_destroy_cmdq;
9751247 struct vpu_ipc_msg_payload_hws_set_context_sched_properties
9761248 hws_set_context_sched_properties;
1249+ struct vpu_ipc_msg_payload_hws_set_scheduling_log hws_set_scheduling_log;
1250+ struct vpu_ipc_msg_payload_hws_scheduling_log_notification hws_scheduling_log_notification;
1251+ struct vpu_ipc_msg_payload_hws_suspend_cmdq hws_suspend_cmdq;
1252+ struct vpu_ipc_msg_payload_hws_resume_cmdq hws_resume_cmdq;
1253+ struct vpu_ipc_msg_payload_hws_resume_engine hws_resume_engine;
1254+ struct vpu_ipc_msg_payload_pwr_d0i3_enter pwr_d0i3_enter;
1255+ struct vpu_ipc_msg_payload_pwr_dct_control pwr_dct_control;
9771256 };
9781257
9791258 /*
drivers/accel/qaic/Makefile+2−1
@@ -9,4 +9,5 @@ qaic-y := \ · 8 unmodified lines
99 mhi_controller.o \
1010 qaic_control.o \
1111 qaic_data.o \
12− qaic_drv.o
12+ qaic_drv.o \
13+ qaic_timesync.o
drivers/accel/qaic/mhi_controller.c+40−4
@@ -348,7 +348,7 @@ static struct mhi_channel_config aic100_channels[] = { · 347 unmodified lines
348348 .local_elements = 0,
349349 .event_ring = 0,
350350 .dir = DMA_TO_DEVICE,
351− .ee_mask = MHI_CH_EE_SBL | MHI_CH_EE_AMSS,
351+ .ee_mask = MHI_CH_EE_SBL,
352352 .pollcfg = 0,
353353 .doorbell = MHI_DB_BRST_DISABLE,
354354 .lpm_notify = false,
@@ -364,7 +364,39 @@ static struct mhi_channel_config aic100_channels[] = { · 9 unmodified lines
364364 .local_elements = 0,
365365 .event_ring = 0,
366366 .dir = DMA_FROM_DEVICE,
367− .ee_mask = MHI_CH_EE_SBL | MHI_CH_EE_AMSS,
367+ .ee_mask = MHI_CH_EE_SBL,
368+ .pollcfg = 0,
369+ .doorbell = MHI_DB_BRST_DISABLE,
370+ .lpm_notify = false,
371+ .offload_channel = false,
372+ .doorbell_mode_switch = false,
373+ .auto_queue = false,
374+ .wake_capable = false,
375+ },
376+ {
377+ .name = "QAIC_TIMESYNC_PERIODIC",
378+ .num = 22,
379+ .num_elements = 32,
380+ .local_elements = 0,
381+ .event_ring = 0,
382+ .dir = DMA_TO_DEVICE,
383+ .ee_mask = MHI_CH_EE_AMSS,
384+ .pollcfg = 0,
385+ .doorbell = MHI_DB_BRST_DISABLE,
386+ .lpm_notify = false,
387+ .offload_channel = false,
388+ .doorbell_mode_switch = false,
389+ .auto_queue = false,
390+ .wake_capable = false,
391+ },
392+ {
393+ .num = 23,
394+ .name = "QAIC_TIMESYNC_PERIODIC",
395+ .num_elements = 32,
396+ .local_elements = 0,
397+ .event_ring = 0,
398+ .dir = DMA_FROM_DEVICE,
399+ .ee_mask = MHI_CH_EE_AMSS,
368400 .pollcfg = 0,
369401 .doorbell = MHI_DB_BRST_DISABLE,
370402 .lpm_notify = false,
@@ -437,7 +469,7 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback re · 66 unmodified lines
437469 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n");
438470 /* this event occurs in non-atomic context */
439471 if (reason == MHI_CB_SYS_ERROR)
440− qaic_dev_reset_clean_local_state(qdev, true);
472+ qaic_dev_reset_clean_local_state(qdev);
441473 }
442474
443475 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl)
@@ -468,7 +500,7 @@ static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl) · 24 unmodified lines
468500 }
469501
470502 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar,
471− int mhi_irq)
503+ int mhi_irq, bool shared_msi)
472504 {
473505 struct mhi_controller *mhi_cntrl;
474506 int ret;
@@ -500,6 +532,10 @@ struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, voi · 25 unmodified lines
500532 return ERR_PTR(-ENOMEM);
501533
502534 mhi_cntrl->irq[0] = mhi_irq;
535+
536+ if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */
537+ mhi_cntrl->irq_flags = IRQF_SHARED;
538+
503539 mhi_cntrl->fw_image = "qcom/aic100/sbl.bin";
504540
505541 /* use latest configured timeout */
drivers/accel/qaic/mhi_controller.h+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
88 #define MHICONTROLLERQAIC_H_
99
1010 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar,
11− int mhi_irq);
11+ int mhi_irq, bool shared_msi);
1212 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up);
1313 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl);
1414 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl);
drivers/accel/qaic/qaic.h+18−3
@@ -31,6 +31,15 @@ · 30 unmodified lines
3131 #define to_drm(qddev) (&(qddev)->drm)
3232 #define to_accel_kdev(qddev) (to_drm(qddev)->accel->kdev) /* Return Linux device of accel node */
3333
34+enum __packed dev_states {
35+ /* Device is offline or will be very soon */
36+ QAIC_OFFLINE,
37+ /* Device is booting, not clear if it's in a usable state */
38+ QAIC_BOOT,
39+ /* Device is fully operational */
40+ QAIC_ONLINE,
41+};
42+
3443 extern bool datapath_polling;
3544
3645 struct qaic_user {
@@ -121,8 +130,10 @@ struct qaic_device { · 84 unmodified lines
121130 struct workqueue_struct *cntl_wq;
122131 /* Synchronizes all the users of device during cleanup */
123132 struct srcu_struct dev_lock;
124− /* true: Device under reset; false: Device not under reset */
125− bool in_reset;
133+ /* Track the state of the device during resets */
134+ enum dev_states dev_state;
135+ /* true: single MSI is used to operate device */
136+ bool single_msi;
126137 /*
127138 * true: A tx MHI transaction has failed and a rx buffer is still queued
128139 * in control device. Such a buffer is considered lost rx buffer
@@ -137,6 +148,10 @@ struct qaic_device { · 8 unmodified lines
137148 u32 (*gen_crc)(void *msg);
138149 /* Validate the CRC of a control message */
139150 bool (*valid_crc)(void *msg);
151+ /* MHI "QAIC_TIMESYNC" channel device */
152+ struct mhi_device *qts_ch;
153+ /* Work queue for tasks related to MHI "QAIC_TIMESYNC" channel */
154+ struct workqueue_struct *qts_wq;
140155 };
141156
142157 struct qaic_drm_device {
@@ -268,7 +283,7 @@ void wakeup_dbc(struct qaic_device *qdev, u32 dbc_id); · 125 unmodified lines
268283 void release_dbc(struct qaic_device *qdev, u32 dbc_id);
269284
270285 void wake_all_cntl(struct qaic_device *qdev);
271−void qaic_dev_reset_clean_local_state(struct qaic_device *qdev, bool exit_reset);
286+void qaic_dev_reset_clean_local_state(struct qaic_device *qdev);
272287
273288 struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf);
274289
drivers/accel/qaic/qaic_control.c+4−3
@@ -1022,7 +1022,8 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u · 1021 unmodified lines
10221022 int xfer_count = 0;
10231023 int retry_count;
10241024
1025− if (qdev->in_reset) {
1025+ /* Allow QAIC_BOOT state since we need to check control protocol version */
1026+ if (qdev->dev_state == QAIC_OFFLINE) {
10261027 mutex_unlock(&qdev->cntl_mutex);
10271028 return ERR_PTR(-ENODEV);
10281029 }
@@ -1138,7 +1139,7 @@ static int abort_dma_cont(struct qaic_device *qdev, struct wrapper_list *wrapper · 109 unmodified lines
11381139 if (!list_is_first(&wrapper->list, &wrappers->list))
11391140 kref_put(&wrapper->ref_count, free_wrapper);
11401141
1141− wrapper = add_wrapper(wrappers, offsetof(struct wrapper_msg, trans) + sizeof(*out_trans));
1142+ wrapper = add_wrapper(wrappers, sizeof(*wrapper));
11421143
11431144 if (!wrapper)
11441145 return -ENOMEM;
@@ -1306,7 +1307,7 @@ int qaic_manage_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ · 161 unmodified lines
13061307 qdev = usr->qddev->qdev;
13071308
13081309 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
1309− if (qdev->in_reset) {
1310+ if (qdev->dev_state != QAIC_ONLINE) {
13101311 srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id);
13111312 srcu_read_unlock(&usr->qddev_lock, usr_rcu_id);
13121313 return -ENODEV;
drivers/accel/qaic/qaic_data.c+70−77
@@ -51,6 +51,7 @@ · 50 unmodified lines
5151 })
5252 #define NUM_EVENTS 128
5353 #define NUM_DELAYS 10
54+#define fifo_at(base, offset) ((base) + (offset) * get_dbc_req_elem_size())
5455
5556 static unsigned int wait_exec_default_timeout_ms = 5000; /* 5 sec default */
5657 module_param(wait_exec_default_timeout_ms, uint, 0600);
@@ -451,7 +452,7 @@ static int create_sgt(struct qaic_device *qdev, struct sg_table **sgt_out, u64 s · 394 unmodified lines
451452 * later
452453 */
453454 buf_extra = (PAGE_SIZE - size % PAGE_SIZE) % PAGE_SIZE;
454− max_order = min(MAX_ORDER - 1, get_order(size));
455+ max_order = min(MAX_ORDER, get_order(size));
455456 } else {
456457 /* allocate a single page for book keeping */
457458 nr_pages = 1;
@@ -689,7 +690,7 @@ int qaic_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *fi · 231 unmodified lines
689690
690691 qdev = usr->qddev->qdev;
691692 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
692− if (qdev->in_reset) {
693+ if (qdev->dev_state != QAIC_ONLINE) {
693694 ret = -ENODEV;
694695 goto unlock_dev_srcu;
695696 }
@@ -748,7 +749,7 @@ int qaic_mmap_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file · 52 unmodified lines
748749
749750 qdev = usr->qddev->qdev;
750751 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
751− if (qdev->in_reset) {
752+ if (qdev->dev_state != QAIC_ONLINE) {
752753 ret = -ENODEV;
753754 goto unlock_dev_srcu;
754755 }
@@ -969,7 +970,7 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi · 214 unmodified lines
969970
970971 qdev = usr->qddev->qdev;
971972 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
972− if (qdev->in_reset) {
973+ if (qdev->dev_state != QAIC_ONLINE) {
973974 ret = -ENODEV;
974975 goto unlock_dev_srcu;
975976 }
@@ -1058,6 +1059,16 @@ unlock_usr_srcu: · 82 unmodified lines
10581059 return ret;
10591060 }
10601061
1062+static inline u32 fifo_space_avail(u32 head, u32 tail, u32 q_size)
1063+{
1064+ u32 avail = head - tail - 1;
1065+
1066+ if (head <= tail)
1067+ avail += q_size;
1068+
1069+ return avail;
1070+}
1071+
10611072 static inline int copy_exec_reqs(struct qaic_device *qdev, struct bo_slice *slice, u32 dbc_id,
10621073 u32 head, u32 *ptail)
10631074 {
@@ -1066,27 +1077,20 @@ static inline int copy_exec_reqs(struct qaic_device *qdev, struct bo_slice *slic · 2 unmodified lines
10661077 u32 tail = *ptail;
10671078 u32 avail;
10681079
1069− avail = head - tail;
1070− if (head <= tail)
1071− avail += dbc->nelem;
1072−
1073− --avail;
1074−
1080+ avail = fifo_space_avail(head, tail, dbc->nelem);
10751081 if (avail < slice->nents)
10761082 return -EAGAIN;
10771083
10781084 if (tail + slice->nents > dbc->nelem) {
10791085 avail = dbc->nelem - tail;
10801086 avail = min_t(u32, avail, slice->nents);
1081− memcpy(dbc->req_q_base + tail * get_dbc_req_elem_size(), reqs,
1082− sizeof(*reqs) * avail);
1087+ memcpy(fifo_at(dbc->req_q_base, tail), reqs, sizeof(*reqs) * avail);
10831088 reqs += avail;
10841089 avail = slice->nents - avail;
10851090 if (avail)
10861091 memcpy(dbc->req_q_base, reqs, sizeof(*reqs) * avail);
10871092 } else {
1088− memcpy(dbc->req_q_base + tail * get_dbc_req_elem_size(), reqs,
1089− sizeof(*reqs) * slice->nents);
1093+ memcpy(fifo_at(dbc->req_q_base, tail), reqs, sizeof(*reqs) * slice->nents);
10901094 }
10911095
10921096 *ptail = (tail + slice->nents) % dbc->nelem;
@@ -1094,46 +1098,31 @@ static inline int copy_exec_reqs(struct qaic_device *qdev, struct bo_slice *slic · 1 unmodified line
10941098 return 0;
10951099 }
10961100
1097−/*
1098− * Based on the value of resize we may only need to transmit first_n
1099− * entries and the last entry, with last_bytes to send from the last entry.
1100− * Note that first_n could be 0.
1101− */
11021101 static inline int copy_partial_exec_reqs(struct qaic_device *qdev, struct bo_slice *slice,
1103− u64 resize, u32 dbc_id, u32 head, u32 *ptail)
1102+ u64 resize, struct dma_bridge_chan *dbc, u32 head,
1103+ u32 *ptail)
11041104 {
1105− struct dma_bridge_chan *dbc = &qdev->dbc[dbc_id];
11061105 struct dbc_req *reqs = slice->reqs;
11071106 struct dbc_req *last_req;
11081107 u32 tail = *ptail;
1109− u64 total_bytes;
11101108 u64 last_bytes;
11111109 u32 first_n;
11121110 u32 avail;
1113− int ret;
1114− int i;
1115−
1116− avail = head - tail;
1117− if (head <= tail)
1118− avail += dbc->nelem;
11191111
1120− --avail;
1112+ avail = fifo_space_avail(head, tail, dbc->nelem);
11211113
1122− total_bytes = 0;
1123− for (i = 0; i < slice->nents; i++) {
1124− total_bytes += le32_to_cpu(reqs[i].len);
1125− if (total_bytes >= resize)
1114+ /*
1115+ * After this for loop is complete, first_n represents the index
1116+ * of the last DMA request of this slice that needs to be
1117+ * transferred after resizing and last_bytes represents DMA size
1118+ * of that request.
1119+ */
1120+ last_bytes = resize;
1121+ for (first_n = 0; first_n < slice->nents; first_n++)
1122+ if (last_bytes > le32_to_cpu(reqs[first_n].len))
1123+ last_bytes -= le32_to_cpu(reqs[first_n].len);
1124+ else
11261125 break;
1127− }
1128−
1129− if (total_bytes < resize) {
1130− /* User space should have used the full buffer path. */
1131− ret = -EINVAL;
1132− return ret;
1133− }
1134−
1135− first_n = i;
1136− last_bytes = i ? resize + le32_to_cpu(reqs[i].len) - total_bytes : resize;
11371126
11381127 if (avail < (first_n + 1))
11391128 return -EAGAIN;
@@ -1142,22 +1131,21 @@ static inline int copy_partial_exec_reqs(struct qaic_device *qdev, struct bo_sli · 2 unmodified lines
11421131 if (tail + first_n > dbc->nelem) {
11431132 avail = dbc->nelem - tail;
11441133 avail = min_t(u32, avail, first_n);
1145− memcpy(dbc->req_q_base + tail * get_dbc_req_elem_size(), reqs,
1146− sizeof(*reqs) * avail);
1134+ memcpy(fifo_at(dbc->req_q_base, tail), reqs, sizeof(*reqs) * avail);
11471135 last_req = reqs + avail;
11481136 avail = first_n - avail;
11491137 if (avail)
11501138 memcpy(dbc->req_q_base, last_req, sizeof(*reqs) * avail);
11511139 } else {
1152− memcpy(dbc->req_q_base + tail * get_dbc_req_elem_size(), reqs,
1153− sizeof(*reqs) * first_n);
1140+ memcpy(fifo_at(dbc->req_q_base, tail), reqs, sizeof(*reqs) * first_n);
11541141 }
11551142 }
11561143
1157− /* Copy over the last entry. Here we need to adjust len to the left over
1144+ /*
1145+ * Copy over the last entry. Here we need to adjust len to the left over
11581146 * size, and set src and dst to the entry it is copied to.
11591147 */
1160− last_req = dbc->req_q_base + (tail + first_n) % dbc->nelem * get_dbc_req_elem_size();
1148+ last_req = fifo_at(dbc->req_q_base, (tail + first_n) % dbc->nelem);
11611149 memcpy(last_req, reqs + slice->nents - 1, sizeof(*reqs));
11621150
11631151 /*
@@ -1168,6 +1156,9 @@ static inline int copy_partial_exec_reqs(struct qaic_device *qdev, struct bo_sli · 4 unmodified lines
11681156 last_req->len = cpu_to_le32((u32)last_bytes);
11691157 last_req->src_addr = reqs[first_n].src_addr;
11701158 last_req->dest_addr = reqs[first_n].dest_addr;
1159+ if (!last_bytes)
1160+ /* Disable DMA transfer */
1161+ last_req->cmd = GENMASK(7, 2) & reqs[first_n].cmd;
11711162
11721163 *ptail = (tail + first_n + 1) % dbc->nelem;
11731164
@@ -1227,26 +1218,17 @@ static int send_bo_list_to_device(struct qaic_device *qdev, struct drm_file *fil · 53 unmodified lines
12271218 bo->req_id = dbc->next_req_id++;
12281219
12291220 list_for_each_entry(slice, &bo->slices, slice) {
1230− /*
1231− * If this slice does not fall under the given
1232− * resize then skip this slice and continue the loop
1233− */
1234− if (is_partial && pexec[i].resize && pexec[i].resize <= slice->offset)
1235− continue;
1236−
12371221 for (j = 0; j < slice->nents; j++)
12381222 slice->reqs[j].req_id = cpu_to_le16(bo->req_id);
12391223
1240− /*
1241− * If it is a partial execute ioctl call then check if
1242− * resize has cut this slice short then do a partial copy
1243− * else do complete copy
1244− */
1245− if (is_partial && pexec[i].resize &&
1246− pexec[i].resize < slice->offset + slice->size)
1224+ if (is_partial && (!pexec[i].resize || pexec[i].resize <= slice->offset))
1225+ /* Configure the slice for no DMA transfer */
1226+ ret = copy_partial_exec_reqs(qdev, slice, 0, dbc, head, tail);
1227+ else if (is_partial && pexec[i].resize < slice->offset + slice->size)
1228+ /* Configure the slice to be partially DMA transferred */
12471229 ret = copy_partial_exec_reqs(qdev, slice,
1248− pexec[i].resize - slice->offset,
1249− dbc->id, head, tail);
1230+ pexec[i].resize - slice->offset, dbc,
1231+ head, tail);
12501232 else
12511233 ret = copy_exec_reqs(qdev, slice, dbc->id, head, tail);
12521234 if (ret) {
@@ -1359,7 +1341,7 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr · 106 unmodified lines
13591341
13601342 qdev = usr->qddev->qdev;
13611343 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
1362− if (qdev->in_reset) {
1344+ if (qdev->dev_state != QAIC_ONLINE) {
13631345 ret = -ENODEV;
13641346 goto unlock_dev_srcu;
13651347 }
@@ -1466,6 +1448,16 @@ irqreturn_t dbc_irq_handler(int irq, void *data) · 100 unmodified lines
14661448
14671449 rcu_id = srcu_read_lock(&dbc->ch_lock);
14681450
1451+ if (datapath_polling) {
1452+ srcu_read_unlock(&dbc->ch_lock, rcu_id);
1453+ /*
1454+ * Normally datapath_polling will not have irqs enabled, but
1455+ * when running with only one MSI the interrupt is shared with
1456+ * MHI so it cannot be disabled. Return ASAP instead.
1457+ */
1458+ return IRQ_HANDLED;
1459+ }
1460+
14691461 if (!dbc->usr) {
14701462 srcu_read_unlock(&dbc->ch_lock, rcu_id);
14711463 return IRQ_HANDLED;
@@ -1488,7 +1480,8 @@ irqreturn_t dbc_irq_handler(int irq, void *data) · 16 unmodified lines
14881480 return IRQ_NONE;
14891481 }
14901482
1491− disable_irq_nosync(irq);
1483+ if (!dbc->qdev->single_msi)
1484+ disable_irq_nosync(irq);
14921485 srcu_read_unlock(&dbc->ch_lock, rcu_id);
14931486 return IRQ_WAKE_THREAD;
14941487 }
@@ -1504,7 +1497,7 @@ void irq_polling_work(struct work_struct *work) · 9 unmodified lines
15041497 rcu_id = srcu_read_lock(&dbc->ch_lock);
15051498
15061499 while (1) {
1507− if (dbc->qdev->in_reset) {
1500+ if (dbc->qdev->dev_state != QAIC_ONLINE) {
15081501 srcu_read_unlock(&dbc->ch_lock, rcu_id);
15091502 return;
15101503 }
@@ -1559,12 +1552,12 @@ irqreturn_t dbc_irq_threaded_fn(int irq, void *data) · 48 unmodified lines
15591552 u32 tail;
15601553
15611554 rcu_id = srcu_read_lock(&dbc->ch_lock);
1555+ qdev = dbc->qdev;
15621556
15631557 head = readl(dbc->dbc_base + RSPHP_OFF);
15641558 if (head == U32_MAX) /* PCI link error */
15651559 goto error_out;
15661560
1567− qdev = dbc->qdev;
15681561 read_fifo:
15691562
15701563 if (!event_count) {
@@ -1645,14 +1638,14 @@ read_fifo: · 74 unmodified lines
16451638 goto read_fifo;
16461639
16471640 normal_out:
1648− if (likely(!datapath_polling))
1641+ if (!qdev->single_msi && likely(!datapath_polling))
16491642 enable_irq(irq);
1650− else
1643+ else if (unlikely(datapath_polling))
16511644 schedule_work(&dbc->poll_work);
16521645 /* checking the fifo and enabling irqs is a race, missed event check */
16531646 tail = readl(dbc->dbc_base + RSPTP_OFF);
16541647 if (tail != U32_MAX && head != tail) {
1655− if (likely(!datapath_polling))
1648+ if (!qdev->single_msi && likely(!datapath_polling))
16561649 disable_irq_nosync(irq);
16571650 goto read_fifo;
16581651 }
@@ -1661,9 +1654,9 @@ normal_out: · 2 unmodified lines
16611654
16621655 error_out:
16631656 srcu_read_unlock(&dbc->ch_lock, rcu_id);
1664− if (likely(!datapath_polling))
1657+ if (!qdev->single_msi && likely(!datapath_polling))
16651658 enable_irq(irq);
1666− else
1659+ else if (unlikely(datapath_polling))
16671660 schedule_work(&dbc->poll_work);
16681661
16691662 return IRQ_HANDLED;
@@ -1694,7 +1687,7 @@ int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file · 24 unmodified lines
16941687
16951688 qdev = usr->qddev->qdev;
16961689 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
1697− if (qdev->in_reset) {
1690+ if (qdev->dev_state != QAIC_ONLINE) {
16981691 ret = -ENODEV;
16991692 goto unlock_dev_srcu;
17001693 }
@@ -1763,7 +1756,7 @@ int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file · 62 unmodified lines
17631756
17641757 qdev = usr->qddev->qdev;
17651758 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
1766− if (qdev->in_reset) {
1759+ if (qdev->dev_state != QAIC_ONLINE) {
17671760 ret = -ENODEV;
17681761 goto unlock_dev_srcu;
17691762 }
@@ -1854,7 +1847,7 @@ int qaic_detach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi · 84 unmodified lines
18541847
18551848 qdev = usr->qddev->qdev;
18561849 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
1857− if (qdev->in_reset) {
1850+ if (qdev->dev_state != QAIC_ONLINE) {
18581851 ret = -ENODEV;
18591852 goto unlock_dev_srcu;
18601853 }
drivers/accel/qaic/qaic_drv.c+57−41
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/idr.h>
99 #include <linux/interrupt.h>
1010 #include <linux/list.h>
11+#include <linux/kobject.h>
1112 #include <linux/kref.h>
1213 #include <linux/mhi.h>
1314 #include <linux/module.h>
@@ -27,6 +28,7 @@ · 13 unmodified lines
2728
2829 #include "mhi_controller.h"
2930 #include "qaic.h"
31+#include "qaic_timesync.h"
3032
3133 MODULE_IMPORT_NS(DMA_BUF);
3234
@@ -42,9 +44,6 @@ MODULE_PARM_DESC(datapath_polling, "Operate the datapath in polling mode"); · 9 unmodified lines
4244 static bool link_up;
4345 static DEFINE_IDA(qaic_usrs);
4446
45−static int qaic_create_drm_device(struct qaic_device *qdev, s32 partition_id);
46−static void qaic_destroy_drm_device(struct qaic_device *qdev, s32 partition_id);
47−
4847 static void free_usr(struct kref *kref)
4948 {
5049 struct qaic_user *usr = container_of(kref, struct qaic_user, ref_count);
@@ -63,7 +62,7 @@ static int qaic_open(struct drm_device *dev, struct drm_file *file) · 12 unmodified lines
6362 int ret;
6463
6564 rcu_id = srcu_read_lock(&qdev->dev_lock);
66− if (qdev->in_reset) {
65+ if (qdev->dev_state != QAIC_ONLINE) {
6766 ret = -ENODEV;
6867 goto dev_unlock;
6968 }
@@ -120,7 +119,7 @@ static void qaic_postclose(struct drm_device *dev, struct drm_file *file) · 50 unmodified lines
120119 if (qddev) {
121120 qdev = qddev->qdev;
122121 qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
123− if (!qdev->in_reset) {
122+ if (qdev->dev_state == QAIC_ONLINE) {
124123 qaic_release_usr(qdev, usr);
125124 for (i = 0; i < qdev->num_dbc; ++i)
126125 if (qdev->dbc[i].usr && qdev->dbc[i].usr->handle == usr->handle)
@@ -182,13 +181,6 @@ static int qaic_create_drm_device(struct qaic_device *qdev, s32 partition_id) · 55 unmodified lines
182181
183182 qddev->partition_id = partition_id;
184183
185− /*
186− * drm_dev_unregister() sets the driver data to NULL and
187− * drm_dev_register() does not update the driver data. During a SOC
188− * reset drm dev is unregistered and registered again leaving the
189− * driver data to NULL.
190− */
191− dev_set_drvdata(to_accel_kdev(qddev), drm->accel);
192184 ret = drm_dev_register(drm, 0);
193185 if (ret)
194186 pci_dbg(qdev->pdev, "drm_dev_register failed %d\n", ret);
@@ -202,7 +194,6 @@ static void qaic_destroy_drm_device(struct qaic_device *qdev, s32 partition_id) · 7 unmodified lines
202194 struct drm_device *drm = to_drm(qddev);
203195 struct qaic_user *usr;
204196
205− drm_dev_get(drm);
206197 drm_dev_unregister(drm);
207198 qddev->partition_id = 0;
208199 /*
@@ -231,7 +222,6 @@ static void qaic_destroy_drm_device(struct qaic_device *qdev, s32 partition_id) · 22 unmodified lines
231222 mutex_lock(&qddev->users_mutex);
232223 }
233224 mutex_unlock(&qddev->users_mutex);
234− drm_dev_put(drm);
235225 }
236226
237227 static int qaic_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
@@ -253,8 +243,6 @@ static int qaic_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id · 15 unmodified lines
253243
254244 qdev = pci_get_drvdata(to_pci_dev(mhi_dev->mhi_cntrl->cntrl_dev));
255245
256− qdev->in_reset = false;
257−
258246 dev_set_drvdata(&mhi_dev->dev, qdev);
259247 qdev->cntl_ch = mhi_dev;
260248
@@ -264,6 +252,7 @@ static int qaic_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id · 3 unmodified lines
264252 return ret;
265253 }
266254
255+ qdev->dev_state = QAIC_BOOT;
267256 ret = get_cntl_version(qdev, NULL, &major, &minor);
268257 if (ret || major != CNTL_MAJOR || minor > CNTL_MINOR) {
269258 pci_err(qdev->pdev, "%s: Control protocol version (%d.%d) not supported. Supported version is (%d.%d). Ret: %d\n",
@@ -271,8 +260,8 @@ static int qaic_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id · 1 unmodified line
271260 ret = -EINVAL;
272261 goto close_control;
273262 }
274−
275− ret = qaic_create_drm_device(qdev, QAIC_NO_PARTITION);
263+ qdev->dev_state = QAIC_ONLINE;
264+ kobject_uevent(&(to_accel_kdev(qdev->qddev))->kobj, KOBJ_ONLINE);
276265
277266 return ret;
278267
@@ -290,7 +279,8 @@ static void qaic_notify_reset(struct qaic_device *qdev) · 11 unmodified lines
290279 {
291280 int i;
292281
293− qdev->in_reset = true;
282+ kobject_uevent(&(to_accel_kdev(qdev->qddev))->kobj, KOBJ_OFFLINE);
283+ qdev->dev_state = QAIC_OFFLINE;
294284 /* wake up any waiters to avoid waiting for timeouts at sync */
295285 wake_all_cntl(qdev);
296286 for (i = 0; i < qdev->num_dbc; ++i)
@@ -298,21 +288,15 @@ static void qaic_notify_reset(struct qaic_device *qdev) · 1 unmodified line
298288 synchronize_srcu(&qdev->dev_lock);
299289 }
300290
301−void qaic_dev_reset_clean_local_state(struct qaic_device *qdev, bool exit_reset)
291+void qaic_dev_reset_clean_local_state(struct qaic_device *qdev)
302292 {
303293 int i;
304294
305295 qaic_notify_reset(qdev);
306296
307− /* remove drmdevs to prevent new users from coming in */
308− qaic_destroy_drm_device(qdev, QAIC_NO_PARTITION);
309−
310297 /* start tearing things down */
311298 for (i = 0; i < qdev->num_dbc; ++i)
312299 release_dbc(qdev, i);
313−
314− if (exit_reset)
315− qdev->in_reset = false;
316300 }
317301
318302 static void cleanup_qdev(struct qaic_device *qdev)
@@ -324,6 +308,7 @@ static void cleanup_qdev(struct qaic_device *qdev) · 5 unmodified lines
324308 cleanup_srcu_struct(&qdev->dev_lock);
325309 pci_set_drvdata(qdev->pdev, NULL);
326310 destroy_workqueue(qdev->cntl_wq);
311+ destroy_workqueue(qdev->qts_wq);
327312 }
328313
329314 static struct qaic_device *create_qdev(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -336,6 +321,7 @@ static struct qaic_device *create_qdev(struct pci_dev *pdev, const struct pci_de · 6 unmodified lines
336321 if (!qdev)
337322 return NULL;
338323
324+ qdev->dev_state = QAIC_OFFLINE;
339325 if (id->device == PCI_DEV_AIC100) {
340326 qdev->num_dbc = 16;
341327 qdev->dbc = devm_kcalloc(&pdev->dev, qdev->num_dbc, sizeof(*qdev->dbc), GFP_KERNEL);
@@ -347,6 +333,12 @@ static struct qaic_device *create_qdev(struct pci_dev *pdev, const struct pci_de · 5 unmodified lines
347333 if (!qdev->cntl_wq)
348334 return NULL;
349335
336+ qdev->qts_wq = alloc_workqueue("qaic_ts", WQ_UNBOUND, 0);
337+ if (!qdev->qts_wq) {
338+ destroy_workqueue(qdev->cntl_wq);
339+ return NULL;
340+ }
341+
350342 pci_set_drvdata(pdev, qdev);
351343 qdev->pdev = pdev;
352344
@@ -424,14 +416,24 @@ static int init_msi(struct qaic_device *qdev, struct pci_dev *pdev) · 71 unmodified lines
424416 int i;
425417
426418 /* Managed release since we use pcim_enable_device */
427− ret = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
428− if (ret < 0)
429− return ret;
419+ ret = pci_alloc_irq_vectors(pdev, 32, 32, PCI_IRQ_MSI);
420+ if (ret == -ENOSPC) {
421+ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
422+ if (ret < 0)
423+ return ret;
430424
431− if (ret < 32) {
432− pci_err(pdev, "%s: Requested 32 MSIs. Obtained %d MSIs which is less than the 32 required.\n",
433− __func__, ret);
434− return -ENODEV;
425+ /*
426+ * Operate in one MSI mode. All interrupts will be directed to
427+ * MSI0; every interrupt will wake up all the interrupt handlers
428+ * (MHI and DBC[0-15]). Since the interrupt is now shared, it is
429+ * not disabled during DBC threaded handler, but only one thread
430+ * will be allowed to run per DBC, so while it can be
431+ * interrupted, it shouldn't race with itself.
432+ */
433+ qdev->single_msi = true;
434+ pci_info(pdev, "Allocating 32 MSIs failed, operating in 1 MSI mode. Performance may be impacted.\n");
435+ } else if (ret < 0) {
436+ return ret;
435437 }
436438
437439 mhi_irq = pci_irq_vector(pdev, 0);
@@ -439,15 +441,17 @@ static int init_msi(struct qaic_device *qdev, struct pci_dev *pdev) · 1 unmodified line
439441 return mhi_irq;
440442
441443 for (i = 0; i < qdev->num_dbc; ++i) {
442− ret = devm_request_threaded_irq(&pdev->dev, pci_irq_vector(pdev, i + 1),
444+ ret = devm_request_threaded_irq(&pdev->dev,
445+ pci_irq_vector(pdev, qdev->single_msi ? 0 : i + 1),
443446 dbc_irq_handler, dbc_irq_threaded_fn, IRQF_SHARED,
444447 "qaic_dbc", &qdev->dbc[i]);
445448 if (ret)
446449 return ret;
447450
448451 if (datapath_polling) {
449− qdev->dbc[i].irq = pci_irq_vector(pdev, i + 1);
450− disable_irq_nosync(qdev->dbc[i].irq);
452+ qdev->dbc[i].irq = pci_irq_vector(pdev, qdev->single_msi ? 0 : i + 1);
453+ if (!qdev->single_msi)
454+ disable_irq_nosync(qdev->dbc[i].irq);
451455 INIT_WORK(&qdev->dbc[i].poll_work, irq_polling_work);
452456 }
453457 }
@@ -479,14 +483,21 @@ static int qaic_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 25 unmodified lines
479483 goto cleanup_qdev;
480484 }
481485
482− qdev->mhi_cntrl = qaic_mhi_register_controller(pdev, qdev->bar_0, mhi_irq);
486+ ret = qaic_create_drm_device(qdev, QAIC_NO_PARTITION);
487+ if (ret)
488+ goto cleanup_qdev;
489+
490+ qdev->mhi_cntrl = qaic_mhi_register_controller(pdev, qdev->bar_0, mhi_irq,
491+ qdev->single_msi);
483492 if (IS_ERR(qdev->mhi_cntrl)) {
484493 ret = PTR_ERR(qdev->mhi_cntrl);
485− goto cleanup_qdev;
494+ goto cleanup_drm_dev;
486495 }
487496
488497 return 0;
489498
499+cleanup_drm_dev:
500+ qaic_destroy_drm_device(qdev, QAIC_NO_PARTITION);
490501 cleanup_qdev:
491502 cleanup_qdev(qdev);
492503 return ret;
@@ -499,7 +510,8 @@ static void qaic_pci_remove(struct pci_dev *pdev) · 6 unmodified lines
499510 if (!qdev)
500511 return;
501512
502− qaic_dev_reset_clean_local_state(qdev, false);
513+ qaic_dev_reset_clean_local_state(qdev);
514+ qaic_destroy_drm_device(qdev, QAIC_NO_PARTITION);
503515 qaic_mhi_free_controller(qdev->mhi_cntrl, link_up);
504516 cleanup_qdev(qdev);
505517 }
@@ -522,14 +534,13 @@ static void qaic_pci_reset_prepare(struct pci_dev *pdev) · 16 unmodified lines
522534
523535 qaic_notify_reset(qdev);
524536 qaic_mhi_start_reset(qdev->mhi_cntrl);
525− qaic_dev_reset_clean_local_state(qdev, false);
537+ qaic_dev_reset_clean_local_state(qdev);
526538 }
527539
528540 static void qaic_pci_reset_done(struct pci_dev *pdev)
529541 {
530542 struct qaic_device *qdev = pci_get_drvdata(pdev);
531543
532− qdev->in_reset = false;
533544 qaic_mhi_reset_done(qdev->mhi_cntrl);
534545 }
535546
@@ -586,6 +597,10 @@ static int __init qaic_init(void) · 50 unmodified lines
586597 goto free_pci;
587598 }
588599
600+ ret = qaic_timesync_init();
601+ if (ret)
602+ pr_debug("qaic: qaic_timesync_init failed %d\n", ret);
603+
589604 return 0;
590605
591606 free_pci:
@@ -611,6 +626,7 @@ static void __exit qaic_exit(void) · 19 unmodified lines
611626 * reinitializing the link_up state after the cleanup is done.
612627 */
613628 link_up = true;
629+ qaic_timesync_deinit();
614630 mhi_driver_unregister(&qaic_mhi_driver);
615631 pci_unregister_driver(&qaic_pci_driver);
616632 }
drivers/accel/qaic/qaic_timesync.c+395−0
@@ -0,0 +1,395 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */
3+
4+#include <linux/io.h>
5+#include <linux/kernel.h>
6+#include <linux/math64.h>
7+#include <linux/mhi.h>
8+#include <linux/mod_devicetable.h>
9+#include <linux/module.h>
10+#include <linux/time64.h>
11+#include <linux/timer.h>
12+
13+#include "qaic.h"
14+#include "qaic_timesync.h"
15+
16+#define QTIMER_REG_OFFSET 0xa28
17+#define QAIC_TIMESYNC_SIGNATURE 0x55aa
18+#define QAIC_CONV_QTIMER_TO_US(qtimer) (mul_u64_u32_div(qtimer, 10, 192))
19+
20+static unsigned int timesync_delay_ms = 1000; /* 1 sec default */
21+module_param(timesync_delay_ms, uint, 0600);
22+MODULE_PARM_DESC(timesync_delay_ms, "Delay in ms between two consecutive timesync operations");
23+
24+enum qts_msg_type {
25+ QAIC_TS_CMD_TO_HOST,
26+ QAIC_TS_SYNC_REQ,
27+ QAIC_TS_ACK_TO_HOST,
28+ QAIC_TS_MSG_TYPE_MAX
29+};
30+
31+/**
32+ * struct qts_hdr - Timesync message header structure.
33+ * @signature: Unique signature to identify the timesync message.
34+ * @reserved_1: Reserved for future use.
35+ * @reserved_2: Reserved for future use.
36+ * @msg_type: sub-type of the timesync message.
37+ * @reserved_3: Reserved for future use.
38+ */
39+struct qts_hdr {
40+ __le16 signature;
41+ __le16 reserved_1;
42+ u8 reserved_2;
43+ u8 msg_type;
44+ __le16 reserved_3;
45+} __packed;
46+
47+/**
48+ * struct qts_timeval - Structure to carry time information.
49+ * @tv_sec: Seconds part of the time.
50+ * @tv_usec: uS (microseconds) part of the time.
51+ */
52+struct qts_timeval {
53+ __le64 tv_sec;
54+ __le64 tv_usec;
55+} __packed;
56+
57+/**
58+ * struct qts_host_time_sync_msg_data - Structure to denote the timesync message.
59+ * @header: Header of the timesync message.
60+ * @data: Time information.
61+ */
62+struct qts_host_time_sync_msg_data {
63+ struct qts_hdr header;
64+ struct qts_timeval data;
65+} __packed;
66+
67+/**
68+ * struct mqts_dev - MHI QAIC Timesync Control device.
69+ * @qdev: Pointer to the root device struct driven by QAIC driver.
70+ * @mhi_dev: Pointer to associated MHI device.
71+ * @timer: Timer handle used for timesync.
72+ * @qtimer_addr: Device QTimer register pointer.
73+ * @buff_in_use: atomic variable to track if the sync_msg buffer is in use.
74+ * @dev: Device pointer to qdev->pdev->dev stored for easy access.
75+ * @sync_msg: Buffer used to send timesync message over MHI.
76+ */
77+struct mqts_dev {
78+ struct qaic_device *qdev;
79+ struct mhi_device *mhi_dev;
80+ struct timer_list timer;
81+ void __iomem *qtimer_addr;
82+ atomic_t buff_in_use;
83+ struct device *dev;
84+ struct qts_host_time_sync_msg_data *sync_msg;
85+};
86+
87+struct qts_resp_msg {
88+ struct qts_hdr hdr;
89+} __packed;
90+
91+struct qts_resp {
92+ struct qts_resp_msg data;
93+ struct work_struct work;
94+ struct qaic_device *qdev;
95+};
96+
97+#ifdef readq
98+static u64 read_qtimer(const volatile void __iomem *addr)
99+{
100+ return readq(addr);
101+}
102+#else
103+static u64 read_qtimer(const volatile void __iomem *addr)
104+{
105+ u64 low, high;
106+
107+ low = readl(addr);
108+ high = readl(addr + sizeof(u32));
109+ return low | (high << 32);
110+}
111+#endif
112+
113+static void qaic_timesync_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
114+{
115+ struct mqts_dev *mqtsdev = dev_get_drvdata(&mhi_dev->dev);
116+
117+ dev_dbg(mqtsdev->dev, "%s status: %d xfer_len: %zu\n", __func__,
118+ mhi_result->transaction_status, mhi_result->bytes_xferd);
119+
120+ atomic_set(&mqtsdev->buff_in_use, 0);
121+}
122+
123+static void qaic_timesync_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
124+{
125+ struct mqts_dev *mqtsdev = dev_get_drvdata(&mhi_dev->dev);
126+
127+ dev_err(mqtsdev->dev, "%s no data expected on dl channel\n", __func__);
128+}
129+
130+static void qaic_timesync_timer(struct timer_list *t)
131+{
132+ struct mqts_dev *mqtsdev = from_timer(mqtsdev, t, timer);
133+ struct qts_host_time_sync_msg_data *sync_msg;
134+ u64 device_qtimer_us;
135+ u64 device_qtimer;
136+ u64 host_time_us;
137+ u64 offset_us;
138+ u64 host_sec;
139+ int ret;
140+
141+ if (atomic_read(&mqtsdev->buff_in_use)) {
142+ dev_dbg(mqtsdev->dev, "%s buffer not free, schedule next cycle\n", __func__);
143+ goto mod_timer;
144+ }
145+ atomic_set(&mqtsdev->buff_in_use, 1);
146+
147+ sync_msg = mqtsdev->sync_msg;
148+ sync_msg->header.signature = cpu_to_le16(QAIC_TIMESYNC_SIGNATURE);
149+ sync_msg->header.msg_type = QAIC_TS_SYNC_REQ;
150+ /* Read host UTC time and convert to uS*/
151+ host_time_us = div_u64(ktime_get_real_ns(), NSEC_PER_USEC);
152+ device_qtimer = read_qtimer(mqtsdev->qtimer_addr);
153+ device_qtimer_us = QAIC_CONV_QTIMER_TO_US(device_qtimer);
154+ /* Offset between host UTC and device time */
155+ offset_us = host_time_us - device_qtimer_us;
156+
157+ host_sec = div_u64(offset_us, USEC_PER_SEC);
158+ sync_msg->data.tv_usec = cpu_to_le64(offset_us - host_sec * USEC_PER_SEC);
159+ sync_msg->data.tv_sec = cpu_to_le64(host_sec);
160+ ret = mhi_queue_buf(mqtsdev->mhi_dev, DMA_TO_DEVICE, sync_msg, sizeof(*sync_msg), MHI_EOT);
161+ if (ret && (ret != -EAGAIN)) {
162+ dev_err(mqtsdev->dev, "%s unable to queue to mhi:%d\n", __func__, ret);
163+ return;
164+ } else if (ret == -EAGAIN) {
165+ atomic_set(&mqtsdev->buff_in_use, 0);
166+ }
167+
168+mod_timer:
169+ ret = mod_timer(t, jiffies + msecs_to_jiffies(timesync_delay_ms));
170+ if (ret)
171+ dev_err(mqtsdev->dev, "%s mod_timer error:%d\n", __func__, ret);
172+}
173+
174+static int qaic_timesync_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
175+{
176+ struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_dev->mhi_cntrl->cntrl_dev));
177+ struct mqts_dev *mqtsdev;
178+ struct timer_list *timer;
179+ int ret;
180+
181+ mqtsdev = kzalloc(sizeof(*mqtsdev), GFP_KERNEL);
182+ if (!mqtsdev) {
183+ ret = -ENOMEM;
184+ goto out;
185+ }
186+
187+ timer = &mqtsdev->timer;
188+ mqtsdev->mhi_dev = mhi_dev;
189+ mqtsdev->qdev = qdev;
190+ mqtsdev->dev = &qdev->pdev->dev;
191+
192+ mqtsdev->sync_msg = kzalloc(sizeof(*mqtsdev->sync_msg), GFP_KERNEL);
193+ if (!mqtsdev->sync_msg) {
194+ ret = -ENOMEM;
195+ goto free_mqts_dev;
196+ }
197+ atomic_set(&mqtsdev->buff_in_use, 0);
198+
199+ ret = mhi_prepare_for_transfer(mhi_dev);
200+ if (ret)
201+ goto free_sync_msg;
202+
203+ /* Qtimer register pointer */
204+ mqtsdev->qtimer_addr = qdev->bar_0 + QTIMER_REG_OFFSET;
205+ timer_setup(timer, qaic_timesync_timer, 0);
206+ timer->expires = jiffies + msecs_to_jiffies(timesync_delay_ms);
207+ add_timer(timer);
208+ dev_set_drvdata(&mhi_dev->dev, mqtsdev);
209+
210+ return 0;
211+
212+free_sync_msg:
213+ kfree(mqtsdev->sync_msg);
214+free_mqts_dev:
215+ kfree(mqtsdev);
216+out:
217+ return ret;
218+};
219+
220+static void qaic_timesync_remove(struct mhi_device *mhi_dev)
221+{
222+ struct mqts_dev *mqtsdev = dev_get_drvdata(&mhi_dev->dev);
223+
224+ del_timer_sync(&mqtsdev->timer);
225+ mhi_unprepare_from_transfer(mqtsdev->mhi_dev);
226+ kfree(mqtsdev->sync_msg);
227+ kfree(mqtsdev);
228+}
229+
230+static const struct mhi_device_id qaic_timesync_match_table[] = {
231+ { .chan = "QAIC_TIMESYNC_PERIODIC"},
232+ {},
233+};
234+
235+MODULE_DEVICE_TABLE(mhi, qaic_timesync_match_table);
236+
237+static struct mhi_driver qaic_timesync_driver = {
238+ .id_table = qaic_timesync_match_table,
239+ .remove = qaic_timesync_remove,
240+ .probe = qaic_timesync_probe,
241+ .ul_xfer_cb = qaic_timesync_ul_xfer_cb,
242+ .dl_xfer_cb = qaic_timesync_dl_xfer_cb,
243+ .driver = {
244+ .name = "qaic_timesync_periodic",
245+ },
246+};
247+
248+static void qaic_boot_timesync_worker(struct work_struct *work)
249+{
250+ struct qts_resp *resp = container_of(work, struct qts_resp, work);
251+ struct qts_host_time_sync_msg_data *req;
252+ struct qts_resp_msg data = resp->data;
253+ struct qaic_device *qdev = resp->qdev;
254+ struct mhi_device *mhi_dev;
255+ struct timespec64 ts;
256+ int ret;
257+
258+ mhi_dev = qdev->qts_ch;
259+ /* Queue the response message beforehand to avoid race conditions */
260+ ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, &resp->data, sizeof(resp->data), MHI_EOT);
261+ if (ret) {
262+ kfree(resp);
263+ dev_warn(&mhi_dev->dev, "Failed to re-queue response buffer %d\n", ret);
264+ return;
265+ }
266+
267+ switch (data.hdr.msg_type) {
268+ case QAIC_TS_CMD_TO_HOST:
269+ req = kzalloc(sizeof(*req), GFP_KERNEL);
270+ if (!req)
271+ break;
272+
273+ req->header = data.hdr;
274+ req->header.msg_type = QAIC_TS_SYNC_REQ;
275+ ktime_get_real_ts64(&ts);
276+ req->data.tv_sec = cpu_to_le64(ts.tv_sec);
277+ req->data.tv_usec = cpu_to_le64(div_u64(ts.tv_nsec, NSEC_PER_USEC));
278+
279+ ret = mhi_queue_buf(mhi_dev, DMA_TO_DEVICE, req, sizeof(*req), MHI_EOT);
280+ if (ret) {
281+ kfree(req);
282+ dev_dbg(&mhi_dev->dev, "Failed to send request message. Error %d\n", ret);
283+ }
284+ break;
285+ case QAIC_TS_ACK_TO_HOST:
286+ dev_dbg(&mhi_dev->dev, "ACK received from device\n");
287+ break;
288+ default:
289+ dev_err(&mhi_dev->dev, "Invalid message type %u.\n", data.hdr.msg_type);
290+ }
291+}
292+
293+static int qaic_boot_timesync_queue_resp(struct mhi_device *mhi_dev, struct qaic_device *qdev)
294+{
295+ struct qts_resp *resp;
296+ int ret;
297+
298+ resp = kzalloc(sizeof(*resp), GFP_KERNEL);
299+ if (!resp)
300+ return -ENOMEM;
301+
302+ resp->qdev = qdev;
303+ INIT_WORK(&resp->work, qaic_boot_timesync_worker);
304+
305+ ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, &resp->data, sizeof(resp->data), MHI_EOT);
306+ if (ret) {
307+ kfree(resp);
308+ dev_warn(&mhi_dev->dev, "Failed to queue response buffer %d\n", ret);
309+ return ret;
310+ }
311+
312+ return 0;
313+}
314+
315+static void qaic_boot_timesync_remove(struct mhi_device *mhi_dev)
316+{
317+ struct qaic_device *qdev;
318+
319+ qdev = dev_get_drvdata(&mhi_dev->dev);
320+ mhi_unprepare_from_transfer(qdev->qts_ch);
321+ qdev->qts_ch = NULL;
322+}
323+
324+static int qaic_boot_timesync_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
325+{
326+ struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_dev->mhi_cntrl->cntrl_dev));
327+ int ret;
328+
329+ ret = mhi_prepare_for_transfer(mhi_dev);
330+ if (ret)
331+ return ret;
332+
333+ qdev->qts_ch = mhi_dev;
334+ dev_set_drvdata(&mhi_dev->dev, qdev);
335+
336+ ret = qaic_boot_timesync_queue_resp(mhi_dev, qdev);
337+ if (ret) {
338+ dev_set_drvdata(&mhi_dev->dev, NULL);
339+ qdev->qts_ch = NULL;
340+ mhi_unprepare_from_transfer(mhi_dev);
341+ }
342+
343+ return ret;
344+}
345+
346+static void qaic_boot_timesync_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
347+{
348+ kfree(mhi_result->buf_addr);
349+}
350+
351+static void qaic_boot_timesync_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
352+{
353+ struct qts_resp *resp = container_of(mhi_result->buf_addr, struct qts_resp, data);
354+
355+ if (mhi_result->transaction_status || mhi_result->bytes_xferd != sizeof(resp->data)) {
356+ kfree(resp);
357+ return;
358+ }
359+
360+ queue_work(resp->qdev->qts_wq, &resp->work);
361+}
362+
363+static const struct mhi_device_id qaic_boot_timesync_match_table[] = {
364+ { .chan = "QAIC_TIMESYNC"},
365+ {},
366+};
367+
368+static struct mhi_driver qaic_boot_timesync_driver = {
369+ .id_table = qaic_boot_timesync_match_table,
370+ .remove = qaic_boot_timesync_remove,
371+ .probe = qaic_boot_timesync_probe,
372+ .ul_xfer_cb = qaic_boot_timesync_ul_xfer_cb,
373+ .dl_xfer_cb = qaic_boot_timesync_dl_xfer_cb,
374+ .driver = {
375+ .name = "qaic_timesync",
376+ },
377+};
378+
379+int qaic_timesync_init(void)
380+{
381+ int ret;
382+
383+ ret = mhi_driver_register(&qaic_timesync_driver);
384+ if (ret)
385+ return ret;
386+ ret = mhi_driver_register(&qaic_boot_timesync_driver);
387+
388+ return ret;
389+}
390+
391+void qaic_timesync_deinit(void)
392+{
393+ mhi_driver_unregister(&qaic_boot_timesync_driver);
394+ mhi_driver_unregister(&qaic_timesync_driver);
395+}
drivers/accel/qaic/qaic_timesync.h+11−0
@@ -0,0 +1,11 @@
1+/* SPDX-License-Identifier: GPL-2.0-only
2+ *
3+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4+ */
5+
6+#ifndef __QAIC_TIMESYNC_H__
7+#define __QAIC_TIMESYNC_H__
8+
9+int qaic_timesync_init(void);
10+void qaic_timesync_deinit(void);
11+#endif /* __QAIC_TIMESYNC_H__ */
drivers/acpi/acpi_video.c+1−1
@@ -2031,7 +2031,7 @@ static int acpi_video_bus_add(struct acpi_device *device) · 2030 unmodified lines
20312031 * HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS0
20322032 * evaluated to have functional panel brightness control.
20332033 */
2034− acpi_device_fix_up_power_extended(device);
2034+ acpi_device_fix_up_power_children(device);
20352035
20362036 pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n",
20372037 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
drivers/acpi/device_pm.c+13−0
@@ -397,6 +397,19 @@ void acpi_device_fix_up_power_extended(struct acpi_device *adev) · 396 unmodified lines
397397 }
398398 EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_extended);
399399
400+/**
401+ * acpi_device_fix_up_power_children - Force a device's children into D0.
402+ * @adev: Parent device object whose children's power state is to be fixed up.
403+ *
404+ * Call acpi_device_fix_up_power() for @adev's children so long as they
405+ * are reported as present and enabled.
406+ */
407+void acpi_device_fix_up_power_children(struct acpi_device *adev)
408+{
409+ acpi_dev_for_each_child(adev, fix_up_power_if_applicable, NULL);
410+}
411+EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_children);
412+
400413 int acpi_device_update_power(struct acpi_device *device, int *state_p)
401414 {
402415 int state;
drivers/acpi/processor_idle.c+1−1
@@ -592,7 +592,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) · 591 unmodified lines
592592 while (1) {
593593
594594 if (cx->entry_method == ACPI_CSTATE_HALT)
595− safe_halt();
595+ raw_safe_halt();
596596 else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
597597 io_idle(cx->address);
598598 } else
drivers/acpi/resource.c+7−0
@@ -447,6 +447,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { · 446 unmodified lines
447447 DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"),
448448 },
449449 },
450+ {
451+ /* Asus ExpertBook B1402CVA */
452+ .matches = {
453+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
454+ DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"),
455+ },
456+ },
450457 {
451458 /* Asus ExpertBook B1502CBA */
452459 .matches = {
drivers/ata/pata_isapnp.c+3−0
@@ -82,6 +82,9 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev · 81 unmodified lines
8282 if (pnp_port_valid(idev, 1)) {
8383 ctl_addr = devm_ioport_map(&idev->dev,
8484 pnp_port_start(idev, 1), 1);
85+ if (!ctl_addr)
86+ return -ENOMEM;
87+
8588 ap->ioaddr.altstatus_addr = ctl_addr;
8689 ap->ioaddr.ctl_addr = ctl_addr;
8790 ap->ops = &isapnp_port_ops;
drivers/auxdisplay/Kconfig+2−8
@@ -112,10 +112,7 @@ config CFAG12864B · 111 unmodified lines
112112 depends on X86
113113 depends on FB
114114 depends on KS0108
115− select FB_SYS_FILLRECT
116− select FB_SYS_COPYAREA
117− select FB_SYS_IMAGEBLIT
118− select FB_SYS_FOPS
115+ select FB_SYSMEM_HELPERS
119116 default n
120117 help
121118 If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series,
@@ -170,10 +167,7 @@ config IMG_ASCII_LCD · 48 unmodified lines
170167 config HT16K33
171168 tristate "Holtek Ht16K33 LED controller with keyscan"
172169 depends on FB && I2C && INPUT
173− select FB_SYS_FOPS
174− select FB_SYS_FILLRECT
175− select FB_SYS_COPYAREA
176− select FB_SYS_IMAGEBLIT
170+ select FB_SYSMEM_HELPERS
177171 select INPUT_MATRIXKMAP
178172 select FB_BACKLIGHT
179173 select NEW_LEDS
drivers/auxdisplay/cfag12864bfb.c+5−5
@@ -51,16 +51,15 @@ static int cfag12864bfb_mmap(struct fb_info *info, struct vm_area_struct *vma) · 50 unmodified lines
5151 {
5252 struct page *pages = virt_to_page(cfag12864b_buffer);
5353
54+ vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
55+
5456 return vm_map_pages_zero(vma, &pages, 1);
5557 }
5658
5759 static const struct fb_ops cfag12864bfb_ops = {
5860 .owner = THIS_MODULE,
59− .fb_read = fb_sys_read,
60− .fb_write = fb_sys_write,
61− .fb_fillrect = sys_fillrect,
62− .fb_copyarea = sys_copyarea,
63− .fb_imageblit = sys_imageblit,
61+ __FB_DEFAULT_SYSMEM_OPS_RDWR,
62+ __FB_DEFAULT_SYSMEM_OPS_DRAW,
6463 .fb_mmap = cfag12864bfb_mmap,
6564 };
6665
@@ -72,6 +71,7 @@ static int cfag12864bfb_probe(struct platform_device *device) · 5 unmodified lines
7271 if (!info)
7372 goto none;
7473
74+ info->flags = FBINFO_VIRTFB;
7575 info->screen_buffer = cfag12864b_buffer;
7676 info->screen_size = CFAG12864B_SIZE;
7777 info->fbops = &cfag12864bfb_ops;
drivers/auxdisplay/ht16k33.c+5−5
@@ -351,17 +351,16 @@ static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma) · 350 unmodified lines
351351 struct ht16k33_priv *priv = info->par;
352352 struct page *pages = virt_to_page(priv->fbdev.buffer);
353353
354+ vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
355+
354356 return vm_map_pages_zero(vma, &pages, 1);
355357 }
356358
357359 static const struct fb_ops ht16k33_fb_ops = {
358360 .owner = THIS_MODULE,
359− .fb_read = fb_sys_read,
360− .fb_write = fb_sys_write,
361+ __FB_DEFAULT_SYSMEM_OPS_RDWR,
361362 .fb_blank = ht16k33_blank,
362− .fb_fillrect = sys_fillrect,
363− .fb_copyarea = sys_copyarea,
364− .fb_imageblit = sys_imageblit,
363+ __FB_DEFAULT_SYSMEM_OPS_DRAW,
365364 .fb_mmap = ht16k33_mmap,
366365 };
367366
@@ -640,6 +639,7 @@ static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv, · 272 unmodified lines
640639
641640 INIT_DELAYED_WORK(&priv->work, ht16k33_fb_update);
642641 fbdev->info->fbops = &ht16k33_fb_ops;
642+ fbdev->info->flags |= FBINFO_VIRTFB;
643643 fbdev->info->screen_buffer = fbdev->buffer;
644644 fbdev->info->screen_size = HT16K33_FB_SIZE;
645645 fbdev->info->fix = ht16k33_fb_fix;
drivers/block/nbd.c+75−42
@@ -67,6 +67,7 @@ struct nbd_sock { · 66 unmodified lines
6767 struct recv_thread_args {
6868 struct work_struct work;
6969 struct nbd_device *nbd;
70+ struct nbd_sock *nsock;
7071 int index;
7172 };
7273
@@ -395,6 +396,22 @@ static u32 req_to_nbd_cmd_type(struct request *req) · 322 unmodified lines
395396 }
396397 }
397398
399+static struct nbd_config *nbd_get_config_unlocked(struct nbd_device *nbd)
400+{
401+ if (refcount_inc_not_zero(&nbd->config_refs)) {
402+ /*
403+ * Add smp_mb__after_atomic to ensure that reading nbd->config_refs
404+ * and reading nbd->config is ordered. The pair is the barrier in
405+ * nbd_alloc_and_init_config(), avoid nbd->config_refs is set
406+ * before nbd->config.
407+ */
408+ smp_mb__after_atomic();
409+ return nbd->config;
410+ }
411+
412+ return NULL;
413+}
414+
398415 static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
399416 {
400417 struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
@@ -409,13 +426,13 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req) · 8 unmodified lines
409426 return BLK_EH_DONE;
410427 }
411428
412− if (!refcount_inc_not_zero(&nbd->config_refs)) {
429+ config = nbd_get_config_unlocked(nbd);
430+ if (!config) {
413431 cmd->status = BLK_STS_TIMEOUT;
414432 __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags);
415433 mutex_unlock(&cmd->lock);
416434 goto done;
417435 }
418− config = nbd->config;
419436
420437 if (config->num_connections > 1 ||
421438 (config->num_connections == 1 && nbd->tag_set.timeout)) {
@@ -489,15 +506,9 @@ done: · 67 unmodified lines
489506 return BLK_EH_DONE;
490507 }
491508
492−/*
493− * Send or receive packet. Return a positive value on success and
494− * negtive value on failue, and never return 0.
495− */
496−static int sock_xmit(struct nbd_device *nbd, int index, int send,
497− struct iov_iter *iter, int msg_flags, int *sent)
509+static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
510+ struct iov_iter *iter, int msg_flags, int *sent)
498511 {
499− struct nbd_config *config = nbd->config;
500− struct socket *sock = config->socks[index]->sock;
501512 int result;
502513 struct msghdr msg;
503514 unsigned int noreclaim_flag;
@@ -540,6 +551,19 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, · 36 unmodified lines
540551 return result;
541552 }
542553
554+/*
555+ * Send or receive packet. Return a positive value on success and
556+ * negtive value on failure, and never return 0.
557+ */
558+static int sock_xmit(struct nbd_device *nbd, int index, int send,
559+ struct iov_iter *iter, int msg_flags, int *sent)
560+{
561+ struct nbd_config *config = nbd->config;
562+ struct socket *sock = config->socks[index]->sock;
563+
564+ return __sock_xmit(nbd, sock, send, iter, msg_flags, sent);
565+}
566+
543567 /*
544568 * Different settings for sk->sk_sndtimeo can result in different return values
545569 * if there is a signal pending when we enter sendmsg, because reasons?
@@ -696,7 +720,7 @@ out: · 150 unmodified lines
696720 return 0;
697721 }
698722
699−static int nbd_read_reply(struct nbd_device *nbd, int index,
723+static int nbd_read_reply(struct nbd_device *nbd, struct socket *sock,
700724 struct nbd_reply *reply)
701725 {
702726 struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)};
@@ -705,7 +729,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index, · 2 unmodified lines
705729
706730 reply->magic = 0;
707731 iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply));
708− result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL);
732+ result = __sock_xmit(nbd, sock, 0, &to, MSG_WAITALL, NULL);
709733 if (result < 0) {
710734 if (!nbd_disconnected(nbd->config))
711735 dev_err(disk_to_dev(nbd->disk),
@@ -829,14 +853,14 @@ static void recv_work(struct work_struct *work) · 117 unmodified lines
829853 struct nbd_device *nbd = args->nbd;
830854 struct nbd_config *config = nbd->config;
831855 struct request_queue *q = nbd->disk->queue;
832− struct nbd_sock *nsock;
856+ struct nbd_sock *nsock = args->nsock;
833857 struct nbd_cmd *cmd;
834858 struct request *rq;
835859
836860 while (1) {
837861 struct nbd_reply reply;
838862
839− if (nbd_read_reply(nbd, args->index, &reply))
863+ if (nbd_read_reply(nbd, nsock->sock, &reply))
840864 break;
841865
842866 /*
@@ -871,7 +895,6 @@ static void recv_work(struct work_struct *work) · 28 unmodified lines
871895 percpu_ref_put(&q->q_usage_counter);
872896 }
873897
874− nsock = config->socks[args->index];
875898 mutex_lock(&nsock->tx_lock);
876899 nbd_mark_nsock_dead(nbd, nsock, 1);
877900 mutex_unlock(&nsock->tx_lock);
@@ -977,12 +1000,12 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) · 99 unmodified lines
9771000 struct nbd_sock *nsock;
9781001 int ret;
9791002
980− if (!refcount_inc_not_zero(&nbd->config_refs)) {
1003+ config = nbd_get_config_unlocked(nbd);
1004+ if (!config) {
9811005 dev_err_ratelimited(disk_to_dev(nbd->disk),
9821006 "Socks array is empty\n");
9831007 return -EINVAL;
9841008 }
985− config = nbd->config;
9861009
9871010 if (index >= config->num_connections) {
9881011 dev_err_ratelimited(disk_to_dev(nbd->disk),
@@ -1215,6 +1238,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) · 226 unmodified lines
12151238 INIT_WORK(&args->work, recv_work);
12161239 args->index = i;
12171240 args->nbd = nbd;
1241+ args->nsock = nsock;
12181242 nsock->cookie++;
12191243 mutex_unlock(&nsock->tx_lock);
12201244 sockfd_put(old);
@@ -1397,6 +1421,7 @@ static int nbd_start_device(struct nbd_device *nbd) · 176 unmodified lines
13971421 refcount_inc(&nbd->config_refs);
13981422 INIT_WORK(&args->work, recv_work);
13991423 args->nbd = nbd;
1424+ args->nsock = config->socks[i];
14001425 args->index = i;
14011426 queue_work(nbd->recv_workq, &args->work);
14021427 }
@@ -1530,17 +1555,20 @@ static int nbd_ioctl(struct block_device *bdev, blk_mode_t mode, · 127 unmodified lines
15301555 return error;
15311556 }
15321557
1533−static struct nbd_config *nbd_alloc_config(void)
1558+static int nbd_alloc_and_init_config(struct nbd_device *nbd)
15341559 {
15351560 struct nbd_config *config;
15361561
1562+ if (WARN_ON(nbd->config))
1563+ return -EINVAL;
1564+
15371565 if (!try_module_get(THIS_MODULE))
1538− return ERR_PTR(-ENODEV);
1566+ return -ENODEV;
15391567
15401568 config = kzalloc(sizeof(struct nbd_config), GFP_NOFS);
15411569 if (!config) {
15421570 module_put(THIS_MODULE);
1543− return ERR_PTR(-ENOMEM);
1571+ return -ENOMEM;
15441572 }
15451573
15461574 atomic_set(&config->recv_threads, 0);
@@ -1548,12 +1576,24 @@ static struct nbd_config *nbd_alloc_config(void) · 1 unmodified line
15481576 init_waitqueue_head(&config->conn_wait);
15491577 config->blksize_bits = NBD_DEF_BLKSIZE_BITS;
15501578 atomic_set(&config->live_connections, 0);
1551− return config;
1579+
1580+ nbd->config = config;
1581+ /*
1582+ * Order refcount_set(&nbd->config_refs, 1) and nbd->config assignment,
1583+ * its pair is the barrier in nbd_get_config_unlocked().
1584+ * So nbd_get_config_unlocked() won't see nbd->config as null after
1585+ * refcount_inc_not_zero() succeed.
1586+ */
1587+ smp_mb__before_atomic();
1588+ refcount_set(&nbd->config_refs, 1);
1589+
1590+ return 0;
15521591 }
15531592
15541593 static int nbd_open(struct gendisk *disk, blk_mode_t mode)
15551594 {
15561595 struct nbd_device *nbd;
1596+ struct nbd_config *config;
15571597 int ret = 0;
15581598
15591599 mutex_lock(&nbd_index_mutex);
@@ -1566,27 +1606,25 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode) · 6 unmodified lines
15661606 ret = -ENXIO;
15671607 goto out;
15681608 }
1569− if (!refcount_inc_not_zero(&nbd->config_refs)) {
1570− struct nbd_config *config;
15711609
1610+ config = nbd_get_config_unlocked(nbd);
1611+ if (!config) {
15721612 mutex_lock(&nbd->config_lock);
15731613 if (refcount_inc_not_zero(&nbd->config_refs)) {
15741614 mutex_unlock(&nbd->config_lock);
15751615 goto out;
15761616 }
1577− config = nbd_alloc_config();
1578− if (IS_ERR(config)) {
1579− ret = PTR_ERR(config);
1617+ ret = nbd_alloc_and_init_config(nbd);
1618+ if (ret) {
15801619 mutex_unlock(&nbd->config_lock);
15811620 goto out;
15821621 }
1583− nbd->config = config;
1584− refcount_set(&nbd->config_refs, 1);
1622+
15851623 refcount_inc(&nbd->refs);
15861624 mutex_unlock(&nbd->config_lock);
15871625 if (max_part)
15881626 set_bit(GD_NEED_PART_SCAN, &disk->state);
1589− } else if (nbd_disconnected(nbd->config)) {
1627+ } else if (nbd_disconnected(config)) {
15901628 if (max_part)
15911629 set_bit(GD_NEED_PART_SCAN, &disk->state);
15921630 }
@@ -1990,22 +2028,17 @@ again: · 397 unmodified lines
19902028 pr_err("nbd%d already in use\n", index);
19912029 return -EBUSY;
19922030 }
1993− if (WARN_ON(nbd->config)) {
1994− mutex_unlock(&nbd->config_lock);
1995− nbd_put(nbd);
1996− return -EINVAL;
1997− }
1998− config = nbd_alloc_config();
1999− if (IS_ERR(config)) {
2031+
2032+ ret = nbd_alloc_and_init_config(nbd);
2033+ if (ret) {
20002034 mutex_unlock(&nbd->config_lock);
20012035 nbd_put(nbd);
20022036 pr_err("couldn't allocate config\n");
2003− return PTR_ERR(config);
2037+ return ret;
20042038 }
2005− nbd->config = config;
2006− refcount_set(&nbd->config_refs, 1);
2007− set_bit(NBD_RT_BOUND, &config->runtime_flags);
20082039
2040+ config = nbd->config;
2041+ set_bit(NBD_RT_BOUND, &config->runtime_flags);
20092042 ret = nbd_genl_size_set(info, nbd);
20102043 if (ret)
20112044 goto out;
@@ -2208,7 +2241,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) · 196 unmodified lines
22082241 }
22092242 mutex_unlock(&nbd_index_mutex);
22102243
2211− if (!refcount_inc_not_zero(&nbd->config_refs)) {
2244+ config = nbd_get_config_unlocked(nbd);
2245+ if (!config) {
22122246 dev_err(nbd_to_dev(nbd),
22132247 "not configured, cannot reconfigure\n");
22142248 nbd_put(nbd);
@@ -2216,7 +2250,6 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) · 1 unmodified line
22162250 }
22172251
22182252 mutex_lock(&nbd->config_lock);
2219− config = nbd->config;
22202253 if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
22212254 !nbd->pid) {
22222255 dev_err(nbd_to_dev(nbd),
drivers/block/null_blk/main.c+13−12
@@ -1464,19 +1464,13 @@ blk_status_t null_process_cmd(struct nullb_cmd *cmd, enum req_op op, · 1463 unmodified lines
14641464 return BLK_STS_OK;
14651465 }
14661466
1467−static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
1468− sector_t nr_sectors, enum req_op op)
1467+static void null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
1468+ sector_t nr_sectors, enum req_op op)
14691469 {
14701470 struct nullb_device *dev = cmd->nq->dev;
14711471 struct nullb *nullb = dev->nullb;
14721472 blk_status_t sts;
14731473
1474− if (test_bit(NULLB_DEV_FL_THROTTLED, &dev->flags)) {
1475− sts = null_handle_throttled(cmd);
1476− if (sts != BLK_STS_OK)
1477− return sts;
1478− }
1479−
14801474 if (op == REQ_OP_FLUSH) {
14811475 cmd->error = errno_to_blk_status(null_handle_flush(nullb));
14821476 goto out;
@@ -1493,7 +1487,6 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector, · 10 unmodified lines
14931487
14941488 out:
14951489 nullb_complete_cmd(cmd);
1496− return BLK_STS_OK;
14971490 }
14981491
14991492 static enum hrtimer_restart nullb_bwtimer_fn(struct hrtimer *timer)
@@ -1724,8 +1717,6 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 224 unmodified lines
17241717 cmd->fake_timeout = should_timeout_request(rq) ||
17251718 blk_should_fake_timeout(rq->q);
17261719
1727− blk_mq_start_request(rq);
1728−
17291720 if (should_requeue_request(rq)) {
17301721 /*
17311722 * Alternate between hitting the core BUSY path, and the
@@ -1738,6 +1729,15 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 6 unmodified lines
17381729 return BLK_STS_OK;
17391730 }
17401731
1732+ if (test_bit(NULLB_DEV_FL_THROTTLED, &nq->dev->flags)) {
1733+ blk_status_t sts = null_handle_throttled(cmd);
1734+
1735+ if (sts != BLK_STS_OK)
1736+ return sts;
1737+ }
1738+
1739+ blk_mq_start_request(rq);
1740+
17411741 if (is_poll) {
17421742 spin_lock(&nq->poll_lock);
17431743 list_add_tail(&rq->queuelist, &nq->poll_list);
@@ -1747,7 +1747,8 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 3 unmodified lines
17471747 if (cmd->fake_timeout)
17481748 return BLK_STS_OK;
17491749
1750− return null_handle_cmd(cmd, sector, nr_sectors, req_op(rq));
1750+ null_handle_cmd(cmd, sector, nr_sectors, req_op(rq));
1751+ return BLK_STS_OK;
17511752 }
17521753
17531754 static void null_queue_rqs(struct request **rqlist)
drivers/char/agp/Makefile+0−6
@@ -1,12 +1,6 @@
11 # SPDX-License-Identifier: GPL-2.0
22 agpgart-y := backend.o generic.o isoch.o
33
4−ifeq ($(CONFIG_DRM_LEGACY),y)
5−agpgart-$(CONFIG_COMPAT) += compat_ioctl.o
6−agpgart-y += frontend.o
7−endif
8−
9−
104 obj-$(CONFIG_AGP) += agpgart.o
115 obj-$(CONFIG_AGP_ALI) += ali-agp.o
126 obj-$(CONFIG_AGP_ATI) += ati-agp.o
drivers/char/agp/agp.h+0−9
@@ -185,15 +185,6 @@ void agp_put_bridge(struct agp_bridge_data *bridge); · 184 unmodified lines
185185 int agp_add_bridge(struct agp_bridge_data *bridge);
186186 void agp_remove_bridge(struct agp_bridge_data *bridge);
187187
188−/* Frontend routines. */
189−#if IS_ENABLED(CONFIG_DRM_LEGACY)
190−int agp_frontend_initialize(void);
191−void agp_frontend_cleanup(void);
192−#else
193−static inline int agp_frontend_initialize(void) { return 0; }
194−static inline void agp_frontend_cleanup(void) {}
195−#endif
196−
197188 /* Generic routines. */
198189 void agp_generic_enable(struct agp_bridge_data *bridge, u32 mode);
199190 int agp_generic_create_gatt_table(struct agp_bridge_data *bridge);
drivers/char/agp/backend.c+0−11
@@ -293,13 +293,6 @@ int agp_add_bridge(struct agp_bridge_data *bridge) · 292 unmodified lines
293293 }
294294
295295 if (list_empty(&agp_bridges)) {
296− error = agp_frontend_initialize();
297− if (error) {
298− dev_info(&bridge->dev->dev,
299− "agp_frontend_initialize() failed\n");
300− goto frontend_err;
301− }
302−
303296 dev_info(&bridge->dev->dev, "AGP aperture is %dM @ 0x%lx\n",
304297 bridge->driver->fetch_size(), bridge->gart_bus_addr);
305298
@@ -308,8 +301,6 @@ int agp_add_bridge(struct agp_bridge_data *bridge) · 2 unmodified lines
308301 list_add(&bridge->list, &agp_bridges);
309302 return 0;
310303
311−frontend_err:
312− agp_backend_cleanup(bridge);
313304 err_out:
314305 module_put(bridge->driver->owner);
315306 err_put_bridge:
@@ -323,8 +314,6 @@ void agp_remove_bridge(struct agp_bridge_data *bridge) · 7 unmodified lines
323314 {
324315 agp_backend_cleanup(bridge);
325316 list_del(&bridge->list);
326− if (list_empty(&agp_bridges))
327− agp_frontend_cleanup();
328317 module_put(bridge->driver->owner);
329318 }
330319 EXPORT_SYMBOL_GPL(agp_remove_bridge);
drivers/char/agp/compat_ioctl.c+0−291
@@ -1,291 +0,0 @@
1−/*
2− * AGPGART driver frontend compatibility ioctls
3− * Copyright (C) 2004 Silicon Graphics, Inc.
4− * Copyright (C) 2002-2003 Dave Jones
5− * Copyright (C) 1999 Jeff Hartmann
6− * Copyright (C) 1999 Precision Insight, Inc.
7− * Copyright (C) 1999 Xi Graphics, Inc.
8− *
9− * Permission is hereby granted, free of charge, to any person obtaining a
10− * copy of this software and associated documentation files (the "Software"),
11− * to deal in the Software without restriction, including without limitation
12− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13− * and/or sell copies of the Software, and to permit persons to whom the
14− * Software is furnished to do so, subject to the following conditions:
15− *
16− * The above copyright notice and this permission notice shall be included
17− * in all copies or substantial portions of the Software.
18− *
19− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20− * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22− * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
23− * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24− * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25− * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26− *
27− */
28−
29−#include <linux/kernel.h>
30−#include <linux/pci.h>
31−#include <linux/fs.h>
32−#include <linux/agpgart.h>
33−#include <linux/slab.h>
34−#include <linux/uaccess.h>
35−#include "agp.h"
36−#include "compat_ioctl.h"
37−
38−static int compat_agpioc_info_wrap(struct agp_file_private *priv, void __user *arg)
39−{
40− struct agp_info32 userinfo;
41− struct agp_kern_info kerninfo;
42−
43− agp_copy_info(agp_bridge, &kerninfo);
44−
45− userinfo.version.major = kerninfo.version.major;
46− userinfo.version.minor = kerninfo.version.minor;
47− userinfo.bridge_id = kerninfo.device->vendor |
48− (kerninfo.device->device << 16);
49− userinfo.agp_mode = kerninfo.mode;
50− userinfo.aper_base = (compat_long_t)kerninfo.aper_base;
51− userinfo.aper_size = kerninfo.aper_size;
52− userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
53− userinfo.pg_used = kerninfo.current_memory;
54−
55− if (copy_to_user(arg, &userinfo, sizeof(userinfo)))
56− return -EFAULT;
57−
58− return 0;
59−}
60−
61−static int compat_agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg)
62−{
63− struct agp_region32 ureserve;
64− struct agp_region kreserve;
65− struct agp_client *client;
66− struct agp_file_private *client_priv;
67−
68− DBG("");
69− if (copy_from_user(&ureserve, arg, sizeof(ureserve)))
70− return -EFAULT;
71−
72− if ((unsigned) ureserve.seg_count >= ~0U/sizeof(struct agp_segment32))
73− return -EFAULT;
74−
75− kreserve.pid = ureserve.pid;
76− kreserve.seg_count = ureserve.seg_count;
77−
78− client = agp_find_client_by_pid(kreserve.pid);
79−
80− if (kreserve.seg_count == 0) {
81− /* remove a client */
82− client_priv = agp_find_private(kreserve.pid);
83−
84− if (client_priv != NULL) {
85− set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
86− set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
87− }
88− if (client == NULL) {
89− /* client is already removed */
90− return 0;
91− }
92− return agp_remove_client(kreserve.pid);
93− } else {
94− struct agp_segment32 *usegment;
95− struct agp_segment *ksegment;
96− int seg;
97−
98− if (ureserve.seg_count >= 16384)
99− return -EINVAL;
100−
101− usegment = kmalloc_array(ureserve.seg_count,
102− sizeof(*usegment),
103− GFP_KERNEL);
104− if (!usegment)
105− return -ENOMEM;
106−
107− ksegment = kmalloc_array(kreserve.seg_count,
108− sizeof(*ksegment),
109− GFP_KERNEL);
110− if (!ksegment) {
111− kfree(usegment);
112− return -ENOMEM;
113− }
114−
115− if (copy_from_user(usegment, (void __user *) ureserve.seg_list,
116− sizeof(*usegment) * ureserve.seg_count)) {
117− kfree(usegment);
118− kfree(ksegment);
119− return -EFAULT;
120− }
121−
122− for (seg = 0; seg < ureserve.seg_count; seg++) {
123− ksegment[seg].pg_start = usegment[seg].pg_start;
124− ksegment[seg].pg_count = usegment[seg].pg_count;
125− ksegment[seg].prot = usegment[seg].prot;
126− }
127−
128− kfree(usegment);
129− kreserve.seg_list = ksegment;
130−
131− if (client == NULL) {
132− /* Create the client and add the segment */
133− client = agp_create_client(kreserve.pid);
134−
135− if (client == NULL) {
136− kfree(ksegment);
137− return -ENOMEM;
138− }
139− client_priv = agp_find_private(kreserve.pid);
140−
141− if (client_priv != NULL) {
142− set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
143− set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
144− }
145− }
146− return agp_create_segment(client, &kreserve);
147− }
148− /* Will never really happen */
149− return -EINVAL;
150−}
151−
152−static int compat_agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg)
153−{
154− struct agp_memory *memory;
155− struct agp_allocate32 alloc;
156−
157− DBG("");
158− if (copy_from_user(&alloc, arg, sizeof(alloc)))
159− return -EFAULT;
160−
161− memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
162−
163− if (memory == NULL)
164− return -ENOMEM;
165−
166− alloc.key = memory->key;
167− alloc.physical = memory->physical;
168−
169− if (copy_to_user(arg, &alloc, sizeof(alloc))) {
170− agp_free_memory_wrap(memory);
171− return -EFAULT;
172− }
173− return 0;
174−}
175−
176−static int compat_agpioc_bind_wrap(struct agp_file_private *priv, void __user *arg)
177−{
178− struct agp_bind32 bind_info;
179− struct agp_memory *memory;
180−
181− DBG("");
182− if (copy_from_user(&bind_info, arg, sizeof(bind_info)))
183− return -EFAULT;
184−
185− memory = agp_find_mem_by_key(bind_info.key);
186−
187− if (memory == NULL)
188− return -EINVAL;
189−
190− return agp_bind_memory(memory, bind_info.pg_start);
191−}
192−
193−static int compat_agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg)
194−{
195− struct agp_memory *memory;
196− struct agp_unbind32 unbind;
197−
198− DBG("");
199− if (copy_from_user(&unbind, arg, sizeof(unbind)))
200− return -EFAULT;
201−
202− memory = agp_find_mem_by_key(unbind.key);
203−
204− if (memory == NULL)
205− return -EINVAL;
206−
207− return agp_unbind_memory(memory);
208−}
209−
210−long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
211−{
212− struct agp_file_private *curr_priv = file->private_data;
213− int ret_val = -ENOTTY;
214−
215− mutex_lock(&(agp_fe.agp_mutex));
216−
217− if ((agp_fe.current_controller == NULL) &&
218− (cmd != AGPIOC_ACQUIRE32)) {
219− ret_val = -EINVAL;
220− goto ioctl_out;
221− }
222− if ((agp_fe.backend_acquired != true) &&
223− (cmd != AGPIOC_ACQUIRE32)) {
224− ret_val = -EBUSY;
225− goto ioctl_out;
226− }
227− if (cmd != AGPIOC_ACQUIRE32) {
228− if (!(test_bit(AGP_FF_IS_CONTROLLER, &curr_priv->access_flags))) {
229− ret_val = -EPERM;
230− goto ioctl_out;
231− }
232− /* Use the original pid of the controller,
233− * in case it's threaded */
234−
235− if (agp_fe.current_controller->pid != curr_priv->my_pid) {
236− ret_val = -EBUSY;
237− goto ioctl_out;
238− }
239− }
240−
241− switch (cmd) {
242− case AGPIOC_INFO32:
243− ret_val = compat_agpioc_info_wrap(curr_priv, (void __user *) arg);
244− break;
245−
246− case AGPIOC_ACQUIRE32:
247− ret_val = agpioc_acquire_wrap(curr_priv);
248− break;
249−
250− case AGPIOC_RELEASE32:
251− ret_val = agpioc_release_wrap(curr_priv);
252− break;
253−
254− case AGPIOC_SETUP32:
255− ret_val = agpioc_setup_wrap(curr_priv, (void __user *) arg);
256− break;
257−
258− case AGPIOC_RESERVE32:
259− ret_val = compat_agpioc_reserve_wrap(curr_priv, (void __user *) arg);
260− break;
261−
262− case AGPIOC_PROTECT32:
263− ret_val = agpioc_protect_wrap(curr_priv);
264− break;
265−
266− case AGPIOC_ALLOCATE32:
267− ret_val = compat_agpioc_allocate_wrap(curr_priv, (void __user *) arg);
268− break;
269−
270− case AGPIOC_DEALLOCATE32:
271− ret_val = agpioc_deallocate_wrap(curr_priv, (int) arg);
272− break;
273−
274− case AGPIOC_BIND32:
275− ret_val = compat_agpioc_bind_wrap(curr_priv, (void __user *) arg);
276− break;
277−
278− case AGPIOC_UNBIND32:
279− ret_val = compat_agpioc_unbind_wrap(curr_priv, (void __user *) arg);
280− break;
281−
282− case AGPIOC_CHIPSET_FLUSH32:
283− break;
284− }
285−
286−ioctl_out:
287− DBG("ioctl returns %d\n", ret_val);
288− mutex_unlock(&(agp_fe.agp_mutex));
289− return ret_val;
290−}
291−
drivers/char/agp/compat_ioctl.h+0−106
@@ -1,106 +0,0 @@
1−/*
2− * Copyright (C) 1999 Jeff Hartmann
3− * Copyright (C) 1999 Precision Insight, Inc.
4− * Copyright (C) 1999 Xi Graphics, Inc.
5− *
6− * Permission is hereby granted, free of charge, to any person obtaining a
7− * copy of this software and associated documentation files (the "Software"),
8− * to deal in the Software without restriction, including without limitation
9− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10− * and/or sell copies of the Software, and to permit persons to whom the
11− * Software is furnished to do so, subject to the following conditions:
12− *
13− * The above copyright notice and this permission notice shall be included
14− * in all copies or substantial portions of the Software.
15− *
16− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17− * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19− * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20− * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21− * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22− * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23− *
24− */
25−
26−#ifndef _AGP_COMPAT_IOCTL_H
27−#define _AGP_COMPAT_IOCTL_H
28−
29−#include <linux/compat.h>
30−#include <linux/agpgart.h>
31−
32−#define AGPIOC_INFO32 _IOR (AGPIOC_BASE, 0, compat_uptr_t)
33−#define AGPIOC_ACQUIRE32 _IO (AGPIOC_BASE, 1)
34−#define AGPIOC_RELEASE32 _IO (AGPIOC_BASE, 2)
35−#define AGPIOC_SETUP32 _IOW (AGPIOC_BASE, 3, compat_uptr_t)
36−#define AGPIOC_RESERVE32 _IOW (AGPIOC_BASE, 4, compat_uptr_t)
37−#define AGPIOC_PROTECT32 _IOW (AGPIOC_BASE, 5, compat_uptr_t)
38−#define AGPIOC_ALLOCATE32 _IOWR(AGPIOC_BASE, 6, compat_uptr_t)
39−#define AGPIOC_DEALLOCATE32 _IOW (AGPIOC_BASE, 7, compat_int_t)
40−#define AGPIOC_BIND32 _IOW (AGPIOC_BASE, 8, compat_uptr_t)
41−#define AGPIOC_UNBIND32 _IOW (AGPIOC_BASE, 9, compat_uptr_t)
42−#define AGPIOC_CHIPSET_FLUSH32 _IO (AGPIOC_BASE, 10)
43−
44−struct agp_info32 {
45− struct agp_version version; /* version of the driver */
46− u32 bridge_id; /* bridge vendor/device */
47− u32 agp_mode; /* mode info of bridge */
48− compat_long_t aper_base; /* base of aperture */
49− compat_size_t aper_size; /* size of aperture */
50− compat_size_t pg_total; /* max pages (swap + system) */
51− compat_size_t pg_system; /* max pages (system) */
52− compat_size_t pg_used; /* current pages used */
53−};
54−
55−/*
56− * The "prot" down below needs still a "sleep" flag somehow ...
57− */
58−struct agp_segment32 {
59− compat_off_t pg_start; /* starting page to populate */
60− compat_size_t pg_count; /* number of pages */
61− compat_int_t prot; /* prot flags for mmap */
62−};
63−
64−struct agp_region32 {
65− compat_pid_t pid; /* pid of process */
66− compat_size_t seg_count; /* number of segments */
67− struct agp_segment32 *seg_list;
68−};
69−
70−struct agp_allocate32 {
71− compat_int_t key; /* tag of allocation */
72− compat_size_t pg_count; /* number of pages */
73− u32 type; /* 0 == normal, other devspec */
74− u32 physical; /* device specific (some devices
75− * need a phys address of the
76− * actual page behind the gatt
77− * table) */
78−};
79−
80−struct agp_bind32 {
81− compat_int_t key; /* tag of allocation */
82− compat_off_t pg_start; /* starting page to populate */
83−};
84−
85−struct agp_unbind32 {
86− compat_int_t key; /* tag of allocation */
87− u32 priority; /* priority for paging out */
88−};
89−
90−extern struct agp_front_data agp_fe;
91−
92−int agpioc_acquire_wrap(struct agp_file_private *priv);
93−int agpioc_release_wrap(struct agp_file_private *priv);
94−int agpioc_protect_wrap(struct agp_file_private *priv);
95−int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg);
96−int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg);
97−struct agp_file_private *agp_find_private(pid_t pid);
98−struct agp_client *agp_create_client(pid_t id);
99−int agp_remove_client(pid_t id);
100−int agp_create_segment(struct agp_client *client, struct agp_region *region);
101−void agp_free_memory_wrap(struct agp_memory *memory);
102−struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type);
103−struct agp_memory *agp_find_mem_by_key(int key);
104−struct agp_client *agp_find_client_by_pid(pid_t id);
105−
106−#endif /* _AGP_COMPAT_H */
drivers/char/agp/frontend.c+0−1068
@@ -1,1068 +0,0 @@
1−/*
2− * AGPGART driver frontend
3− * Copyright (C) 2004 Silicon Graphics, Inc.
4− * Copyright (C) 2002-2003 Dave Jones
5− * Copyright (C) 1999 Jeff Hartmann
6− * Copyright (C) 1999 Precision Insight, Inc.
7− * Copyright (C) 1999 Xi Graphics, Inc.
8− *
9− * Permission is hereby granted, free of charge, to any person obtaining a
10− * copy of this software and associated documentation files (the "Software"),
11− * to deal in the Software without restriction, including without limitation
12− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13− * and/or sell copies of the Software, and to permit persons to whom the
14− * Software is furnished to do so, subject to the following conditions:
15− *
16− * The above copyright notice and this permission notice shall be included
17− * in all copies or substantial portions of the Software.
18− *
19− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20− * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22− * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
23− * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24− * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25− * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26− *
27− */
28−
29−#include <linux/types.h>
30−#include <linux/kernel.h>
31−#include <linux/module.h>
32−#include <linux/mman.h>
33−#include <linux/pci.h>
34−#include <linux/miscdevice.h>
35−#include <linux/agp_backend.h>
36−#include <linux/agpgart.h>
37−#include <linux/slab.h>
38−#include <linux/mm.h>
39−#include <linux/fs.h>
40−#include <linux/sched.h>
41−#include <linux/uaccess.h>
42−
43−#include "agp.h"
44−#include "compat_ioctl.h"
45−
46−struct agp_front_data agp_fe;
47−
48−struct agp_memory *agp_find_mem_by_key(int key)
49−{
50− struct agp_memory *curr;
51−
52− if (agp_fe.current_controller == NULL)
53− return NULL;
54−
55− curr = agp_fe.current_controller->pool;
56−
57− while (curr != NULL) {
58− if (curr->key == key)
59− break;
60− curr = curr->next;
61− }
62−
63− DBG("key=%d -> mem=%p", key, curr);
64− return curr;
65−}
66−
67−static void agp_remove_from_pool(struct agp_memory *temp)
68−{
69− struct agp_memory *prev;
70− struct agp_memory *next;
71−
72− /* Check to see if this is even in the memory pool */
73−
74− DBG("mem=%p", temp);
75− if (agp_find_mem_by_key(temp->key) != NULL) {
76− next = temp->next;
77− prev = temp->prev;
78−
79− if (prev != NULL) {
80− prev->next = next;
81− if (next != NULL)
82− next->prev = prev;
83−
84− } else {
85− /* This is the first item on the list */
86− if (next != NULL)
87− next->prev = NULL;
88−
89− agp_fe.current_controller->pool = next;
90− }
91− }
92−}
93−
94−/*
95− * Routines for managing each client's segment list -
96− * These routines handle adding and removing segments
97− * to each auth'ed client.
98− */
99−
100−static struct
101−agp_segment_priv *agp_find_seg_in_client(const struct agp_client *client,
102− unsigned long offset,
103− int size, pgprot_t page_prot)
104−{
105− struct agp_segment_priv *seg;
106− int i;
107− off_t pg_start;
108− size_t pg_count;
109−
110− pg_start = offset / 4096;
111− pg_count = size / 4096;
112− seg = *(client->segments);
113−
114− for (i = 0; i < client->num_segments; i++) {
115− if ((seg[i].pg_start == pg_start) &&
116− (seg[i].pg_count == pg_count) &&
117− (pgprot_val(seg[i].prot) == pgprot_val(page_prot))) {
118− return seg + i;
119− }
120− }
121−
122− return NULL;
123−}
124−
125−static void agp_remove_seg_from_client(struct agp_client *client)
126−{
127− DBG("client=%p", client);
128−
129− if (client->segments != NULL) {
130− if (*(client->segments) != NULL) {
131− DBG("Freeing %p from client %p", *(client->segments), client);
132− kfree(*(client->segments));
133− }
134− DBG("Freeing %p from client %p", client->segments, client);
135− kfree(client->segments);
136− client->segments = NULL;
137− }
138−}
139−
140−static void agp_add_seg_to_client(struct agp_client *client,
141− struct agp_segment_priv ** seg, int num_segments)
142−{
143− struct agp_segment_priv **prev_seg;
144−
145− prev_seg = client->segments;
146−
147− if (prev_seg != NULL)
148− agp_remove_seg_from_client(client);
149−
150− DBG("Adding seg %p (%d segments) to client %p", seg, num_segments, client);
151− client->num_segments = num_segments;
152− client->segments = seg;
153−}
154−
155−static pgprot_t agp_convert_mmap_flags(int prot)
156−{
157− unsigned long prot_bits;
158−
159− prot_bits = calc_vm_prot_bits(prot, 0) | VM_SHARED;
160− return vm_get_page_prot(prot_bits);
161−}
162−
163−int agp_create_segment(struct agp_client *client, struct agp_region *region)
164−{
165− struct agp_segment_priv **ret_seg;
166− struct agp_segment_priv *seg;
167− struct agp_segment *user_seg;
168− size_t i;
169−
170− seg = kzalloc((sizeof(struct agp_segment_priv) * region->seg_count), GFP_KERNEL);
171− if (seg == NULL) {
172− kfree(region->seg_list);
173− region->seg_list = NULL;
174− return -ENOMEM;
175− }
176− user_seg = region->seg_list;
177−
178− for (i = 0; i < region->seg_count; i++) {
179− seg[i].pg_start = user_seg[i].pg_start;
180− seg[i].pg_count = user_seg[i].pg_count;
181− seg[i].prot = agp_convert_mmap_flags(user_seg[i].prot);
182− }
183− kfree(region->seg_list);
184− region->seg_list = NULL;
185−
186− ret_seg = kmalloc(sizeof(void *), GFP_KERNEL);
187− if (ret_seg == NULL) {
188− kfree(seg);
189− return -ENOMEM;
190− }
191− *ret_seg = seg;
192− agp_add_seg_to_client(client, ret_seg, region->seg_count);
193− return 0;
194−}
195−
196−/* End - Routines for managing each client's segment list */
197−
198−/* This function must only be called when current_controller != NULL */
199−static void agp_insert_into_pool(struct agp_memory * temp)
200−{
201− struct agp_memory *prev;
202−
203− prev = agp_fe.current_controller->pool;
204−
205− if (prev != NULL) {
206− prev->prev = temp;
207− temp->next = prev;
208− }
209− agp_fe.current_controller->pool = temp;
210−}
211−
212−
213−/* File private list routines */
214−
215−struct agp_file_private *agp_find_private(pid_t pid)
216−{
217− struct agp_file_private *curr;
218−
219− curr = agp_fe.file_priv_list;
220−
221− while (curr != NULL) {
222− if (curr->my_pid == pid)
223− return curr;
224− curr = curr->next;
225− }
226−
227− return NULL;
228−}
229−
230−static void agp_insert_file_private(struct agp_file_private * priv)
231−{
232− struct agp_file_private *prev;
233−
234− prev = agp_fe.file_priv_list;
235−
236− if (prev != NULL)
237− prev->prev = priv;
238− priv->next = prev;
239− agp_fe.file_priv_list = priv;
240−}
241−
242−static void agp_remove_file_private(struct agp_file_private * priv)
243−{
244− struct agp_file_private *next;
245− struct agp_file_private *prev;
246−
247− next = priv->next;
248− prev = priv->prev;
249−
250− if (prev != NULL) {
251− prev->next = next;
252−
253− if (next != NULL)
254− next->prev = prev;
255−
256− } else {
257− if (next != NULL)
258− next->prev = NULL;
259−
260− agp_fe.file_priv_list = next;
261− }
262−}
263−
264−/* End - File flag list routines */
265−
266−/*
267− * Wrappers for agp_free_memory & agp_allocate_memory
268− * These make sure that internal lists are kept updated.
269− */
270−void agp_free_memory_wrap(struct agp_memory *memory)
271−{
272− agp_remove_from_pool(memory);
273− agp_free_memory(memory);
274−}
275−
276−struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
277−{
278− struct agp_memory *memory;
279−
280− memory = agp_allocate_memory(agp_bridge, pg_count, type);
281− if (memory == NULL)
282− return NULL;
283−
284− agp_insert_into_pool(memory);
285− return memory;
286−}
287−
288−/* Routines for managing the list of controllers -
289− * These routines manage the current controller, and the list of
290− * controllers
291− */
292−
293−static struct agp_controller *agp_find_controller_by_pid(pid_t id)
294−{
295− struct agp_controller *controller;
296−
297− controller = agp_fe.controllers;
298−
299− while (controller != NULL) {
300− if (controller->pid == id)
301− return controller;
302− controller = controller->next;
303− }
304−
305− return NULL;
306−}
307−
308−static struct agp_controller *agp_create_controller(pid_t id)
309−{
310− struct agp_controller *controller;
311−
312− controller = kzalloc(sizeof(struct agp_controller), GFP_KERNEL);
313− if (controller == NULL)
314− return NULL;
315−
316− controller->pid = id;
317− return controller;
318−}
319−
320−static int agp_insert_controller(struct agp_controller *controller)
321−{
322− struct agp_controller *prev_controller;
323−
324− prev_controller = agp_fe.controllers;
325− controller->next = prev_controller;
326−
327− if (prev_controller != NULL)
328− prev_controller->prev = controller;
329−
330− agp_fe.controllers = controller;
331−
332− return 0;
333−}
334−
335−static void agp_remove_all_clients(struct agp_controller *controller)
336−{
337− struct agp_client *client;
338− struct agp_client *temp;
339−
340− client = controller->clients;
341−
342− while (client) {
343− struct agp_file_private *priv;
344−
345− temp = client;
346− agp_remove_seg_from_client(temp);
347− priv = agp_find_private(temp->pid);
348−
349− if (priv != NULL) {
350− clear_bit(AGP_FF_IS_VALID, &priv->access_flags);
351− clear_bit(AGP_FF_IS_CLIENT, &priv->access_flags);
352− }
353− client = client->next;
354− kfree(temp);
355− }
356−}
357−
358−static void agp_remove_all_memory(struct agp_controller *controller)
359−{
360− struct agp_memory *memory;
361− struct agp_memory *temp;
362−
363− memory = controller->pool;
364−
365− while (memory) {
366− temp = memory;
367− memory = memory->next;
368− agp_free_memory_wrap(temp);
369− }
370−}
371−
372−static int agp_remove_controller(struct agp_controller *controller)
373−{
374− struct agp_controller *prev_controller;
375− struct agp_controller *next_controller;
376−
377− prev_controller = controller->prev;
378− next_controller = controller->next;
379−
380− if (prev_controller != NULL) {
381− prev_controller->next = next_controller;
382− if (next_controller != NULL)
383− next_controller->prev = prev_controller;
384−
385− } else {
386− if (next_controller != NULL)
387− next_controller->prev = NULL;
388−
389− agp_fe.controllers = next_controller;
390− }
391−
392− agp_remove_all_memory(controller);
393− agp_remove_all_clients(controller);
394−
395− if (agp_fe.current_controller == controller) {
396− agp_fe.current_controller = NULL;
397− agp_fe.backend_acquired = false;
398− agp_backend_release(agp_bridge);
399− }
400− kfree(controller);
401− return 0;
402−}
403−
404−static void agp_controller_make_current(struct agp_controller *controller)
405−{
406− struct agp_client *clients;
407−
408− clients = controller->clients;
409−
410− while (clients != NULL) {
411− struct agp_file_private *priv;
412−
413− priv = agp_find_private(clients->pid);
414−
415− if (priv != NULL) {
416− set_bit(AGP_FF_IS_VALID, &priv->access_flags);
417− set_bit(AGP_FF_IS_CLIENT, &priv->access_flags);
418− }
419− clients = clients->next;
420− }
421−
422− agp_fe.current_controller = controller;
423−}
424−
425−static void agp_controller_release_current(struct agp_controller *controller,
426− struct agp_file_private *controller_priv)
427−{
428− struct agp_client *clients;
429−
430− clear_bit(AGP_FF_IS_VALID, &controller_priv->access_flags);
431− clients = controller->clients;
432−
433− while (clients != NULL) {
434− struct agp_file_private *priv;
435−
436− priv = agp_find_private(clients->pid);
437−
438− if (priv != NULL)
439− clear_bit(AGP_FF_IS_VALID, &priv->access_flags);
440−
441− clients = clients->next;
442− }
443−
444− agp_fe.current_controller = NULL;
445− agp_fe.used_by_controller = false;
446− agp_backend_release(agp_bridge);
447−}
448−
449−/*
450− * Routines for managing client lists -
451− * These routines are for managing the list of auth'ed clients.
452− */
453−
454−static struct agp_client
455−*agp_find_client_in_controller(struct agp_controller *controller, pid_t id)
456−{
457− struct agp_client *client;
458−
459− if (controller == NULL)
460− return NULL;
461−
462− client = controller->clients;
463−
464− while (client != NULL) {
465− if (client->pid == id)
466− return client;
467− client = client->next;
468− }
469−
470− return NULL;
471−}
472−
473−static struct agp_controller *agp_find_controller_for_client(pid_t id)
474−{
475− struct agp_controller *controller;
476−
477− controller = agp_fe.controllers;
478−
479− while (controller != NULL) {
480− if ((agp_find_client_in_controller(controller, id)) != NULL)
481− return controller;
482− controller = controller->next;
483− }
484−
485− return NULL;
486−}
487−
488−struct agp_client *agp_find_client_by_pid(pid_t id)
489−{
490− struct agp_client *temp;
491−
492− if (agp_fe.current_controller == NULL)
493− return NULL;
494−
495− temp = agp_find_client_in_controller(agp_fe.current_controller, id);
496− return temp;
497−}
498−
499−static void agp_insert_client(struct agp_client *client)
500−{
501− struct agp_client *prev_client;
502−
503− prev_client = agp_fe.current_controller->clients;
504− client->next = prev_client;
505−
506− if (prev_client != NULL)
507− prev_client->prev = client;
508−
509− agp_fe.current_controller->clients = client;
510− agp_fe.current_controller->num_clients++;
511−}
512−
513−struct agp_client *agp_create_client(pid_t id)
514−{
515− struct agp_client *new_client;
516−
517− new_client = kzalloc(sizeof(struct agp_client), GFP_KERNEL);
518− if (new_client == NULL)
519− return NULL;
520−
521− new_client->pid = id;
522− agp_insert_client(new_client);
523− return new_client;
524−}
525−
526−int agp_remove_client(pid_t id)
527−{
528− struct agp_client *client;
529− struct agp_client *prev_client;
530− struct agp_client *next_client;
531− struct agp_controller *controller;
532−
533− controller = agp_find_controller_for_client(id);
534− if (controller == NULL)
535− return -EINVAL;
536−
537− client = agp_find_client_in_controller(controller, id);
538− if (client == NULL)
539− return -EINVAL;
540−
541− prev_client = client->prev;
542− next_client = client->next;
543−
544− if (prev_client != NULL) {
545− prev_client->next = next_client;
546− if (next_client != NULL)
547− next_client->prev = prev_client;
548−
549− } else {
550− if (next_client != NULL)
551− next_client->prev = NULL;
552− controller->clients = next_client;
553− }
554−
555− controller->num_clients--;
556− agp_remove_seg_from_client(client);
557− kfree(client);
558− return 0;
559−}
560−
561−/* End - Routines for managing client lists */
562−
563−/* File Operations */
564−
565−static int agp_mmap(struct file *file, struct vm_area_struct *vma)
566−{
567− unsigned int size, current_size;
568− unsigned long offset;
569− struct agp_client *client;
570− struct agp_file_private *priv = file->private_data;
571− struct agp_kern_info kerninfo;
572−
573− mutex_lock(&(agp_fe.agp_mutex));
574−
575− if (agp_fe.backend_acquired != true)
576− goto out_eperm;
577−
578− if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags)))
579− goto out_eperm;
580−
581− agp_copy_info(agp_bridge, &kerninfo);
582− size = vma->vm_end - vma->vm_start;
583− current_size = kerninfo.aper_size;
584− current_size = current_size * 0x100000;
585− offset = vma->vm_pgoff << PAGE_SHIFT;
586− DBG("%lx:%lx", offset, offset+size);
587−
588− if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {
589− if ((size + offset) > current_size)
590− goto out_inval;
591−
592− client = agp_find_client_by_pid(current->pid);
593−
594− if (client == NULL)
595− goto out_eperm;
596−
597− if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot))
598− goto out_inval;
599−
600− DBG("client vm_ops=%p", kerninfo.vm_ops);
601− if (kerninfo.vm_ops) {
602− vma->vm_ops = kerninfo.vm_ops;
603− } else if (io_remap_pfn_range(vma, vma->vm_start,
604− (kerninfo.aper_base + offset) >> PAGE_SHIFT,
605− size,
606− pgprot_writecombine(vma->vm_page_prot))) {
607− goto out_again;
608− }
609− mutex_unlock(&(agp_fe.agp_mutex));
610− return 0;
611− }
612−
613− if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
614− if (size != current_size)
615− goto out_inval;
616−
617− DBG("controller vm_ops=%p", kerninfo.vm_ops);
618− if (kerninfo.vm_ops) {
619− vma->vm_ops = kerninfo.vm_ops;
620− } else if (io_remap_pfn_range(vma, vma->vm_start,
621− kerninfo.aper_base >> PAGE_SHIFT,
622− size,
623− pgprot_writecombine(vma->vm_page_prot))) {
624− goto out_again;
625− }
626− mutex_unlock(&(agp_fe.agp_mutex));
627− return 0;
628− }
629−
630−out_eperm:
631− mutex_unlock(&(agp_fe.agp_mutex));
632− return -EPERM;
633−
634−out_inval:
635− mutex_unlock(&(agp_fe.agp_mutex));
636− return -EINVAL;
637−
638−out_again:
639− mutex_unlock(&(agp_fe.agp_mutex));
640− return -EAGAIN;
641−}
642−
643−static int agp_release(struct inode *inode, struct file *file)
644−{
645− struct agp_file_private *priv = file->private_data;
646−
647− mutex_lock(&(agp_fe.agp_mutex));
648−
649− DBG("priv=%p", priv);
650−
651− if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
652− struct agp_controller *controller;
653−
654− controller = agp_find_controller_by_pid(priv->my_pid);
655−
656− if (controller != NULL) {
657− if (controller == agp_fe.current_controller)
658− agp_controller_release_current(controller, priv);
659− agp_remove_controller(controller);
660− controller = NULL;
661− }
662− }
663−
664− if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags))
665− agp_remove_client(priv->my_pid);
666−
667− agp_remove_file_private(priv);
668− kfree(priv);
669− file->private_data = NULL;
670− mutex_unlock(&(agp_fe.agp_mutex));
671− return 0;
672−}
673−
674−static int agp_open(struct inode *inode, struct file *file)
675−{
676− int minor = iminor(inode);
677− struct agp_file_private *priv;
678− struct agp_client *client;
679−
680− if (minor != AGPGART_MINOR)
681− return -ENXIO;
682−
683− mutex_lock(&(agp_fe.agp_mutex));
684−
685− priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL);
686− if (priv == NULL) {
687− mutex_unlock(&(agp_fe.agp_mutex));
688− return -ENOMEM;
689− }
690−
691− set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
692− priv->my_pid = current->pid;
693−
694− if (capable(CAP_SYS_RAWIO))
695− /* Root priv, can be controller */
696− set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags);
697−
698− client = agp_find_client_by_pid(current->pid);
699−
700− if (client != NULL) {
701− set_bit(AGP_FF_IS_CLIENT, &priv->access_flags);
702− set_bit(AGP_FF_IS_VALID, &priv->access_flags);
703− }
704− file->private_data = (void *) priv;
705− agp_insert_file_private(priv);
706− DBG("private=%p, client=%p", priv, client);
707−
708− mutex_unlock(&(agp_fe.agp_mutex));
709−
710− return 0;
711−}
712−
713−static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg)
714−{
715− struct agp_info userinfo;
716− struct agp_kern_info kerninfo;
717−
718− agp_copy_info(agp_bridge, &kerninfo);
719−
720− memset(&userinfo, 0, sizeof(userinfo));
721− userinfo.version.major = kerninfo.version.major;
722− userinfo.version.minor = kerninfo.version.minor;
723− userinfo.bridge_id = kerninfo.device->vendor |
724− (kerninfo.device->device << 16);
725− userinfo.agp_mode = kerninfo.mode;
726− userinfo.aper_base = kerninfo.aper_base;
727− userinfo.aper_size = kerninfo.aper_size;
728− userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
729− userinfo.pg_used = kerninfo.current_memory;
730−
731− if (copy_to_user(arg, &userinfo, sizeof(struct agp_info)))
732− return -EFAULT;
733−
734− return 0;
735−}
736−
737−int agpioc_acquire_wrap(struct agp_file_private *priv)
738−{
739− struct agp_controller *controller;
740−
741− DBG("");
742−
743− if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags)))
744− return -EPERM;
745−
746− if (agp_fe.current_controller != NULL)
747− return -EBUSY;
748−
749− if (!agp_bridge)
750− return -ENODEV;
751−
752− if (atomic_read(&agp_bridge->agp_in_use))
753− return -EBUSY;
754−
755− atomic_inc(&agp_bridge->agp_in_use);
756−
757− agp_fe.backend_acquired = true;
758−
759− controller = agp_find_controller_by_pid(priv->my_pid);
760−
761− if (controller != NULL) {
762− agp_controller_make_current(controller);
763− } else {
764− controller = agp_create_controller(priv->my_pid);
765−
766− if (controller == NULL) {
767− agp_fe.backend_acquired = false;
768− agp_backend_release(agp_bridge);
769− return -ENOMEM;
770− }
771− agp_insert_controller(controller);
772− agp_controller_make_current(controller);
773− }
774−
775− set_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags);
776− set_bit(AGP_FF_IS_VALID, &priv->access_flags);
777− return 0;
778−}
779−
780−int agpioc_release_wrap(struct agp_file_private *priv)
781−{
782− DBG("");
783− agp_controller_release_current(agp_fe.current_controller, priv);
784− return 0;
785−}
786−
787−int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg)
788−{
789− struct agp_setup mode;
790−
791− DBG("");
792− if (copy_from_user(&mode, arg, sizeof(struct agp_setup)))
793− return -EFAULT;
794−
795− agp_enable(agp_bridge, mode.agp_mode);
796− return 0;
797−}
798−
799−static int agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg)
800−{
801− struct agp_region reserve;
802− struct agp_client *client;
803− struct agp_file_private *client_priv;
804−
805− DBG("");
806− if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
807− return -EFAULT;
808−
809− if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
810− return -EFAULT;
811−
812− client = agp_find_client_by_pid(reserve.pid);
813−
814− if (reserve.seg_count == 0) {
815− /* remove a client */
816− client_priv = agp_find_private(reserve.pid);
817−
818− if (client_priv != NULL) {
819− set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
820− set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
821− }
822− if (client == NULL) {
823− /* client is already removed */
824− return 0;
825− }
826− return agp_remove_client(reserve.pid);
827− } else {
828− struct agp_segment *segment;
829−
830− if (reserve.seg_count >= 16384)
831− return -EINVAL;
832−
833− segment = kmalloc((sizeof(struct agp_segment) * reserve.seg_count),
834− GFP_KERNEL);
835−
836− if (segment == NULL)
837− return -ENOMEM;
838−
839− if (copy_from_user(segment, (void __user *) reserve.seg_list,
840− sizeof(struct agp_segment) * reserve.seg_count)) {
841− kfree(segment);
842− return -EFAULT;
843− }
844− reserve.seg_list = segment;
845−
846− if (client == NULL) {
847− /* Create the client and add the segment */
848− client = agp_create_client(reserve.pid);
849−
850− if (client == NULL) {
851− kfree(segment);
852− return -ENOMEM;
853− }
854− client_priv = agp_find_private(reserve.pid);
855−
856− if (client_priv != NULL) {
857− set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
858− set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
859− }
860− }
861− return agp_create_segment(client, &reserve);
862− }
863− /* Will never really happen */
864− return -EINVAL;
865−}
866−
867−int agpioc_protect_wrap(struct agp_file_private *priv)
868−{
869− DBG("");
870− /* This function is not currently implemented */
871− return -EINVAL;
872−}
873−
874−static int agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg)
875−{
876− struct agp_memory *memory;
877− struct agp_allocate alloc;
878−
879− DBG("");
880− if (copy_from_user(&alloc, arg, sizeof(struct agp_allocate)))
881− return -EFAULT;
882−
883− if (alloc.type >= AGP_USER_TYPES)
884− return -EINVAL;
885−
886− memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
887−
888− if (memory == NULL)
889− return -ENOMEM;
890−
891− alloc.key = memory->key;
892− alloc.physical = memory->physical;
893−
894− if (copy_to_user(arg, &alloc, sizeof(struct agp_allocate))) {
895− agp_free_memory_wrap(memory);
896− return -EFAULT;
897− }
898− return 0;
899−}
900−
901−int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg)
902−{
903− struct agp_memory *memory;
904−
905− DBG("");
906− memory = agp_find_mem_by_key(arg);
907−
908− if (memory == NULL)
909− return -EINVAL;
910−
911− agp_free_memory_wrap(memory);
912− return 0;
913−}
914−
915−static int agpioc_bind_wrap(struct agp_file_private *priv, void __user *arg)
916−{
917− struct agp_bind bind_info;
918− struct agp_memory *memory;
919−
920− DBG("");
921− if (copy_from_user(&bind_info, arg, sizeof(struct agp_bind)))
922− return -EFAULT;
923−
924− memory = agp_find_mem_by_key(bind_info.key);
925−
926− if (memory == NULL)
927− return -EINVAL;
928−
929− return agp_bind_memory(memory, bind_info.pg_start);
930−}
931−
932−static int agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg)
933−{
934− struct agp_memory *memory;
935− struct agp_unbind unbind;
936−
937− DBG("");
938− if (copy_from_user(&unbind, arg, sizeof(struct agp_unbind)))
939− return -EFAULT;
940−
941− memory = agp_find_mem_by_key(unbind.key);
942−
943− if (memory == NULL)
944− return -EINVAL;
945−
946− return agp_unbind_memory(memory);
947−}
948−
949−static long agp_ioctl(struct file *file,
950− unsigned int cmd, unsigned long arg)
951−{
952− struct agp_file_private *curr_priv = file->private_data;
953− int ret_val = -ENOTTY;
954−
955− DBG("priv=%p, cmd=%x", curr_priv, cmd);
956− mutex_lock(&(agp_fe.agp_mutex));
957−
958− if ((agp_fe.current_controller == NULL) &&
959− (cmd != AGPIOC_ACQUIRE)) {
960− ret_val = -EINVAL;
961− goto ioctl_out;
962− }
963− if ((agp_fe.backend_acquired != true) &&
964− (cmd != AGPIOC_ACQUIRE)) {
965− ret_val = -EBUSY;
966− goto ioctl_out;
967− }
968− if (cmd != AGPIOC_ACQUIRE) {
969− if (!(test_bit(AGP_FF_IS_CONTROLLER, &curr_priv->access_flags))) {
970− ret_val = -EPERM;
971− goto ioctl_out;
972− }
973− /* Use the original pid of the controller,
974− * in case it's threaded */
975−
976− if (agp_fe.current_controller->pid != curr_priv->my_pid) {
977− ret_val = -EBUSY;
978− goto ioctl_out;
979− }
980− }
981−
982− switch (cmd) {
983− case AGPIOC_INFO:
984− ret_val = agpioc_info_wrap(curr_priv, (void __user *) arg);
985− break;
986−
987− case AGPIOC_ACQUIRE:
988− ret_val = agpioc_acquire_wrap(curr_priv);
989− break;
990−
991− case AGPIOC_RELEASE:
992− ret_val = agpioc_release_wrap(curr_priv);
993− break;
994−
995− case AGPIOC_SETUP:
996− ret_val = agpioc_setup_wrap(curr_priv, (void __user *) arg);
997− break;
998−
999− case AGPIOC_RESERVE:
1000− ret_val = agpioc_reserve_wrap(curr_priv, (void __user *) arg);
1001− break;
1002−
1003− case AGPIOC_PROTECT:
1004− ret_val = agpioc_protect_wrap(curr_priv);
1005− break;
1006−
1007− case AGPIOC_ALLOCATE:
1008− ret_val = agpioc_allocate_wrap(curr_priv, (void __user *) arg);
1009− break;
1010−
1011− case AGPIOC_DEALLOCATE:
1012− ret_val = agpioc_deallocate_wrap(curr_priv, (int) arg);
1013− break;
1014−
1015− case AGPIOC_BIND:
1016− ret_val = agpioc_bind_wrap(curr_priv, (void __user *) arg);
1017− break;
1018−
1019− case AGPIOC_UNBIND:
1020− ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg);
1021− break;
1022−
1023− case AGPIOC_CHIPSET_FLUSH:
1024− break;
1025− }
1026−
1027−ioctl_out:
1028− DBG("ioctl returns %d\n", ret_val);
1029− mutex_unlock(&(agp_fe.agp_mutex));
1030− return ret_val;
1031−}
1032−
1033−static const struct file_operations agp_fops =
1034−{
1035− .owner = THIS_MODULE,
1036− .llseek = no_llseek,
1037− .unlocked_ioctl = agp_ioctl,
1038−#ifdef CONFIG_COMPAT
1039− .compat_ioctl = compat_agp_ioctl,
1040−#endif
1041− .mmap = agp_mmap,
1042− .open = agp_open,
1043− .release = agp_release,
1044−};
1045−
1046−static struct miscdevice agp_miscdev =
1047−{
1048− .minor = AGPGART_MINOR,
1049− .name = "agpgart",
1050− .fops = &agp_fops
1051−};
1052−
1053−int agp_frontend_initialize(void)
1054−{
1055− memset(&agp_fe, 0, sizeof(struct agp_front_data));
1056− mutex_init(&(agp_fe.agp_mutex));
1057−
1058− if (misc_register(&agp_miscdev)) {
1059− printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR);
1060− return -EIO;
1061− }
1062− return 0;
1063−}
1064−
1065−void agp_frontend_cleanup(void)
1066−{
1067− misc_deregister(&agp_miscdev);
1068−}
drivers/dma-buf/dma-buf.c+2−2
@@ -46,12 +46,12 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen) · 45 unmodified lines
4646 {
4747 struct dma_buf *dmabuf;
4848 char name[DMA_BUF_NAME_LEN];
49− size_t ret = 0;
49+ ssize_t ret = 0;
5050
5151 dmabuf = dentry->d_fsdata;
5252 spin_lock(&dmabuf->name_lock);
5353 if (dmabuf->name)
54− ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN);
54+ ret = strscpy(name, dmabuf->name, sizeof(name));
5555 spin_unlock(&dmabuf->name_lock);
5656
5757 return dynamic_dname(buffer, buflen, "/%s:%s",
drivers/dma-buf/dma-fence.c+2−1
@@ -934,7 +934,8 @@ EXPORT_SYMBOL(dma_fence_wait_any_timeout); · 933 unmodified lines
934934 * the GPU's devfreq to reduce frequency, when in fact the opposite is what is
935935 * needed.
936936 *
937− * To this end, deadline hint(s) can be set on a &dma_fence via &dma_fence_set_deadline.
937+ * To this end, deadline hint(s) can be set on a &dma_fence via &dma_fence_set_deadline
938+ * (or indirectly via userspace facing ioctls like &sync_set_deadline).
938939 * The deadline hint provides a way for the waiting driver, or userspace, to
939940 * convey an appropriate sense of urgency to the signaling driver.
940941 *
drivers/dma-buf/sw_sync.c+82−0
@@ -52,12 +52,33 @@ struct sw_sync_create_fence_data { · 51 unmodified lines
5252 __s32 fence; /* fd of new fence */
5353 };
5454
55+/**
56+ * struct sw_sync_get_deadline - get the deadline hint of a sw_sync fence
57+ * @deadline_ns: absolute time of the deadline
58+ * @pad: must be zero
59+ * @fence_fd: the sw_sync fence fd (in)
60+ *
61+ * Return the earliest deadline set on the fence. The timebase for the
62+ * deadline is CLOCK_MONOTONIC (same as vblank). If there is no deadline
63+ * set on the fence, this ioctl will return -ENOENT.
64+ */
65+struct sw_sync_get_deadline {
66+ __u64 deadline_ns;
67+ __u32 pad;
68+ __s32 fence_fd;
69+};
70+
5571 #define SW_SYNC_IOC_MAGIC 'W'
5672
5773 #define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
5874 struct sw_sync_create_fence_data)
5975
6076 #define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
77+#define SW_SYNC_GET_DEADLINE _IOWR(SW_SYNC_IOC_MAGIC, 2, \
78+ struct sw_sync_get_deadline)
79+
80+
81+#define SW_SYNC_HAS_DEADLINE_BIT DMA_FENCE_FLAG_USER_BITS
6182
6283 static const struct dma_fence_ops timeline_fence_ops;
6384
@@ -171,6 +192,22 @@ static void timeline_fence_timeline_value_str(struct dma_fence *fence, · 107 unmodified lines
171192 snprintf(str, size, "%d", parent->value);
172193 }
173194
195+static void timeline_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
196+{
197+ struct sync_pt *pt = dma_fence_to_sync_pt(fence);
198+ unsigned long flags;
199+
200+ spin_lock_irqsave(fence->lock, flags);
201+ if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
202+ if (ktime_before(deadline, pt->deadline))
203+ pt->deadline = deadline;
204+ } else {
205+ pt->deadline = deadline;
206+ __set_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags);
207+ }
208+ spin_unlock_irqrestore(fence->lock, flags);
209+}
210+
174211 static const struct dma_fence_ops timeline_fence_ops = {
175212 .get_driver_name = timeline_fence_get_driver_name,
176213 .get_timeline_name = timeline_fence_get_timeline_name,
@@ -179,6 +216,7 @@ static const struct dma_fence_ops timeline_fence_ops = { · 2 unmodified lines
179216 .release = timeline_fence_release,
180217 .fence_value_str = timeline_fence_value_str,
181218 .timeline_value_str = timeline_fence_timeline_value_str,
219+ .set_deadline = timeline_fence_set_deadline,
182220 };
183221
184222 /**
@@ -387,6 +425,47 @@ static long sw_sync_ioctl_inc(struct sync_timeline *obj, unsigned long arg) · 202 unmodified lines
387425 return 0;
388426 }
389427
428+static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long arg)
429+{
430+ struct sw_sync_get_deadline data;
431+ struct dma_fence *fence;
432+ unsigned long flags;
433+ struct sync_pt *pt;
434+ int ret = 0;
435+
436+ if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
437+ return -EFAULT;
438+
439+ if (data.deadline_ns || data.pad)
440+ return -EINVAL;
441+
442+ fence = sync_file_get_fence(data.fence_fd);
443+ if (!fence)
444+ return -EINVAL;
445+
446+ pt = dma_fence_to_sync_pt(fence);
447+ if (!pt)
448+ return -EINVAL;
449+
450+ spin_lock_irqsave(fence->lock, flags);
451+ if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
452+ data.deadline_ns = ktime_to_ns(pt->deadline);
453+ } else {
454+ ret = -ENOENT;
455+ }
456+ spin_unlock_irqrestore(fence->lock, flags);
457+
458+ dma_fence_put(fence);
459+
460+ if (ret)
461+ return ret;
462+
463+ if (copy_to_user((void __user *)arg, &data, sizeof(data)))
464+ return -EFAULT;
465+
466+ return 0;
467+}
468+
390469 static long sw_sync_ioctl(struct file *file, unsigned int cmd,
391470 unsigned long arg)
392471 {
@@ -399,6 +478,9 @@ static long sw_sync_ioctl(struct file *file, unsigned int cmd, · 6 unmodified lines
399478 case SW_SYNC_IOC_INC:
400479 return sw_sync_ioctl_inc(obj, arg);
401480
481+ case SW_SYNC_GET_DEADLINE:
482+ return sw_sync_ioctl_get_deadline(obj, arg);
483+
402484 default:
403485 return -ENOTTY;
404486 }
drivers/dma-buf/sync_debug.h+2−0
@@ -55,11 +55,13 @@ static inline struct sync_timeline *dma_fence_parent(struct dma_fence *fence) · 54 unmodified lines
5555 * @base: base fence object
5656 * @link: link on the sync timeline's list
5757 * @node: node in the sync timeline's tree
58+ * @deadline: the earliest fence deadline hint
5859 */
5960 struct sync_pt {
6061 struct dma_fence base;
6162 struct list_head link;
6263 struct rb_node node;
64+ ktime_t deadline;
6365 };
6466
6567 extern const struct file_operations sw_sync_debugfs_fops;
drivers/dma-buf/sync_file.c+19−0
@@ -347,6 +347,22 @@ out: · 346 unmodified lines
347347 return ret;
348348 }
349349
350+static int sync_file_ioctl_set_deadline(struct sync_file *sync_file,
351+ unsigned long arg)
352+{
353+ struct sync_set_deadline ts;
354+
355+ if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
356+ return -EFAULT;
357+
358+ if (ts.pad)
359+ return -EINVAL;
360+
361+ dma_fence_set_deadline(sync_file->fence, ns_to_ktime(ts.deadline_ns));
362+
363+ return 0;
364+}
365+
350366 static long sync_file_ioctl(struct file *file, unsigned int cmd,
351367 unsigned long arg)
352368 {
@@ -359,6 +375,9 @@ static long sync_file_ioctl(struct file *file, unsigned int cmd, · 6 unmodified lines
359375 case SYNC_IOC_FILE_INFO:
360376 return sync_file_ioctl_fence_info(sync_file, arg);
361377
378+ case SYNC_IOC_SET_DEADLINE:
379+ return sync_file_ioctl_set_deadline(sync_file, arg);
380+
362381 default:
363382 return -ENOTTY;
364383 }
drivers/dpll/dpll_netlink.c+12−5
@@ -1093,9 +1093,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info) · 1092 unmodified lines
10931093 return -ENOMEM;
10941094 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
10951095 DPLL_CMD_PIN_ID_GET);
1096− if (!hdr)
1096+ if (!hdr) {
1097+ nlmsg_free(msg);
10971098 return -EMSGSIZE;
1098−
1099+ }
10991100 pin = dpll_pin_find_from_nlattr(info);
11001101 if (!IS_ERR(pin)) {
11011102 ret = dpll_msg_add_pin_handle(msg, pin);
@@ -1123,8 +1124,10 @@ int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info) · 21 unmodified lines
11231124 return -ENOMEM;
11241125 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
11251126 DPLL_CMD_PIN_GET);
1126− if (!hdr)
1127+ if (!hdr) {
1128+ nlmsg_free(msg);
11271129 return -EMSGSIZE;
1130+ }
11281131 ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
11291132 if (ret) {
11301133 nlmsg_free(msg);
@@ -1256,8 +1259,10 @@ int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info) · 125 unmodified lines
12561259 return -ENOMEM;
12571260 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
12581261 DPLL_CMD_DEVICE_ID_GET);
1259− if (!hdr)
1262+ if (!hdr) {
1263+ nlmsg_free(msg);
12601264 return -EMSGSIZE;
1265+ }
12611266
12621267 dpll = dpll_device_find_from_nlattr(info);
12631268 if (!IS_ERR(dpll)) {
@@ -1284,8 +1289,10 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info) · 20 unmodified lines
12841289 return -ENOMEM;
12851290 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
12861291 DPLL_CMD_DEVICE_GET);
1287− if (!hdr)
1292+ if (!hdr) {
1293+ nlmsg_free(msg);
12881294 return -EMSGSIZE;
1295+ }
12891296
12901297 ret = dpll_device_get_one(dpll, msg, info->extack);
12911298 if (ret) {
drivers/firmware/Kconfig+1−1
@@ -131,7 +131,7 @@ config RASPBERRYPI_FIRMWARE · 130 unmodified lines
131131
132132 config FW_CFG_SYSFS
133133 tristate "QEMU fw_cfg device support in sysfs"
134− depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || SPARC || X86)
134+ depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || RISCV || SPARC || X86)
135135 depends on HAS_IOPORT_MAP
136136 default n
137137 help
drivers/firmware/qemu_fw_cfg.c+1−1
@@ -211,7 +211,7 @@ static void fw_cfg_io_cleanup(void) · 210 unmodified lines
211211
212212 /* arch-specific ctrl & data register offsets are not available in ACPI, DT */
213213 #if !(defined(FW_CFG_CTRL_OFF) && defined(FW_CFG_DATA_OFF))
214−# if (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
214+# if (defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_RISCV))
215215 # define FW_CFG_CTRL_OFF 0x08
216216 # define FW_CFG_DATA_OFF 0x00
217217 # define FW_CFG_DMA_OFF 0x10
drivers/gpu/drm/Kconfig+9−27
@@ -74,16 +74,17 @@ config DRM_KUNIT_TEST_HELPERS · 73 unmodified lines
7474
7575 config DRM_KUNIT_TEST
7676 tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
77− depends on DRM && KUNIT
78− select PRIME_NUMBERS
77+ depends on DRM && KUNIT && MMU
78+ select DRM_BUDDY
7979 select DRM_DISPLAY_DP_HELPER
8080 select DRM_DISPLAY_HELPER
81− select DRM_LIB_RANDOM
82− select DRM_KMS_HELPER
83− select DRM_BUDDY
81+ select DRM_EXEC
8482 select DRM_EXPORT_FOR_TESTS if m
83+ select DRM_GEM_SHMEM_HELPER
84+ select DRM_KMS_HELPER
8585 select DRM_KUNIT_TEST_HELPERS
86− select DRM_EXEC
86+ select DRM_LIB_RANDOM
87+ select PRIME_NUMBERS
8788 default KUNIT_ALL_TESTS
8889 help
8990 This builds unit tests for DRM. This option is not useful for
@@ -394,6 +395,8 @@ source "drivers/gpu/drm/solomon/Kconfig" · 304 unmodified lines
394395
395396 source "drivers/gpu/drm/sprd/Kconfig"
396397
398+source "drivers/gpu/drm/imagination/Kconfig"
399+
397400 config DRM_HYPERV
398401 tristate "DRM Support for Hyper-V synthetic video device"
399402 depends on DRM && PCI && MMU && HYPERV
@@ -407,27 +410,6 @@ config DRM_HYPERV · 7 unmodified lines
407410
408411 If M is selected the module will be called hyperv_drm.
409412
410−# Keep legacy drivers last
411−
412−menuconfig DRM_LEGACY
413− bool "Enable legacy drivers (DANGEROUS)"
414− depends on DRM && MMU
415− help
416− Enable legacy DRI1 drivers. Those drivers expose unsafe and dangerous
417− APIs to user-space, which can be used to circumvent access
418− restrictions and other security measures. For backwards compatibility
419− those drivers are still available, but their use is highly
420− inadvisable and might harm your system.
421−
422− You are recommended to use the safe modeset-only drivers instead, and
423− perform 3D emulation in user-space.
424−
425− Unless you have strong reasons to go rogue, say "N".
426−
427−if DRM_LEGACY
428−# leave here to list legacy drivers
429−endif # DRM_LEGACY
430−
431413 config DRM_EXPORT_FOR_TESTS
432414 bool
433415
drivers/gpu/drm/Makefile+2−12
@@ -22,6 +22,7 @@ drm-y := \ · 21 unmodified lines
2222 drm_drv.o \
2323 drm_dumb_buffers.o \
2424 drm_edid.o \
25+ drm_eld.o \
2526 drm_encoder.o \
2627 drm_file.o \
2728 drm_fourcc.o \
@@ -46,18 +47,6 @@ drm-y := \ · 18 unmodified lines
4647 drm_vblank_work.o \
4748 drm_vma_manager.o \
4849 drm_writeback.o
49−drm-$(CONFIG_DRM_LEGACY) += \
50− drm_agpsupport.o \
51− drm_bufs.o \
52− drm_context.o \
53− drm_dma.o \
54− drm_hashtab.o \
55− drm_irq.o \
56− drm_legacy_misc.o \
57− drm_lock.o \
58− drm_memory.o \
59− drm_scatter.o \
60− drm_vm.o
6150 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
6251 drm-$(CONFIG_COMPAT) += drm_ioc32.o
6352 drm-$(CONFIG_DRM_PANEL) += drm_panel.o
@@ -198,3 +187,4 @@ obj-$(CONFIG_DRM_HYPERV) += hyperv/ · 134 unmodified lines
198187 obj-y += solomon/
199188 obj-$(CONFIG_DRM_SPRD) += sprd/
200189 obj-$(CONFIG_DRM_LOONGSON) += loongson/
190+obj-$(CONFIG_DRM_POWERVR) += imagination/
drivers/gpu/drm/amd/amdgpu/amdgpu.h+1−0
@@ -248,6 +248,7 @@ extern int amdgpu_umsch_mm; · 247 unmodified lines
248248 extern int amdgpu_seamless;
249249
250250 extern int amdgpu_user_partt_mode;
251+extern int amdgpu_agp;
251252
252253 #define AMDGPU_VM_MAX_NUM_CTX 4096
253254 #define AMDGPU_SG_THRESHOLD (256*1024*1024)
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c+1−1
@@ -290,7 +290,7 @@ static int suspend_resume_compute_scheduler(struct amdgpu_device *adev, bool sus · 289 unmodified lines
290290 for (i = 0; i < adev->gfx.num_compute_rings; i++) {
291291 struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
292292
293− if (!(ring && ring->sched.thread))
293+ if (!(ring && drm_sched_wqueue_ready(&ring->sched)))
294294 continue;
295295
296296 /* stop secheduler and drain ring. */
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+1−1
@@ -207,7 +207,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, · 206 unmodified lines
207207 }
208208
209209 for (i = 0; i < p->nchunks; i++) {
210− struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
210+ struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
211211 struct drm_amdgpu_cs_chunk user_chunk;
212212 uint32_t __user *cdata;
213213
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c+2−2
@@ -73,10 +73,10 @@ amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio) · 72 unmodified lines
7373 return DRM_SCHED_PRIORITY_NORMAL;
7474
7575 case AMDGPU_CTX_PRIORITY_VERY_LOW:
76− return DRM_SCHED_PRIORITY_MIN;
76+ return DRM_SCHED_PRIORITY_LOW;
7777
7878 case AMDGPU_CTX_PRIORITY_LOW:
79− return DRM_SCHED_PRIORITY_MIN;
79+ return DRM_SCHED_PRIORITY_LOW;
8080
8181 case AMDGPU_CTX_PRIORITY_NORMAL:
8282 return DRM_SCHED_PRIORITY_NORMAL;
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c+8−7
@@ -1665,9 +1665,9 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) · 1664 unmodified lines
16651665 for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
16661666 struct amdgpu_ring *ring = adev->rings[i];
16671667
1668− if (!ring || !ring->sched.thread)
1668+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
16691669 continue;
1670− kthread_park(ring->sched.thread);
1670+ drm_sched_wqueue_stop(&ring->sched);
16711671 }
16721672
16731673 seq_puts(m, "run ib test:\n");
@@ -1681,9 +1681,9 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) · 7 unmodified lines
16811681 for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
16821682 struct amdgpu_ring *ring = adev->rings[i];
16831683
1684− if (!ring || !ring->sched.thread)
1684+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
16851685 continue;
1686− kthread_unpark(ring->sched.thread);
1686+ drm_sched_wqueue_start(&ring->sched);
16871687 }
16881688
16891689 up_write(&adev->reset_domain->sem);
@@ -1903,7 +1903,8 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) · 213 unmodified lines
19031903
19041904 ring = adev->rings[val];
19051905
1906− if (!ring || !ring->funcs->preempt_ib || !ring->sched.thread)
1906+ if (!ring || !ring->funcs->preempt_ib ||
1907+ !drm_sched_wqueue_ready(&ring->sched))
19071908 return -EINVAL;
19081909
19091910 /* the last preemption failed */
@@ -1921,7 +1922,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) · 11 unmodified lines
19211922 goto pro_end;
19221923
19231924 /* stop the scheduler */
1924− kthread_park(ring->sched.thread);
1925+ drm_sched_wqueue_stop(&ring->sched);
19251926
19261927 /* preempt the IB */
19271928 r = amdgpu_ring_preempt_ib(ring);
@@ -1955,7 +1956,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) · 27 unmodified lines
19551956
19561957 failure:
19571958 /* restart the scheduler */
1958− kthread_unpark(ring->sched.thread);
1959+ drm_sched_wqueue_start(&ring->sched);
19591960
19601961 up_read(&adev->reset_domain->sem);
19611962
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+7−7
@@ -2573,7 +2573,7 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev) · 2572 unmodified lines
25732573 break;
25742574 }
25752575
2576− r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
2576+ r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, NULL,
25772577 DRM_SCHED_PRIORITY_COUNT,
25782578 ring->num_hw_submission, 0,
25792579 timeout, adev->reset_domain->wq,
@@ -4964,7 +4964,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev) · 2384 unmodified lines
49644964 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
49654965 struct amdgpu_ring *ring = adev->rings[i];
49664966
4967− if (!ring || !ring->sched.thread)
4967+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
49684968 continue;
49694969
49704970 spin_lock(&ring->sched.job_list_lock);
@@ -5103,7 +5103,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, · 132 unmodified lines
51035103 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
51045104 struct amdgpu_ring *ring = adev->rings[i];
51055105
5106− if (!ring || !ring->sched.thread)
5106+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
51075107 continue;
51085108
51095109 /* Clear job fence from fence drv to avoid force_completion
@@ -5592,7 +5592,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 482 unmodified lines
55925592 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
55935593 struct amdgpu_ring *ring = tmp_adev->rings[i];
55945594
5595− if (!ring || !ring->sched.thread)
5595+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
55965596 continue;
55975597
55985598 drm_sched_stop(&ring->sched, job ? &job->base : NULL);
@@ -5668,7 +5668,7 @@ skip_hw_reset: · 69 unmodified lines
56685668 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
56695669 struct amdgpu_ring *ring = tmp_adev->rings[i];
56705670
5671− if (!ring || !ring->sched.thread)
5671+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
56725672 continue;
56735673
56745674 drm_sched_start(&ring->sched, true);
@@ -5991,7 +5991,7 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta · 316 unmodified lines
59915991 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
59925992 struct amdgpu_ring *ring = adev->rings[i];
59935993
5994− if (!ring || !ring->sched.thread)
5994+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
59955995 continue;
59965996
59975997 drm_sched_stop(&ring->sched, NULL);
@@ -6119,7 +6119,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev) · 121 unmodified lines
61196119 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
61206120 struct amdgpu_ring *ring = adev->rings[i];
61216121
6122− if (!ring || !ring->sched.thread)
6122+ if (!ring || !drm_sched_wqueue_ready(&ring->sched))
61236123 continue;
61246124
61256125 drm_sched_start(&ring->sched, true);
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+10−0
@@ -207,6 +207,7 @@ int amdgpu_user_partt_mode = AMDGPU_AUTO_COMPUTE_PARTITION_MODE; · 206 unmodified lines
207207 int amdgpu_umsch_mm;
208208 int amdgpu_seamless = -1; /* auto */
209209 uint amdgpu_debug_mask;
210+int amdgpu_agp = -1; /* auto */
210211
211212 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
212213
@@ -961,6 +962,15 @@ module_param_named(seamless, amdgpu_seamless, int, 0444); · 748 unmodified lines
961962 MODULE_PARM_DESC(debug_mask, "debug options for amdgpu, disabled by default");
962963 module_param_named(debug_mask, amdgpu_debug_mask, uint, 0444);
963964
965+/**
966+ * DOC: agp (int)
967+ * Enable the AGP aperture. This provides an aperture in the GPU's internal
968+ * address space for direct access to system memory. Note that these accesses
969+ * are non-snooped, so they are only used for access to uncached memory.
970+ */
971+MODULE_PARM_DESC(agp, "AGP (-1 = auto (default), 0 = disable, 1 = enable)");
972+module_param_named(agp, amdgpu_agp, int, 0444);
973+
964974 /* These devices are not supported by amdgpu.
965975 * They are supported by the mach64, r128, radeon drivers
966976 */
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c+2−2
@@ -115,7 +115,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 114 unmodified lines
115115 if (!entity)
116116 return 0;
117117
118− return drm_sched_job_init(&(*job)->base, entity, owner);
118+ return drm_sched_job_init(&(*job)->base, entity, 1, owner);
119119 }
120120
121121 int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
@@ -325,7 +325,7 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched) · 203 unmodified lines
325325 int i;
326326
327327 /* Signal all jobs not yet scheduled */
328− for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
328+ for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++) {
329329 struct drm_sched_rq *rq = sched->sched_rq[i];
330330 spin_lock(&rq->lock);
331331 list_for_each_entry(s_entity, &rq->entities, list) {
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c+5−0
@@ -1473,6 +1473,11 @@ int psp_xgmi_get_topology_info(struct psp_context *psp, · 1472 unmodified lines
14731473 topology->nodes[i].num_links = (requires_reflection && topology->nodes[i].num_links) ?
14741474 topology->nodes[i].num_links : node_num_links;
14751475 }
1476+ /* popluate the connected port num info if supported and available */
1477+ if (ta_port_num_support && topology->nodes[i].num_links) {
1478+ memcpy(topology->nodes[i].port_num, link_extend_info_output->nodes[i].port_num,
1479+ sizeof(struct xgmi_connected_port_num) * TA_XGMI__MAX_PORT_NUM);
1480+ }
14761481
14771482 /* reflect the topology information for bi-directionality */
14781483 if (requires_reflection && topology->nodes[i].num_hops)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h+1−0
@@ -150,6 +150,7 @@ struct psp_xgmi_node_info { · 149 unmodified lines
150150 uint8_t is_sharing_enabled;
151151 enum ta_xgmi_assigned_sdma_engine sdma_engine;
152152 uint8_t num_links;
153+ struct xgmi_connected_port_num port_num[TA_XGMI__MAX_PORT_NUM];
153154 };
154155
155156 struct psp_xgmi_topology_info {
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c+1−1
@@ -1188,7 +1188,7 @@ static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev, · 1187 unmodified lines
11881188 }
11891189
11901190 if (block_obj->hw_ops->query_ras_error_count)
1191− block_obj->hw_ops->query_ras_error_count(adev, &err_data);
1191+ block_obj->hw_ops->query_ras_error_count(adev, err_data);
11921192
11931193 if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
11941194 (info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c+1−0
@@ -398,6 +398,7 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) · 397 unmodified lines
398398 * amdgpu_uvd_entity_init - init entity
399399 *
400400 * @adev: amdgpu_device pointer
401+ * @ring: amdgpu_ring pointer to check
401402 *
402403 * Initialize the entity used for handle management in the kernel driver.
403404 */
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c+1−0
@@ -230,6 +230,7 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) · 229 unmodified lines
230230 * amdgpu_vce_entity_init - init entity
231231 *
232232 * @adev: amdgpu_device pointer
233+ * @ring: amdgpu_ring pointer to check
233234 *
234235 * Initialize the entity used for handle management in the kernel driver.
235236 */
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c+1−1
@@ -675,7 +675,7 @@ static void gmc_v10_0_vram_gtt_location(struct amdgpu_device *adev, · 674 unmodified lines
675675 amdgpu_gmc_set_agp_default(adev, mc);
676676 amdgpu_gmc_vram_location(adev, &adev->gmc, base);
677677 amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
678− if (!amdgpu_sriov_vf(adev))
678+ if (!amdgpu_sriov_vf(adev) && (amdgpu_agp == 1))
679679 amdgpu_gmc_agp_location(adev, mc);
680680
681681 /* base offset of vram pages */
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c+3−2
@@ -640,8 +640,9 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev, · 639 unmodified lines
640640 amdgpu_gmc_set_agp_default(adev, mc);
641641 amdgpu_gmc_vram_location(adev, &adev->gmc, base);
642642 amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_HIGH);
643− if (!amdgpu_sriov_vf(adev) ||
644− (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(11, 5, 0)))
643+ if (!amdgpu_sriov_vf(adev) &&
644+ (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(11, 5, 0)) &&
645+ (amdgpu_agp == 1))
645646 amdgpu_gmc_agp_location(adev, mc);
646647
647648 /* base offset of vram pages */
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c+4−3
@@ -1630,7 +1630,7 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev, · 1629 unmodified lines
16301630 } else {
16311631 amdgpu_gmc_vram_location(adev, mc, base);
16321632 amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
1633− if (!amdgpu_sriov_vf(adev))
1633+ if (!amdgpu_sriov_vf(adev) && (amdgpu_agp == 1))
16341634 amdgpu_gmc_agp_location(adev, mc);
16351635 }
16361636 /* base offset of vram pages */
@@ -2170,8 +2170,6 @@ static int gmc_v9_0_sw_fini(void *handle) · 533 unmodified lines
21702170
21712171 if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3))
21722172 amdgpu_gmc_sysfs_fini(adev);
2173− adev->gmc.num_mem_partitions = 0;
2174− kfree(adev->gmc.mem_partitions);
21752173
21762174 amdgpu_gmc_ras_fini(adev);
21772175 amdgpu_gem_force_release(adev);
@@ -2185,6 +2183,9 @@ static int gmc_v9_0_sw_fini(void *handle) · 7 unmodified lines
21852183 amdgpu_bo_free_kernel(&adev->gmc.pdb0_bo, NULL, &adev->gmc.ptr_pdb0);
21862184 amdgpu_bo_fini(adev);
21872185
2186+ adev->gmc.num_mem_partitions = 0;
2187+ kfree(adev->gmc.mem_partitions);
2188+
21882189 return 0;
21892190 }
21902191
drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c+3−3
@@ -130,6 +130,9 @@ static void mmhub_v1_8_init_system_aperture_regs(struct amdgpu_device *adev) · 129 unmodified lines
130130 uint64_t value;
131131 int i;
132132
133+ if (amdgpu_sriov_vf(adev))
134+ return;
135+
133136 inst_mask = adev->aid_mask;
134137 for_each_inst(i, inst_mask) {
135138 /* Program the AGP BAR */
@@ -139,9 +142,6 @@ static void mmhub_v1_8_init_system_aperture_regs(struct amdgpu_device *adev) · 3 unmodified lines
139142 WREG32_SOC15(MMHUB, i, regMC_VM_AGP_TOP,
140143 adev->gmc.agp_end >> 24);
141144
142− if (amdgpu_sriov_vf(adev))
143− return;
144−
145145 /* Program the system aperture low logical page number. */
146146 WREG32_SOC15(MMHUB, i, regMC_VM_SYSTEM_APERTURE_LOW_ADDR,
147147 min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+19−14
@@ -85,12 +85,13 @@ · 84 unmodified lines
8585 #include <drm/drm_atomic_uapi.h>
8686 #include <drm/drm_atomic_helper.h>
8787 #include <drm/drm_blend.h>
88+#include <drm/drm_fixed.h>
8889 #include <drm/drm_fourcc.h>
8990 #include <drm/drm_edid.h>
91+#include <drm/drm_eld.h>
9092 #include <drm/drm_vblank.h>
9193 #include <drm/drm_audio_component.h>
9294 #include <drm/drm_gem_atomic_helper.h>
93−#include <drm/drm_plane_helper.h>
9495
9596 #include <acpi/video.h>
9697
@@ -2079,7 +2080,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 1982 unmodified lines
20792080 struct dmub_srv_create_params create_params;
20802081 struct dmub_srv_region_params region_params;
20812082 struct dmub_srv_region_info region_info;
2082− struct dmub_srv_fb_params fb_params;
2083+ struct dmub_srv_memory_params memory_params;
20832084 struct dmub_srv_fb_info *fb_info;
20842085 struct dmub_srv *dmub_srv;
20852086 const struct dmcub_firmware_header_v1_0 *hdr;
@@ -2182,6 +2183,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 96 unmodified lines
21822183 adev->dm.dmub_fw->data +
21832184 le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
21842185 PSP_HEADER_BYTES;
2186+ region_params.is_mailbox_in_inbox = false;
21852187
21862188 status = dmub_srv_calc_region_info(dmub_srv, &region_params,
21872189 &region_info);
@@ -2205,10 +2207,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 17 unmodified lines
22052207 return r;
22062208
22072209 /* Rebase the regions on the framebuffer address. */
2208− memset(&fb_params, 0, sizeof(fb_params));
2209− fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr;
2210− fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr;
2211− fb_params.region_info = &region_info;
2210+ memset(&memory_params, 0, sizeof(memory_params));
2211+ memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr;
2212+ memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr;
2213+ memory_params.region_info = &region_info;
22122214
22132215 adev->dm.dmub_fb_info =
22142216 kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL);
@@ -2220,7 +2222,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 5 unmodified lines
22202222 return -ENOMEM;
22212223 }
22222224
2223− status = dmub_srv_calc_fb_info(dmub_srv, &fb_params, fb_info);
2225+ status = dmub_srv_calc_mem_info(dmub_srv, &memory_params, fb_info);
22242226 if (status != DMUB_STATUS_OK) {
22252227 DRM_ERROR("Error calculating DMUB FB info: %d\n", status);
22262228 return -EINVAL;
@@ -6908,8 +6910,8 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, · 4681 unmodified lines
69086910 if (IS_ERR(mst_state))
69096911 return PTR_ERR(mst_state);
69106912
6911− if (!mst_state->pbn_div)
6912− mst_state->pbn_div = dm_mst_get_pbn_divider(aconnector->mst_root->dc_link);
6913+ if (!mst_state->pbn_div.full)
6914+ mst_state->pbn_div.full = dfixed_const(dm_mst_get_pbn_divider(aconnector->mst_root->dc_link));
69136915
69146916 if (!state->duplicated) {
69156917 int max_bpc = conn_state->max_requested_bpc;
@@ -6921,7 +6923,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, · 5 unmodified lines
69216923 max_bpc);
69226924 bpp = convert_dc_color_depth_into_bpc(color_depth) * 3;
69236925 clock = adjusted_mode->clock;
6924− dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false);
6926+ dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp << 4);
69256927 }
69266928
69276929 dm_new_connector_state->vcpi_slots =
@@ -7481,6 +7483,9 @@ static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap, · 553 unmodified lines
74817483 int i;
74827484 int result = -EIO;
74837485
7486+ if (!ddc_service->ddc_pin || !ddc_service->ddc_pin->hw_info.hw_supported)
7487+ return result;
7488+
74847489 cmd.payloads = kcalloc(num, sizeof(struct i2c_payload), GFP_KERNEL);
74857490
74867491 if (!cmd.payloads)
@@ -9603,14 +9608,14 @@ static bool should_reset_plane(struct drm_atomic_state *state, · 2116 unmodified lines
96039608 struct drm_plane *other;
96049609 struct drm_plane_state *old_other_state, *new_other_state;
96059610 struct drm_crtc_state *new_crtc_state;
9611+ struct amdgpu_device *adev = drm_to_adev(plane->dev);
96069612 int i;
96079613
96089614 /*
9609− * TODO: Remove this hack once the checks below are sufficient
9610− * enough to determine when we need to reset all the planes on
9611− * the stream.
9615+ * TODO: Remove this hack for all asics once it proves that the
9616+ * fast updates works fine on DCN3.2+.
96129617 */
9613− if (state->allow_modeset)
9618+ if (adev->ip_versions[DCE_HWIP][0] < IP_VERSION(3, 2, 0) && state->allow_modeset)
96149619 return true;
96159620
96169621 /* Exit early if we know that we're adding or removing the plane. */
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c+3−5
@@ -31,6 +31,7 @@ · 30 unmodified lines
3131 #include <drm/drm_probe_helper.h>
3232 #include <drm/amdgpu_drm.h>
3333 #include <drm/drm_edid.h>
34+#include <drm/drm_fixed.h>
3435
3536 #include "dm_services.h"
3637 #include "amdgpu.h"
@@ -210,7 +211,7 @@ static void dm_helpers_construct_old_payload( · 173 unmodified lines
210211 struct drm_dp_mst_atomic_payload *old_payload)
211212 {
212213 struct drm_dp_mst_atomic_payload *pos;
213− int pbn_per_slot = mst_state->pbn_div;
214+ int pbn_per_slot = dfixed_trunc(mst_state->pbn_div);
214215 u8 next_payload_vc_start = mgr->next_start_slot;
215216 u8 payload_vc_start = new_payload->vc_start_slot;
216217 u8 allocated_time_slots;
@@ -536,11 +537,8 @@ bool dm_helpers_dp_read_dpcd( · 319 unmodified lines
536537
537538 struct amdgpu_dm_connector *aconnector = link->priv;
538539
539− if (!aconnector) {
540− drm_dbg_dp(aconnector->base.dev,
541− "Failed to find connector for link!\n");
540+ if (!aconnector)
542541 return false;
543− }
544542
545543 return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address, data,
546544 size) == size;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c+18−18
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include <drm/display/drm_dp_mst_helper.h>
2828 #include <drm/drm_atomic.h>
2929 #include <drm/drm_atomic_helper.h>
30+#include <drm/drm_fixed.h>
3031 #include "dm_services.h"
3132 #include "amdgpu.h"
3233 #include "amdgpu_dm.h"
@@ -941,10 +942,10 @@ static int increase_dsc_bpp(struct drm_atomic_state *state, · 908 unmodified lines
941942 link_timeslots_used = 0;
942943
943944 for (i = 0; i < count; i++)
944− link_timeslots_used += DIV_ROUND_UP(vars[i + k].pbn, mst_state->pbn_div);
945+ link_timeslots_used += DIV_ROUND_UP(vars[i + k].pbn, dfixed_trunc(mst_state->pbn_div));
945946
946947 fair_pbn_alloc =
947− (63 - link_timeslots_used) / remaining_to_increase * mst_state->pbn_div;
948+ (63 - link_timeslots_used) / remaining_to_increase * dfixed_trunc(mst_state->pbn_div);
948949
949950 if (initial_slack[next_index] > fair_pbn_alloc) {
950951 vars[next_index].pbn += fair_pbn_alloc;
@@ -1604,31 +1605,31 @@ enum dc_status dm_dp_mst_is_port_support_mode( · 653 unmodified lines
16041605 unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
16051606 unsigned int max_compressed_bw_in_kbps = 0;
16061607 struct dc_dsc_bw_range bw_range = {0};
1607− struct drm_dp_mst_topology_mgr *mst_mgr;
1608+ uint16_t full_pbn = aconnector->mst_output_port->full_pbn;
16081609
16091610 /*
1610− * check if the mode could be supported if DSC pass-through is supported
1611− * AND check if there enough bandwidth available to support the mode
1612− * with DSC enabled.
1611+ * Consider the case with the depth of the mst topology tree is equal or less than 2
1612+ * A. When dsc bitstream can be transmitted along the entire path
1613+ * 1. dsc is possible between source and branch/leaf device (common dsc params is possible), AND
1614+ * 2. dsc passthrough supported at MST branch, or
1615+ * 3. dsc decoding supported at leaf MST device
1616+ * Use maximum dsc compression as bw constraint
1617+ * B. When dsc bitstream cannot be transmitted along the entire path
1618+ * Use native bw as bw constraint
16131619 */
16141620 if (is_dsc_common_config_possible(stream, &bw_range) &&
1615− aconnector->mst_output_port->passthrough_aux) {
1616− mst_mgr = aconnector->mst_output_port->mgr;
1617− mutex_lock(&mst_mgr->lock);
1618−
1621+ (aconnector->mst_output_port->passthrough_aux ||
1622+ aconnector->dsc_aux == &aconnector->mst_output_port->aux)) {
16191623 cur_link_settings = stream->link->verified_link_cap;
16201624
16211625 upper_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
1622− &cur_link_settings
1623− );
1624− down_link_bw_in_kbps = kbps_from_pbn(aconnector->mst_output_port->full_pbn);
1626+ &cur_link_settings);
1627+ down_link_bw_in_kbps = kbps_from_pbn(full_pbn);
16251628
16261629 /* pick the bottleneck */
16271630 end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps,
16281631 down_link_bw_in_kbps);
16291632
1630− mutex_unlock(&mst_mgr->lock);
1631−
16321633 /*
16331634 * use the maximum dsc compression bandwidth as the required
16341635 * bandwidth for the mode
@@ -1642,9 +1643,8 @@ enum dc_status dm_dp_mst_is_port_support_mode( · 7 unmodified lines
16421643 } else {
16431644 /* check if mode could be supported within full_pbn */
16441645 bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
1645− pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false);
1646−
1647− if (pbn > aconnector->mst_output_port->full_pbn)
1646+ pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp << 4);
1647+ if (pbn > full_pbn)
16481648 return DC_FAIL_BANDWIDTH_VALIDATE;
16491649 }
16501650
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c+9−9
@@ -820,22 +820,22 @@ static void dcn35_set_idle_state(struct clk_mgr *clk_mgr_base, bool allow_idle) · 819 unmodified lines
820820
821821 if (dc->config.disable_ips == DMUB_IPS_ENABLE ||
822822 dc->config.disable_ips == DMUB_IPS_DISABLE_DYNAMIC) {
823− val |= DMUB_IPS1_ALLOW_MASK;
824− val |= DMUB_IPS2_ALLOW_MASK;
825− } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) {
826823 val = val & ~DMUB_IPS1_ALLOW_MASK;
827824 val = val & ~DMUB_IPS2_ALLOW_MASK;
828− } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2) {
829− val |= DMUB_IPS1_ALLOW_MASK;
830− val = val & ~DMUB_IPS2_ALLOW_MASK;
831− } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2_Z10) {
825+ } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) {
832826 val |= DMUB_IPS1_ALLOW_MASK;
833827 val |= DMUB_IPS2_ALLOW_MASK;
828+ } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2) {
829+ val = val & ~DMUB_IPS1_ALLOW_MASK;
830+ val |= DMUB_IPS2_ALLOW_MASK;
831+ } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2_Z10) {
832+ val = val & ~DMUB_IPS1_ALLOW_MASK;
833+ val = val & ~DMUB_IPS2_ALLOW_MASK;
834834 }
835835
836836 if (!allow_idle) {
837− val = val & ~DMUB_IPS1_ALLOW_MASK;
838− val = val & ~DMUB_IPS2_ALLOW_MASK;
837+ val |= DMUB_IPS1_ALLOW_MASK;
838+ val |= DMUB_IPS2_ALLOW_MASK;
839839 }
840840
841841 dcn35_smu_write_ips_scratch(clk_mgr, val);
drivers/gpu/drm/amd/display/dc/core/dc.c+3−3
@@ -3178,7 +3178,7 @@ static bool update_planes_and_stream_state(struct dc *dc, · 3177 unmodified lines
31783178 struct pipe_ctx *otg_master = resource_get_otg_master_for_stream(&context->res_ctx,
31793179 context->streams[i]);
31803180
3181− if (otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE)
3181+ if (otg_master && otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE)
31823182 resource_build_test_pattern_params(&context->res_ctx, otg_master);
31833183 }
31843184 }
@@ -4934,8 +4934,8 @@ bool dc_dmub_is_ips_idle_state(struct dc *dc) · 1749 unmodified lines
49344934 if (dc->hwss.get_idle_state)
49354935 idle_state = dc->hwss.get_idle_state(dc);
49364936
4937− if ((idle_state & DMUB_IPS1_ALLOW_MASK) ||
4938− (idle_state & DMUB_IPS2_ALLOW_MASK))
4937+ if (!(idle_state & DMUB_IPS1_ALLOW_MASK) ||
4938+ !(idle_state & DMUB_IPS2_ALLOW_MASK))
49394939 return true;
49404940
49414941 return false;
drivers/gpu/drm/amd/display/dc/core/dc_resource.c+3−0
@@ -5190,6 +5190,9 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy( · 5189 unmodified lines
51905190 sec_next = sec_pipe->next_odm_pipe;
51915191 sec_prev = sec_pipe->prev_odm_pipe;
51925192
5193+ if (pri_pipe == NULL)
5194+ return false;
5195+
51935196 *sec_pipe = *pri_pipe;
51945197
51955198 sec_pipe->top_pipe = sec_top;
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c+5−5
@@ -1202,11 +1202,11 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc) · 1201 unmodified lines
12021202 allow_state = dc->hwss.get_idle_state(dc);
12031203 dc->hwss.set_idle_state(dc, false);
12041204
1205− if (allow_state & DMUB_IPS2_ALLOW_MASK) {
1205+ if (!(allow_state & DMUB_IPS2_ALLOW_MASK)) {
12061206 // Wait for evaluation time
12071207 udelay(dc->debug.ips2_eval_delay_us);
12081208 commit_state = dc->hwss.get_idle_state(dc);
1209− if (commit_state & DMUB_IPS2_COMMIT_MASK) {
1209+ if (!(commit_state & DMUB_IPS2_COMMIT_MASK)) {
12101210 // Tell PMFW to exit low power state
12111211 dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr);
12121212
@@ -1216,7 +1216,7 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc) · 3 unmodified lines
12161216
12171217 for (i = 0; i < max_num_polls; ++i) {
12181218 commit_state = dc->hwss.get_idle_state(dc);
1219− if (!(commit_state & DMUB_IPS2_COMMIT_MASK))
1219+ if (commit_state & DMUB_IPS2_COMMIT_MASK)
12201220 break;
12211221
12221222 udelay(1);
@@ -1235,10 +1235,10 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc) · 12 unmodified lines
12351235 }
12361236
12371237 dc_dmub_srv_notify_idle(dc, false);
1238− if (allow_state & DMUB_IPS1_ALLOW_MASK) {
1238+ if (!(allow_state & DMUB_IPS1_ALLOW_MASK)) {
12391239 for (i = 0; i < max_num_polls; ++i) {
12401240 commit_state = dc->hwss.get_idle_state(dc);
1241− if (!(commit_state & DMUB_IPS1_COMMIT_MASK))
1241+ if (commit_state & DMUB_IPS1_COMMIT_MASK)
12421242 break;
12431243
12441244 udelay(1);
drivers/gpu/drm/amd/display/dc/dc_types.h+1−0
@@ -177,6 +177,7 @@ struct dc_panel_patch { · 176 unmodified lines
177177 unsigned int disable_fams;
178178 unsigned int skip_avmute;
179179 unsigned int mst_start_top_delay;
180+ unsigned int remove_sink_ext_caps;
180181 };
181182
182183 struct dc_edid_caps {
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_stream_encoder.c+4−6
@@ -261,12 +261,6 @@ static void enc35_stream_encoder_enable( · 260 unmodified lines
261261 /* invalid mode ! */
262262 ASSERT_CRITICAL(false);
263263 }
264−
265− REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1);
266− REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1);
267− } else {
268− REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0);
269− REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0);
270264 }
271265 }
272266
@@ -436,6 +430,8 @@ static void enc35_disable_fifo(struct stream_encoder *enc) · 163 unmodified lines
436430 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
437431
438432 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 0);
433+ REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0);
434+ REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0);
439435 }
440436
441437 static void enc35_enable_fifo(struct stream_encoder *enc)
@@ -443,6 +439,8 @@ static void enc35_enable_fifo(struct stream_encoder *enc) · 1 unmodified line
443439 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
444440
445441 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7);
442+ REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1);
443+ REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1);
446444
447445 enc35_reset_fifo(enc, true);
448446 enc35_reset_fifo(enc, false);
drivers/gpu/drm/amd/display/dc/link/link_detection.c+3−0
@@ -1088,6 +1088,9 @@ static bool detect_link_and_local_sink(struct dc_link *link, · 1087 unmodified lines
10881088 if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
10891089 link->ctx->dc->debug.hdmi20_disable = true;
10901090
1091+ if (sink->edid_caps.panel_patch.remove_sink_ext_caps)
1092+ link->dpcd_sink_ext_caps.raw = 0;
1093+
10911094 if (dc_is_hdmi_signal(link->connector_signal))
10921095 read_scdc_caps(link->ddc, link->local_sink);
10931096
drivers/gpu/drm/amd/display/dmub/dmub_srv.h+14−8
@@ -195,6 +195,7 @@ struct dmub_srv_region_params { · 194 unmodified lines
195195 uint32_t vbios_size;
196196 const uint8_t *fw_inst_const;
197197 const uint8_t *fw_bss_data;
198+ bool is_mailbox_in_inbox;
198199 };
199200
200201 /**
@@ -214,20 +215,25 @@ struct dmub_srv_region_params { · 13 unmodified lines
214215 */
215216 struct dmub_srv_region_info {
216217 uint32_t fb_size;
218+ uint32_t inbox_size;
217219 uint8_t num_regions;
218220 struct dmub_region regions[DMUB_WINDOW_TOTAL];
219221 };
220222
221223 /**
222− * struct dmub_srv_fb_params - parameters used for driver fb setup
224+ * struct dmub_srv_memory_params - parameters used for driver fb setup
223225 * @region_info: region info calculated by dmub service
224− * @cpu_addr: base cpu address for the framebuffer
225− * @gpu_addr: base gpu virtual address for the framebuffer
226+ * @cpu_fb_addr: base cpu address for the framebuffer
227+ * @cpu_inbox_addr: base cpu address for the gart
228+ * @gpu_fb_addr: base gpu virtual address for the framebuffer
229+ * @gpu_inbox_addr: base gpu virtual address for the gart
226230 */
227−struct dmub_srv_fb_params {
231+struct dmub_srv_memory_params {
228232 const struct dmub_srv_region_info *region_info;
229− void *cpu_addr;
230− uint64_t gpu_addr;
233+ void *cpu_fb_addr;
234+ void *cpu_inbox_addr;
235+ uint64_t gpu_fb_addr;
236+ uint64_t gpu_inbox_addr;
231237 };
232238
233239 /**
@@ -563,8 +569,8 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 329 unmodified lines
563569 * DMUB_STATUS_OK - success
564570 * DMUB_STATUS_INVALID - unspecified error
565571 */
566−enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
567− const struct dmub_srv_fb_params *params,
572+enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
573+ const struct dmub_srv_memory_params *params,
568574 struct dmub_srv_fb_info *out);
569575
570576 /**
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c+39−11
@@ -434,7 +434,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 433 unmodified lines
434434 uint32_t fw_state_size = DMUB_FW_STATE_SIZE;
435435 uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE;
436436 uint32_t scratch_mem_size = DMUB_SCRATCH_MEM_SIZE;
437−
437+ uint32_t previous_top = 0;
438438 if (!dmub->sw_init)
439439 return DMUB_STATUS_INVALID;
440440
@@ -459,8 +459,15 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 18 unmodified lines
459459 bios->base = dmub_align(stack->top, 256);
460460 bios->top = bios->base + params->vbios_size;
461461
462− mail->base = dmub_align(bios->top, 256);
463− mail->top = mail->base + DMUB_MAILBOX_SIZE;
462+ if (params->is_mailbox_in_inbox) {
463+ mail->base = 0;
464+ mail->top = mail->base + DMUB_MAILBOX_SIZE;
465+ previous_top = bios->top;
466+ } else {
467+ mail->base = dmub_align(bios->top, 256);
468+ mail->top = mail->base + DMUB_MAILBOX_SIZE;
469+ previous_top = mail->top;
470+ }
464471
465472 fw_info = dmub_get_fw_meta_info(params);
466473
@@ -479,7 +486,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 12 unmodified lines
479486 dmub->fw_version = fw_info->fw_version;
480487 }
481488
482− trace_buff->base = dmub_align(mail->top, 256);
489+ trace_buff->base = dmub_align(previous_top, 256);
483490 trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64);
484491
485492 fw_state->base = dmub_align(trace_buff->top, 256);
@@ -490,11 +497,14 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 4 unmodified lines
490497
491498 out->fb_size = dmub_align(scratch_mem->top, 4096);
492499
500+ if (params->is_mailbox_in_inbox)
501+ out->inbox_size = dmub_align(mail->top, 4096);
502+
493503 return DMUB_STATUS_OK;
494504 }
495505
496−enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
497− const struct dmub_srv_fb_params *params,
506+enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
507+ const struct dmub_srv_memory_params *params,
498508 struct dmub_srv_fb_info *out)
499509 {
500510 uint8_t *cpu_base;
@@ -509,8 +519,8 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, · 8 unmodified lines
509519 if (params->region_info->num_regions != DMUB_NUM_WINDOWS)
510520 return DMUB_STATUS_INVALID;
511521
512− cpu_base = (uint8_t *)params->cpu_addr;
513− gpu_base = params->gpu_addr;
522+ cpu_base = (uint8_t *)params->cpu_fb_addr;
523+ gpu_base = params->gpu_fb_addr;
514524
515525 for (i = 0; i < DMUB_NUM_WINDOWS; ++i) {
516526 const struct dmub_region *reg =
@@ -518,6 +528,12 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, · 1 unmodified line
518528
519529 out->fb[i].cpu_addr = cpu_base + reg->base;
520530 out->fb[i].gpu_addr = gpu_base + reg->base;
531+
532+ if (i == DMUB_WINDOW_4_MAILBOX && params->cpu_inbox_addr != 0) {
533+ out->fb[i].cpu_addr = (uint8_t *)params->cpu_inbox_addr + reg->base;
534+ out->fb[i].gpu_addr = params->gpu_inbox_addr + reg->base;
535+ }
536+
521537 out->fb[i].size = reg->top - reg->base;
522538 }
523539
@@ -707,9 +723,16 @@ enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub) · 183 unmodified lines
707723 return DMUB_STATUS_INVALID;
708724
709725 if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) {
710− dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
711− dmub->inbox1_rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub);
712− dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
726+ uint32_t rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
727+ uint32_t wptr = dmub->hw_funcs.get_inbox1_wptr(dmub);
728+
729+ if (rptr > dmub->inbox1_rb.capacity || wptr > dmub->inbox1_rb.capacity) {
730+ return DMUB_STATUS_HW_FAILURE;
731+ } else {
732+ dmub->inbox1_rb.rptr = rptr;
733+ dmub->inbox1_rb.wrpt = wptr;
734+ dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
735+ }
713736 }
714737
715738 return DMUB_STATUS_OK;
@@ -743,6 +766,11 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, · 27 unmodified lines
743766 if (!dmub->hw_init)
744767 return DMUB_STATUS_INVALID;
745768
769+ if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity ||
770+ dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) {
771+ return DMUB_STATUS_HW_FAILURE;
772+ }
773+
746774 if (dmub_rb_push_front(&dmub->inbox1_rb, cmd))
747775 return DMUB_STATUS_OK;
748776
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h+9−1
@@ -123,7 +123,7 @@ typedef enum { · 122 unmodified lines
123123 VOLTAGE_GUARDBAND_COUNT
124124 } GFX_GUARDBAND_e;
125125
126−#define SMU_METRICS_TABLE_VERSION 0x8
126+#define SMU_METRICS_TABLE_VERSION 0x9
127127
128128 typedef struct __attribute__((packed, aligned(4))) {
129129 uint32_t AccumulationCounter;
@@ -211,6 +211,14 @@ typedef struct __attribute__((packed, aligned(4))) { · 81 unmodified lines
211211 //XGMI Data tranfser size
212212 uint64_t XgmiReadDataSizeAcc[8];//in KByte
213213 uint64_t XgmiWriteDataSizeAcc[8];//in KByte
214+
215+ //PCIE BW Data and error count
216+ uint32_t PcieBandwidth[4];
217+ uint32_t PCIeL0ToRecoveryCountAcc; // The Pcie counter itself is accumulated
218+ uint32_t PCIenReplayAAcc; // The Pcie counter itself is accumulated
219+ uint32_t PCIenReplayARolloverCountAcc; // The Pcie counter itself is accumulated
220+ uint32_t PCIeNAKSentCountAcc; // The Pcie counter itself is accumulated
221+ uint32_t PCIeNAKReceivedCountAcc; // The Pcie counter itself is accumulated
214222 } MetricsTable_t;
215223
216224 #define SMU_VF_METRICS_TABLE_VERSION 0x3
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c+9−1
@@ -1454,7 +1454,7 @@ static int smu_v13_0_6_register_irq_handler(struct smu_context *smu) · 1453 unmodified lines
14541454
14551455 static int smu_v13_0_6_notify_unload(struct smu_context *smu)
14561456 {
1457− if (smu->smc_fw_version <= 0x553500)
1457+ if (amdgpu_in_reset(smu->adev))
14581458 return 0;
14591459
14601460 dev_dbg(smu->adev->dev, "Notify PMFW about driver unload");
@@ -2095,6 +2095,14 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table · 634 unmodified lines
20952095 smu_v13_0_6_get_current_pcie_link_speed(smu);
20962096 gpu_metrics->pcie_bandwidth_acc =
20972097 SMUQ10_ROUND(metrics->PcieBandwidthAcc[0]);
2098+ gpu_metrics->pcie_bandwidth_inst =
2099+ SMUQ10_ROUND(metrics->PcieBandwidth[0]);
2100+ gpu_metrics->pcie_l0_to_recov_count_acc =
2101+ metrics->PCIeL0ToRecoveryCountAcc;
2102+ gpu_metrics->pcie_replay_count_acc =
2103+ metrics->PCIenReplayAAcc;
2104+ gpu_metrics->pcie_replay_rover_count_acc =
2105+ metrics->PCIenReplayARolloverCountAcc;
20982106 }
20992107
21002108 gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
drivers/gpu/drm/armada/armada_crtc.c+9−20
@@ -7,8 +7,9 @@ · 6 unmodified lines
77 #include <linux/clk.h>
88 #include <linux/component.h>
99 #include <linux/module.h>
10−#include <linux/of_device.h>
10+#include <linux/of.h>
1111 #include <linux/platform_device.h>
12+#include <linux/property.h>
1213
1314 #include <drm/drm_atomic.h>
1415 #include <drm/drm_atomic_helper.h>
@@ -1012,26 +1013,17 @@ armada_lcd_bind(struct device *dev, struct device *master, void *data) · 997 unmodified lines
10121013 int irq = platform_get_irq(pdev, 0);
10131014 const struct armada_variant *variant;
10141015 struct device_node *port = NULL;
1016+ struct device_node *np, *parent = dev->of_node;
10151017
10161018 if (irq < 0)
10171019 return irq;
10181020
1019− if (!dev->of_node) {
1020− const struct platform_device_id *id;
10211021
1022− id = platform_get_device_id(pdev);
1023− if (!id)
1024− return -ENXIO;
1025−
1026− variant = (const struct armada_variant *)id->driver_data;
1027− } else {
1028− const struct of_device_id *match;
1029− struct device_node *np, *parent = dev->of_node;
1030−
1031− match = of_match_device(dev->driver->of_match_table, dev);
1032− if (!match)
1033− return -ENXIO;
1022+ variant = device_get_match_data(dev);
1023+ if (!variant)
1024+ return -ENXIO;
10341025
1026+ if (parent) {
10351027 np = of_get_child_by_name(parent, "ports");
10361028 if (np)
10371029 parent = np;
@@ -1041,8 +1033,6 @@ armada_lcd_bind(struct device *dev, struct device *master, void *data) · 3 unmodified lines
10411033 dev_err(dev, "no port node found in %pOF\n", parent);
10421034 return -ENXIO;
10431035 }
1044−
1045− variant = match->data;
10461036 }
10471037
10481038 return armada_drm_crtc_create(drm, dev, res, irq, variant, port);
@@ -1066,10 +1056,9 @@ static int armada_lcd_probe(struct platform_device *pdev) · 17 unmodified lines
10661056 return component_add(&pdev->dev, &armada_lcd_ops);
10671057 }
10681058
1069−static int armada_lcd_remove(struct platform_device *pdev)
1059+static void armada_lcd_remove(struct platform_device *pdev)
10701060 {
10711061 component_del(&pdev->dev, &armada_lcd_ops);
1072− return 0;
10731062 }
10741063
10751064 static const struct of_device_id armada_lcd_of_match[] = {
@@ -1095,7 +1084,7 @@ MODULE_DEVICE_TABLE(platform, armada_lcd_platform_ids); · 19 unmodified lines
10951084
10961085 struct platform_driver armada_lcd_platform_driver = {
10971086 .probe = armada_lcd_probe,
1098− .remove = armada_lcd_remove,
1087+ .remove_new = armada_lcd_remove,
10991088 .driver = {
11001089 .name = "armada-lcd",
11011090 .owner = THIS_MODULE,
drivers/gpu/drm/armada/armada_drv.c+2−3
@@ -226,10 +226,9 @@ static int armada_drm_probe(struct platform_device *pdev) · 225 unmodified lines
226226 match);
227227 }
228228
229−static int armada_drm_remove(struct platform_device *pdev)
229+static void armada_drm_remove(struct platform_device *pdev)
230230 {
231231 component_master_del(&pdev->dev, &armada_master_ops);
232− return 0;
233232 }
234233
235234 static void armada_drm_shutdown(struct platform_device *pdev)
@@ -249,7 +248,7 @@ MODULE_DEVICE_TABLE(platform, armada_drm_platform_ids); · 13 unmodified lines
249248
250249 static struct platform_driver armada_drm_platform_driver = {
251250 .probe = armada_drm_probe,
252− .remove = armada_drm_remove,
251+ .remove_new = armada_drm_remove,
253252 .shutdown = armada_drm_shutdown,
254253 .driver = {
255254 .name = "armada-drm",
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c+4−6
@@ -6,10 +6,10 @@ · 5 unmodified lines
66 #include <linux/irq.h>
77 #include <linux/mfd/syscon.h>
88 #include <linux/module.h>
9−#include <linux/of.h>
10−#include <linux/of_device.h>
9+#include <linux/mod_devicetable.h>
1110 #include <linux/of_reserved_mem.h>
1211 #include <linux/platform_device.h>
12+#include <linux/property.h>
1313 #include <linux/regmap.h>
1414 #include <linux/reset.h>
1515
@@ -143,7 +143,6 @@ static int aspeed_gfx_load(struct drm_device *drm) · 127 unmodified lines
143143 struct aspeed_gfx *priv = to_aspeed_gfx(drm);
144144 struct device_node *np = pdev->dev.of_node;
145145 const struct aspeed_gfx_config *config;
146− const struct of_device_id *match;
147146 struct resource *res;
148147 int ret;
149148
@@ -152,10 +151,9 @@ static int aspeed_gfx_load(struct drm_device *drm) · 2 unmodified lines
152151 if (IS_ERR(priv->base))
153152 return PTR_ERR(priv->base);
154153
155− match = of_match_device(aspeed_gfx_match, &pdev->dev);
156− if (!match)
154+ config = device_get_match_data(&pdev->dev);
155+ if (!config)
157156 return -EINVAL;
158− config = match->data;
159157
160158 priv->dac_reg = config->dac_reg;
161159 priv->int_clr_reg = config->int_clear_reg;
drivers/gpu/drm/ast/ast_drv.c+255−8
@@ -89,11 +89,194 @@ static const struct pci_device_id ast_pciidlist[] = { · 88 unmodified lines
8989
9090 MODULE_DEVICE_TABLE(pci, ast_pciidlist);
9191
92+static bool ast_is_vga_enabled(void __iomem *ioregs)
93+{
94+ u8 vgaer = __ast_read8(ioregs, AST_IO_VGAER);
95+
96+ return vgaer & AST_IO_VGAER_VGA_ENABLE;
97+}
98+
99+static void ast_enable_vga(void __iomem *ioregs)
100+{
101+ __ast_write8(ioregs, AST_IO_VGAER, AST_IO_VGAER_VGA_ENABLE);
102+ __ast_write8(ioregs, AST_IO_VGAMR_W, AST_IO_VGAMR_IOSEL);
103+}
104+
105+/*
106+ * Run this function as part of the HW device cleanup; not
107+ * when the DRM device gets released.
108+ */
109+static void ast_enable_mmio_release(void *data)
110+{
111+ void __iomem *ioregs = (void __force __iomem *)data;
112+
113+ /* enable standard VGA decode */
114+ __ast_write8_i(ioregs, AST_IO_VGACRI, 0xa1, AST_IO_VGACRA1_MMIO_ENABLED);
115+}
116+
117+static int ast_enable_mmio(struct device *dev, void __iomem *ioregs)
118+{
119+ void *data = (void __force *)ioregs;
120+
121+ __ast_write8_i(ioregs, AST_IO_VGACRI, 0xa1,
122+ AST_IO_VGACRA1_MMIO_ENABLED |
123+ AST_IO_VGACRA1_VGAIO_DISABLED);
124+
125+ return devm_add_action_or_reset(dev, ast_enable_mmio_release, data);
126+}
127+
128+static void ast_open_key(void __iomem *ioregs)
129+{
130+ __ast_write8_i(ioregs, AST_IO_VGACRI, 0x80, AST_IO_VGACR80_PASSWORD);
131+}
132+
133+static int ast_detect_chip(struct pci_dev *pdev,
134+ void __iomem *regs, void __iomem *ioregs,
135+ enum ast_chip *chip_out,
136+ enum ast_config_mode *config_mode_out)
137+{
138+ struct device *dev = &pdev->dev;
139+ struct device_node *np = dev->of_node;
140+ enum ast_config_mode config_mode = ast_use_defaults;
141+ uint32_t scu_rev = 0xffffffff;
142+ enum ast_chip chip;
143+ u32 data;
144+ u8 vgacrd0, vgacrd1;
145+
146+ /*
147+ * Find configuration mode and read SCU revision
148+ */
149+
150+ /* Check if we have device-tree properties */
151+ if (np && !of_property_read_u32(np, "aspeed,scu-revision-id", &data)) {
152+ /* We do, disable P2A access */
153+ config_mode = ast_use_dt;
154+ scu_rev = data;
155+ } else if (pdev->device == PCI_CHIP_AST2000) { // Not all families have a P2A bridge
156+ /*
157+ * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge
158+ * is disabled. We force using P2A if VGA only mode bit
159+ * is set D[7]
160+ */
161+ vgacrd0 = __ast_read8_i(ioregs, AST_IO_VGACRI, 0xd0);
162+ vgacrd1 = __ast_read8_i(ioregs, AST_IO_VGACRI, 0xd1);
163+ if (!(vgacrd0 & 0x80) || !(vgacrd1 & 0x10)) {
164+
165+ /*
166+ * We have a P2A bridge and it is enabled.
167+ */
168+
169+ /* Patch AST2500/AST2510 */
170+ if ((pdev->revision & 0xf0) == 0x40) {
171+ if (!(vgacrd0 & AST_VRAM_INIT_STATUS_MASK))
172+ ast_patch_ahb_2500(regs);
173+ }
174+
175+ /* Double check that it's actually working */
176+ data = __ast_read32(regs, 0xf004);
177+ if ((data != 0xffffffff) && (data != 0x00)) {
178+ config_mode = ast_use_p2a;
179+
180+ /* Read SCU7c (silicon revision register) */
181+ __ast_write32(regs, 0xf004, 0x1e6e0000);
182+ __ast_write32(regs, 0xf000, 0x1);
183+ scu_rev = __ast_read32(regs, 0x1207c);
184+ }
185+ }
186+ }
187+
188+ switch (config_mode) {
189+ case ast_use_defaults:
190+ dev_info(dev, "Using default configuration\n");
191+ break;
192+ case ast_use_dt:
193+ dev_info(dev, "Using device-tree for configuration\n");
194+ break;
195+ case ast_use_p2a:
196+ dev_info(dev, "Using P2A bridge for configuration\n");
197+ break;
198+ }
199+
200+ /*
201+ * Identify chipset
202+ */
203+
204+ if (pdev->revision >= 0x50) {
205+ chip = AST2600;
206+ dev_info(dev, "AST 2600 detected\n");
207+ } else if (pdev->revision >= 0x40) {
208+ switch (scu_rev & 0x300) {
209+ case 0x0100:
210+ chip = AST2510;
211+ dev_info(dev, "AST 2510 detected\n");
212+ break;
213+ default:
214+ chip = AST2500;
215+ dev_info(dev, "AST 2500 detected\n");
216+ break;
217+ }
218+ } else if (pdev->revision >= 0x30) {
219+ switch (scu_rev & 0x300) {
220+ case 0x0100:
221+ chip = AST1400;
222+ dev_info(dev, "AST 1400 detected\n");
223+ break;
224+ default:
225+ chip = AST2400;
226+ dev_info(dev, "AST 2400 detected\n");
227+ break;
228+ }
229+ } else if (pdev->revision >= 0x20) {
230+ switch (scu_rev & 0x300) {
231+ case 0x0000:
232+ chip = AST1300;
233+ dev_info(dev, "AST 1300 detected\n");
234+ break;
235+ default:
236+ chip = AST2300;
237+ dev_info(dev, "AST 2300 detected\n");
238+ break;
239+ }
240+ } else if (pdev->revision >= 0x10) {
241+ switch (scu_rev & 0x0300) {
242+ case 0x0200:
243+ chip = AST1100;
244+ dev_info(dev, "AST 1100 detected\n");
245+ break;
246+ case 0x0100:
247+ chip = AST2200;
248+ dev_info(dev, "AST 2200 detected\n");
249+ break;
250+ case 0x0000:
251+ chip = AST2150;
252+ dev_info(dev, "AST 2150 detected\n");
253+ break;
254+ default:
255+ chip = AST2100;
256+ dev_info(dev, "AST 2100 detected\n");
257+ break;
258+ }
259+ } else {
260+ chip = AST2000;
261+ dev_info(dev, "AST 2000 detected\n");
262+ }
263+
264+ *chip_out = chip;
265+ *config_mode_out = config_mode;
266+
267+ return 0;
268+}
269+
92270 static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
93271 {
94− struct ast_device *ast;
95− struct drm_device *dev;
272+ struct device *dev = &pdev->dev;
96273 int ret;
274+ void __iomem *regs;
275+ void __iomem *ioregs;
276+ enum ast_config_mode config_mode;
277+ enum ast_chip chip;
278+ struct drm_device *drm;
279+ bool need_post = false;
97280
98281 ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &ast_driver);
99282 if (ret)
@@ -103,16 +286,80 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 3 unmodified lines
103286 if (ret)
104287 return ret;
105288
106− ast = ast_device_create(&ast_driver, pdev, ent->driver_data);
107− if (IS_ERR(ast))
108− return PTR_ERR(ast);
109− dev = &ast->base;
289+ regs = pcim_iomap(pdev, 1, 0);
290+ if (!regs)
291+ return -EIO;
292+
293+ if (pdev->revision >= 0x40) {
294+ /*
295+ * On AST2500 and later models, MMIO is enabled by
296+ * default. Adopt it to be compatible with ARM.
297+ */
298+ resource_size_t len = pci_resource_len(pdev, 1);
299+
300+ if (len < AST_IO_MM_OFFSET)
301+ return -EIO;
302+ if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH)
303+ return -EIO;
304+ ioregs = regs + AST_IO_MM_OFFSET;
305+ } else if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
306+ /*
307+ * Map I/O registers if we have a PCI BAR for I/O.
308+ */
309+ resource_size_t len = pci_resource_len(pdev, 2);
310+
311+ if (len < AST_IO_MM_LENGTH)
312+ return -EIO;
313+ ioregs = pcim_iomap(pdev, 2, 0);
314+ if (!ioregs)
315+ return -EIO;
316+ } else {
317+ /*
318+ * Anything else is best effort.
319+ */
320+ resource_size_t len = pci_resource_len(pdev, 1);
321+
322+ if (len < AST_IO_MM_OFFSET)
323+ return -EIO;
324+ if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH)
325+ return -EIO;
326+ ioregs = regs + AST_IO_MM_OFFSET;
327+
328+ dev_info(dev, "Platform has no I/O space, using MMIO\n");
329+ }
330+
331+ if (!ast_is_vga_enabled(ioregs)) {
332+ dev_info(dev, "VGA not enabled on entry, requesting chip POST\n");
333+ need_post = true;
334+ }
335+
336+ /*
337+ * If VGA isn't enabled, we need to enable now or subsequent
338+ * access to the scratch registers will fail.
339+ */
340+ if (need_post)
341+ ast_enable_vga(ioregs);
342+ /* Enable extended register access */
343+ ast_open_key(ioregs);
344+
345+ ret = ast_enable_mmio(dev, ioregs);
346+ if (ret)
347+ return ret;
348+
349+ ret = ast_detect_chip(pdev, regs, ioregs, &chip, &config_mode);
350+ if (ret)
351+ return ret;
352+
353+ drm = ast_device_create(pdev, &ast_driver, chip, config_mode, regs, ioregs, need_post);
354+ if (IS_ERR(drm))
355+ return PTR_ERR(drm);
356+ pci_set_drvdata(pdev, drm);
110357
111− ret = drm_dev_register(dev, ent->driver_data);
358+ ret = drm_dev_register(drm, ent->driver_data);
112359 if (ret)
113360 return ret;
114361
115− drm_fbdev_generic_setup(dev, 32);
362+ drm_fbdev_generic_setup(drm, 32);
116363
117364 return 0;
118365 }
drivers/gpu/drm/ast/ast_drv.h+86−28
@@ -98,6 +98,12 @@ enum ast_tx_chip { · 97 unmodified lines
9898 #define AST_TX_DP501_BIT BIT(AST_TX_DP501)
9999 #define AST_TX_ASTDP_BIT BIT(AST_TX_ASTDP)
100100
101+enum ast_config_mode {
102+ ast_use_p2a,
103+ ast_use_dt,
104+ ast_use_defaults
105+};
106+
101107 #define AST_DRAM_512Mx16 0
102108 #define AST_DRAM_1Gx16 1
103109 #define AST_DRAM_512Mx32 2
@@ -174,6 +180,17 @@ to_ast_sil164_connector(struct drm_connector *connector) · 70 unmodified lines
174180 return container_of(connector, struct ast_sil164_connector, base);
175181 }
176182
183+struct ast_bmc_connector {
184+ struct drm_connector base;
185+ struct drm_connector *physical_connector;
186+};
187+
188+static inline struct ast_bmc_connector *
189+to_ast_bmc_connector(struct drm_connector *connector)
190+{
191+ return container_of(connector, struct ast_bmc_connector, base);
192+}
193+
177194 /*
178195 * Device
179196 */
@@ -181,12 +198,13 @@ to_ast_sil164_connector(struct drm_connector *connector) · 1 unmodified line
181198 struct ast_device {
182199 struct drm_device base;
183200
184− struct mutex ioregs_lock; /* Protects access to I/O registers in ioregs */
185201 void __iomem *regs;
186202 void __iomem *ioregs;
187203 void __iomem *dp501_fw_buf;
188204
205+ enum ast_config_mode config_mode;
189206 enum ast_chip chip;
207+
190208 uint32_t dram_bus_width;
191209 uint32_t dram_type;
192210 uint32_t mclk;
@@ -196,6 +214,8 @@ struct ast_device { · 3 unmodified lines
196214 unsigned long vram_size;
197215 unsigned long vram_fb_available;
198216
217+ struct mutex modeset_lock; /* Protects access to modeset I/O registers in ioregs */
218+
199219 struct ast_plane primary_plane;
200220 struct ast_plane cursor_plane;
201221 struct drm_crtc crtc;
@@ -218,16 +238,11 @@ struct ast_device { · 16 unmodified lines
218238 } astdp;
219239 struct {
220240 struct drm_encoder encoder;
221− struct drm_connector connector;
241+ struct ast_bmc_connector bmc_connector;
222242 } bmc;
223243 } output;
224244
225245 bool support_wide_screen;
226− enum {
227− ast_use_p2a,
228− ast_use_dt,
229− ast_use_defaults
230− } config_mode;
231246
232247 unsigned long tx_chip_types; /* bitfield of enum ast_chip_type */
233248 u8 *dp501_fw_addr;
@@ -239,9 +254,13 @@ static inline struct ast_device *to_ast_device(struct drm_device *dev) · 5 unmodified lines
239254 return container_of(dev, struct ast_device, base);
240255 }
241256
242−struct ast_device *ast_device_create(const struct drm_driver *drv,
243− struct pci_dev *pdev,
244− unsigned long flags);
257+struct drm_device *ast_device_create(struct pci_dev *pdev,
258+ const struct drm_driver *drv,
259+ enum ast_chip chip,
260+ enum ast_config_mode config_mode,
261+ void __iomem *regs,
262+ void __iomem *ioregs,
263+ bool need_post);
245264
246265 static inline unsigned long __ast_gen(struct ast_device *ast)
247266 {
@@ -261,55 +280,94 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) · 13 unmodified lines
261280 #define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6)
262281 #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7)
263282
283+static inline u8 __ast_read8(const void __iomem *addr, u32 reg)
284+{
285+ return ioread8(addr + reg);
286+}
287+
288+static inline u32 __ast_read32(const void __iomem *addr, u32 reg)
289+{
290+ return ioread32(addr + reg);
291+}
292+
293+static inline void __ast_write8(void __iomem *addr, u32 reg, u8 val)
294+{
295+ iowrite8(val, addr + reg);
296+}
297+
298+static inline void __ast_write32(void __iomem *addr, u32 reg, u32 val)
299+{
300+ iowrite32(val, addr + reg);
301+}
302+
303+static inline u8 __ast_read8_i(void __iomem *addr, u32 reg, u8 index)
304+{
305+ __ast_write8(addr, reg, index);
306+ return __ast_read8(addr, reg + 1);
307+}
308+
309+static inline u8 __ast_read8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 read_mask)
310+{
311+ u8 val = __ast_read8_i(addr, reg, index);
312+
313+ return val & read_mask;
314+}
315+
316+static inline void __ast_write8_i(void __iomem *addr, u32 reg, u8 index, u8 val)
317+{
318+ __ast_write8(addr, reg, index);
319+ __ast_write8(addr, reg + 1, val);
320+}
321+
322+static inline void __ast_write8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 read_mask,
323+ u8 val)
324+{
325+ u8 tmp = __ast_read8_i_masked(addr, reg, index, read_mask);
326+
327+ tmp |= val;
328+ __ast_write8_i(addr, reg, index, tmp);
329+}
330+
264331 static inline u32 ast_read32(struct ast_device *ast, u32 reg)
265332 {
266− return ioread32(ast->regs + reg);
333+ return __ast_read32(ast->regs, reg);
267334 }
268335
269336 static inline void ast_write32(struct ast_device *ast, u32 reg, u32 val)
270337 {
271− iowrite32(val, ast->regs + reg);
338+ __ast_write32(ast->regs, reg, val);
272339 }
273340
274341 static inline u8 ast_io_read8(struct ast_device *ast, u32 reg)
275342 {
276− return ioread8(ast->ioregs + reg);
343+ return __ast_read8(ast->ioregs, reg);
277344 }
278345
279346 static inline void ast_io_write8(struct ast_device *ast, u32 reg, u8 val)
280347 {
281− iowrite8(val, ast->ioregs + reg);
348+ __ast_write8(ast->ioregs, reg, val);
282349 }
283350
284351 static inline u8 ast_get_index_reg(struct ast_device *ast, u32 base, u8 index)
285352 {
286− ast_io_write8(ast, base, index);
287− ++base;
288− return ast_io_read8(ast, base);
353+ return __ast_read8_i(ast->ioregs, base, index);
289354 }
290355
291356 static inline u8 ast_get_index_reg_mask(struct ast_device *ast, u32 base, u8 index,
292357 u8 preserve_mask)
293358 {
294− u8 val = ast_get_index_reg(ast, base, index);
295−
296− return val & preserve_mask;
359+ return __ast_read8_i_masked(ast->ioregs, base, index, preserve_mask);
297360 }
298361
299362 static inline void ast_set_index_reg(struct ast_device *ast, u32 base, u8 index, u8 val)
300363 {
301− ast_io_write8(ast, base, index);
302− ++base;
303− ast_io_write8(ast, base, val);
364+ __ast_write8_i(ast->ioregs, base, index, val);
304365 }
305366
306367 static inline void ast_set_index_reg_mask(struct ast_device *ast, u32 base, u8 index,
307368 u8 preserve_mask, u8 val)
308369 {
309− u8 tmp = ast_get_index_reg_mask(ast, base, index, preserve_mask);
310−
311− tmp |= val;
312− ast_set_index_reg(ast, base, index, tmp);
370+ __ast_write8_i_masked(ast->ioregs, base, index, preserve_mask, val);
313371 }
314372
315373 #define AST_VIDMEM_SIZE_8M 0x00800000
@@ -431,7 +489,7 @@ int ast_mm_init(struct ast_device *ast); · 115 unmodified lines
431489 void ast_post_gpu(struct drm_device *dev);
432490 u32 ast_mindwm(struct ast_device *ast, u32 r);
433491 void ast_moutdwm(struct ast_device *ast, u32 r, u32 v);
434−void ast_patch_ahb_2500(struct ast_device *ast);
492+void ast_patch_ahb_2500(void __iomem *regs);
435493 /* ast dp501 */
436494 void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
437495 bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
drivers/gpu/drm/ast/ast_main.c+14−230
@@ -35,180 +35,6 @@ · 34 unmodified lines
3535
3636 #include "ast_drv.h"
3737
38−static bool ast_is_vga_enabled(struct drm_device *dev)
39−{
40− struct ast_device *ast = to_ast_device(dev);
41− u8 ch;
42−
43− ch = ast_io_read8(ast, AST_IO_VGAER);
44−
45− return !!(ch & 0x01);
46−}
47−
48−static void ast_enable_vga(struct drm_device *dev)
49−{
50− struct ast_device *ast = to_ast_device(dev);
51−
52− ast_io_write8(ast, AST_IO_VGAER, 0x01);
53− ast_io_write8(ast, AST_IO_VGAMR_W, 0x01);
54−}
55−
56−/*
57− * Run this function as part of the HW device cleanup; not
58− * when the DRM device gets released.
59− */
60−static void ast_enable_mmio_release(void *data)
61−{
62− struct ast_device *ast = data;
63−
64− /* enable standard VGA decode */
65− ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x04);
66−}
67−
68−static int ast_enable_mmio(struct ast_device *ast)
69−{
70− struct drm_device *dev = &ast->base;
71−
72− ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
73−
74− return devm_add_action_or_reset(dev->dev, ast_enable_mmio_release, ast);
75−}
76−
77−static void ast_open_key(struct ast_device *ast)
78−{
79− ast_set_index_reg(ast, AST_IO_VGACRI, 0x80, 0xA8);
80−}
81−
82−static int ast_device_config_init(struct ast_device *ast)
83−{
84− struct drm_device *dev = &ast->base;
85− struct pci_dev *pdev = to_pci_dev(dev->dev);
86− struct device_node *np = dev->dev->of_node;
87− uint32_t scu_rev = 0xffffffff;
88− u32 data;
89− u8 jregd0, jregd1;
90−
91− /*
92− * Find configuration mode and read SCU revision
93− */
94−
95− ast->config_mode = ast_use_defaults;
96−
97− /* Check if we have device-tree properties */
98− if (np && !of_property_read_u32(np, "aspeed,scu-revision-id", &data)) {
99− /* We do, disable P2A access */
100− ast->config_mode = ast_use_dt;
101− scu_rev = data;
102− } else if (pdev->device == PCI_CHIP_AST2000) { // Not all families have a P2A bridge
103− /*
104− * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge
105− * is disabled. We force using P2A if VGA only mode bit
106− * is set D[7]
107− */
108− jregd0 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
109− jregd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff);
110− if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
111−
112− /*
113− * We have a P2A bridge and it is enabled.
114− */
115−
116− /* Patch AST2500/AST2510 */
117− if ((pdev->revision & 0xf0) == 0x40) {
118− if (!(jregd0 & AST_VRAM_INIT_STATUS_MASK))
119− ast_patch_ahb_2500(ast);
120− }
121−
122− /* Double check that it's actually working */
123− data = ast_read32(ast, 0xf004);
124− if ((data != 0xffffffff) && (data != 0x00)) {
125− ast->config_mode = ast_use_p2a;
126−
127− /* Read SCU7c (silicon revision register) */
128− ast_write32(ast, 0xf004, 0x1e6e0000);
129− ast_write32(ast, 0xf000, 0x1);
130− scu_rev = ast_read32(ast, 0x1207c);
131− }
132− }
133− }
134−
135− switch (ast->config_mode) {
136− case ast_use_defaults:
137− drm_info(dev, "Using default configuration\n");
138− break;
139− case ast_use_dt:
140− drm_info(dev, "Using device-tree for configuration\n");
141− break;
142− case ast_use_p2a:
143− drm_info(dev, "Using P2A bridge for configuration\n");
144− break;
145− }
146−
147− /*
148− * Identify chipset
149− */
150−
151− if (pdev->revision >= 0x50) {
152− ast->chip = AST2600;
153− drm_info(dev, "AST 2600 detected\n");
154− } else if (pdev->revision >= 0x40) {
155− switch (scu_rev & 0x300) {
156− case 0x0100:
157− ast->chip = AST2510;
158− drm_info(dev, "AST 2510 detected\n");
159− break;
160− default:
161− ast->chip = AST2500;
162− drm_info(dev, "AST 2500 detected\n");
163− }
164− } else if (pdev->revision >= 0x30) {
165− switch (scu_rev & 0x300) {
166− case 0x0100:
167− ast->chip = AST1400;
168− drm_info(dev, "AST 1400 detected\n");
169− break;
170− default:
171− ast->chip = AST2400;
172− drm_info(dev, "AST 2400 detected\n");
173− }
174− } else if (pdev->revision >= 0x20) {
175− switch (scu_rev & 0x300) {
176− case 0x0000:
177− ast->chip = AST1300;
178− drm_info(dev, "AST 1300 detected\n");
179− break;
180− default:
181− ast->chip = AST2300;
182− drm_info(dev, "AST 2300 detected\n");
183− break;
184− }
185− } else if (pdev->revision >= 0x10) {
186− switch (scu_rev & 0x0300) {
187− case 0x0200:
188− ast->chip = AST1100;
189− drm_info(dev, "AST 1100 detected\n");
190− break;
191− case 0x0100:
192− ast->chip = AST2200;
193− drm_info(dev, "AST 2200 detected\n");
194− break;
195− case 0x0000:
196− ast->chip = AST2150;
197− drm_info(dev, "AST 2150 detected\n");
198− break;
199− default:
200− ast->chip = AST2100;
201− drm_info(dev, "AST 2100 detected\n");
202− break;
203− }
204− } else {
205− ast->chip = AST2000;
206− drm_info(dev, "AST 2000 detected\n");
207− }
208−
209− return 0;
210−}
211−
21238 static void ast_detect_widescreen(struct ast_device *ast)
21339 {
21440 u8 jreg;
@@ -424,69 +250,27 @@ static int ast_get_dram_info(struct drm_device *dev) · 209 unmodified lines
424250 return 0;
425251 }
426252
427−struct ast_device *ast_device_create(const struct drm_driver *drv,
428− struct pci_dev *pdev,
429− unsigned long flags)
253+struct drm_device *ast_device_create(struct pci_dev *pdev,
254+ const struct drm_driver *drv,
255+ enum ast_chip chip,
256+ enum ast_config_mode config_mode,
257+ void __iomem *regs,
258+ void __iomem *ioregs,
259+ bool need_post)
430260 {
431261 struct drm_device *dev;
432262 struct ast_device *ast;
433− bool need_post = false;
434− int ret = 0;
263+ int ret;
435264
436265 ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base);
437266 if (IS_ERR(ast))
438− return ast;
267+ return ERR_CAST(ast);
439268 dev = &ast->base;
440269
441− pci_set_drvdata(pdev, dev);
442−
443− ret = drmm_mutex_init(dev, &ast->ioregs_lock);
444− if (ret)
445− return ERR_PTR(ret);
446−
447− ast->regs = pcim_iomap(pdev, 1, 0);
448− if (!ast->regs)
449− return ERR_PTR(-EIO);
450−
451− /*
452− * After AST2500, MMIO is enabled by default, and it should be adopted
453− * to be compatible with Arm.
454− */
455− if (pdev->revision >= 0x40) {
456− ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
457− } else if (!(pci_resource_flags(pdev, 2) & IORESOURCE_IO)) {
458− drm_info(dev, "platform has no IO space, trying MMIO\n");
459− ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
460− }
461−
462− /* "map" IO regs if the above hasn't done so already */
463− if (!ast->ioregs) {
464− ast->ioregs = pcim_iomap(pdev, 2, 0);
465− if (!ast->ioregs)
466− return ERR_PTR(-EIO);
467− }
468−
469− if (!ast_is_vga_enabled(dev)) {
470− drm_info(dev, "VGA not enabled on entry, requesting chip POST\n");
471− need_post = true;
472− }
473−
474− /*
475− * If VGA isn't enabled, we need to enable now or subsequent
476− * access to the scratch registers will fail.
477− */
478− if (need_post)
479− ast_enable_vga(dev);
480−
481− /* Enable extended register access */
482− ast_open_key(ast);
483− ret = ast_enable_mmio(ast);
484− if (ret)
485− return ERR_PTR(ret);
486−
487− ret = ast_device_config_init(ast);
488− if (ret)
489− return ERR_PTR(ret);
270+ ast->chip = chip;
271+ ast->config_mode = config_mode;
272+ ast->regs = regs;
273+ ast->ioregs = ioregs;
490274
491275 ast_detect_widescreen(ast);
492276 ast_detect_tx_chip(ast, need_post);
@@ -517,5 +301,5 @@ struct ast_device *ast_device_create(const struct drm_driver *drv, · 24 unmodified lines
517301 if (ret)
518302 return ERR_PTR(ret);
519303
520− return ast;
304+ return dev;
521305 }
drivers/gpu/drm/ast/ast_mode.c+70−18
@@ -1358,13 +1358,13 @@ static int ast_vga_connector_helper_get_modes(struct drm_connector *connector) · 1357 unmodified lines
13581358 * Protect access to I/O registers from concurrent modesetting
13591359 * by acquiring the I/O-register lock.
13601360 */
1361− mutex_lock(&ast->ioregs_lock);
1361+ mutex_lock(&ast->modeset_lock);
13621362
13631363 edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter);
13641364 if (!edid)
13651365 goto err_mutex_unlock;
13661366
1367− mutex_unlock(&ast->ioregs_lock);
1367+ mutex_unlock(&ast->modeset_lock);
13681368
13691369 count = drm_add_edid_modes(connector, edid);
13701370 kfree(edid);
@@ -1372,7 +1372,7 @@ static int ast_vga_connector_helper_get_modes(struct drm_connector *connector) · 1 unmodified line
13721372 return count;
13731373
13741374 err_mutex_unlock:
1375− mutex_unlock(&ast->ioregs_lock);
1375+ mutex_unlock(&ast->modeset_lock);
13761376 err_drm_connector_update_edid_property:
13771377 drm_connector_update_edid_property(connector, NULL);
13781378 return 0;
@@ -1464,13 +1464,13 @@ static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector · 85 unmodified lines
14641464 * Protect access to I/O registers from concurrent modesetting
14651465 * by acquiring the I/O-register lock.
14661466 */
1467− mutex_lock(&ast->ioregs_lock);
1467+ mutex_lock(&ast->modeset_lock);
14681468
14691469 edid = drm_get_edid(connector, &ast_sil164_connector->i2c->adapter);
14701470 if (!edid)
14711471 goto err_mutex_unlock;
14721472
1473− mutex_unlock(&ast->ioregs_lock);
1473+ mutex_unlock(&ast->modeset_lock);
14741474
14751475 count = drm_add_edid_modes(connector, edid);
14761476 kfree(edid);
@@ -1478,7 +1478,7 @@ static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector · 1 unmodified line
14781478 return count;
14791479
14801480 err_mutex_unlock:
1481− mutex_unlock(&ast->ioregs_lock);
1481+ mutex_unlock(&ast->modeset_lock);
14821482 err_drm_connector_update_edid_property:
14831483 drm_connector_update_edid_property(connector, NULL);
14841484 return 0;
@@ -1670,13 +1670,13 @@ static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector) · 185 unmodified lines
16701670 * Protect access to I/O registers from concurrent modesetting
16711671 * by acquiring the I/O-register lock.
16721672 */
1673− mutex_lock(&ast->ioregs_lock);
1673+ mutex_lock(&ast->modeset_lock);
16741674
16751675 succ = ast_astdp_read_edid(connector->dev, edid);
16761676 if (succ < 0)
16771677 goto err_mutex_unlock;
16781678
1679− mutex_unlock(&ast->ioregs_lock);
1679+ mutex_unlock(&ast->modeset_lock);
16801680
16811681 drm_connector_update_edid_property(connector, edid);
16821682 count = drm_add_edid_modes(connector, edid);
@@ -1685,7 +1685,7 @@ static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector) · 2 unmodified lines
16851685 return count;
16861686
16871687 err_mutex_unlock:
1688− mutex_unlock(&ast->ioregs_lock);
1688+ mutex_unlock(&ast->modeset_lock);
16891689 kfree(edid);
16901690 err_drm_connector_update_edid_property:
16911691 drm_connector_update_edid_property(connector, NULL);
@@ -1767,6 +1767,30 @@ static const struct drm_encoder_funcs ast_bmc_encoder_funcs = { · 75 unmodified lines
17671767 .destroy = drm_encoder_cleanup,
17681768 };
17691769
1770+static int ast_bmc_connector_helper_detect_ctx(struct drm_connector *connector,
1771+ struct drm_modeset_acquire_ctx *ctx,
1772+ bool force)
1773+{
1774+ struct ast_bmc_connector *bmc_connector = to_ast_bmc_connector(connector);
1775+ struct drm_connector *physical_connector = bmc_connector->physical_connector;
1776+
1777+ /*
1778+ * Most user-space compositors cannot handle more than one connected
1779+ * connector per CRTC. Hence, we only mark the BMC as connected if the
1780+ * physical connector is disconnected. If the physical connector's status
1781+ * is connected or unknown, the BMC remains disconnected. This has no
1782+ * effect on the output of the BMC.
1783+ *
1784+ * FIXME: Remove this logic once user-space compositors can handle more
1785+ * than one connector per CRTC. The BMC should always be connected.
1786+ */
1787+
1788+ if (physical_connector && physical_connector->status == connector_status_disconnected)
1789+ return connector_status_connected;
1790+
1791+ return connector_status_disconnected;
1792+}
1793+
17701794 static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector)
17711795 {
17721796 return drm_add_modes_noedid(connector, 4096, 4096);
@@ -1774,6 +1798,7 @@ static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector) · 1 unmodified line
17741798
17751799 static const struct drm_connector_helper_funcs ast_bmc_connector_helper_funcs = {
17761800 .get_modes = ast_bmc_connector_helper_get_modes,
1801+ .detect_ctx = ast_bmc_connector_helper_detect_ctx,
17771802 };
17781803
17791804 static const struct drm_connector_funcs ast_bmc_connector_funcs = {
@@ -1784,12 +1809,33 @@ static const struct drm_connector_funcs ast_bmc_connector_funcs = { · 4 unmodified lines
17841809 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
17851810 };
17861811
1787−static int ast_bmc_output_init(struct ast_device *ast)
1812+static int ast_bmc_connector_init(struct drm_device *dev,
1813+ struct ast_bmc_connector *bmc_connector,
1814+ struct drm_connector *physical_connector)
1815+{
1816+ struct drm_connector *connector = &bmc_connector->base;
1817+ int ret;
1818+
1819+ ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs,
1820+ DRM_MODE_CONNECTOR_VIRTUAL);
1821+ if (ret)
1822+ return ret;
1823+
1824+ drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs);
1825+
1826+ bmc_connector->physical_connector = physical_connector;
1827+
1828+ return 0;
1829+}
1830+
1831+static int ast_bmc_output_init(struct ast_device *ast,
1832+ struct drm_connector *physical_connector)
17881833 {
17891834 struct drm_device *dev = &ast->base;
17901835 struct drm_crtc *crtc = &ast->crtc;
17911836 struct drm_encoder *encoder = &ast->output.bmc.encoder;
1792− struct drm_connector *connector = &ast->output.bmc.connector;
1837+ struct ast_bmc_connector *bmc_connector = &ast->output.bmc.bmc_connector;
1838+ struct drm_connector *connector = &bmc_connector->base;
17931839 int ret;
17941840
17951841 ret = drm_encoder_init(dev, encoder,
@@ -1799,13 +1845,10 @@ static int ast_bmc_output_init(struct ast_device *ast) · 3 unmodified lines
17991845 return ret;
18001846 encoder->possible_crtcs = drm_crtc_mask(crtc);
18011847
1802− ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs,
1803− DRM_MODE_CONNECTOR_VIRTUAL);
1848+ ret = ast_bmc_connector_init(dev, bmc_connector, physical_connector);
18041849 if (ret)
18051850 return ret;
18061851
1807− drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs);
1808−
18091852 ret = drm_connector_attach_encoder(connector, encoder);
18101853 if (ret)
18111854 return ret;
@@ -1827,9 +1870,9 @@ static void ast_mode_config_helper_atomic_commit_tail(struct drm_atomic_state *s · 15 unmodified lines
18271870 * display modes. Protect access to I/O registers by acquiring
18281871 * the I/O-register lock. Released in atomic_flush().
18291872 */
1830− mutex_lock(&ast->ioregs_lock);
1873+ mutex_lock(&ast->modeset_lock);
18311874 drm_atomic_helper_commit_tail_rpm(state);
1832− mutex_unlock(&ast->ioregs_lock);
1875+ mutex_unlock(&ast->modeset_lock);
18331876 }
18341877
18351878 static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = {
@@ -1864,8 +1907,13 @@ static const struct drm_mode_config_funcs ast_mode_config_funcs = { · 28 unmodified lines
18641907 int ast_mode_config_init(struct ast_device *ast)
18651908 {
18661909 struct drm_device *dev = &ast->base;
1910+ struct drm_connector *physical_connector = NULL;
18671911 int ret;
18681912
1913+ ret = drmm_mutex_init(dev, &ast->modeset_lock);
1914+ if (ret)
1915+ return ret;
1916+
18691917 ret = drmm_mode_config_init(dev);
18701918 if (ret)
18711919 return ret;
@@ -1904,23 +1952,27 @@ int ast_mode_config_init(struct ast_device *ast) · 32 unmodified lines
19041952 ret = ast_vga_output_init(ast);
19051953 if (ret)
19061954 return ret;
1955+ physical_connector = &ast->output.vga.vga_connector.base;
19071956 }
19081957 if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
19091958 ret = ast_sil164_output_init(ast);
19101959 if (ret)
19111960 return ret;
1961+ physical_connector = &ast->output.sil164.sil164_connector.base;
19121962 }
19131963 if (ast->tx_chip_types & AST_TX_DP501_BIT) {
19141964 ret = ast_dp501_output_init(ast);
19151965 if (ret)
19161966 return ret;
1967+ physical_connector = &ast->output.dp501.connector;
19171968 }
19181969 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
19191970 ret = ast_astdp_output_init(ast);
19201971 if (ret)
19211972 return ret;
1973+ physical_connector = &ast->output.astdp.connector;
19221974 }
1923− ret = ast_bmc_output_init(ast);
1975+ ret = ast_bmc_output_init(ast, physical_connector);
19241976 if (ret)
19251977 return ret;
19261978
drivers/gpu/drm/ast/ast_post.c+45−28
@@ -77,28 +77,42 @@ ast_set_def_ext_reg(struct drm_device *dev) · 76 unmodified lines
7777 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg);
7878 }
7979
80−u32 ast_mindwm(struct ast_device *ast, u32 r)
80+static u32 __ast_mindwm(void __iomem *regs, u32 r)
8181 {
82− uint32_t data;
82+ u32 data;
8383
84− ast_write32(ast, 0xf004, r & 0xffff0000);
85− ast_write32(ast, 0xf000, 0x1);
84+ __ast_write32(regs, 0xf004, r & 0xffff0000);
85+ __ast_write32(regs, 0xf000, 0x1);
8686
8787 do {
88− data = ast_read32(ast, 0xf004) & 0xffff0000;
88+ data = __ast_read32(regs, 0xf004) & 0xffff0000;
8989 } while (data != (r & 0xffff0000));
90− return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
90+
91+ return __ast_read32(regs, 0x10000 + (r & 0x0000ffff));
9192 }
9293
93−void ast_moutdwm(struct ast_device *ast, u32 r, u32 v)
94+static void __ast_moutdwm(void __iomem *regs, u32 r, u32 v)
9495 {
95− uint32_t data;
96− ast_write32(ast, 0xf004, r & 0xffff0000);
97− ast_write32(ast, 0xf000, 0x1);
96+ u32 data;
97+
98+ __ast_write32(regs, 0xf004, r & 0xffff0000);
99+ __ast_write32(regs, 0xf000, 0x1);
100+
98101 do {
99− data = ast_read32(ast, 0xf004) & 0xffff0000;
102+ data = __ast_read32(regs, 0xf004) & 0xffff0000;
100103 } while (data != (r & 0xffff0000));
101− ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
104+
105+ __ast_write32(regs, 0x10000 + (r & 0x0000ffff), v);
106+}
107+
108+u32 ast_mindwm(struct ast_device *ast, u32 r)
109+{
110+ return __ast_mindwm(ast->regs, r);
111+}
112+
113+void ast_moutdwm(struct ast_device *ast, u32 r, u32 v)
114+{
115+ __ast_moutdwm(ast->regs, r, v);
102116 }
103117
104118 /*
@@ -1987,17 +2001,18 @@ static bool ast_dram_init_2500(struct ast_device *ast) · 1882 unmodified lines
19872001 return true;
19882002 }
19892003
1990−void ast_patch_ahb_2500(struct ast_device *ast)
2004+void ast_patch_ahb_2500(void __iomem *regs)
19912005 {
1992− u32 data;
2006+ u32 data;
19932007
19942008 /* Clear bus lock condition */
1995− ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
1996− ast_moutdwm(ast, 0x1e600084, 0x00010000);
1997− ast_moutdwm(ast, 0x1e600088, 0x00000000);
1998− ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
1999− data = ast_mindwm(ast, 0x1e6e2070);
2000− if (data & 0x08000000) { /* check fast reset */
2009+ __ast_moutdwm(regs, 0x1e600000, 0xAEED1A03);
2010+ __ast_moutdwm(regs, 0x1e600084, 0x00010000);
2011+ __ast_moutdwm(regs, 0x1e600088, 0x00000000);
2012+ __ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
2013+
2014+ data = __ast_mindwm(regs, 0x1e6e2070);
2015+ if (data & 0x08000000) { /* check fast reset */
20012016 /*
20022017 * If "Fast restet" is enabled for ARM-ICE debugger,
20032018 * then WDT needs to enable, that
@@ -2009,16 +2024,18 @@ void ast_patch_ahb_2500(struct ast_device *ast) · 5 unmodified lines
20092024 * [1]:= 1:WDT will be cleeared and disabled after timeout occurs
20102025 * [0]:= 1:WDT enable
20112026 */
2012− ast_moutdwm(ast, 0x1E785004, 0x00000010);
2013− ast_moutdwm(ast, 0x1E785008, 0x00004755);
2014− ast_moutdwm(ast, 0x1E78500c, 0x00000033);
2027+ __ast_moutdwm(regs, 0x1E785004, 0x00000010);
2028+ __ast_moutdwm(regs, 0x1E785008, 0x00004755);
2029+ __ast_moutdwm(regs, 0x1E78500c, 0x00000033);
20152030 udelay(1000);
20162031 }
2032+
20172033 do {
2018− ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
2019− data = ast_mindwm(ast, 0x1e6e2000);
2020− } while (data != 1);
2021− ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */
2034+ __ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
2035+ data = __ast_mindwm(regs, 0x1e6e2000);
2036+ } while (data != 1);
2037+
2038+ __ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */
20222039 }
20232040
20242041 void ast_post_chip_2500(struct drm_device *dev)
@@ -2030,7 +2047,7 @@ void ast_post_chip_2500(struct drm_device *dev) · 5 unmodified lines
20302047 reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
20312048 if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
20322049 /* Clear bus lock condition */
2033− ast_patch_ahb_2500(ast);
2050+ ast_patch_ahb_2500(ast->regs);
20342051
20352052 /* Disable watchdog */
20362053 ast_moutdwm(ast, 0x1E78502C, 0x00000000);
drivers/gpu/drm/ast/ast_reg.h+10−2
@@ -10,10 +10,17 @@ · 9 unmodified lines
1010 */
1111
1212 #define AST_IO_MM_OFFSET (0x380)
13+#define AST_IO_MM_LENGTH (128)
1314
1415 #define AST_IO_VGAARI_W (0x40)
16+
1517 #define AST_IO_VGAMR_W (0x42)
18+#define AST_IO_VGAMR_R (0x4c)
19+#define AST_IO_VGAMR_IOSEL BIT(0)
20+
1621 #define AST_IO_VGAER (0x43)
22+#define AST_IO_VGAER_VGA_ENABLE BIT(0)
23+
1724 #define AST_IO_VGASRI (0x44)
1825 #define AST_IO_VGADRR (0x47)
1926 #define AST_IO_VGADWR (0x48)
@@ -21,14 +28,15 @@ · 1 unmodified line
2128 #define AST_IO_VGAGRI (0x4E)
2229
2330 #define AST_IO_VGACRI (0x54)
31+#define AST_IO_VGACR80_PASSWORD (0xa8)
32+#define AST_IO_VGACRA1_VGAIO_DISABLED BIT(1)
33+#define AST_IO_VGACRA1_MMIO_ENABLED BIT(2)
2434 #define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */
2535 #define AST_IO_VGACRCB_HWC_ENABLED BIT(1)
2636
2737 #define AST_IO_VGAIR1_R (0x5A)
2838 #define AST_IO_VGAIR1_VREFRESH BIT(3)
2939
30−#define AST_IO_VGAMR_R (0x4C)
31−
3240 /*
3341 * Display Transmitter Type
3442 */
drivers/gpu/drm/bridge/Kconfig+17−0
@@ -12,6 +12,23 @@ config DRM_PANEL_BRIDGE · 11 unmodified lines
1212 help
1313 DRM bridge wrapper of DRM panels
1414
15+config DRM_AUX_BRIDGE
16+ tristate
17+ depends on DRM_BRIDGE && OF
18+ select AUXILIARY_BUS
19+ select DRM_PANEL_BRIDGE
20+ help
21+ Simple transparent bridge that is used by several non-DRM drivers to
22+ build bridges chain.
23+
24+config DRM_AUX_HPD_BRIDGE
25+ tristate
26+ depends on DRM_BRIDGE && OF
27+ select AUXILIARY_BUS
28+ help
29+ Simple bridge that terminates the bridge chain and provides HPD
30+ support.
31+
1532 menu "Display Interface Bridges"
1633 depends on DRM && DRM_BRIDGE
1734
drivers/gpu/drm/bridge/Makefile+2−0
@@ -1,4 +1,6 @@
11 # SPDX-License-Identifier: GPL-2.0
2+obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
3+obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
24 obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
35 obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
46 obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
drivers/gpu/drm/bridge/analogix/anx7625.c+36−18
@@ -1298,10 +1298,32 @@ static void anx7625_config(struct anx7625_data *ctx) · 1297 unmodified lines
12981298 XTAL_FRQ_SEL, XTAL_FRQ_27M);
12991299 }
13001300
1301+static int anx7625_hpd_timer_config(struct anx7625_data *ctx)
1302+{
1303+ int ret;
1304+
1305+ /* Set irq detect window to 2ms */
1306+ ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
1307+ HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF);
1308+ ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
1309+ HPD_DET_TIMER_BIT8_15,
1310+ (HPD_TIME >> 8) & 0xFF);
1311+ ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
1312+ HPD_DET_TIMER_BIT16_23,
1313+ (HPD_TIME >> 16) & 0xFF);
1314+
1315+ return ret;
1316+}
1317+
1318+static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx)
1319+{
1320+ return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, GPIO_CTRL_2);
1321+}
1322+
13011323 static void anx7625_disable_pd_protocol(struct anx7625_data *ctx)
13021324 {
13031325 struct device *dev = ctx->dev;
1304− int ret;
1326+ int ret, val;
13051327
13061328 /* Reset main ocm */
13071329 ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40);
@@ -1315,6 +1337,19 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) · 7 unmodified lines
13151337 DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n");
13161338 else
13171339 DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n");
1340+
1341+ /*
1342+ * Make sure the HPD GPIO already be configured after OCM release before
1343+ * setting HPD detect window register. Here we poll the status register
1344+ * at maximum 40ms, then config HPD irq detect window register
1345+ */
1346+ readx_poll_timeout(anx7625_read_hpd_gpio_config_status,
1347+ ctx, val,
1348+ ((val & HPD_SOURCE) || (val < 0)),
1349+ 2000, 2000 * 20);
1350+
1351+ /* Set HPD irq detect window to 2ms */
1352+ anx7625_hpd_timer_config(ctx);
13181353 }
13191354
13201355 static int anx7625_ocm_loading_check(struct anx7625_data *ctx)
@@ -1437,20 +1472,6 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) · 116 unmodified lines
14371472
14381473 static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx)
14391474 {
1440− int ret;
1441−
1442− /* Set irq detect window to 2ms */
1443− ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
1444− HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF);
1445− ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
1446− HPD_DET_TIMER_BIT8_15,
1447− (HPD_TIME >> 8) & 0xFF);
1448− ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
1449− HPD_DET_TIMER_BIT16_23,
1450− (HPD_TIME >> 16) & 0xFF);
1451− if (ret < 0)
1452− return ret;
1453−
14541475 return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
14551476 }
14561477
@@ -1464,9 +1485,6 @@ static int _anx7625_hpd_polling(struct anx7625_data *ctx, · 7 unmodified lines
14641485 if (ctx->pdata.intp_irq)
14651486 return 0;
14661487
1467− /* Delay 200ms for FW HPD de-bounce */
1468− msleep(200);
1469−
14701488 ret = readx_poll_timeout(anx7625_read_hpd_status_p0,
14711489 ctx, val,
14721490 ((val & HPD_STATUS) || (val < 0)),
drivers/gpu/drm/bridge/analogix/anx7625.h+4−0
@@ -259,6 +259,10 @@ · 258 unmodified lines
259259 #define AP_MIPI_RX_EN BIT(5) /* 1: MIPI RX input in 0: no RX in */
260260 #define AP_DISABLE_PD BIT(6)
261261 #define AP_DISABLE_DISPLAY BIT(7)
262+
263+#define GPIO_CTRL_2 0x49
264+#define HPD_SOURCE BIT(6)
265+
262266 /***************************************************************/
263267 /* Register definition of device address 0x84 */
264268 #define MIPI_PHY_CONTROL_3 0x03
drivers/gpu/drm/bridge/aux-bridge.c+140−0
@@ -0,0 +1,140 @@
1+// SPDX-License-Identifier: GPL-2.0+
2+/*
3+ * Copyright (C) 2023 Linaro Ltd.
4+ *
5+ * Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
6+ */
7+#include <linux/auxiliary_bus.h>
8+#include <linux/module.h>
9+
10+#include <drm/drm_bridge.h>
11+#include <drm/bridge/aux-bridge.h>
12+
13+static DEFINE_IDA(drm_aux_bridge_ida);
14+
15+static void drm_aux_bridge_release(struct device *dev)
16+{
17+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
18+
19+ ida_free(&drm_aux_bridge_ida, adev->id);
20+
21+ kfree(adev);
22+}
23+
24+static void drm_aux_bridge_unregister_adev(void *_adev)
25+{
26+ struct auxiliary_device *adev = _adev;
27+
28+ auxiliary_device_delete(adev);
29+ auxiliary_device_uninit(adev);
30+}
31+
32+/**
33+ * drm_aux_bridge_register - Create a simple bridge device to link the chain
34+ * @parent: device instance providing this bridge
35+ *
36+ * Creates a simple DRM bridge that doesn't implement any drm_bridge
37+ * operations. Such bridges merely fill a place in the bridge chain linking
38+ * surrounding DRM bridges.
39+ *
40+ * Return: zero on success, negative error code on failure
41+ */
42+int drm_aux_bridge_register(struct device *parent)
43+{
44+ struct auxiliary_device *adev;
45+ int ret;
46+
47+ adev = kzalloc(sizeof(*adev), GFP_KERNEL);
48+ if (!adev)
49+ return -ENOMEM;
50+
51+ ret = ida_alloc(&drm_aux_bridge_ida, GFP_KERNEL);
52+ if (ret < 0) {
53+ kfree(adev);
54+ return ret;
55+ }
56+
57+ adev->id = ret;
58+ adev->name = "aux_bridge";
59+ adev->dev.parent = parent;
60+ adev->dev.of_node = parent->of_node;
61+ adev->dev.release = drm_aux_bridge_release;
62+
63+ ret = auxiliary_device_init(adev);
64+ if (ret) {
65+ ida_free(&drm_aux_bridge_ida, adev->id);
66+ kfree(adev);
67+ return ret;
68+ }
69+
70+ ret = auxiliary_device_add(adev);
71+ if (ret) {
72+ auxiliary_device_uninit(adev);
73+ return ret;
74+ }
75+
76+ return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, adev);
77+}
78+EXPORT_SYMBOL_GPL(drm_aux_bridge_register);
79+
80+struct drm_aux_bridge_data {
81+ struct drm_bridge bridge;
82+ struct drm_bridge *next_bridge;
83+ struct device *dev;
84+};
85+
86+static int drm_aux_bridge_attach(struct drm_bridge *bridge,
87+ enum drm_bridge_attach_flags flags)
88+{
89+ struct drm_aux_bridge_data *data;
90+
91+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
92+ return -EINVAL;
93+
94+ data = container_of(bridge, struct drm_aux_bridge_data, bridge);
95+
96+ return drm_bridge_attach(bridge->encoder, data->next_bridge, bridge,
97+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
98+}
99+
100+static const struct drm_bridge_funcs drm_aux_bridge_funcs = {
101+ .attach = drm_aux_bridge_attach,
102+};
103+
104+static int drm_aux_bridge_probe(struct auxiliary_device *auxdev,
105+ const struct auxiliary_device_id *id)
106+{
107+ struct drm_aux_bridge_data *data;
108+
109+ data = devm_kzalloc(&auxdev->dev, sizeof(*data), GFP_KERNEL);
110+ if (!data)
111+ return -ENOMEM;
112+
113+ data->dev = &auxdev->dev;
114+ data->next_bridge = devm_drm_of_get_bridge(&auxdev->dev, auxdev->dev.of_node, 0, 0);
115+ if (IS_ERR(data->next_bridge))
116+ return dev_err_probe(&auxdev->dev, PTR_ERR(data->next_bridge),
117+ "failed to acquire drm_bridge\n");
118+
119+ data->bridge.funcs = &drm_aux_bridge_funcs;
120+ data->bridge.of_node = data->dev->of_node;
121+
122+ return devm_drm_bridge_add(data->dev, &data->bridge);
123+}
124+
125+static const struct auxiliary_device_id drm_aux_bridge_table[] = {
126+ { .name = KBUILD_MODNAME ".aux_bridge" },
127+ {},
128+};
129+MODULE_DEVICE_TABLE(auxiliary, drm_aux_bridge_table);
130+
131+static struct auxiliary_driver drm_aux_bridge_drv = {
132+ .name = "aux_bridge",
133+ .id_table = drm_aux_bridge_table,
134+ .probe = drm_aux_bridge_probe,
135+};
136+module_auxiliary_driver(drm_aux_bridge_drv);
137+
138+MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
139+MODULE_DESCRIPTION("DRM transparent bridge");
140+MODULE_LICENSE("GPL");
drivers/gpu/drm/bridge/aux-hpd-bridge.c+163−0
@@ -0,0 +1,163 @@
1+// SPDX-License-Identifier: GPL-2.0+
2+/*
3+ * Copyright (C) 2023 Linaro Ltd.
4+ *
5+ * Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
6+ */
7+#include <linux/auxiliary_bus.h>
8+#include <linux/module.h>
9+#include <linux/of.h>
10+
11+#include <drm/drm_bridge.h>
12+#include <drm/bridge/aux-bridge.h>
13+
14+static DEFINE_IDA(drm_aux_hpd_bridge_ida);
15+
16+struct drm_aux_hpd_bridge_data {
17+ struct drm_bridge bridge;
18+ struct device *dev;
19+};
20+
21+static void drm_aux_hpd_bridge_release(struct device *dev)
22+{
23+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
24+
25+ ida_free(&drm_aux_hpd_bridge_ida, adev->id);
26+
27+ of_node_put(adev->dev.platform_data);
28+
29+ kfree(adev);
30+}
31+
32+static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
33+{
34+ struct auxiliary_device *adev = _adev;
35+
36+ auxiliary_device_delete(adev);
37+ auxiliary_device_uninit(adev);
38+}
39+
40+/**
41+ * drm_dp_hpd_bridge_register - Create a simple HPD DisplayPort bridge
42+ * @parent: device instance providing this bridge
43+ * @np: device node pointer corresponding to this bridge instance
44+ *
45+ * Creates a simple DRM bridge with the type set to
46+ * DRM_MODE_CONNECTOR_DisplayPort, which terminates the bridge chain and is
47+ * able to send the HPD events.
48+ *
49+ * Return: device instance that will handle created bridge or an error code
50+ * encoded into the pointer.
51+ */
52+struct device *drm_dp_hpd_bridge_register(struct device *parent,
53+ struct device_node *np)
54+{
55+ struct auxiliary_device *adev;
56+ int ret;
57+
58+ adev = kzalloc(sizeof(*adev), GFP_KERNEL);
59+ if (!adev)
60+ return ERR_PTR(-ENOMEM);
61+
62+ ret = ida_alloc(&drm_aux_hpd_bridge_ida, GFP_KERNEL);
63+ if (ret < 0) {
64+ kfree(adev);
65+ return ERR_PTR(ret);
66+ }
67+
68+ adev->id = ret;
69+ adev->name = "dp_hpd_bridge";
70+ adev->dev.parent = parent;
71+ adev->dev.of_node = parent->of_node;
72+ adev->dev.release = drm_aux_hpd_bridge_release;
73+ adev->dev.platform_data = np;
74+
75+ ret = auxiliary_device_init(adev);
76+ if (ret) {
77+ ida_free(&drm_aux_hpd_bridge_ida, adev->id);
78+ kfree(adev);
79+ return ERR_PTR(ret);
80+ }
81+
82+ ret = auxiliary_device_add(adev);
83+ if (ret) {
84+ auxiliary_device_uninit(adev);
85+ return ERR_PTR(ret);
86+ }
87+
88+ ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_unregister_adev, adev);
89+ if (ret)
90+ return ERR_PTR(ret);
91+
92+ return &adev->dev;
93+}
94+EXPORT_SYMBOL_GPL(drm_dp_hpd_bridge_register);
95+
96+/**
97+ * drm_aux_hpd_bridge_notify - notify hot plug detection events
98+ * @dev: device created for the HPD bridge
99+ * @status: output connection status
100+ *
101+ * A wrapper around drm_bridge_hpd_notify() that is used to report hot plug
102+ * detection events for bridges created via drm_dp_hpd_bridge_register().
103+ *
104+ * This function shall be called in a context that can sleep.
105+ */
106+void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
107+{
108+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
109+ struct drm_aux_hpd_bridge_data *data = auxiliary_get_drvdata(adev);
110+
111+ if (!data)
112+ return;
113+
114+ drm_bridge_hpd_notify(&data->bridge, status);
115+}
116+EXPORT_SYMBOL_GPL(drm_aux_hpd_bridge_notify);
117+
118+static int drm_aux_hpd_bridge_attach(struct drm_bridge *bridge,
119+ enum drm_bridge_attach_flags flags)
120+{
121+ return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
122+}
123+
124+static const struct drm_bridge_funcs drm_aux_hpd_bridge_funcs = {
125+ .attach = drm_aux_hpd_bridge_attach,
126+};
127+
128+static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
129+ const struct auxiliary_device_id *id)
130+{
131+ struct drm_aux_hpd_bridge_data *data;
132+
133+ data = devm_kzalloc(&auxdev->dev, sizeof(*data), GFP_KERNEL);
134+ if (!data)
135+ return -ENOMEM;
136+
137+ data->dev = &auxdev->dev;
138+ data->bridge.funcs = &drm_aux_hpd_bridge_funcs;
139+ data->bridge.of_node = dev_get_platdata(data->dev);
140+ data->bridge.ops = DRM_BRIDGE_OP_HPD;
141+ data->bridge.type = id->driver_data;
142+
143+ auxiliary_set_drvdata(auxdev, data);
144+
145+ return devm_drm_bridge_add(data->dev, &data->bridge);
146+}
147+
148+static const struct auxiliary_device_id drm_aux_hpd_bridge_table[] = {
149+ { .name = KBUILD_MODNAME ".dp_hpd_bridge", .driver_data = DRM_MODE_CONNECTOR_DisplayPort, },
150+ {},
151+};
152+MODULE_DEVICE_TABLE(auxiliary, drm_aux_hpd_bridge_table);
153+
154+static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
155+ .name = "aux_hpd_bridge",
156+ .id_table = drm_aux_hpd_bridge_table,
157+ .probe = drm_aux_hpd_bridge_probe,
158+};
159+module_auxiliary_driver(drm_aux_hpd_bridge_drv);
160+
161+MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
162+MODULE_DESCRIPTION("DRM HPD bridge");
163+MODULE_LICENSE("GPL");
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c+10−12
@@ -2596,11 +2596,10 @@ clk_disable: · 2595 unmodified lines
25962596 return ret;
25972597 }
25982598
2599−static int cdns_mhdp_remove(struct platform_device *pdev)
2599+static void cdns_mhdp_remove(struct platform_device *pdev)
26002600 {
26012601 struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev);
26022602 unsigned long timeout = msecs_to_jiffies(100);
2603− bool stop_fw = false;
26042603 int ret;
26052604
26062605 drm_bridge_remove(&mhdp->bridge);
@@ -2608,18 +2607,19 @@ static int cdns_mhdp_remove(struct platform_device *pdev) · 1 unmodified line
26082607 ret = wait_event_timeout(mhdp->fw_load_wq,
26092608 mhdp->hw_state == MHDP_HW_READY,
26102609 timeout);
2611− if (ret == 0)
2612− dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n",
2613− __func__);
2614− else
2615− stop_fw = true;
2616−
26172610 spin_lock(&mhdp->start_lock);
26182611 mhdp->hw_state = MHDP_HW_STOPPED;
26192612 spin_unlock(&mhdp->start_lock);
26202613
2621− if (stop_fw)
2614+ if (ret == 0) {
2615+ dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n",
2616+ __func__);
2617+ } else {
26222618 ret = cdns_mhdp_set_firmware_active(mhdp, false);
2619+ if (ret)
2620+ dev_err(mhdp->dev, "Failed to stop firmware (%pe)\n",
2621+ ERR_PTR(ret));
2622+ }
26232623
26242624 phy_exit(mhdp->phy);
26252625
@@ -2634,8 +2634,6 @@ static int cdns_mhdp_remove(struct platform_device *pdev) · 8 unmodified lines
26342634 /* Ignoring mhdp->hdcp.check_work and mhdp->hdcp.prop_work here. */
26352635
26362636 clk_disable_unprepare(mhdp->clk);
2637−
2638− return ret;
26392637 }
26402638
26412639 static const struct of_device_id mhdp_ids[] = {
@@ -2658,7 +2656,7 @@ static struct platform_driver mhdp_driver = { · 16 unmodified lines
26582656 .of_match_table = mhdp_ids,
26592657 },
26602658 .probe = cdns_mhdp_probe,
2661− .remove = cdns_mhdp_remove,
2659+ .remove_new = cdns_mhdp_remove,
26622660 };
26632661 module_platform_driver(mhdp_driver);
26642662
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c+2−1
@@ -403,7 +403,8 @@ static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp) · 402 unmodified lines
403403
404404 static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type)
405405 {
406− int ret, tries = 3;
406+ int ret = -EINVAL;
407+ int tries = 3;
407408 u32 i;
408409
409410 for (i = 0; i < tries; i++) {
drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c+2−2
@@ -226,8 +226,8 @@ dphy_pll_get_configure_from_opts(struct imx93_dsi *dsi, · 225 unmodified lines
226226 unsigned long fout;
227227 unsigned long best_fout = 0;
228228 unsigned int fvco_div;
229− unsigned int min_n, max_n, n, best_n;
230− unsigned long m, best_m;
229+ unsigned int min_n, max_n, n, best_n = UINT_MAX;
230+ unsigned long m, best_m = 0;
231231 unsigned long min_delta = ULONG_MAX;
232232 unsigned long delta;
233233 u64 tmp;
drivers/gpu/drm/bridge/lontium-lt8912b.c+58−0
@@ -43,6 +43,8 @@ struct lt8912 { · 42 unmodified lines
4343
4444 struct videomode mode;
4545
46+ struct regulator_bulk_data supplies[7];
47+
4648 u8 data_lanes;
4749 bool is_power_on;
4850 };
@@ -257,6 +259,12 @@ static int lt8912_free_i2c(struct lt8912 *lt) · 208 unmodified lines
257259
258260 static int lt8912_hard_power_on(struct lt8912 *lt)
259261 {
262+ int ret;
263+
264+ ret = regulator_bulk_enable(ARRAY_SIZE(lt->supplies), lt->supplies);
265+ if (ret)
266+ return ret;
267+
260268 gpiod_set_value_cansleep(lt->gp_reset, 0);
261269 msleep(20);
262270
@@ -267,6 +275,9 @@ static void lt8912_hard_power_off(struct lt8912 *lt) · 4 unmodified lines
267275 {
268276 gpiod_set_value_cansleep(lt->gp_reset, 1);
269277 msleep(20);
278+
279+ regulator_bulk_disable(ARRAY_SIZE(lt->supplies), lt->supplies);
280+
270281 lt->is_power_on = false;
271282 }
272283
@@ -634,6 +645,48 @@ static const struct drm_bridge_funcs lt8912_bridge_funcs = { · 361 unmodified lines
634645 .get_edid = lt8912_bridge_get_edid,
635646 };
636647
648+static int lt8912_bridge_resume(struct device *dev)
649+{
650+ struct lt8912 *lt = dev_get_drvdata(dev);
651+ int ret;
652+
653+ ret = lt8912_hard_power_on(lt);
654+ if (ret)
655+ return ret;
656+
657+ ret = lt8912_soft_power_on(lt);
658+ if (ret)
659+ return ret;
660+
661+ return lt8912_video_on(lt);
662+}
663+
664+static int lt8912_bridge_suspend(struct device *dev)
665+{
666+ struct lt8912 *lt = dev_get_drvdata(dev);
667+
668+ lt8912_hard_power_off(lt);
669+
670+ return 0;
671+}
672+
673+static DEFINE_SIMPLE_DEV_PM_OPS(lt8912_bridge_pm_ops, lt8912_bridge_suspend, lt8912_bridge_resume);
674+
675+static int lt8912_get_regulators(struct lt8912 *lt)
676+{
677+ unsigned int i;
678+ const char * const supply_names[] = {
679+ "vdd", "vccmipirx", "vccsysclk", "vcclvdstx",
680+ "vcchdmitx", "vcclvdspll", "vcchdmipll"
681+ };
682+
683+ for (i = 0; i < ARRAY_SIZE(lt->supplies); i++)
684+ lt->supplies[i].supply = supply_names[i];
685+
686+ return devm_regulator_bulk_get(lt->dev, ARRAY_SIZE(lt->supplies),
687+ lt->supplies);
688+}
689+
637690 static int lt8912_parse_dt(struct lt8912 *lt)
638691 {
639692 struct gpio_desc *gp_reset;
@@ -685,6 +738,10 @@ static int lt8912_parse_dt(struct lt8912 *lt) · 45 unmodified lines
685738 goto err_free_host_node;
686739 }
687740
741+ ret = lt8912_get_regulators(lt);
742+ if (ret)
743+ goto err_free_host_node;
744+
688745 of_node_put(port_node);
689746 return 0;
690747
@@ -770,6 +827,7 @@ static struct i2c_driver lt8912_i2c_driver = { · 79 unmodified lines
770827 .driver = {
771828 .name = "lt8912",
772829 .of_match_table = lt8912_dt_match,
830+ .pm = pm_sleep_ptr(&lt8912_bridge_pm_ops),
773831 },
774832 .probe = lt8912_probe,
775833 .remove = lt8912_remove,
drivers/gpu/drm/bridge/nxp-ptn3460.c+3−3
@@ -54,13 +54,13 @@ static int ptn3460_read_bytes(struct ptn3460_bridge *ptn_bridge, char addr, · 53 unmodified lines
5454 int ret;
5555
5656 ret = i2c_master_send(ptn_bridge->client, &addr, 1);
57− if (ret <= 0) {
57+ if (ret < 0) {
5858 DRM_ERROR("Failed to send i2c command, ret=%d\n", ret);
5959 return ret;
6060 }
6161
6262 ret = i2c_master_recv(ptn_bridge->client, buf, len);
63− if (ret <= 0) {
63+ if (ret < 0) {
6464 DRM_ERROR("Failed to recv i2c data, ret=%d\n", ret);
6565 return ret;
6666 }
@@ -78,7 +78,7 @@ static int ptn3460_write_byte(struct ptn3460_bridge *ptn_bridge, char addr, · 11 unmodified lines
7878 buf[1] = val;
7979
8080 ret = i2c_master_send(ptn_bridge->client, buf, ARRAY_SIZE(buf));
81− if (ret <= 0) {
81+ if (ret < 0) {
8282 DRM_ERROR("Failed to send i2c command, ret=%d\n", ret);
8383 return ret;
8484 }
drivers/gpu/drm/bridge/tc358767.c+1−1
@@ -2273,7 +2273,7 @@ static int tc_probe(struct i2c_client *client) · 2272 unmodified lines
22732273 } else {
22742274 if (tc->hpd_pin < 0 || tc->hpd_pin > 1) {
22752275 dev_err(dev, "failed to parse HPD number\n");
2276− return ret;
2276+ return -EINVAL;
22772277 }
22782278 }
22792279
drivers/gpu/drm/bridge/ti-sn65dsi86.c+2−4
@@ -1413,11 +1413,9 @@ static int ti_sn_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, · 1412 unmodified lines
14131413 int ret;
14141414
14151415 if (!pdata->pwm_enabled) {
1416− ret = pm_runtime_get_sync(pdata->dev);
1417− if (ret < 0) {
1418− pm_runtime_put_sync(pdata->dev);
1416+ ret = pm_runtime_resume_and_get(pdata->dev);
1417+ if (ret < 0)
14191418 return ret;
1420− }
14211419 }
14221420
14231421 if (state->enabled) {
drivers/gpu/drm/bridge/ti-tpd12s015.c+2−4
@@ -179,13 +179,11 @@ static int tpd12s015_probe(struct platform_device *pdev) · 178 unmodified lines
179179 return 0;
180180 }
181181
182−static int __exit tpd12s015_remove(struct platform_device *pdev)
182+static void tpd12s015_remove(struct platform_device *pdev)
183183 {
184184 struct tpd12s015_device *tpd = platform_get_drvdata(pdev);
185185
186186 drm_bridge_remove(&tpd->bridge);
187−
188− return 0;
189187 }
190188
191189 static const struct of_device_id tpd12s015_of_match[] = {
@@ -197,7 +195,7 @@ MODULE_DEVICE_TABLE(of, tpd12s015_of_match); · 5 unmodified lines
197195
198196 static struct platform_driver tpd12s015_driver = {
199197 .probe = tpd12s015_probe,
200− .remove = __exit_p(tpd12s015_remove),
198+ .remove_new = tpd12s015_remove,
201199 .driver = {
202200 .name = "tpd12s015",
203201 .of_match_table = tpd12s015_of_match,
drivers/gpu/drm/ci/xfails/requirements.txt+3−3
@@ -5,7 +5,7 @@ termcolor==2.3.0 · 4 unmodified lines
55 certifi==2023.7.22
66 charset-normalizer==3.2.0
77 idna==3.4
8−pip==23.2.1
8+pip==23.3
99 python-gitlab==3.15.0
1010 requests==2.31.0
1111 requests-toolbelt==1.0.0
@@ -13,5 +13,5 @@ ruamel.yaml==0.17.32 · 1 unmodified line
1313 ruamel.yaml.clib==0.2.7
1414 setuptools==68.0.0
1515 tenacity==8.2.3
16−urllib3==2.0.4
17−wheel==0.41.1
16+urllib3==2.0.7
17+wheel==0.41.1
drivers/gpu/drm/display/drm_dp_helper.c+161−0
@@ -2245,6 +2245,8 @@ static const struct dpcd_quirk dpcd_quirk_list[] = { · 2244 unmodified lines
22452245 { OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) },
22462246 /* Synaptics DP1.4 MST hubs can support DSC without virtual DPCD */
22472247 { OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
2248+ /* Synaptics DP1.4 MST hubs require DSC for some modes on which it applies HBLANK expansion. */
2249+ { OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC) },
22482250 /* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low DP_MAX_LINK_RATE */
22492251 { OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) },
22502252 };
@@ -2326,6 +2328,33 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, · 75 unmodified lines
23262328 }
23272329 EXPORT_SYMBOL(drm_dp_read_desc);
23282330
2331+/**
2332+ * drm_dp_dsc_sink_bpp_incr() - Get bits per pixel increment
2333+ * @dsc_dpcd: DSC capabilities from DPCD
2334+ *
2335+ * Returns the bpp precision supported by the DP sink.
2336+ */
2337+u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
2338+{
2339+ u8 bpp_increment_dpcd = dsc_dpcd[DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT];
2340+
2341+ switch (bpp_increment_dpcd) {
2342+ case DP_DSC_BITS_PER_PIXEL_1_16:
2343+ return 16;
2344+ case DP_DSC_BITS_PER_PIXEL_1_8:
2345+ return 8;
2346+ case DP_DSC_BITS_PER_PIXEL_1_4:
2347+ return 4;
2348+ case DP_DSC_BITS_PER_PIXEL_1_2:
2349+ return 2;
2350+ case DP_DSC_BITS_PER_PIXEL_1_1:
2351+ return 1;
2352+ }
2353+
2354+ return 0;
2355+}
2356+EXPORT_SYMBOL(drm_dp_dsc_sink_bpp_incr);
2357+
23292358 /**
23302359 * drm_dp_dsc_sink_max_slice_count() - Get the max slice count
23312360 * supported by the DSC sink.
@@ -3898,3 +3927,135 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) · 1566 unmodified lines
38983927 EXPORT_SYMBOL(drm_panel_dp_aux_backlight);
38993928
39003929 #endif
3930+
3931+/* See DP Standard v2.1 2.6.4.4.1.1, 2.8.4.4, 2.8.7 */
3932+static int drm_dp_link_symbol_cycles(int lane_count, int pixels, int bpp_x16,
3933+ int symbol_size, bool is_mst)
3934+{
3935+ int cycles = DIV_ROUND_UP(pixels * bpp_x16, 16 * symbol_size * lane_count);
3936+ int align = is_mst ? 4 / lane_count : 1;
3937+
3938+ return ALIGN(cycles, align);
3939+}
3940+
3941+static int drm_dp_link_dsc_symbol_cycles(int lane_count, int pixels, int slice_count,
3942+ int bpp_x16, int symbol_size, bool is_mst)
3943+{
3944+ int slice_pixels = DIV_ROUND_UP(pixels, slice_count);
3945+ int slice_data_cycles = drm_dp_link_symbol_cycles(lane_count, slice_pixels,
3946+ bpp_x16, symbol_size, is_mst);
3947+ int slice_eoc_cycles = is_mst ? 4 / lane_count : 1;
3948+
3949+ return slice_count * (slice_data_cycles + slice_eoc_cycles);
3950+}
3951+
3952+/**
3953+ * drm_dp_bw_overhead - Calculate the BW overhead of a DP link stream
3954+ * @lane_count: DP link lane count
3955+ * @hactive: pixel count of the active period in one scanline of the stream
3956+ * @dsc_slice_count: DSC slice count if @flags/DRM_DP_LINK_BW_OVERHEAD_DSC is set
3957+ * @bpp_x16: bits per pixel in .4 binary fixed point
3958+ * @flags: DRM_DP_OVERHEAD_x flags
3959+ *
3960+ * Calculate the BW allocation overhead of a DP link stream, depending
3961+ * on the link's
3962+ * - @lane_count
3963+ * - SST/MST mode (@flags / %DRM_DP_OVERHEAD_MST)
3964+ * - symbol size (@flags / %DRM_DP_OVERHEAD_UHBR)
3965+ * - FEC mode (@flags / %DRM_DP_OVERHEAD_FEC)
3966+ * - SSC/REF_CLK mode (@flags / %DRM_DP_OVERHEAD_SSC_REF_CLK)
3967+ * as well as the stream's
3968+ * - @hactive timing
3969+ * - @bpp_x16 color depth
3970+ * - compression mode (@flags / %DRM_DP_OVERHEAD_DSC).
3971+ * Note that this overhead doesn't account for the 8b/10b, 128b/132b
3972+ * channel coding efficiency, for that see
3973+ * @drm_dp_link_bw_channel_coding_efficiency().
3974+ *
3975+ * Returns the overhead as 100% + overhead% in 1ppm units.
3976+ */
3977+int drm_dp_bw_overhead(int lane_count, int hactive,
3978+ int dsc_slice_count,
3979+ int bpp_x16, unsigned long flags)
3980+{
3981+ int symbol_size = flags & DRM_DP_BW_OVERHEAD_UHBR ? 32 : 8;
3982+ bool is_mst = flags & DRM_DP_BW_OVERHEAD_MST;
3983+ u32 overhead = 1000000;
3984+ int symbol_cycles;
3985+
3986+ /*
3987+ * DP Standard v2.1 2.6.4.1
3988+ * SSC downspread and ref clock variation margin:
3989+ * 5300ppm + 300ppm ~ 0.6%
3990+ */
3991+ if (flags & DRM_DP_BW_OVERHEAD_SSC_REF_CLK)
3992+ overhead += 6000;
3993+
3994+ /*
3995+ * DP Standard v2.1 2.6.4.1.1, 3.5.1.5.4:
3996+ * FEC symbol insertions for 8b/10b channel coding:
3997+ * After each 250 data symbols on 2-4 lanes:
3998+ * 250 LL + 5 FEC_PARITY_PH + 1 CD_ADJ (256 byte FEC block)
3999+ * After each 2 x 250 data symbols on 1 lane:
4000+ * 2 * 250 LL + 11 FEC_PARITY_PH + 1 CD_ADJ (512 byte FEC block)
4001+ * After 256 (2-4 lanes) or 128 (1 lane) FEC blocks:
4002+ * 256 * 256 bytes + 1 FEC_PM
4003+ * or
4004+ * 128 * 512 bytes + 1 FEC_PM
4005+ * (256 * 6 + 1) / (256 * 250) = 2.4015625 %
4006+ */
4007+ if (flags & DRM_DP_BW_OVERHEAD_FEC)
4008+ overhead += 24016;
4009+
4010+ /*
4011+ * DP Standard v2.1 2.7.9, 5.9.7
4012+ * The FEC overhead for UHBR is accounted for in its 96.71% channel
4013+ * coding efficiency.
4014+ */
4015+ WARN_ON((flags & DRM_DP_BW_OVERHEAD_UHBR) &&
4016+ (flags & DRM_DP_BW_OVERHEAD_FEC));
4017+
4018+ if (flags & DRM_DP_BW_OVERHEAD_DSC)
4019+ symbol_cycles = drm_dp_link_dsc_symbol_cycles(lane_count, hactive,
4020+ dsc_slice_count,
4021+ bpp_x16, symbol_size,
4022+ is_mst);
4023+ else
4024+ symbol_cycles = drm_dp_link_symbol_cycles(lane_count, hactive,
4025+ bpp_x16, symbol_size,
4026+ is_mst);
4027+
4028+ return DIV_ROUND_UP_ULL(mul_u32_u32(symbol_cycles * symbol_size * lane_count,
4029+ overhead * 16),
4030+ hactive * bpp_x16);
4031+}
4032+EXPORT_SYMBOL(drm_dp_bw_overhead);
4033+
4034+/**
4035+ * drm_dp_bw_channel_coding_efficiency - Get a DP link's channel coding efficiency
4036+ * @is_uhbr: Whether the link has a 128b/132b channel coding
4037+ *
4038+ * Return the channel coding efficiency of the given DP link type, which is
4039+ * either 8b/10b or 128b/132b (aka UHBR). The corresponding overhead includes
4040+ * the 8b -> 10b, 128b -> 132b pixel data to link symbol conversion overhead
4041+ * and for 128b/132b any link or PHY level control symbol insertion overhead
4042+ * (LLCP, FEC, PHY sync, see DP Standard v2.1 3.5.2.18). For 8b/10b the
4043+ * corresponding FEC overhead is BW allocation specific, included in the value
4044+ * returned by drm_dp_bw_overhead().
4045+ *
4046+ * Returns the efficiency in the 100%/coding-overhead% ratio in
4047+ * 1ppm units.
4048+ */
4049+int drm_dp_bw_channel_coding_efficiency(bool is_uhbr)
4050+{
4051+ if (is_uhbr)
4052+ return 967100;
4053+ else
4054+ /*
4055+ * Note that on 8b/10b MST the efficiency is only
4056+ * 78.75% due to the 1 out of 64 MTPH packet overhead,
4057+ * not accounted for here.
4058+ */
4059+ return 800000;
4060+}
4061+EXPORT_SYMBOL(drm_dp_bw_channel_coding_efficiency);
drivers/gpu/drm/display/drm_dp_mst_topology.c+181−53
@@ -43,6 +43,7 @@ · 42 unmodified lines
4343 #include <drm/drm_atomic_helper.h>
4444 #include <drm/drm_drv.h>
4545 #include <drm/drm_edid.h>
46+#include <drm/drm_fixed.h>
4647 #include <drm/drm_print.h>
4748 #include <drm/drm_probe_helper.h>
4849
@@ -3578,16 +3579,26 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, · 3529 unmodified lines
35783579 * value is in units of PBNs/(timeslots/1 MTP). This value can be used to
35793580 * convert the number of PBNs required for a given stream to the number of
35803581 * timeslots this stream requires in each MTP.
3582+ *
3583+ * Returns the BW / timeslot value in 20.12 fixed point format.
35813584 */
3582−int drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,
3583− int link_rate, int link_lane_count)
3585+fixed20_12 drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,
3586+ int link_rate, int link_lane_count)
35843587 {
3588+ int ch_coding_efficiency =
3589+ drm_dp_bw_channel_coding_efficiency(drm_dp_is_uhbr_rate(link_rate));
3590+ fixed20_12 ret;
3591+
35853592 if (link_rate == 0 || link_lane_count == 0)
35863593 drm_dbg_kms(mgr->dev, "invalid link rate/lane count: (%d / %d)\n",
35873594 link_rate, link_lane_count);
35883595
3589− /* See DP v2.0 2.6.4.2, VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */
3590− return link_rate * link_lane_count / 54000;
3596+ /* See DP v2.0 2.6.4.2, 2.7.6.3 VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */
3597+ ret.full = DIV_ROUND_DOWN_ULL(mul_u32_u32(link_rate * link_lane_count,
3598+ ch_coding_efficiency),
3599+ (1000000ULL * 8 * 5400) >> 12);
3600+
3601+ return ret;
35913602 }
35923603 EXPORT_SYMBOL(drm_dp_get_vc_payload_bw);
35933604
@@ -4335,7 +4346,7 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, · 741 unmodified lines
43354346 }
43364347 }
43374348
4338− req_slots = DIV_ROUND_UP(pbn, topology_state->pbn_div);
4349+ req_slots = DIV_ROUND_UP(dfixed_const(pbn), topology_state->pbn_div.full);
43394350
43404351 drm_dbg_atomic(mgr->dev, "[CONNECTOR:%d:%s] [MST PORT:%p] TU %d -> %d\n",
43414352 port->connector->base.id, port->connector->name,
@@ -4718,35 +4729,36 @@ EXPORT_SYMBOL(drm_dp_check_act_status); · 376 unmodified lines
47184729
47194730 /**
47204731 * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode.
4721− * @clock: dot clock for the mode
4722− * @bpp: bpp for the mode.
4723− * @dsc: DSC mode. If true, bpp has units of 1/16 of a bit per pixel
4732+ * @clock: dot clock
4733+ * @bpp: bpp as .4 binary fixed point
47244734 *
47254735 * This uses the formula in the spec to calculate the PBN value for a mode.
47264736 */
4727−int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc)
4737+int drm_dp_calc_pbn_mode(int clock, int bpp)
47284738 {
47294739 /*
4730− * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
47314740 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
47324741 * common multiplier to render an integer PBN for all link rate/lane
47334742 * counts combinations
47344743 * calculate
4735− * peak_kbps *= (1006/1000)
4736− * peak_kbps *= (64/54)
4737− * peak_kbps *= 8 convert to bytes
4738− *
4739− * If the bpp is in units of 1/16, further divide by 16. Put this
4740− * factor in the numerator rather than the denominator to avoid
4741− * integer overflow
4744+ * peak_kbps = clock * bpp / 16
4745+ * peak_kbps *= SSC overhead / 1000000
4746+ * peak_kbps /= 8 convert to Kbytes
4747+ * peak_kBps *= (64/54) / 1000 convert to PBN
47424748 */
4749+ /*
4750+ * TODO: Use the actual link and mode parameters to calculate
4751+ * the overhead. For now it's assumed that these are
4752+ * 4 link lanes, 4096 hactive pixels, which don't add any
4753+ * significant data padding overhead and that there is no DSC
4754+ * or FEC overhead.
4755+ */
4756+ int overhead = drm_dp_bw_overhead(4, 4096, 0, bpp,
4757+ DRM_DP_BW_OVERHEAD_MST |
4758+ DRM_DP_BW_OVERHEAD_SSC_REF_CLK);
47434759
4744− if (dsc)
4745− return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 1006),
4746− 8 * 54 * 1000 * 1000);
4747−
4748− return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006),
4749− 8 * 54 * 1000 * 1000);
4760+ return DIV64_U64_ROUND_UP(mul_u32_u32(clock * bpp, 64 * overhead >> 4),
4761+ 1000000ULL * 8 * 54 * 1000);
47504762 }
47514763 EXPORT_SYMBOL(drm_dp_calc_pbn_mode);
47524764
@@ -4871,7 +4883,8 @@ void drm_dp_mst_dump_topology(struct seq_file *m, · 118 unmodified lines
48714883 state = to_drm_dp_mst_topology_state(mgr->base.state);
48724884 seq_printf(m, "\n*** Atomic state info ***\n");
48734885 seq_printf(m, "payload_mask: %x, max_payloads: %d, start_slot: %u, pbn_div: %d\n",
4874− state->payload_mask, mgr->max_payloads, state->start_slot, state->pbn_div);
4886+ state->payload_mask, mgr->max_payloads, state->start_slot,
4887+ dfixed_trunc(state->pbn_div));
48754888
48764889 seq_printf(m, "\n| idx | port | vcpi | slots | pbn | dsc | status | sink name |\n");
48774890 for (i = 0; i < mgr->max_payloads; i++) {
@@ -5136,13 +5149,67 @@ static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port, · 258 unmodified lines
51365149 return false;
51375150 }
51385151
5152+static bool
5153+drm_dp_mst_port_downstream_of_parent_locked(struct drm_dp_mst_topology_mgr *mgr,
5154+ struct drm_dp_mst_port *port,
5155+ struct drm_dp_mst_port *parent)
5156+{
5157+ if (!mgr->mst_primary)
5158+ return false;
5159+
5160+ port = drm_dp_mst_topology_get_port_validated_locked(mgr->mst_primary,
5161+ port);
5162+ if (!port)
5163+ return false;
5164+
5165+ if (!parent)
5166+ return true;
5167+
5168+ parent = drm_dp_mst_topology_get_port_validated_locked(mgr->mst_primary,
5169+ parent);
5170+ if (!parent)
5171+ return false;
5172+
5173+ if (!parent->mstb)
5174+ return false;
5175+
5176+ return drm_dp_mst_port_downstream_of_branch(port, parent->mstb);
5177+}
5178+
5179+/**
5180+ * drm_dp_mst_port_downstream_of_parent - check if a port is downstream of a parent port
5181+ * @mgr: MST topology manager
5182+ * @port: the port being looked up
5183+ * @parent: the parent port
5184+ *
5185+ * The function returns %true if @port is downstream of @parent. If @parent is
5186+ * %NULL - denoting the root port - the function returns %true if @port is in
5187+ * @mgr's topology.
5188+ */
5189+bool
5190+drm_dp_mst_port_downstream_of_parent(struct drm_dp_mst_topology_mgr *mgr,
5191+ struct drm_dp_mst_port *port,
5192+ struct drm_dp_mst_port *parent)
5193+{
5194+ bool ret;
5195+
5196+ mutex_lock(&mgr->lock);
5197+ ret = drm_dp_mst_port_downstream_of_parent_locked(mgr, port, parent);
5198+ mutex_unlock(&mgr->lock);
5199+
5200+ return ret;
5201+}
5202+EXPORT_SYMBOL(drm_dp_mst_port_downstream_of_parent);
5203+
51395204 static int
51405205 drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
5141− struct drm_dp_mst_topology_state *state);
5206+ struct drm_dp_mst_topology_state *state,
5207+ struct drm_dp_mst_port **failing_port);
51425208
51435209 static int
51445210 drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb,
5145− struct drm_dp_mst_topology_state *state)
5211+ struct drm_dp_mst_topology_state *state,
5212+ struct drm_dp_mst_port **failing_port)
51465213 {
51475214 struct drm_dp_mst_atomic_payload *payload;
51485215 struct drm_dp_mst_port *port;
@@ -5171,7 +5238,7 @@ drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, · 22 unmodified lines
51715238 drm_dbg_atomic(mstb->mgr->dev, "[MSTB:%p] Checking bandwidth limits\n", mstb);
51725239
51735240 list_for_each_entry(port, &mstb->ports, next) {
5174− ret = drm_dp_mst_atomic_check_port_bw_limit(port, state);
5241+ ret = drm_dp_mst_atomic_check_port_bw_limit(port, state, failing_port);
51755242 if (ret < 0)
51765243 return ret;
51775244
@@ -5183,7 +5250,8 @@ drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, · 5 unmodified lines
51835250
51845251 static int
51855252 drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
5186− struct drm_dp_mst_topology_state *state)
5253+ struct drm_dp_mst_topology_state *state,
5254+ struct drm_dp_mst_port **failing_port)
51875255 {
51885256 struct drm_dp_mst_atomic_payload *payload;
51895257 int pbn_used = 0;
@@ -5204,13 +5272,15 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, · 14 unmodified lines
52045272 drm_dbg_atomic(port->mgr->dev,
52055273 "[MSTB:%p] [MST PORT:%p] no BW available for the port\n",
52065274 port->parent, port);
5275+ *failing_port = port;
52075276 return -EINVAL;
52085277 }
52095278
52105279 pbn_used = payload->pbn;
52115280 } else {
52125281 pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb,
5213− state);
5282+ state,
5283+ failing_port);
52145284 if (pbn_used <= 0)
52155285 return pbn_used;
52165286 }
@@ -5219,6 +5289,7 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, · 2 unmodified lines
52195289 drm_dbg_atomic(port->mgr->dev,
52205290 "[MSTB:%p] [MST PORT:%p] required PBN of %d exceeds port limit of %d\n",
52215291 port->parent, port, pbn_used, port->full_pbn);
5292+ *failing_port = port;
52225293 return -ENOSPC;
52235294 }
52245295
@@ -5271,10 +5342,10 @@ drm_dp_mst_atomic_check_payload_alloc_limits(struct drm_dp_mst_topology_mgr *mgr · 46 unmodified lines
52715342 }
52725343
52735344 if (!payload_count)
5274− mst_state->pbn_div = 0;
5345+ mst_state->pbn_div.full = dfixed_const(0);
52755346
52765347 drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p TU pbn_div=%d avail=%d used=%d\n",
5277− mgr, mst_state, mst_state->pbn_div, avail_slots,
5348+ mgr, mst_state, dfixed_trunc(mst_state->pbn_div), avail_slots,
52785349 mst_state->total_avail_slots - avail_slots);
52795350
52805351 return 0;
@@ -5396,20 +5467,82 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, · 115 unmodified lines
53965467 }
53975468 EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc);
53985469
5470+/**
5471+ * drm_dp_mst_atomic_check_mgr - Check the atomic state of an MST topology manager
5472+ * @state: The global atomic state
5473+ * @mgr: Manager to check
5474+ * @mst_state: The MST atomic state for @mgr
5475+ * @failing_port: Returns the port with a BW limitation
5476+ *
5477+ * Checks the given MST manager's topology state for an atomic update to ensure
5478+ * that it's valid. This includes checking whether there's enough bandwidth to
5479+ * support the new timeslot allocations in the atomic update.
5480+ *
5481+ * Any atomic drivers supporting DP MST must make sure to call this or
5482+ * the drm_dp_mst_atomic_check() function after checking the rest of their state
5483+ * in their &drm_mode_config_funcs.atomic_check() callback.
5484+ *
5485+ * See also:
5486+ * drm_dp_mst_atomic_check()
5487+ * drm_dp_atomic_find_time_slots()
5488+ * drm_dp_atomic_release_time_slots()
5489+ *
5490+ * Returns:
5491+ * - 0 if the new state is valid
5492+ * - %-ENOSPC, if the new state is invalid, because of BW limitation
5493+ * @failing_port is set to:
5494+ * - The non-root port where a BW limit check failed
5495+ * with all the ports downstream of @failing_port passing
5496+ * the BW limit check.
5497+ * The returned port pointer is valid until at least
5498+ * one payload downstream of it exists.
5499+ * - %NULL if the BW limit check failed at the root port
5500+ * with all the ports downstream of the root port passing
5501+ * the BW limit check.
5502+ * - %-EINVAL, if the new state is invalid, because the root port has
5503+ * too many payloads.
5504+ */
5505+int drm_dp_mst_atomic_check_mgr(struct drm_atomic_state *state,
5506+ struct drm_dp_mst_topology_mgr *mgr,
5507+ struct drm_dp_mst_topology_state *mst_state,
5508+ struct drm_dp_mst_port **failing_port)
5509+{
5510+ int ret;
5511+
5512+ *failing_port = NULL;
5513+
5514+ if (!mgr->mst_state)
5515+ return 0;
5516+
5517+ mutex_lock(&mgr->lock);
5518+ ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
5519+ mst_state,
5520+ failing_port);
5521+ mutex_unlock(&mgr->lock);
5522+
5523+ if (ret < 0)
5524+ return ret;
5525+
5526+ return drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state);
5527+}
5528+EXPORT_SYMBOL(drm_dp_mst_atomic_check_mgr);
5529+
53995530 /**
54005531 * drm_dp_mst_atomic_check - Check that the new state of an MST topology in an
54015532 * atomic update is valid
54025533 * @state: Pointer to the new &struct drm_dp_mst_topology_state
54035534 *
54045535 * Checks the given topology state for an atomic update to ensure that it's
5405− * valid. This includes checking whether there's enough bandwidth to support
5406− * the new timeslot allocations in the atomic update.
5536+ * valid, calling drm_dp_mst_atomic_check_mgr() for all MST manager in the
5537+ * atomic state. This includes checking whether there's enough bandwidth to
5538+ * support the new timeslot allocations in the atomic update.
54075539 *
54085540 * Any atomic drivers supporting DP MST must make sure to call this after
54095541 * checking the rest of their state in their
54105542 * &drm_mode_config_funcs.atomic_check() callback.
54115543 *
54125544 * See also:
5545+ * drm_dp_mst_atomic_check_mgr()
54135546 * drm_dp_atomic_find_time_slots()
54145547 * drm_dp_atomic_release_time_slots()
54155548 *
@@ -5424,21 +5557,11 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state) · 8 unmodified lines
54245557 int i, ret = 0;
54255558
54265559 for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
5427− if (!mgr->mst_state)
5428− continue;
5560+ struct drm_dp_mst_port *tmp_port;
54295561
5430− ret = drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state);
5562+ ret = drm_dp_mst_atomic_check_mgr(state, mgr, mst_state, &tmp_port);
54315563 if (ret)
54325564 break;
5433−
5434− mutex_lock(&mgr->lock);
5435− ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
5436− mst_state);
5437− mutex_unlock(&mgr->lock);
5438− if (ret < 0)
5439− break;
5440− else
5441− ret = 0;
54425565 }
54435566
54445567 return ret;
@@ -5894,6 +6017,7 @@ static bool drm_dp_mst_is_virtual_dpcd(struct drm_dp_mst_port *port) · 449 unmodified lines
58946017 struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
58956018 {
58966019 struct drm_dp_mst_port *immediate_upstream_port;
6020+ struct drm_dp_aux *immediate_upstream_aux;
58976021 struct drm_dp_mst_port *fec_port;
58986022 struct drm_dp_desc desc = {};
58996023 u8 endpoint_fec;
@@ -5958,21 +6082,25 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) · 58 unmodified lines
59586082 * - Port is on primary branch device
59596083 * - Not a VGA adapter (DP_DWN_STRM_PORT_TYPE_ANALOG)
59606084 */
5961− if (drm_dp_read_desc(port->mgr->aux, &desc, true))
6085+ if (immediate_upstream_port)
6086+ immediate_upstream_aux = &immediate_upstream_port->aux;
6087+ else
6088+ immediate_upstream_aux = port->mgr->aux;
6089+
6090+ if (drm_dp_read_desc(immediate_upstream_aux, &desc, true))
59626091 return NULL;
59636092
5964− if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) &&
5965− port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
5966− port->parent == port->mgr->mst_primary) {
6093+ if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) {
59676094 u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
59686095
5969− if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
6096+ if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0)
59706097 return NULL;
59716098
5972− if ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) &&
6099+ if (dpcd_ext[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
6100+ ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) &&
59736101 ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK)
5974− != DP_DWN_STRM_PORT_TYPE_ANALOG))
5975− return port->mgr->aux;
6102+ != DP_DWN_STRM_PORT_TYPE_ANALOG)))
6103+ return immediate_upstream_aux;
59766104 }
59776105
59786106 /*
drivers/gpu/drm/drm_agpsupport.c+0−451
@@ -1,451 +0,0 @@
1−/*
2− * \file drm_agpsupport.c
3− * DRM support for AGP/GART backend
4− *
5− * \author Rickard E. (Rik) Faith <faith@valinux.com>
6− * \author Gareth Hughes <gareth@valinux.com>
7− */
8−
9−/*
10− * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11− * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12− * All Rights Reserved.
13− *
14− * Permission is hereby granted, free of charge, to any person obtaining a
15− * copy of this software and associated documentation files (the "Software"),
16− * to deal in the Software without restriction, including without limitation
17− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18− * and/or sell copies of the Software, and to permit persons to whom the
19− * Software is furnished to do so, subject to the following conditions:
20− *
21− * The above copyright notice and this permission notice (including the next
22− * paragraph) shall be included in all copies or substantial portions of the
23− * Software.
24− *
25− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26− * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28− * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29− * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30− * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31− * OTHER DEALINGS IN THE SOFTWARE.
32− */
33−
34−#include <linux/module.h>
35−#include <linux/pci.h>
36−#include <linux/slab.h>
37−
38−#if IS_ENABLED(CONFIG_AGP)
39−#include <asm/agp.h>
40−#endif
41−
42−#include <drm/drm_device.h>
43−#include <drm/drm_drv.h>
44−#include <drm/drm_file.h>
45−#include <drm/drm_print.h>
46−
47−#include "drm_legacy.h"
48−
49−#if IS_ENABLED(CONFIG_AGP)
50−
51−/*
52− * Get AGP information.
53− *
54− * \return zero on success or a negative number on failure.
55− *
56− * Verifies the AGP device has been initialized and acquired and fills in the
57− * drm_agp_info structure with the information in drm_agp_head::agp_info.
58− */
59−int drm_legacy_agp_info(struct drm_device *dev, struct drm_agp_info *info)
60−{
61− struct agp_kern_info *kern;
62−
63− if (!dev->agp || !dev->agp->acquired)
64− return -EINVAL;
65−
66− kern = &dev->agp->agp_info;
67− info->agp_version_major = kern->version.major;
68− info->agp_version_minor = kern->version.minor;
69− info->mode = kern->mode;
70− info->aperture_base = kern->aper_base;
71− info->aperture_size = kern->aper_size * 1024 * 1024;
72− info->memory_allowed = kern->max_memory << PAGE_SHIFT;
73− info->memory_used = kern->current_memory << PAGE_SHIFT;
74− info->id_vendor = kern->device->vendor;
75− info->id_device = kern->device->device;
76−
77− return 0;
78−}
79−EXPORT_SYMBOL(drm_legacy_agp_info);
80−
81−int drm_legacy_agp_info_ioctl(struct drm_device *dev, void *data,
82− struct drm_file *file_priv)
83−{
84− struct drm_agp_info *info = data;
85− int err;
86−
87− err = drm_legacy_agp_info(dev, info);
88− if (err)
89− return err;
90−
91− return 0;
92−}
93−
94−/*
95− * Acquire the AGP device.
96− *
97− * \param dev DRM device that is to acquire AGP.
98− * \return zero on success or a negative number on failure.
99− *
100− * Verifies the AGP device hasn't been acquired before and calls
101− * \c agp_backend_acquire.
102− */
103−int drm_legacy_agp_acquire(struct drm_device *dev)
104−{
105− struct pci_dev *pdev = to_pci_dev(dev->dev);
106−
107− if (!dev->agp)
108− return -ENODEV;
109− if (dev->agp->acquired)
110− return -EBUSY;
111− dev->agp->bridge = agp_backend_acquire(pdev);
112− if (!dev->agp->bridge)
113− return -ENODEV;
114− dev->agp->acquired = 1;
115− return 0;
116−}
117−EXPORT_SYMBOL(drm_legacy_agp_acquire);
118−
119−/*
120− * Acquire the AGP device (ioctl).
121− *
122− * \return zero on success or a negative number on failure.
123− *
124− * Verifies the AGP device hasn't been acquired before and calls
125− * \c agp_backend_acquire.
126− */
127−int drm_legacy_agp_acquire_ioctl(struct drm_device *dev, void *data,
128− struct drm_file *file_priv)
129−{
130− return drm_legacy_agp_acquire((struct drm_device *)file_priv->minor->dev);
131−}
132−
133−/*
134− * Release the AGP device.
135− *
136− * \param dev DRM device that is to release AGP.
137− * \return zero on success or a negative number on failure.
138− *
139− * Verifies the AGP device has been acquired and calls \c agp_backend_release.
140− */
141−int drm_legacy_agp_release(struct drm_device *dev)
142−{
143− if (!dev->agp || !dev->agp->acquired)
144− return -EINVAL;
145− agp_backend_release(dev->agp->bridge);
146− dev->agp->acquired = 0;
147− return 0;
148−}
149−EXPORT_SYMBOL(drm_legacy_agp_release);
150−
151−int drm_legacy_agp_release_ioctl(struct drm_device *dev, void *data,
152− struct drm_file *file_priv)
153−{
154− return drm_legacy_agp_release(dev);
155−}
156−
157−/*
158− * Enable the AGP bus.
159− *
160− * \param dev DRM device that has previously acquired AGP.
161− * \param mode Requested AGP mode.
162− * \return zero on success or a negative number on failure.
163− *
164− * Verifies the AGP device has been acquired but not enabled, and calls
165− * \c agp_enable.
166− */
167−int drm_legacy_agp_enable(struct drm_device *dev, struct drm_agp_mode mode)
168−{
169− if (!dev->agp || !dev->agp->acquired)
170− return -EINVAL;
171−
172− dev->agp->mode = mode.mode;
173− agp_enable(dev->agp->bridge, mode.mode);
174− dev->agp->enabled = 1;
175− return 0;
176−}
177−EXPORT_SYMBOL(drm_legacy_agp_enable);
178−
179−int drm_legacy_agp_enable_ioctl(struct drm_device *dev, void *data,
180− struct drm_file *file_priv)
181−{
182− struct drm_agp_mode *mode = data;
183−
184− return drm_legacy_agp_enable(dev, *mode);
185−}
186−
187−/*
188− * Allocate AGP memory.
189− *
190− * \return zero on success or a negative number on failure.
191− *
192− * Verifies the AGP device is present and has been acquired, allocates the
193− * memory via agp_allocate_memory() and creates a drm_agp_mem entry for it.
194− */
195−int drm_legacy_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request)
196−{
197− struct drm_agp_mem *entry;
198− struct agp_memory *memory;
199− unsigned long pages;
200− u32 type;
201−
202− if (!dev->agp || !dev->agp->acquired)
203− return -EINVAL;
204− entry = kzalloc(sizeof(*entry), GFP_KERNEL);
205− if (!entry)
206− return -ENOMEM;
207−
208− pages = DIV_ROUND_UP(request->size, PAGE_SIZE);
209− type = (u32) request->type;
210− memory = agp_allocate_memory(dev->agp->bridge, pages, type);
211− if (!memory) {
212− kfree(entry);
213− return -ENOMEM;
214− }
215−
216− entry->handle = (unsigned long)memory->key + 1;
217− entry->memory = memory;
218− entry->bound = 0;
219− entry->pages = pages;
220− list_add(&entry->head, &dev->agp->memory);
221−
222− request->handle = entry->handle;
223− request->physical = memory->physical;
224−
225− return 0;
226−}
227−EXPORT_SYMBOL(drm_legacy_agp_alloc);
228−
229−
230−int drm_legacy_agp_alloc_ioctl(struct drm_device *dev, void *data,
231− struct drm_file *file_priv)
232−{
233− struct drm_agp_buffer *request = data;
234−
235− return drm_legacy_agp_alloc(dev, request);
236−}
237−
238−/*
239− * Search for the AGP memory entry associated with a handle.
240− *
241− * \param dev DRM device structure.
242− * \param handle AGP memory handle.
243− * \return pointer to the drm_agp_mem structure associated with \p handle.
244− *
245− * Walks through drm_agp_head::memory until finding a matching handle.
246− */
247−static struct drm_agp_mem *drm_legacy_agp_lookup_entry(struct drm_device *dev,
248− unsigned long handle)
249−{
250− struct drm_agp_mem *entry;
251−
252− list_for_each_entry(entry, &dev->agp->memory, head) {
253− if (entry->handle == handle)
254− return entry;
255− }
256− return NULL;
257−}
258−
259−/*
260− * Unbind AGP memory from the GATT (ioctl).
261− *
262− * \return zero on success or a negative number on failure.
263− *
264− * Verifies the AGP device is present and acquired, looks-up the AGP memory
265− * entry and passes it to the unbind_agp() function.
266− */
267−int drm_legacy_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request)
268−{
269− struct drm_agp_mem *entry;
270− int ret;
271−
272− if (!dev->agp || !dev->agp->acquired)
273− return -EINVAL;
274− entry = drm_legacy_agp_lookup_entry(dev, request->handle);
275− if (!entry || !entry->bound)
276− return -EINVAL;
277− ret = agp_unbind_memory(entry->memory);
278− if (ret == 0)
279− entry->bound = 0;
280− return ret;
281−}
282−EXPORT_SYMBOL(drm_legacy_agp_unbind);
283−
284−
285−int drm_legacy_agp_unbind_ioctl(struct drm_device *dev, void *data,
286− struct drm_file *file_priv)
287−{
288− struct drm_agp_binding *request = data;
289−
290− return drm_legacy_agp_unbind(dev, request);
291−}
292−
293−/*
294− * Bind AGP memory into the GATT (ioctl)
295− *
296− * \return zero on success or a negative number on failure.
297− *
298− * Verifies the AGP device is present and has been acquired and that no memory
299− * is currently bound into the GATT. Looks-up the AGP memory entry and passes
300− * it to bind_agp() function.
301− */
302−int drm_legacy_agp_bind(struct drm_device *dev, struct drm_agp_binding *request)
303−{
304− struct drm_agp_mem *entry;
305− int retcode;
306− int page;
307−
308− if (!dev->agp || !dev->agp->acquired)
309− return -EINVAL;
310− entry = drm_legacy_agp_lookup_entry(dev, request->handle);
311− if (!entry || entry->bound)
312− return -EINVAL;
313− page = DIV_ROUND_UP(request->offset, PAGE_SIZE);
314− retcode = agp_bind_memory(entry->memory, page);
315− if (retcode)
316− return retcode;
317− entry->bound = dev->agp->base + (page << PAGE_SHIFT);
318− DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
319− dev->agp->base, entry->bound);
320− return 0;
321−}
322−EXPORT_SYMBOL(drm_legacy_agp_bind);
323−
324−
325−int drm_legacy_agp_bind_ioctl(struct drm_device *dev, void *data,
326− struct drm_file *file_priv)
327−{
328− struct drm_agp_binding *request = data;
329−
330− return drm_legacy_agp_bind(dev, request);
331−}
332−
333−/*
334− * Free AGP memory (ioctl).
335− *
336− * \return zero on success or a negative number on failure.
337− *
338− * Verifies the AGP device is present and has been acquired and looks up the
339− * AGP memory entry. If the memory is currently bound, unbind it via
340− * unbind_agp(). Frees it via free_agp() as well as the entry itself
341− * and unlinks from the doubly linked list it's inserted in.
342− */
343−int drm_legacy_agp_free(struct drm_device *dev, struct drm_agp_buffer *request)
344−{
345− struct drm_agp_mem *entry;
346−
347− if (!dev->agp || !dev->agp->acquired)
348− return -EINVAL;
349− entry = drm_legacy_agp_lookup_entry(dev, request->handle);
350− if (!entry)
351− return -EINVAL;
352− if (entry->bound)
353− agp_unbind_memory(entry->memory);
354−
355− list_del(&entry->head);
356−
357− agp_free_memory(entry->memory);
358− kfree(entry);
359− return 0;
360−}
361−EXPORT_SYMBOL(drm_legacy_agp_free);
362−
363−
364−int drm_legacy_agp_free_ioctl(struct drm_device *dev, void *data,
365− struct drm_file *file_priv)
366−{
367− struct drm_agp_buffer *request = data;
368−
369− return drm_legacy_agp_free(dev, request);
370−}
371−
372−/*
373− * Initialize the AGP resources.
374− *
375− * \return pointer to a drm_agp_head structure.
376− *
377− * Gets the drm_agp_t structure which is made available by the agpgart module
378− * via the inter_module_* functions. Creates and initializes a drm_agp_head
379− * structure.
380− *
381− * Note that final cleanup of the kmalloced structure is directly done in
382− * drm_pci_agp_destroy.
383− */
384−struct drm_agp_head *drm_legacy_agp_init(struct drm_device *dev)
385−{
386− struct pci_dev *pdev = to_pci_dev(dev->dev);
387− struct drm_agp_head *head = NULL;
388−
389− head = kzalloc(sizeof(*head), GFP_KERNEL);
390− if (!head)
391− return NULL;
392− head->bridge = agp_find_bridge(pdev);
393− if (!head->bridge) {
394− head->bridge = agp_backend_acquire(pdev);
395− if (!head->bridge) {
396− kfree(head);
397− return NULL;
398− }
399− agp_copy_info(head->bridge, &head->agp_info);
400− agp_backend_release(head->bridge);
401− } else {
402− agp_copy_info(head->bridge, &head->agp_info);
403− }
404− if (head->agp_info.chipset == NOT_SUPPORTED) {
405− kfree(head);
406− return NULL;
407− }
408− INIT_LIST_HEAD(&head->memory);
409− head->cant_use_aperture = head->agp_info.cant_use_aperture;
410− head->page_mask = head->agp_info.page_mask;
411− head->base = head->agp_info.aper_base;
412− return head;
413−}
414−/* Only exported for i810.ko */
415−EXPORT_SYMBOL(drm_legacy_agp_init);
416−
417−/**
418− * drm_legacy_agp_clear - Clear AGP resource list
419− * @dev: DRM device
420− *
421− * Iterate over all AGP resources and remove them. But keep the AGP head
422− * intact so it can still be used. It is safe to call this if AGP is disabled or
423− * was already removed.
424− *
425− * Cleanup is only done for drivers who have DRIVER_LEGACY set.
426− */
427−void drm_legacy_agp_clear(struct drm_device *dev)
428−{
429− struct drm_agp_mem *entry, *tempe;
430−
431− if (!dev->agp)
432− return;
433− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
434− return;
435−
436− list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
437− if (entry->bound)
438− agp_unbind_memory(entry->memory);
439− agp_free_memory(entry->memory);
440− kfree(entry);
441− }
442− INIT_LIST_HEAD(&dev->agp->memory);
443−
444− if (dev->agp->acquired)
445− drm_legacy_agp_release(dev);
446−
447− dev->agp->acquired = 0;
448− dev->agp->enabled = 0;
449−}
450−
451−#endif
drivers/gpu/drm/drm_atomic.c+9−0
@@ -1773,6 +1773,7 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, · 1772 unmodified lines
17731773 struct drm_crtc *crtc;
17741774 struct drm_connector *connector;
17751775 struct drm_connector_list_iter conn_iter;
1776+ struct drm_private_obj *obj;
17761777
17771778 if (!drm_drv_uses_atomic_modeset(dev))
17781779 return;
@@ -1801,6 +1802,14 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, · 22 unmodified lines
18011802 if (take_locks)
18021803 drm_modeset_unlock(&dev->mode_config.connection_mutex);
18031804 drm_connector_list_iter_end(&conn_iter);
1805+
1806+ list_for_each_entry(obj, &config->privobj_list, head) {
1807+ if (take_locks)
1808+ drm_modeset_lock(&obj->lock, NULL);
1809+ drm_atomic_private_obj_print_state(p, obj->state);
1810+ if (take_locks)
1811+ drm_modeset_unlock(&obj->lock);
1812+ }
18041813 }
18051814
18061815 /**
drivers/gpu/drm/drm_atomic_helper.c+11−9
@@ -795,9 +795,9 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, · 794 unmodified lines
795795 EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
796796
797797 /**
798− * drm_atomic_helper_check_wb_encoder_state() - Check writeback encoder state
799− * @encoder: encoder state to check
800− * @conn_state: connector state to check
798+ * drm_atomic_helper_check_wb_connector_state() - Check writeback connector state
799+ * @connector: corresponding connector
800+ * @state: the driver state object
801801 *
802802 * Checks if the writeback connector state is valid, and returns an error if it
803803 * isn't.
@@ -806,9 +806,11 @@ EXPORT_SYMBOL(drm_atomic_helper_check_modeset); · 2 unmodified lines
806806 * Zero for success or -errno
807807 */
808808 int
809−drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder,
810− struct drm_connector_state *conn_state)
809+drm_atomic_helper_check_wb_connector_state(struct drm_connector *connector,
810+ struct drm_atomic_state *state)
811811 {
812+ struct drm_connector_state *conn_state =
813+ drm_atomic_get_new_connector_state(state, connector);
812814 struct drm_writeback_job *wb_job = conn_state->writeback_job;
813815 struct drm_property_blob *pixel_format_blob;
814816 struct drm_framebuffer *fb;
@@ -827,11 +829,11 @@ drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, · 12 unmodified lines
827829 if (fb->format->format == formats[i])
828830 return 0;
829831
830− drm_dbg_kms(encoder->dev, "Invalid pixel format %p4cc\n", &fb->format->format);
832+ drm_dbg_kms(connector->dev, "Invalid pixel format %p4cc\n", &fb->format->format);
831833
832834 return -EINVAL;
833835 }
834−EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state);
836+EXPORT_SYMBOL(drm_atomic_helper_check_wb_connector_state);
835837
836838 /**
837839 * drm_atomic_helper_check_plane_state() - Check plane state for validity
@@ -2382,10 +2384,10 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, · 1544 unmodified lines
23822384 EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
23832385
23842386 /**
2385− * drm_atomic_helper_wait_for_dependencies - wait for required preceeding commits
2387+ * drm_atomic_helper_wait_for_dependencies - wait for required preceding commits
23862388 * @old_state: atomic state object with old state structures
23872389 *
2388− * This function waits for all preceeding commits that touch the same CRTC as
2390+ * This function waits for all preceding commits that touch the same CRTC as
23892391 * @old_state to both be committed to the hardware (as signalled by
23902392 * drm_atomic_helper_commit_hw_done()) and executed by the hardware (as signalled
23912393 * by calling drm_crtc_send_vblank_event() on the &drm_crtc_state.event).
drivers/gpu/drm/drm_atomic_state_helper.c+14−0
@@ -275,6 +275,20 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, · 274 unmodified lines
275275 plane_state->normalized_zpos = val;
276276 }
277277 }
278+
279+ if (plane->hotspot_x_property) {
280+ if (!drm_object_property_get_default_value(&plane->base,
281+ plane->hotspot_x_property,
282+ &val))
283+ plane_state->hotspot_x = val;
284+ }
285+
286+ if (plane->hotspot_y_property) {
287+ if (!drm_object_property_get_default_value(&plane->base,
288+ plane->hotspot_y_property,
289+ &val))
290+ plane_state->hotspot_y = val;
291+ }
278292 }
279293 EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
280294
drivers/gpu/drm/drm_atomic_uapi.c+91−6
@@ -593,6 +593,22 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, · 592 unmodified lines
593593 } else if (plane->funcs->atomic_set_property) {
594594 return plane->funcs->atomic_set_property(plane, state,
595595 property, val);
596+ } else if (property == plane->hotspot_x_property) {
597+ if (plane->type != DRM_PLANE_TYPE_CURSOR) {
598+ drm_dbg_atomic(plane->dev,
599+ "[PLANE:%d:%s] is not a cursor plane: 0x%llx\n",
600+ plane->base.id, plane->name, val);
601+ return -EINVAL;
602+ }
603+ state->hotspot_x = val;
604+ } else if (property == plane->hotspot_y_property) {
605+ if (plane->type != DRM_PLANE_TYPE_CURSOR) {
606+ drm_dbg_atomic(plane->dev,
607+ "[PLANE:%d:%s] is not a cursor plane: 0x%llx\n",
608+ plane->base.id, plane->name, val);
609+ return -EINVAL;
610+ }
611+ state->hotspot_y = val;
596612 } else {
597613 drm_dbg_atomic(plane->dev,
598614 "[PLANE:%d:%s] unknown property [PROP:%d:%s]\n",
@@ -653,6 +669,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, · 54 unmodified lines
653669 *val = state->scaling_filter;
654670 } else if (plane->funcs->atomic_get_property) {
655671 return plane->funcs->atomic_get_property(plane, state, property, val);
672+ } else if (property == plane->hotspot_x_property) {
673+ *val = state->hotspot_x;
674+ } else if (property == plane->hotspot_y_property) {
675+ *val = state->hotspot_y;
656676 } else {
657677 drm_dbg_atomic(dev,
658678 "[PLANE:%d:%s] unknown property [PROP:%d:%s]\n",
@@ -1006,13 +1026,28 @@ out: · 347 unmodified lines
10061026 return ret;
10071027 }
10081028
1029+static int drm_atomic_check_prop_changes(int ret, uint64_t old_val, uint64_t prop_value,
1030+ struct drm_property *prop)
1031+{
1032+ if (ret != 0 || old_val != prop_value) {
1033+ drm_dbg_atomic(prop->dev,
1034+ "[PROP:%d:%s] No prop can be changed during async flip\n",
1035+ prop->base.id, prop->name);
1036+ return -EINVAL;
1037+ }
1038+
1039+ return 0;
1040+}
1041+
10091042 int drm_atomic_set_property(struct drm_atomic_state *state,
10101043 struct drm_file *file_priv,
10111044 struct drm_mode_object *obj,
10121045 struct drm_property *prop,
1013− uint64_t prop_value)
1046+ u64 prop_value,
1047+ bool async_flip)
10141048 {
10151049 struct drm_mode_object *ref;
1050+ u64 old_val;
10161051 int ret;
10171052
10181053 if (!drm_property_change_valid_get(prop, prop_value, &ref))
@@ -1029,6 +1064,13 @@ int drm_atomic_set_property(struct drm_atomic_state *state, · 10 unmodified lines
10291064 break;
10301065 }
10311066
1067+ if (async_flip) {
1068+ ret = drm_atomic_connector_get_property(connector, connector_state,
1069+ prop, &old_val);
1070+ ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
1071+ break;
1072+ }
1073+
10321074 ret = drm_atomic_connector_set_property(connector,
10331075 connector_state, file_priv,
10341076 prop, prop_value);
@@ -1044,6 +1086,13 @@ int drm_atomic_set_property(struct drm_atomic_state *state, · 9 unmodified lines
10441086 break;
10451087 }
10461088
1089+ if (async_flip) {
1090+ ret = drm_atomic_crtc_get_property(crtc, crtc_state,
1091+ prop, &old_val);
1092+ ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
1093+ break;
1094+ }
1095+
10471096 ret = drm_atomic_crtc_set_property(crtc,
10481097 crtc_state, prop, prop_value);
10491098 break;
@@ -1051,6 +1100,7 @@ int drm_atomic_set_property(struct drm_atomic_state *state, · 1 unmodified line
10511100 case DRM_MODE_OBJECT_PLANE: {
10521101 struct drm_plane *plane = obj_to_plane(obj);
10531102 struct drm_plane_state *plane_state;
1103+ struct drm_mode_config *config = &plane->dev->mode_config;
10541104
10551105 plane_state = drm_atomic_get_plane_state(state, plane);
10561106 if (IS_ERR(plane_state)) {
@@ -1058,6 +1108,21 @@ int drm_atomic_set_property(struct drm_atomic_state *state, · 1 unmodified line
10581108 break;
10591109 }
10601110
1111+ if (async_flip && prop != config->prop_fb_id) {
1112+ ret = drm_atomic_plane_get_property(plane, plane_state,
1113+ prop, &old_val);
1114+ ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
1115+ break;
1116+ }
1117+
1118+ if (async_flip && plane_state->plane->type != DRM_PLANE_TYPE_PRIMARY) {
1119+ drm_dbg_atomic(prop->dev,
1120+ "[OBJECT:%d] Only primary planes can be changed during async flip\n",
1121+ obj->id);
1122+ ret = -EINVAL;
1123+ break;
1124+ }
1125+
10611126 ret = drm_atomic_plane_set_property(plane,
10621127 plane_state, file_priv,
10631128 prop, prop_value);
@@ -1323,6 +1388,18 @@ static void complete_signaling(struct drm_device *dev, · 259 unmodified lines
13231388 kfree(fence_state);
13241389 }
13251390
1391+static void
1392+set_async_flip(struct drm_atomic_state *state)
1393+{
1394+ struct drm_crtc *crtc;
1395+ struct drm_crtc_state *crtc_state;
1396+ int i;
1397+
1398+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1399+ crtc_state->async_flip = true;
1400+ }
1401+}
1402+
13261403 int drm_mode_atomic_ioctl(struct drm_device *dev,
13271404 void *data, struct drm_file *file_priv)
13281405 {
@@ -1337,6 +1414,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, · 8 unmodified lines
13371414 struct drm_out_fence_state *fence_state;
13381415 int ret = 0;
13391416 unsigned int i, j, num_fences;
1417+ bool async_flip = false;
13401418
13411419 /* disallow for drivers not supporting atomic: */
13421420 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
@@ -1363,9 +1441,13 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, · 20 unmodified lines
13631441 }
13641442
13651443 if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) {
1366− drm_dbg_atomic(dev,
1367− "commit failed: invalid flag DRM_MODE_PAGE_FLIP_ASYNC\n");
1368− return -EINVAL;
1444+ if (!dev->mode_config.async_page_flip) {
1445+ drm_dbg_atomic(dev,
1446+ "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported\n");
1447+ return -EINVAL;
1448+ }
1449+
1450+ async_flip = true;
13691451 }
13701452
13711453 /* can't test and expect an event at the same time. */
@@ -1450,8 +1532,8 @@ retry: · 78 unmodified lines
14501532 goto out;
14511533 }
14521534
1453− ret = drm_atomic_set_property(state, file_priv,
1454− obj, prop, prop_value);
1535+ ret = drm_atomic_set_property(state, file_priv, obj,
1536+ prop, prop_value, async_flip);
14551537 if (ret) {
14561538 drm_mode_object_put(obj);
14571539 goto out;
@@ -1468,6 +1550,9 @@ retry: · 10 unmodified lines
14681550 if (ret)
14691551 goto out;
14701552
1553+ if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC)
1554+ set_async_flip(state);
1555+
14711556 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
14721557 ret = drm_atomic_check_only(state);
14731558 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
drivers/gpu/drm/drm_auth.c+1−7
@@ -37,13 +37,12 @@ · 36 unmodified lines
3737 #include <drm/drm_print.h>
3838
3939 #include "drm_internal.h"
40−#include "drm_legacy.h"
4140
4241 /**
4342 * DOC: master and authentication
4443 *
4544 * &struct drm_master is used to track groups of clients with open
46− * primary/legacy device nodes. For every &struct drm_file which has had at
45+ * primary device nodes. For every &struct drm_file which has had at
4746 * least once successfully became the device master (either through the
4847 * SET_MASTER IOCTL, or implicitly through opening the primary device node when
4948 * no one else is the current master that time) there exists one &drm_master.
@@ -139,7 +138,6 @@ struct drm_master *drm_master_create(struct drm_device *dev) · 89 unmodified lines
139138 return NULL;
140139
141140 kref_init(&master->refcount);
142− drm_master_legacy_init(master);
143141 idr_init_base(&master->magic_map, 1);
144142 master->dev = dev;
145143
@@ -365,8 +363,6 @@ void drm_master_release(struct drm_file *file_priv) · 219 unmodified lines
365363 if (!drm_is_current_master_locked(file_priv))
366364 goto out;
367365
368− drm_legacy_lock_master_cleanup(dev, master);
369−
370366 if (dev->master == file_priv->master)
371367 drm_drop_master(dev, file_priv);
372368 out:
@@ -429,8 +425,6 @@ static void drm_master_destroy(struct kref *kref) · 56 unmodified lines
429425 if (drm_core_check_feature(dev, DRIVER_MODESET))
430426 drm_lease_destroy(master);
431427
432− drm_legacy_master_rmmaps(dev, master);
433−
434428 idr_destroy(&master->magic_map);
435429 idr_destroy(&master->leases);
436430 idr_destroy(&master->lessee_idr);
drivers/gpu/drm/drm_bridge.c+0−44
@@ -1347,50 +1347,6 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np) · 1346 unmodified lines
13471347 EXPORT_SYMBOL(of_drm_find_bridge);
13481348 #endif
13491349
1350−#ifdef CONFIG_DEBUG_FS
1351−static int drm_bridge_chains_info(struct seq_file *m, void *data)
1352−{
1353− struct drm_debugfs_entry *entry = m->private;
1354− struct drm_device *dev = entry->dev;
1355− struct drm_printer p = drm_seq_file_printer(m);
1356− struct drm_mode_config *config = &dev->mode_config;
1357− struct drm_encoder *encoder;
1358− unsigned int bridge_idx = 0;
1359−
1360− list_for_each_entry(encoder, &config->encoder_list, head) {
1361− struct drm_bridge *bridge;
1362−
1363− drm_printf(&p, "encoder[%u]\n", encoder->base.id);
1364−
1365− drm_for_each_bridge_in_chain(encoder, bridge) {
1366− drm_printf(&p, "\tbridge[%u] type: %u, ops: %#x",
1367− bridge_idx, bridge->type, bridge->ops);
1368−
1369−#ifdef CONFIG_OF
1370− if (bridge->of_node)
1371− drm_printf(&p, ", OF: %pOFfc", bridge->of_node);
1372−#endif
1373−
1374− drm_printf(&p, "\n");
1375−
1376− bridge_idx++;
1377− }
1378− }
1379−
1380− return 0;
1381−}
1382−
1383−static const struct drm_debugfs_info drm_bridge_debugfs_list[] = {
1384− { "bridge_chains", drm_bridge_chains_info, 0 },
1385−};
1386−
1387−void drm_bridge_debugfs_init(struct drm_device *dev)
1388−{
1389− drm_debugfs_add_files(dev, drm_bridge_debugfs_list,
1390− ARRAY_SIZE(drm_bridge_debugfs_list));
1391−}
1392−#endif
1393−
13941350 MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
13951351 MODULE_DESCRIPTION("DRM bridge infrastructure");
13961352 MODULE_LICENSE("GPL and additional rights");
drivers/gpu/drm/drm_bridge_connector.c+0−6
@@ -198,12 +198,6 @@ static void drm_bridge_connector_destroy(struct drm_connector *connector) · 197 unmodified lines
198198 struct drm_bridge_connector *bridge_connector =
199199 to_drm_bridge_connector(connector);
200200
201− if (bridge_connector->bridge_hpd) {
202− struct drm_bridge *hpd = bridge_connector->bridge_hpd;
203−
204− drm_bridge_hpd_disable(hpd);
205− }
206−
207201 drm_connector_unregister(connector);
208202 drm_connector_cleanup(connector);
209203
drivers/gpu/drm/drm_bufs.c+0−1627
@@ -1,1627 +0,0 @@
1−/*
2− * Legacy: Generic DRM Buffer Management
3− *
4− * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
5− * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6− * All Rights Reserved.
7− *
8− * Author: Rickard E. (Rik) Faith <faith@valinux.com>
9− * Author: Gareth Hughes <gareth@valinux.com>
10− *
11− * Permission is hereby granted, free of charge, to any person obtaining a
12− * copy of this software and associated documentation files (the "Software"),
13− * to deal in the Software without restriction, including without limitation
14− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15− * and/or sell copies of the Software, and to permit persons to whom the
16− * Software is furnished to do so, subject to the following conditions:
17− *
18− * The above copyright notice and this permission notice (including the next
19− * paragraph) shall be included in all copies or substantial portions of the
20− * Software.
21− *
22− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23− * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25− * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26− * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27− * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28− * OTHER DEALINGS IN THE SOFTWARE.
29− */
30−
31−#include <linux/export.h>
32−#include <linux/log2.h>
33−#include <linux/mm.h>
34−#include <linux/mman.h>
35−#include <linux/nospec.h>
36−#include <linux/pci.h>
37−#include <linux/slab.h>
38−#include <linux/uaccess.h>
39−#include <linux/vmalloc.h>
40−
41−#include <asm/shmparam.h>
42−
43−#include <drm/drm_device.h>
44−#include <drm/drm_drv.h>
45−#include <drm/drm_file.h>
46−#include <drm/drm_print.h>
47−
48−#include "drm_legacy.h"
49−
50−
51−static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
52− struct drm_local_map *map)
53−{
54− struct drm_map_list *entry;
55−
56− list_for_each_entry(entry, &dev->maplist, head) {
57− /*
58− * Because the kernel-userspace ABI is fixed at a 32-bit offset
59− * while PCI resources may live above that, we only compare the
60− * lower 32 bits of the map offset for maps of type
61− * _DRM_FRAMEBUFFER or _DRM_REGISTERS.
62− * It is assumed that if a driver have more than one resource
63− * of each type, the lower 32 bits are different.
64− */
65− if (!entry->map ||
66− map->type != entry->map->type ||
67− entry->master != dev->master)
68− continue;
69− switch (map->type) {
70− case _DRM_SHM:
71− if (map->flags != _DRM_CONTAINS_LOCK)
72− break;
73− return entry;
74− case _DRM_REGISTERS:
75− case _DRM_FRAME_BUFFER:
76− if ((entry->map->offset & 0xffffffff) ==
77− (map->offset & 0xffffffff))
78− return entry;
79− break;
80− default: /* Make gcc happy */
81− break;
82− }
83− if (entry->map->offset == map->offset)
84− return entry;
85− }
86−
87− return NULL;
88−}
89−
90−static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
91− unsigned long user_token, int hashed_handle, int shm)
92−{
93− int use_hashed_handle, shift;
94− unsigned long add;
95−
96−#if (BITS_PER_LONG == 64)
97− use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
98−#elif (BITS_PER_LONG == 32)
99− use_hashed_handle = hashed_handle;
100−#else
101−#error Unsupported long size. Neither 64 nor 32 bits.
102−#endif
103−
104− if (!use_hashed_handle) {
105− int ret;
106−
107− hash->key = user_token >> PAGE_SHIFT;
108− ret = drm_ht_insert_item(&dev->map_hash, hash);
109− if (ret != -EINVAL)
110− return ret;
111− }
112−
113− shift = 0;
114− add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT;
115− if (shm && (SHMLBA > PAGE_SIZE)) {
116− int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1;
117−
118− /* For shared memory, we have to preserve the SHMLBA
119− * bits of the eventual vma->vm_pgoff value during
120− * mmap(). Otherwise we run into cache aliasing problems
121− * on some platforms. On these platforms, the pgoff of
122− * a mmap() request is used to pick a suitable virtual
123− * address for the mmap() region such that it will not
124− * cause cache aliasing problems.
125− *
126− * Therefore, make sure the SHMLBA relevant bits of the
127− * hash value we use are equal to those in the original
128− * kernel virtual address.
129− */
130− shift = bits;
131− add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL));
132− }
133−
134− return drm_ht_just_insert_please(&dev->map_hash, hash,
135− user_token, 32 - PAGE_SHIFT - 3,
136− shift, add);
137−}
138−
139−/*
140− * Core function to create a range of memory available for mapping by a
141− * non-root process.
142− *
143− * Adjusts the memory offset to its absolute value according to the mapping
144− * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
145− * applicable and if supported by the kernel.
146− */
147−static int drm_addmap_core(struct drm_device *dev, resource_size_t offset,
148− unsigned int size, enum drm_map_type type,
149− enum drm_map_flags flags,
150− struct drm_map_list **maplist)
151−{
152− struct drm_local_map *map;
153− struct drm_map_list *list;
154− unsigned long user_token;
155− int ret;
156−
157− map = kmalloc(sizeof(*map), GFP_KERNEL);
158− if (!map)
159− return -ENOMEM;
160−
161− map->offset = offset;
162− map->size = size;
163− map->flags = flags;
164− map->type = type;
165−
166− /* Only allow shared memory to be removable since we only keep enough
167− * book keeping information about shared memory to allow for removal
168− * when processes fork.
169− */
170− if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) {
171− kfree(map);
172− return -EINVAL;
173− }
174− DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
175− (unsigned long long)map->offset, map->size, map->type);
176−
177− /* page-align _DRM_SHM maps. They are allocated here so there is no security
178− * hole created by that and it works around various broken drivers that use
179− * a non-aligned quantity to map the SAREA. --BenH
180− */
181− if (map->type == _DRM_SHM)
182− map->size = PAGE_ALIGN(map->size);
183−
184− if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
185− kfree(map);
186− return -EINVAL;
187− }
188− map->mtrr = -1;
189− map->handle = NULL;
190−
191− switch (map->type) {
192− case _DRM_REGISTERS:
193− case _DRM_FRAME_BUFFER:
194−#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__)
195− if (map->offset + (map->size-1) < map->offset ||
196− map->offset < virt_to_phys(high_memory)) {
197− kfree(map);
198− return -EINVAL;
199− }
200−#endif
201− /* Some drivers preinitialize some maps, without the X Server
202− * needing to be aware of it. Therefore, we just return success
203− * when the server tries to create a duplicate map.
204− */
205− list = drm_find_matching_map(dev, map);
206− if (list != NULL) {
207− if (list->map->size != map->size) {
208− DRM_DEBUG("Matching maps of type %d with "
209− "mismatched sizes, (%ld vs %ld)\n",
210− map->type, map->size,
211− list->map->size);
212− list->map->size = map->size;
213− }
214−
215− kfree(map);
216− *maplist = list;
217− return 0;
218− }
219−
220− if (map->type == _DRM_FRAME_BUFFER ||
221− (map->flags & _DRM_WRITE_COMBINING)) {
222− map->mtrr =
223− arch_phys_wc_add(map->offset, map->size);
224− }
225− if (map->type == _DRM_REGISTERS) {
226− if (map->flags & _DRM_WRITE_COMBINING)
227− map->handle = ioremap_wc(map->offset,
228− map->size);
229− else
230− map->handle = ioremap(map->offset, map->size);
231− if (!map->handle) {
232− kfree(map);
233− return -ENOMEM;
234− }
235− }
236−
237− break;
238− case _DRM_SHM:
239− list = drm_find_matching_map(dev, map);
240− if (list != NULL) {
241− if (list->map->size != map->size) {
242− DRM_DEBUG("Matching maps of type %d with "
243− "mismatched sizes, (%ld vs %ld)\n",
244− map->type, map->size, list->map->size);
245− list->map->size = map->size;
246− }
247−
248− kfree(map);
249− *maplist = list;
250− return 0;
251− }
252− map->handle = vmalloc_user(map->size);
253− DRM_DEBUG("%lu %d %p\n",
254− map->size, order_base_2(map->size), map->handle);
255− if (!map->handle) {
256− kfree(map);
257− return -ENOMEM;
258− }
259− map->offset = (unsigned long)map->handle;
260− if (map->flags & _DRM_CONTAINS_LOCK) {
261− /* Prevent a 2nd X Server from creating a 2nd lock */
262− if (dev->master->lock.hw_lock != NULL) {
263− vfree(map->handle);
264− kfree(map);
265− return -EBUSY;
266− }
267− dev->sigdata.lock = dev->master->lock.hw_lock = map->handle; /* Pointer to lock */
268− }
269− break;
270− case _DRM_AGP: {
271− struct drm_agp_mem *entry;
272− int valid = 0;
273−
274− if (!dev->agp) {
275− kfree(map);
276− return -EINVAL;
277− }
278−#ifdef __alpha__
279− map->offset += dev->hose->mem_space->start;
280−#endif
281− /* In some cases (i810 driver), user space may have already
282− * added the AGP base itself, because dev->agp->base previously
283− * only got set during AGP enable. So, only add the base
284− * address if the map's offset isn't already within the
285− * aperture.
286− */
287− if (map->offset < dev->agp->base ||
288− map->offset > dev->agp->base +
289− dev->agp->agp_info.aper_size * 1024 * 1024 - 1) {
290− map->offset += dev->agp->base;
291− }
292− map->mtrr = dev->agp->agp_mtrr; /* for getmap */
293−
294− /* This assumes the DRM is in total control of AGP space.
295− * It's not always the case as AGP can be in the control
296− * of user space (i.e. i810 driver). So this loop will get
297− * skipped and we double check that dev->agp->memory is
298− * actually set as well as being invalid before EPERM'ing
299− */
300− list_for_each_entry(entry, &dev->agp->memory, head) {
301− if ((map->offset >= entry->bound) &&
302− (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) {
303− valid = 1;
304− break;
305− }
306− }
307− if (!list_empty(&dev->agp->memory) && !valid) {
308− kfree(map);
309− return -EPERM;
310− }
311− DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n",
312− (unsigned long long)map->offset, map->size);
313−
314− break;
315− }
316− case _DRM_SCATTER_GATHER:
317− if (!dev->sg) {
318− kfree(map);
319− return -EINVAL;
320− }
321− map->offset += (unsigned long)dev->sg->virtual;
322− break;
323− case _DRM_CONSISTENT:
324− /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
325− * As we're limiting the address to 2^32-1 (or less),
326− * casting it down to 32 bits is no problem, but we
327− * need to point to a 64bit variable first.
328− */
329− map->handle = dma_alloc_coherent(dev->dev,
330− map->size,
331− &map->offset,
332− GFP_KERNEL);
333− if (!map->handle) {
334− kfree(map);
335− return -ENOMEM;
336− }
337− break;
338− default:
339− kfree(map);
340− return -EINVAL;
341− }
342−
343− list = kzalloc(sizeof(*list), GFP_KERNEL);
344− if (!list) {
345− if (map->type == _DRM_REGISTERS)
346− iounmap(map->handle);
347− kfree(map);
348− return -EINVAL;
349− }
350− list->map = map;
351−
352− mutex_lock(&dev->struct_mutex);
353− list_add(&list->head, &dev->maplist);
354−
355− /* Assign a 32-bit handle */
356− /* We do it here so that dev->struct_mutex protects the increment */
357− user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
358− map->offset;
359− ret = drm_map_handle(dev, &list->hash, user_token, 0,
360− (map->type == _DRM_SHM));
361− if (ret) {
362− if (map->type == _DRM_REGISTERS)
363− iounmap(map->handle);
364− kfree(map);
365− kfree(list);
366− mutex_unlock(&dev->struct_mutex);
367− return ret;
368− }
369−
370− list->user_token = list->hash.key << PAGE_SHIFT;
371− mutex_unlock(&dev->struct_mutex);
372−
373− if (!(map->flags & _DRM_DRIVER))
374− list->master = dev->master;
375− *maplist = list;
376− return 0;
377−}
378−
379−int drm_legacy_addmap(struct drm_device *dev, resource_size_t offset,
380− unsigned int size, enum drm_map_type type,
381− enum drm_map_flags flags, struct drm_local_map **map_ptr)
382−{
383− struct drm_map_list *list;
384− int rc;
385−
386− rc = drm_addmap_core(dev, offset, size, type, flags, &list);
387− if (!rc)
388− *map_ptr = list->map;
389− return rc;
390−}
391−EXPORT_SYMBOL(drm_legacy_addmap);
392−
393−struct drm_local_map *drm_legacy_findmap(struct drm_device *dev,
394− unsigned int token)
395−{
396− struct drm_map_list *_entry;
397−
398− list_for_each_entry(_entry, &dev->maplist, head)
399− if (_entry->user_token == token)
400− return _entry->map;
401− return NULL;
402−}
403−EXPORT_SYMBOL(drm_legacy_findmap);
404−
405−/*
406− * Ioctl to specify a range of memory that is available for mapping by a
407− * non-root process.
408− *
409− * \param inode device inode.
410− * \param file_priv DRM file private.
411− * \param cmd command.
412− * \param arg pointer to a drm_map structure.
413− * \return zero on success or a negative value on error.
414− *
415− */
416−int drm_legacy_addmap_ioctl(struct drm_device *dev, void *data,
417− struct drm_file *file_priv)
418−{
419− struct drm_map *map = data;
420− struct drm_map_list *maplist;
421− int err;
422−
423− if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP || map->type == _DRM_SHM))
424− return -EPERM;
425−
426− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
427− return -EOPNOTSUPP;
428−
429− err = drm_addmap_core(dev, map->offset, map->size, map->type,
430− map->flags, &maplist);
431−
432− if (err)
433− return err;
434−
435− /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
436− map->handle = (void *)(unsigned long)maplist->user_token;
437−
438− /*
439− * It appears that there are no users of this value whatsoever --
440− * drmAddMap just discards it. Let's not encourage its use.
441− * (Keeping drm_addmap_core's returned mtrr value would be wrong --
442− * it's not a real mtrr index anymore.)
443− */
444− map->mtrr = -1;
445−
446− return 0;
447−}
448−
449−/*
450− * Get a mapping information.
451− *
452− * \param inode device inode.
453− * \param file_priv DRM file private.
454− * \param cmd command.
455− * \param arg user argument, pointing to a drm_map structure.
456− *
457− * \return zero on success or a negative number on failure.
458− *
459− * Searches for the mapping with the specified offset and copies its information
460− * into userspace
461− */
462−int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data,
463− struct drm_file *file_priv)
464−{
465− struct drm_map *map = data;
466− struct drm_map_list *r_list = NULL;
467− struct list_head *list;
468− int idx;
469− int i;
470−
471− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
472− return -EOPNOTSUPP;
473−
474− idx = map->offset;
475− if (idx < 0)
476− return -EINVAL;
477−
478− i = 0;
479− mutex_lock(&dev->struct_mutex);
480− list_for_each(list, &dev->maplist) {
481− if (i == idx) {
482− r_list = list_entry(list, struct drm_map_list, head);
483− break;
484− }
485− i++;
486− }
487− if (!r_list || !r_list->map) {
488− mutex_unlock(&dev->struct_mutex);
489− return -EINVAL;
490− }
491−
492− map->offset = r_list->map->offset;
493− map->size = r_list->map->size;
494− map->type = r_list->map->type;
495− map->flags = r_list->map->flags;
496− map->handle = (void *)(unsigned long) r_list->user_token;
497− map->mtrr = arch_phys_wc_index(r_list->map->mtrr);
498−
499− mutex_unlock(&dev->struct_mutex);
500−
501− return 0;
502−}
503−
504−/*
505− * Remove a map private from list and deallocate resources if the mapping
506− * isn't in use.
507− *
508− * Searches the map on drm_device::maplist, removes it from the list, see if
509− * it's being used, and free any associated resource (such as MTRR's) if it's not
510− * being on use.
511− *
512− * \sa drm_legacy_addmap
513− */
514−int drm_legacy_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
515−{
516− struct drm_map_list *r_list = NULL, *list_t;
517− int found = 0;
518− struct drm_master *master;
519−
520− /* Find the list entry for the map and remove it */
521− list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
522− if (r_list->map == map) {
523− master = r_list->master;
524− list_del(&r_list->head);
525− drm_ht_remove_key(&dev->map_hash,
526− r_list->user_token >> PAGE_SHIFT);
527− kfree(r_list);
528− found = 1;
529− break;
530− }
531− }
532−
533− if (!found)
534− return -EINVAL;
535−
536− switch (map->type) {
537− case _DRM_REGISTERS:
538− iounmap(map->handle);
539− fallthrough;
540− case _DRM_FRAME_BUFFER:
541− arch_phys_wc_del(map->mtrr);
542− break;
543− case _DRM_SHM:
544− vfree(map->handle);
545− if (master) {
546− if (dev->sigdata.lock == master->lock.hw_lock)
547− dev->sigdata.lock = NULL;
548− master->lock.hw_lock = NULL; /* SHM removed */
549− master->lock.file_priv = NULL;
550− wake_up_interruptible_all(&master->lock.lock_queue);
551− }
552− break;
553− case _DRM_AGP:
554− case _DRM_SCATTER_GATHER:
555− break;
556− case _DRM_CONSISTENT:
557− dma_free_coherent(dev->dev,
558− map->size,
559− map->handle,
560− map->offset);
561− break;
562− }
563− kfree(map);
564−
565− return 0;
566−}
567−EXPORT_SYMBOL(drm_legacy_rmmap_locked);
568−
569−void drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map)
570−{
571− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
572− return;
573−
574− mutex_lock(&dev->struct_mutex);
575− drm_legacy_rmmap_locked(dev, map);
576− mutex_unlock(&dev->struct_mutex);
577−}
578−EXPORT_SYMBOL(drm_legacy_rmmap);
579−
580−void drm_legacy_master_rmmaps(struct drm_device *dev, struct drm_master *master)
581−{
582− struct drm_map_list *r_list, *list_temp;
583−
584− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
585− return;
586−
587− mutex_lock(&dev->struct_mutex);
588− list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
589− if (r_list->master == master) {
590− drm_legacy_rmmap_locked(dev, r_list->map);
591− r_list = NULL;
592− }
593− }
594− mutex_unlock(&dev->struct_mutex);
595−}
596−
597−void drm_legacy_rmmaps(struct drm_device *dev)
598−{
599− struct drm_map_list *r_list, *list_temp;
600−
601− list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
602− drm_legacy_rmmap(dev, r_list->map);
603−}
604−
605−/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
606− * the last close of the device, and this is necessary for cleanup when things
607− * exit uncleanly. Therefore, having userland manually remove mappings seems
608− * like a pointless exercise since they're going away anyway.
609− *
610− * One use case might be after addmap is allowed for normal users for SHM and
611− * gets used by drivers that the server doesn't need to care about. This seems
612− * unlikely.
613− *
614− * \param inode device inode.
615− * \param file_priv DRM file private.
616− * \param cmd command.
617− * \param arg pointer to a struct drm_map structure.
618− * \return zero on success or a negative value on error.
619− */
620−int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data,
621− struct drm_file *file_priv)
622−{
623− struct drm_map *request = data;
624− struct drm_local_map *map = NULL;
625− struct drm_map_list *r_list;
626− int ret;
627−
628− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
629− return -EOPNOTSUPP;
630−
631− mutex_lock(&dev->struct_mutex);
632− list_for_each_entry(r_list, &dev->maplist, head) {
633− if (r_list->map &&
634− r_list->user_token == (unsigned long)request->handle &&
635− r_list->map->flags & _DRM_REMOVABLE) {
636− map = r_list->map;
637− break;
638− }
639− }
640−
641− /* List has wrapped around to the head pointer, or it's empty we didn't
642− * find anything.
643− */
644− if (list_empty(&dev->maplist) || !map) {
645− mutex_unlock(&dev->struct_mutex);
646− return -EINVAL;
647− }
648−
649− /* Register and framebuffer maps are permanent */
650− if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
651− mutex_unlock(&dev->struct_mutex);
652− return 0;
653− }
654−
655− ret = drm_legacy_rmmap_locked(dev, map);
656−
657− mutex_unlock(&dev->struct_mutex);
658−
659− return ret;
660−}
661−
662−/*
663− * Cleanup after an error on one of the addbufs() functions.
664− *
665− * \param dev DRM device.
666− * \param entry buffer entry where the error occurred.
667− *
668− * Frees any pages and buffers associated with the given entry.
669− */
670−static void drm_cleanup_buf_error(struct drm_device *dev,
671− struct drm_buf_entry *entry)
672−{
673− drm_dma_handle_t *dmah;
674− int i;
675−
676− if (entry->seg_count) {
677− for (i = 0; i < entry->seg_count; i++) {
678− if (entry->seglist[i]) {
679− dmah = entry->seglist[i];
680− dma_free_coherent(dev->dev,
681− dmah->size,
682− dmah->vaddr,
683− dmah->busaddr);
684− kfree(dmah);
685− }
686− }
687− kfree(entry->seglist);
688−
689− entry->seg_count = 0;
690− }
691−
692− if (entry->buf_count) {
693− for (i = 0; i < entry->buf_count; i++) {
694− kfree(entry->buflist[i].dev_private);
695− }
696− kfree(entry->buflist);
697−
698− entry->buf_count = 0;
699− }
700−}
701−
702−#if IS_ENABLED(CONFIG_AGP)
703−/*
704− * Add AGP buffers for DMA transfers.
705− *
706− * \param dev struct drm_device to which the buffers are to be added.
707− * \param request pointer to a struct drm_buf_desc describing the request.
708− * \return zero on success or a negative number on failure.
709− *
710− * After some sanity checks creates a drm_buf structure for each buffer and
711− * reallocates the buffer list of the same size order to accommodate the new
712− * buffers.
713− */
714−int drm_legacy_addbufs_agp(struct drm_device *dev,
715− struct drm_buf_desc *request)
716−{
717− struct drm_device_dma *dma = dev->dma;
718− struct drm_buf_entry *entry;
719− struct drm_agp_mem *agp_entry;
720− struct drm_buf *buf;
721− unsigned long offset;
722− unsigned long agp_offset;
723− int count;
724− int order;
725− int size;
726− int alignment;
727− int page_order;
728− int total;
729− int byte_count;
730− int i, valid;
731− struct drm_buf **temp_buflist;
732−
733− if (!dma)
734− return -EINVAL;
735−
736− count = request->count;
737− order = order_base_2(request->size);
738− size = 1 << order;
739−
740− alignment = (request->flags & _DRM_PAGE_ALIGN)
741− ? PAGE_ALIGN(size) : size;
742− page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
743− total = PAGE_SIZE << page_order;
744−
745− byte_count = 0;
746− agp_offset = dev->agp->base + request->agp_start;
747−
748− DRM_DEBUG("count: %d\n", count);
749− DRM_DEBUG("order: %d\n", order);
750− DRM_DEBUG("size: %d\n", size);
751− DRM_DEBUG("agp_offset: %lx\n", agp_offset);
752− DRM_DEBUG("alignment: %d\n", alignment);
753− DRM_DEBUG("page_order: %d\n", page_order);
754− DRM_DEBUG("total: %d\n", total);
755−
756− if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
757− return -EINVAL;
758−
759− /* Make sure buffers are located in AGP memory that we own */
760− valid = 0;
761− list_for_each_entry(agp_entry, &dev->agp->memory, head) {
762− if ((agp_offset >= agp_entry->bound) &&
763− (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) {
764− valid = 1;
765− break;
766− }
767− }
768− if (!list_empty(&dev->agp->memory) && !valid) {
769− DRM_DEBUG("zone invalid\n");
770− return -EINVAL;
771− }
772− spin_lock(&dev->buf_lock);
773− if (dev->buf_use) {
774− spin_unlock(&dev->buf_lock);
775− return -EBUSY;
776− }
777− atomic_inc(&dev->buf_alloc);
778− spin_unlock(&dev->buf_lock);
779−
780− mutex_lock(&dev->struct_mutex);
781− entry = &dma->bufs[order];
782− if (entry->buf_count) {
783− mutex_unlock(&dev->struct_mutex);
784− atomic_dec(&dev->buf_alloc);
785− return -ENOMEM; /* May only call once for each order */
786− }
787−
788− if (count < 0 || count > 4096) {
789− mutex_unlock(&dev->struct_mutex);
790− atomic_dec(&dev->buf_alloc);
791− return -EINVAL;
792− }
793−
794− entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL);
795− if (!entry->buflist) {
796− mutex_unlock(&dev->struct_mutex);
797− atomic_dec(&dev->buf_alloc);
798− return -ENOMEM;
799− }
800−
801− entry->buf_size = size;
802− entry->page_order = page_order;
803−
804− offset = 0;
805−
806− while (entry->buf_count < count) {
807− buf = &entry->buflist[entry->buf_count];
808− buf->idx = dma->buf_count + entry->buf_count;
809− buf->total = alignment;
810− buf->order = order;
811− buf->used = 0;
812−
813− buf->offset = (dma->byte_count + offset);
814− buf->bus_address = agp_offset + offset;
815− buf->address = (void *)(agp_offset + offset);
816− buf->next = NULL;
817− buf->waiting = 0;
818− buf->pending = 0;
819− buf->file_priv = NULL;
820−
821− buf->dev_priv_size = dev->driver->dev_priv_size;
822− buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL);
823− if (!buf->dev_private) {
824− /* Set count correctly so we free the proper amount. */
825− entry->buf_count = count;
826− drm_cleanup_buf_error(dev, entry);
827− mutex_unlock(&dev->struct_mutex);
828− atomic_dec(&dev->buf_alloc);
829− return -ENOMEM;
830− }
831−
832− DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
833−
834− offset += alignment;
835− entry->buf_count++;
836− byte_count += PAGE_SIZE << page_order;
837− }
838−
839− DRM_DEBUG("byte_count: %d\n", byte_count);
840−
841− temp_buflist = krealloc(dma->buflist,
842− (dma->buf_count + entry->buf_count) *
843− sizeof(*dma->buflist), GFP_KERNEL);
844− if (!temp_buflist) {
845− /* Free the entry because it isn't valid */
846− drm_cleanup_buf_error(dev, entry);
847− mutex_unlock(&dev->struct_mutex);
848− atomic_dec(&dev->buf_alloc);
849− return -ENOMEM;
850− }
851− dma->buflist = temp_buflist;
852−
853− for (i = 0; i < entry->buf_count; i++) {
854− dma->buflist[i + dma->buf_count] = &entry->buflist[i];
855− }
856−
857− dma->buf_count += entry->buf_count;
858− dma->seg_count += entry->seg_count;
859− dma->page_count += byte_count >> PAGE_SHIFT;
860− dma->byte_count += byte_count;
861−
862− DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
863− DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
864−
865− mutex_unlock(&dev->struct_mutex);
866−
867− request->count = entry->buf_count;
868− request->size = size;
869−
870− dma->flags = _DRM_DMA_USE_AGP;
871−
872− atomic_dec(&dev->buf_alloc);
873− return 0;
874−}
875−EXPORT_SYMBOL(drm_legacy_addbufs_agp);
876−#endif /* CONFIG_AGP */
877−
878−int drm_legacy_addbufs_pci(struct drm_device *dev,
879− struct drm_buf_desc *request)
880−{
881− struct drm_device_dma *dma = dev->dma;
882− int count;
883− int order;
884− int size;
885− int total;
886− int page_order;
887− struct drm_buf_entry *entry;
888− drm_dma_handle_t *dmah;
889− struct drm_buf *buf;
890− int alignment;
891− unsigned long offset;
892− int i;
893− int byte_count;
894− int page_count;
895− unsigned long *temp_pagelist;
896− struct drm_buf **temp_buflist;
897−
898− if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
899− return -EOPNOTSUPP;
900−
901− if (!dma)
902− return -EINVAL;
903−
904− if (!capable(CAP_SYS_ADMIN))
905− return -EPERM;
906−
907− count = request->count;
908− order = order_base_2(request->size);
909− size = 1 << order;
910−
911− DRM_DEBUG("count=%d, size=%d (%d), order=%d\n",
912− request->count, request->size, size, order);
913−
914− if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
915− return -EINVAL;
916−
917− alignment = (request->flags & _DRM_PAGE_ALIGN)
918− ? PAGE_ALIGN(size) : size;
919− page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
920− total = PAGE_SIZE << page_order;
921−
922− spin_lock(&dev->buf_lock);
923− if (dev->buf_use) {
924− spin_unlock(&dev->buf_lock);
925− return -EBUSY;
926− }
927− atomic_inc(&dev->buf_alloc);
928− spin_unlock(&dev->buf_lock);
929−
930− mutex_lock(&dev->struct_mutex);
931− entry = &dma->bufs[order];
932− if (entry->buf_count) {
933− mutex_unlock(&dev->struct_mutex);
934− atomic_dec(&dev->buf_alloc);
935− return -ENOMEM; /* May only call once for each order */
936− }
937−
938− if (count < 0 || count > 4096) {
939− mutex_unlock(&dev->struct_mutex);
940− atomic_dec(&dev->buf_alloc);
941− return -EINVAL;
942− }
943−
944− entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL);
945− if (!entry->buflist) {
946− mutex_unlock(&dev->struct_mutex);
947− atomic_dec(&dev->buf_alloc);
948− return -ENOMEM;
949− }
950−
951− entry->seglist = kcalloc(count, sizeof(*entry->seglist), GFP_KERNEL);
952− if (!entry->seglist) {
953− kfree(entry->buflist);
954− mutex_unlock(&dev->struct_mutex);
955− atomic_dec(&dev->buf_alloc);
956− return -ENOMEM;
957− }
958−
959− /* Keep the original pagelist until we know all the allocations
960− * have succeeded
961− */
962− temp_pagelist = kmalloc_array(dma->page_count + (count << page_order),
963− sizeof(*dma->pagelist),
964− GFP_KERNEL);
965− if (!temp_pagelist) {
966− kfree(entry->buflist);
967− kfree(entry->seglist);
968− mutex_unlock(&dev->struct_mutex);
969− atomic_dec(&dev->buf_alloc);
970− return -ENOMEM;
971− }
972− memcpy(temp_pagelist,
973− dma->pagelist, dma->page_count * sizeof(*dma->pagelist));
974− DRM_DEBUG("pagelist: %d entries\n",
975− dma->page_count + (count << page_order));
976−
977− entry->buf_size = size;
978− entry->page_order = page_order;
979− byte_count = 0;
980− page_count = 0;
981−
982− while (entry->buf_count < count) {
983− dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
984− if (!dmah) {
985− /* Set count correctly so we free the proper amount. */
986− entry->buf_count = count;
987− entry->seg_count = count;
988− drm_cleanup_buf_error(dev, entry);
989− kfree(temp_pagelist);
990− mutex_unlock(&dev->struct_mutex);
991− atomic_dec(&dev->buf_alloc);
992− return -ENOMEM;
993− }
994−
995− dmah->size = total;
996− dmah->vaddr = dma_alloc_coherent(dev->dev,
997− dmah->size,
998− &dmah->busaddr,
999− GFP_KERNEL);
1000− if (!dmah->vaddr) {
1001− kfree(dmah);
1002−
1003− /* Set count correctly so we free the proper amount. */
1004− entry->buf_count = count;
1005− entry->seg_count = count;
1006− drm_cleanup_buf_error(dev, entry);
1007− kfree(temp_pagelist);
1008− mutex_unlock(&dev->struct_mutex);
1009− atomic_dec(&dev->buf_alloc);
1010− return -ENOMEM;
1011− }
1012− entry->seglist[entry->seg_count++] = dmah;
1013− for (i = 0; i < (1 << page_order); i++) {
1014− DRM_DEBUG("page %d @ 0x%08lx\n",
1015− dma->page_count + page_count,
1016− (unsigned long)dmah->vaddr + PAGE_SIZE * i);
1017− temp_pagelist[dma->page_count + page_count++]
1018− = (unsigned long)dmah->vaddr + PAGE_SIZE * i;
1019− }
1020− for (offset = 0;
1021− offset + size <= total && entry->buf_count < count;
1022− offset += alignment, ++entry->buf_count) {
1023− buf = &entry->buflist[entry->buf_count];
1024− buf->idx = dma->buf_count + entry->buf_count;
1025− buf->total = alignment;
1026− buf->order = order;
1027− buf->used = 0;
1028− buf->offset = (dma->byte_count + byte_count + offset);
1029− buf->address = (void *)(dmah->vaddr + offset);
1030− buf->bus_address = dmah->busaddr + offset;
1031− buf->next = NULL;
1032− buf->waiting = 0;
1033− buf->pending = 0;
1034− buf->file_priv = NULL;
1035−
1036− buf->dev_priv_size = dev->driver->dev_priv_size;
1037− buf->dev_private = kzalloc(buf->dev_priv_size,
1038− GFP_KERNEL);
1039− if (!buf->dev_private) {
1040− /* Set count correctly so we free the proper amount. */
1041− entry->buf_count = count;
1042− entry->seg_count = count;
1043− drm_cleanup_buf_error(dev, entry);
1044− kfree(temp_pagelist);
1045− mutex_unlock(&dev->struct_mutex);
1046− atomic_dec(&dev->buf_alloc);
1047− return -ENOMEM;
1048− }
1049−
1050− DRM_DEBUG("buffer %d @ %p\n",
1051− entry->buf_count, buf->address);
1052− }
1053− byte_count += PAGE_SIZE << page_order;
1054− }
1055−
1056− temp_buflist = krealloc(dma->buflist,
1057− (dma->buf_count + entry->buf_count) *
1058− sizeof(*dma->buflist), GFP_KERNEL);
1059− if (!temp_buflist) {
1060− /* Free the entry because it isn't valid */
1061− drm_cleanup_buf_error(dev, entry);
1062− kfree(temp_pagelist);
1063− mutex_unlock(&dev->struct_mutex);
1064− atomic_dec(&dev->buf_alloc);
1065− return -ENOMEM;
1066− }
1067− dma->buflist = temp_buflist;
1068−
1069− for (i = 0; i < entry->buf_count; i++) {
1070− dma->buflist[i + dma->buf_count] = &entry->buflist[i];
1071− }
1072−
1073− /* No allocations failed, so now we can replace the original pagelist
1074− * with the new one.
1075− */
1076− if (dma->page_count) {
1077− kfree(dma->pagelist);
1078− }
1079− dma->pagelist = temp_pagelist;
1080−
1081− dma->buf_count += entry->buf_count;
1082− dma->seg_count += entry->seg_count;
1083− dma->page_count += entry->seg_count << page_order;
1084− dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
1085−
1086− mutex_unlock(&dev->struct_mutex);
1087−
1088− request->count = entry->buf_count;
1089− request->size = size;
1090−
1091− if (request->flags & _DRM_PCI_BUFFER_RO)
1092− dma->flags = _DRM_DMA_USE_PCI_RO;
1093−
1094− atomic_dec(&dev->buf_alloc);
1095− return 0;
1096−
1097−}
1098−EXPORT_SYMBOL(drm_legacy_addbufs_pci);
1099−
1100−static int drm_legacy_addbufs_sg(struct drm_device *dev,
1101− struct drm_buf_desc *request)
1102−{
1103− struct drm_device_dma *dma = dev->dma;
1104− struct drm_buf_entry *entry;
1105− struct drm_buf *buf;
1106− unsigned long offset;
1107− unsigned long agp_offset;
1108− int count;
1109− int order;
1110− int size;
1111− int alignment;
1112− int page_order;
1113− int total;
1114− int byte_count;
1115− int i;
1116− struct drm_buf **temp_buflist;
1117−
1118− if (!drm_core_check_feature(dev, DRIVER_SG))
1119− return -EOPNOTSUPP;
1120−
1121− if (!dma)
1122− return -EINVAL;
1123−
1124− if (!capable(CAP_SYS_ADMIN))
1125− return -EPERM;
1126−
1127− count = request->count;
1128− order = order_base_2(request->size);
1129− size = 1 << order;
1130−
1131− alignment = (request->flags & _DRM_PAGE_ALIGN)
1132− ? PAGE_ALIGN(size) : size;
1133− page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
1134− total = PAGE_SIZE << page_order;
1135−
1136− byte_count = 0;
1137− agp_offset = request->agp_start;
1138−
1139− DRM_DEBUG("count: %d\n", count);
1140− DRM_DEBUG("order: %d\n", order);
1141− DRM_DEBUG("size: %d\n", size);
1142− DRM_DEBUG("agp_offset: %lu\n", agp_offset);
1143− DRM_DEBUG("alignment: %d\n", alignment);
1144− DRM_DEBUG("page_order: %d\n", page_order);
1145− DRM_DEBUG("total: %d\n", total);
1146−
1147− if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
1148− return -EINVAL;
1149−
1150− spin_lock(&dev->buf_lock);
1151− if (dev->buf_use) {
1152− spin_unlock(&dev->buf_lock);
1153− return -EBUSY;
1154− }
1155− atomic_inc(&dev->buf_alloc);
1156− spin_unlock(&dev->buf_lock);
1157−
1158− mutex_lock(&dev->struct_mutex);
1159− entry = &dma->bufs[order];
1160− if (entry->buf_count) {
1161− mutex_unlock(&dev->struct_mutex);
1162− atomic_dec(&dev->buf_alloc);
1163− return -ENOMEM; /* May only call once for each order */
1164− }
1165−
1166− if (count < 0 || count > 4096) {
1167− mutex_unlock(&dev->struct_mutex);
1168− atomic_dec(&dev->buf_alloc);
1169− return -EINVAL;
1170− }
1171−
1172− entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL);
1173− if (!entry->buflist) {
1174− mutex_unlock(&dev->struct_mutex);
1175− atomic_dec(&dev->buf_alloc);
1176− return -ENOMEM;
1177− }
1178−
1179− entry->buf_size = size;
1180− entry->page_order = page_order;
1181−
1182− offset = 0;
1183−
1184− while (entry->buf_count < count) {
1185− buf = &entry->buflist[entry->buf_count];
1186− buf->idx = dma->buf_count + entry->buf_count;
1187− buf->total = alignment;
1188− buf->order = order;
1189− buf->used = 0;
1190−
1191− buf->offset = (dma->byte_count + offset);
1192− buf->bus_address = agp_offset + offset;
1193− buf->address = (void *)(agp_offset + offset
1194− + (unsigned long)dev->sg->virtual);
1195− buf->next = NULL;
1196− buf->waiting = 0;
1197− buf->pending = 0;
1198− buf->file_priv = NULL;
1199−
1200− buf->dev_priv_size = dev->driver->dev_priv_size;
1201− buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL);
1202− if (!buf->dev_private) {
1203− /* Set count correctly so we free the proper amount. */
1204− entry->buf_count = count;
1205− drm_cleanup_buf_error(dev, entry);
1206− mutex_unlock(&dev->struct_mutex);
1207− atomic_dec(&dev->buf_alloc);
1208− return -ENOMEM;
1209− }
1210−
1211− DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1212−
1213− offset += alignment;
1214− entry->buf_count++;
1215− byte_count += PAGE_SIZE << page_order;
1216− }
1217−
1218− DRM_DEBUG("byte_count: %d\n", byte_count);
1219−
1220− temp_buflist = krealloc(dma->buflist,
1221− (dma->buf_count + entry->buf_count) *
1222− sizeof(*dma->buflist), GFP_KERNEL);
1223− if (!temp_buflist) {
1224− /* Free the entry because it isn't valid */
1225− drm_cleanup_buf_error(dev, entry);
1226− mutex_unlock(&dev->struct_mutex);
1227− atomic_dec(&dev->buf_alloc);
1228− return -ENOMEM;
1229− }
1230− dma->buflist = temp_buflist;
1231−
1232− for (i = 0; i < entry->buf_count; i++) {
1233− dma->buflist[i + dma->buf_count] = &entry->buflist[i];
1234− }
1235−
1236− dma->buf_count += entry->buf_count;
1237− dma->seg_count += entry->seg_count;
1238− dma->page_count += byte_count >> PAGE_SHIFT;
1239− dma->byte_count += byte_count;
1240−
1241− DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
1242− DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
1243−
1244− mutex_unlock(&dev->struct_mutex);
1245−
1246− request->count = entry->buf_count;
1247− request->size = size;
1248−
1249− dma->flags = _DRM_DMA_USE_SG;
1250−
1251− atomic_dec(&dev->buf_alloc);
1252− return 0;
1253−}
1254−
1255−/*
1256− * Add buffers for DMA transfers (ioctl).
1257− *
1258− * \param inode device inode.
1259− * \param file_priv DRM file private.
1260− * \param cmd command.
1261− * \param arg pointer to a struct drm_buf_desc request.
1262− * \return zero on success or a negative number on failure.
1263− *
1264− * According with the memory type specified in drm_buf_desc::flags and the
1265− * build options, it dispatches the call either to addbufs_agp(),
1266− * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
1267− * PCI memory respectively.
1268− */
1269−int drm_legacy_addbufs(struct drm_device *dev, void *data,
1270− struct drm_file *file_priv)
1271−{
1272− struct drm_buf_desc *request = data;
1273− int ret;
1274−
1275− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
1276− return -EOPNOTSUPP;
1277−
1278− if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1279− return -EOPNOTSUPP;
1280−
1281−#if IS_ENABLED(CONFIG_AGP)
1282− if (request->flags & _DRM_AGP_BUFFER)
1283− ret = drm_legacy_addbufs_agp(dev, request);
1284− else
1285−#endif
1286− if (request->flags & _DRM_SG_BUFFER)
1287− ret = drm_legacy_addbufs_sg(dev, request);
1288− else if (request->flags & _DRM_FB_BUFFER)
1289− ret = -EINVAL;
1290− else
1291− ret = drm_legacy_addbufs_pci(dev, request);
1292−
1293− return ret;
1294−}
1295−
1296−/*
1297− * Get information about the buffer mappings.
1298− *
1299− * This was originally mean for debugging purposes, or by a sophisticated
1300− * client library to determine how best to use the available buffers (e.g.,
1301− * large buffers can be used for image transfer).
1302− *
1303− * \param inode device inode.
1304− * \param file_priv DRM file private.
1305− * \param cmd command.
1306− * \param arg pointer to a drm_buf_info structure.
1307− * \return zero on success or a negative number on failure.
1308− *
1309− * Increments drm_device::buf_use while holding the drm_device::buf_lock
1310− * lock, preventing of allocating more buffers after this call. Information
1311− * about each requested buffer is then copied into user space.
1312− */
1313−int __drm_legacy_infobufs(struct drm_device *dev,
1314− void *data, int *p,
1315− int (*f)(void *, int, struct drm_buf_entry *))
1316−{
1317− struct drm_device_dma *dma = dev->dma;
1318− int i;
1319− int count;
1320−
1321− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
1322− return -EOPNOTSUPP;
1323−
1324− if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1325− return -EOPNOTSUPP;
1326−
1327− if (!dma)
1328− return -EINVAL;
1329−
1330− spin_lock(&dev->buf_lock);
1331− if (atomic_read(&dev->buf_alloc)) {
1332− spin_unlock(&dev->buf_lock);
1333− return -EBUSY;
1334− }
1335− ++dev->buf_use; /* Can't allocate more after this call */
1336− spin_unlock(&dev->buf_lock);
1337−
1338− for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
1339− if (dma->bufs[i].buf_count)
1340− ++count;
1341− }
1342−
1343− DRM_DEBUG("count = %d\n", count);
1344−
1345− if (*p >= count) {
1346− for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
1347− struct drm_buf_entry *from = &dma->bufs[i];
1348−
1349− if (from->buf_count) {
1350− if (f(data, count, from) < 0)
1351− return -EFAULT;
1352− DRM_DEBUG("%d %d %d %d %d\n",
1353− i,
1354− dma->bufs[i].buf_count,
1355− dma->bufs[i].buf_size,
1356− dma->bufs[i].low_mark,
1357− dma->bufs[i].high_mark);
1358− ++count;
1359− }
1360− }
1361− }
1362− *p = count;
1363−
1364− return 0;
1365−}
1366−
1367−static int copy_one_buf(void *data, int count, struct drm_buf_entry *from)
1368−{
1369− struct drm_buf_info *request = data;
1370− struct drm_buf_desc __user *to = &request->list[count];
1371− struct drm_buf_desc v = {.count = from->buf_count,
1372− .size = from->buf_size,
1373− .low_mark = from->low_mark,
1374− .high_mark = from->high_mark};
1375−
1376− if (copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags)))
1377− return -EFAULT;
1378− return 0;
1379−}
1380−
1381−int drm_legacy_infobufs(struct drm_device *dev, void *data,
1382− struct drm_file *file_priv)
1383−{
1384− struct drm_buf_info *request = data;
1385−
1386− return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf);
1387−}
1388−
1389−/*
1390− * Specifies a low and high water mark for buffer allocation
1391− *
1392− * \param inode device inode.
1393− * \param file_priv DRM file private.
1394− * \param cmd command.
1395− * \param arg a pointer to a drm_buf_desc structure.
1396− * \return zero on success or a negative number on failure.
1397− *
1398− * Verifies that the size order is bounded between the admissible orders and
1399− * updates the respective drm_device_dma::bufs entry low and high water mark.
1400− *
1401− * \note This ioctl is deprecated and mostly never used.
1402− */
1403−int drm_legacy_markbufs(struct drm_device *dev, void *data,
1404− struct drm_file *file_priv)
1405−{
1406− struct drm_device_dma *dma = dev->dma;
1407− struct drm_buf_desc *request = data;
1408− int order;
1409− struct drm_buf_entry *entry;
1410−
1411− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
1412− return -EOPNOTSUPP;
1413−
1414− if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1415− return -EOPNOTSUPP;
1416−
1417− if (!dma)
1418− return -EINVAL;
1419−
1420− DRM_DEBUG("%d, %d, %d\n",
1421− request->size, request->low_mark, request->high_mark);
1422− order = order_base_2(request->size);
1423− if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
1424− return -EINVAL;
1425− entry = &dma->bufs[order];
1426−
1427− if (request->low_mark < 0 || request->low_mark > entry->buf_count)
1428− return -EINVAL;
1429− if (request->high_mark < 0 || request->high_mark > entry->buf_count)
1430− return -EINVAL;
1431−
1432− entry->low_mark = request->low_mark;
1433− entry->high_mark = request->high_mark;
1434−
1435− return 0;
1436−}
1437−
1438−/*
1439− * Unreserve the buffers in list, previously reserved using drmDMA.
1440− *
1441− * \param inode device inode.
1442− * \param file_priv DRM file private.
1443− * \param cmd command.
1444− * \param arg pointer to a drm_buf_free structure.
1445− * \return zero on success or a negative number on failure.
1446− *
1447− * Calls free_buffer() for each used buffer.
1448− * This function is primarily used for debugging.
1449− */
1450−int drm_legacy_freebufs(struct drm_device *dev, void *data,
1451− struct drm_file *file_priv)
1452−{
1453− struct drm_device_dma *dma = dev->dma;
1454− struct drm_buf_free *request = data;
1455− int i;
1456− int idx;
1457− struct drm_buf *buf;
1458−
1459− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
1460− return -EOPNOTSUPP;
1461−
1462− if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1463− return -EOPNOTSUPP;
1464−
1465− if (!dma)
1466− return -EINVAL;
1467−
1468− DRM_DEBUG("%d\n", request->count);
1469− for (i = 0; i < request->count; i++) {
1470− if (copy_from_user(&idx, &request->list[i], sizeof(idx)))
1471− return -EFAULT;
1472− if (idx < 0 || idx >= dma->buf_count) {
1473− DRM_ERROR("Index %d (of %d max)\n",
1474− idx, dma->buf_count - 1);
1475− return -EINVAL;
1476− }
1477− idx = array_index_nospec(idx, dma->buf_count);
1478− buf = dma->buflist[idx];
1479− if (buf->file_priv != file_priv) {
1480− DRM_ERROR("Process %d freeing buffer not owned\n",
1481− task_pid_nr(current));
1482− return -EINVAL;
1483− }
1484− drm_legacy_free_buffer(dev, buf);
1485− }
1486−
1487− return 0;
1488−}
1489−
1490−/*
1491− * Maps all of the DMA buffers into client-virtual space (ioctl).
1492− *
1493− * \param inode device inode.
1494− * \param file_priv DRM file private.
1495− * \param cmd command.
1496− * \param arg pointer to a drm_buf_map structure.
1497− * \return zero on success or a negative number on failure.
1498− *
1499− * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information
1500− * about each buffer into user space. For PCI buffers, it calls vm_mmap() with
1501− * offset equal to 0, which drm_mmap() interprets as PCI buffers and calls
1502− * drm_mmap_dma().
1503− */
1504−int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p,
1505− void __user **v,
1506− int (*f)(void *, int, unsigned long,
1507− struct drm_buf *),
1508− struct drm_file *file_priv)
1509−{
1510− struct drm_device_dma *dma = dev->dma;
1511− int retcode = 0;
1512− unsigned long virtual;
1513− int i;
1514−
1515− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
1516− return -EOPNOTSUPP;
1517−
1518− if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1519− return -EOPNOTSUPP;
1520−
1521− if (!dma)
1522− return -EINVAL;
1523−
1524− spin_lock(&dev->buf_lock);
1525− if (atomic_read(&dev->buf_alloc)) {
1526− spin_unlock(&dev->buf_lock);
1527− return -EBUSY;
1528− }
1529− dev->buf_use++; /* Can't allocate more after this call */
1530− spin_unlock(&dev->buf_lock);
1531−
1532− if (*p >= dma->buf_count) {
1533− if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP))
1534− || (drm_core_check_feature(dev, DRIVER_SG)
1535− && (dma->flags & _DRM_DMA_USE_SG))) {
1536− struct drm_local_map *map = dev->agp_buffer_map;
1537− unsigned long token = dev->agp_buffer_token;
1538−
1539− if (!map) {
1540− retcode = -EINVAL;
1541− goto done;
1542− }
1543− virtual = vm_mmap(file_priv->filp, 0, map->size,
1544− PROT_READ | PROT_WRITE,
1545− MAP_SHARED,
1546− token);
1547− } else {
1548− virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,
1549− PROT_READ | PROT_WRITE,
1550− MAP_SHARED, 0);
1551− }
1552− if (virtual > -1024UL) {
1553− /* Real error */
1554− retcode = (signed long)virtual;
1555− goto done;
1556− }
1557− *v = (void __user *)virtual;
1558−
1559− for (i = 0; i < dma->buf_count; i++) {
1560− if (f(data, i, virtual, dma->buflist[i]) < 0) {
1561− retcode = -EFAULT;
1562− goto done;
1563− }
1564− }
1565− }
1566− done:
1567− *p = dma->buf_count;
1568− DRM_DEBUG("%d buffers, retcode = %d\n", *p, retcode);
1569−
1570− return retcode;
1571−}
1572−
1573−static int map_one_buf(void *data, int idx, unsigned long virtual,
1574− struct drm_buf *buf)
1575−{
1576− struct drm_buf_map *request = data;
1577− unsigned long address = virtual + buf->offset; /* *** */
1578−
1579− if (copy_to_user(&request->list[idx].idx, &buf->idx,
1580− sizeof(request->list[0].idx)))
1581− return -EFAULT;
1582− if (copy_to_user(&request->list[idx].total, &buf->total,
1583− sizeof(request->list[0].total)))
1584− return -EFAULT;
1585− if (clear_user(&request->list[idx].used, sizeof(int)))
1586− return -EFAULT;
1587− if (copy_to_user(&request->list[idx].address, &address,
1588− sizeof(address)))
1589− return -EFAULT;
1590− return 0;
1591−}
1592−
1593−int drm_legacy_mapbufs(struct drm_device *dev, void *data,
1594− struct drm_file *file_priv)
1595−{
1596− struct drm_buf_map *request = data;
1597−
1598− return __drm_legacy_mapbufs(dev, data, &request->count,
1599− &request->virtual, map_one_buf,
1600− file_priv);
1601−}
1602−
1603−int drm_legacy_dma_ioctl(struct drm_device *dev, void *data,
1604− struct drm_file *file_priv)
1605−{
1606− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
1607− return -EOPNOTSUPP;
1608−
1609− if (dev->driver->dma_ioctl)
1610− return dev->driver->dma_ioctl(dev, data, file_priv);
1611− else
1612− return -EINVAL;
1613−}
1614−
1615−struct drm_local_map *drm_legacy_getsarea(struct drm_device *dev)
1616−{
1617− struct drm_map_list *entry;
1618−
1619− list_for_each_entry(entry, &dev->maplist, head) {
1620− if (entry->map && entry->map->type == _DRM_SHM &&
1621− (entry->map->flags & _DRM_CONTAINS_LOCK)) {
1622− return entry->map;
1623− }
1624− }
1625− return NULL;
1626−}
1627−EXPORT_SYMBOL(drm_legacy_getsarea);
drivers/gpu/drm/drm_client.c+1−11
@@ -5,7 +5,6 @@ · 4 unmodified lines
55
66 #include <linux/iosys-map.h>
77 #include <linux/list.h>
8−#include <linux/module.h>
98 #include <linux/mutex.h>
109 #include <linux/seq_file.h>
1110 #include <linux/slab.h>
@@ -84,16 +83,13 @@ int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, · 72 unmodified lines
8483 if (!drm_core_check_feature(dev, DRIVER_MODESET) || !dev->driver->dumb_create)
8584 return -EOPNOTSUPP;
8685
87− if (funcs && !try_module_get(funcs->owner))
88− return -ENODEV;
89−
9086 client->dev = dev;
9187 client->name = name;
9288 client->funcs = funcs;
9389
9490 ret = drm_client_modeset_create(client);
9591 if (ret)
96− goto err_put_module;
92+ return ret;
9793
9894 ret = drm_client_open(client);
9995 if (ret)
@@ -105,10 +101,6 @@ int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, · 5 unmodified lines
105101
106102 err_free:
107103 drm_client_modeset_free(client);
108−err_put_module:
109− if (funcs)
110− module_put(funcs->owner);
111−
112104 return ret;
113105 }
114106 EXPORT_SYMBOL(drm_client_init);
@@ -177,8 +169,6 @@ void drm_client_release(struct drm_client_dev *client) · 62 unmodified lines
177169 drm_client_modeset_free(client);
178170 drm_client_close(client);
179171 drm_dev_put(dev);
180− if (client->funcs)
181− module_put(client->funcs->owner);
182172 }
183173 EXPORT_SYMBOL(drm_client_release);
184174
drivers/gpu/drm/drm_connector.c+6−0
@@ -1198,6 +1198,12 @@ static const u32 dp_colorspaces = · 1197 unmodified lines
11981198 * drm_connector_set_path_property(), in the case of DP MST with the
11991199 * path property the MST manager created. Userspace cannot change this
12001200 * property.
1201+ *
1202+ * In the case of DP MST, the property has the format
1203+ * ``mst:<parent>-<ports>`` where ``<parent>`` is the KMS object ID of the
1204+ * parent connector and ``<ports>`` is a hyphen-separated list of DP MST
1205+ * port numbers. Note, KMS object IDs are not guaranteed to be stable
1206+ * across reboots.
12011207 * TILE:
12021208 * Connector tile group property to indicate how a set of DRM connector
12031209 * compose together into one logical screen. This is used by both high-res
drivers/gpu/drm/drm_context.c+0−513
@@ -1,513 +0,0 @@
1−/*
2− * Legacy: Generic DRM Contexts
3− *
4− * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
5− * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6− * All Rights Reserved.
7− *
8− * Author: Rickard E. (Rik) Faith <faith@valinux.com>
9− * Author: Gareth Hughes <gareth@valinux.com>
10− *
11− * Permission is hereby granted, free of charge, to any person obtaining a
12− * copy of this software and associated documentation files (the "Software"),
13− * to deal in the Software without restriction, including without limitation
14− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15− * and/or sell copies of the Software, and to permit persons to whom the
16− * Software is furnished to do so, subject to the following conditions:
17− *
18− * The above copyright notice and this permission notice (including the next
19− * paragraph) shall be included in all copies or substantial portions of the
20− * Software.
21− *
22− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23− * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25− * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26− * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27− * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28− * OTHER DEALINGS IN THE SOFTWARE.
29− */
30−
31−#include <linux/slab.h>
32−#include <linux/uaccess.h>
33−
34−#include <drm/drm_drv.h>
35−#include <drm/drm_file.h>
36−#include <drm/drm_print.h>
37−
38−#include "drm_legacy.h"
39−
40−struct drm_ctx_list {
41− struct list_head head;
42− drm_context_t handle;
43− struct drm_file *tag;
44−};
45−
46−/******************************************************************/
47−/** \name Context bitmap support */
48−/*@{*/
49−
50−/*
51− * Free a handle from the context bitmap.
52− *
53− * \param dev DRM device.
54− * \param ctx_handle context handle.
55− *
56− * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
57− * in drm_device::ctx_idr, while holding the drm_device::struct_mutex
58− * lock.
59− */
60−void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
61−{
62− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
63− return;
64−
65− mutex_lock(&dev->struct_mutex);
66− idr_remove(&dev->ctx_idr, ctx_handle);
67− mutex_unlock(&dev->struct_mutex);
68−}
69−
70−/*
71− * Context bitmap allocation.
72− *
73− * \param dev DRM device.
74− * \return (non-negative) context handle on success or a negative number on failure.
75− *
76− * Allocate a new idr from drm_device::ctx_idr while holding the
77− * drm_device::struct_mutex lock.
78− */
79−static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
80−{
81− int ret;
82−
83− mutex_lock(&dev->struct_mutex);
84− ret = idr_alloc(&dev->ctx_idr, NULL, DRM_RESERVED_CONTEXTS, 0,
85− GFP_KERNEL);
86− mutex_unlock(&dev->struct_mutex);
87− return ret;
88−}
89−
90−/*
91− * Context bitmap initialization.
92− *
93− * \param dev DRM device.
94− *
95− * Initialise the drm_device::ctx_idr
96− */
97−void drm_legacy_ctxbitmap_init(struct drm_device * dev)
98−{
99− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
100− return;
101−
102− idr_init(&dev->ctx_idr);
103−}
104−
105−/*
106− * Context bitmap cleanup.
107− *
108− * \param dev DRM device.
109− *
110− * Free all idr members using drm_ctx_sarea_free helper function
111− * while holding the drm_device::struct_mutex lock.
112− */
113−void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
114−{
115− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
116− return;
117−
118− mutex_lock(&dev->struct_mutex);
119− idr_destroy(&dev->ctx_idr);
120− mutex_unlock(&dev->struct_mutex);
121−}
122−
123−/**
124− * drm_legacy_ctxbitmap_flush() - Flush all contexts owned by a file
125− * @dev: DRM device to operate on
126− * @file: Open file to flush contexts for
127− *
128− * This iterates over all contexts on @dev and drops them if they're owned by
129− * @file. Note that after this call returns, new contexts might be added if
130− * the file is still alive.
131− */
132−void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
133−{
134− struct drm_ctx_list *pos, *tmp;
135−
136− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
137− return;
138−
139− mutex_lock(&dev->ctxlist_mutex);
140−
141− list_for_each_entry_safe(pos, tmp, &dev->ctxlist, head) {
142− if (pos->tag == file &&
143− pos->handle != DRM_KERNEL_CONTEXT) {
144− if (dev->driver->context_dtor)
145− dev->driver->context_dtor(dev, pos->handle);
146−
147− drm_legacy_ctxbitmap_free(dev, pos->handle);
148− list_del(&pos->head);
149− kfree(pos);
150− }
151− }
152−
153− mutex_unlock(&dev->ctxlist_mutex);
154−}
155−
156−/*@}*/
157−
158−/******************************************************************/
159−/** \name Per Context SAREA Support */
160−/*@{*/
161−
162−/*
163− * Get per-context SAREA.
164− *
165− * \param inode device inode.
166− * \param file_priv DRM file private.
167− * \param cmd command.
168− * \param arg user argument pointing to a drm_ctx_priv_map structure.
169− * \return zero on success or a negative number on failure.
170− *
171− * Gets the map from drm_device::ctx_idr with the handle specified and
172− * returns its handle.
173− */
174−int drm_legacy_getsareactx(struct drm_device *dev, void *data,
175− struct drm_file *file_priv)
176−{
177− struct drm_ctx_priv_map *request = data;
178− struct drm_local_map *map;
179− struct drm_map_list *_entry;
180−
181− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
182− return -EOPNOTSUPP;
183−
184− mutex_lock(&dev->struct_mutex);
185−
186− map = idr_find(&dev->ctx_idr, request->ctx_id);
187− if (!map) {
188− mutex_unlock(&dev->struct_mutex);
189− return -EINVAL;
190− }
191−
192− request->handle = NULL;
193− list_for_each_entry(_entry, &dev->maplist, head) {
194− if (_entry->map == map) {
195− request->handle =
196− (void *)(unsigned long)_entry->user_token;
197− break;
198− }
199− }
200−
201− mutex_unlock(&dev->struct_mutex);
202−
203− if (request->handle == NULL)
204− return -EINVAL;
205−
206− return 0;
207−}
208−
209−/*
210− * Set per-context SAREA.
211− *
212− * \param inode device inode.
213− * \param file_priv DRM file private.
214− * \param cmd command.
215− * \param arg user argument pointing to a drm_ctx_priv_map structure.
216− * \return zero on success or a negative number on failure.
217− *
218− * Searches the mapping specified in \p arg and update the entry in
219− * drm_device::ctx_idr with it.
220− */
221−int drm_legacy_setsareactx(struct drm_device *dev, void *data,
222− struct drm_file *file_priv)
223−{
224− struct drm_ctx_priv_map *request = data;
225− struct drm_local_map *map = NULL;
226− struct drm_map_list *r_list = NULL;
227−
228− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
229− return -EOPNOTSUPP;
230−
231− mutex_lock(&dev->struct_mutex);
232− list_for_each_entry(r_list, &dev->maplist, head) {
233− if (r_list->map
234− && r_list->user_token == (unsigned long) request->handle)
235− goto found;
236− }
237− bad:
238− mutex_unlock(&dev->struct_mutex);
239− return -EINVAL;
240−
241− found:
242− map = r_list->map;
243− if (!map)
244− goto bad;
245−
246− if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id)))
247− goto bad;
248−
249− mutex_unlock(&dev->struct_mutex);
250−
251− return 0;
252−}
253−
254−/*@}*/
255−
256−/******************************************************************/
257−/** \name The actual DRM context handling routines */
258−/*@{*/
259−
260−/*
261− * Switch context.
262− *
263− * \param dev DRM device.
264− * \param old old context handle.
265− * \param new new context handle.
266− * \return zero on success or a negative number on failure.
267− *
268− * Attempt to set drm_device::context_flag.
269− */
270−static int drm_context_switch(struct drm_device * dev, int old, int new)
271−{
272− if (test_and_set_bit(0, &dev->context_flag)) {
273− DRM_ERROR("Reentering -- FIXME\n");
274− return -EBUSY;
275− }
276−
277− DRM_DEBUG("Context switch from %d to %d\n", old, new);
278−
279− if (new == dev->last_context) {
280− clear_bit(0, &dev->context_flag);
281− return 0;
282− }
283−
284− return 0;
285−}
286−
287−/*
288− * Complete context switch.
289− *
290− * \param dev DRM device.
291− * \param new new context handle.
292− * \return zero on success or a negative number on failure.
293− *
294− * Updates drm_device::last_context and drm_device::last_switch. Verifies the
295− * hardware lock is held, clears the drm_device::context_flag and wakes up
296− * drm_device::context_wait.
297− */
298−static int drm_context_switch_complete(struct drm_device *dev,
299− struct drm_file *file_priv, int new)
300−{
301− dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
302−
303− if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock)) {
304− DRM_ERROR("Lock isn't held after context switch\n");
305− }
306−
307− /* If a context switch is ever initiated
308− when the kernel holds the lock, release
309− that lock here.
310− */
311− clear_bit(0, &dev->context_flag);
312−
313− return 0;
314−}
315−
316−/*
317− * Reserve contexts.
318− *
319− * \param inode device inode.
320− * \param file_priv DRM file private.
321− * \param cmd command.
322− * \param arg user argument pointing to a drm_ctx_res structure.
323− * \return zero on success or a negative number on failure.
324− */
325−int drm_legacy_resctx(struct drm_device *dev, void *data,
326− struct drm_file *file_priv)
327−{
328− struct drm_ctx_res *res = data;
329− struct drm_ctx ctx;
330− int i;
331−
332− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
333− return -EOPNOTSUPP;
334−
335− if (res->count >= DRM_RESERVED_CONTEXTS) {
336− memset(&ctx, 0, sizeof(ctx));
337− for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
338− ctx.handle = i;
339− if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx)))
340− return -EFAULT;
341− }
342− }
343− res->count = DRM_RESERVED_CONTEXTS;
344−
345− return 0;
346−}
347−
348−/*
349− * Add context.
350− *
351− * \param inode device inode.
352− * \param file_priv DRM file private.
353− * \param cmd command.
354− * \param arg user argument pointing to a drm_ctx structure.
355− * \return zero on success or a negative number on failure.
356− *
357− * Get a new handle for the context and copy to userspace.
358− */
359−int drm_legacy_addctx(struct drm_device *dev, void *data,
360− struct drm_file *file_priv)
361−{
362− struct drm_ctx_list *ctx_entry;
363− struct drm_ctx *ctx = data;
364− int tmp_handle;
365−
366− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
367− return -EOPNOTSUPP;
368−
369− tmp_handle = drm_legacy_ctxbitmap_next(dev);
370− if (tmp_handle == DRM_KERNEL_CONTEXT) {
371− /* Skip kernel's context and get a new one. */
372− tmp_handle = drm_legacy_ctxbitmap_next(dev);
373− }
374− DRM_DEBUG("%d\n", tmp_handle);
375− if (tmp_handle < 0) {
376− DRM_DEBUG("Not enough free contexts.\n");
377− /* Should this return -EBUSY instead? */
378− return tmp_handle;
379− }
380−
381− ctx->handle = tmp_handle;
382−
383− ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL);
384− if (!ctx_entry) {
385− DRM_DEBUG("out of memory\n");
386− return -ENOMEM;
387− }
388−
389− INIT_LIST_HEAD(&ctx_entry->head);
390− ctx_entry->handle = ctx->handle;
391− ctx_entry->tag = file_priv;
392−
393− mutex_lock(&dev->ctxlist_mutex);
394− list_add(&ctx_entry->head, &dev->ctxlist);
395− mutex_unlock(&dev->ctxlist_mutex);
396−
397− return 0;
398−}
399−
400−/*
401− * Get context.
402− *
403− * \param inode device inode.
404− * \param file_priv DRM file private.
405− * \param cmd command.
406− * \param arg user argument pointing to a drm_ctx structure.
407− * \return zero on success or a negative number on failure.
408− */
409−int drm_legacy_getctx(struct drm_device *dev, void *data,
410− struct drm_file *file_priv)
411−{
412− struct drm_ctx *ctx = data;
413−
414− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
415− return -EOPNOTSUPP;
416−
417− /* This is 0, because we don't handle any context flags */
418− ctx->flags = 0;
419−
420− return 0;
421−}
422−
423−/*
424− * Switch context.
425− *
426− * \param inode device inode.
427− * \param file_priv DRM file private.
428− * \param cmd command.
429− * \param arg user argument pointing to a drm_ctx structure.
430− * \return zero on success or a negative number on failure.
431− *
432− * Calls context_switch().
433− */
434−int drm_legacy_switchctx(struct drm_device *dev, void *data,
435− struct drm_file *file_priv)
436−{
437− struct drm_ctx *ctx = data;
438−
439− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
440− return -EOPNOTSUPP;
441−
442− DRM_DEBUG("%d\n", ctx->handle);
443− return drm_context_switch(dev, dev->last_context, ctx->handle);
444−}
445−
446−/*
447− * New context.
448− *
449− * \param inode device inode.
450− * \param file_priv DRM file private.
451− * \param cmd command.
452− * \param arg user argument pointing to a drm_ctx structure.
453− * \return zero on success or a negative number on failure.
454− *
455− * Calls context_switch_complete().
456− */
457−int drm_legacy_newctx(struct drm_device *dev, void *data,
458− struct drm_file *file_priv)
459−{
460− struct drm_ctx *ctx = data;
461−
462− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
463− return -EOPNOTSUPP;
464−
465− DRM_DEBUG("%d\n", ctx->handle);
466− drm_context_switch_complete(dev, file_priv, ctx->handle);
467−
468− return 0;
469−}
470−
471−/*
472− * Remove context.
473− *
474− * \param inode device inode.
475− * \param file_priv DRM file private.
476− * \param cmd command.
477− * \param arg user argument pointing to a drm_ctx structure.
478− * \return zero on success or a negative number on failure.
479− *
480− * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
481− */
482−int drm_legacy_rmctx(struct drm_device *dev, void *data,
483− struct drm_file *file_priv)
484−{
485− struct drm_ctx *ctx = data;
486−
487− if (!drm_core_check_feature(dev, DRIVER_LEGACY))
488− return -EOPNOTSUPP;
489−
490− DRM_DEBUG("%d\n", ctx->handle);
491− if (ctx->handle != DRM_KERNEL_CONTEXT) {
492− if (dev->driver->context_dtor)
493− dev->driver->context_dtor(dev, ctx->handle);
494− drm_legacy_ctxbitmap_free(dev, ctx->handle);
495− }
496−
497− mutex_lock(&dev->ctxlist_mutex);
498− if (!list_empty(&dev->ctxlist)) {
499− struct drm_ctx_list *pos, *n;
500−
501− list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
502− if (pos->handle == ctx->handle) {
503− list_del(&pos->head);
504− kfree(pos);
505− }
506− }
507− }
508− mutex_unlock(&dev->ctxlist_mutex);
509−
510− return 0;
511−}
512−
513−/*@}*/
drivers/gpu/drm/drm_crtc_helper.c+2−5
@@ -439,11 +439,8 @@ EXPORT_SYMBOL(drm_crtc_helper_set_mode); · 438 unmodified lines
439439 * @state: atomic state object
440440 *
441441 * Provides a default CRTC-state check handler for CRTCs that only have
442− * one primary plane attached to it.
443− *
444− * This is often the case for the CRTC of simple framebuffers. See also
445− * drm_plane_helper_atomic_check() for the respective plane-state check
446− * helper function.
442+ * one primary plane attached to it. This is often the case for the CRTC
443+ * of simple framebuffers.
447444 *
448445 * RETURNS:
449446 * Zero on success, or an errno code otherwise.
drivers/gpu/drm/drm_crtc_internal.h+3−1
@@ -222,6 +222,8 @@ int drm_mode_addfb2_ioctl(struct drm_device *dev, · 221 unmodified lines
222222 void *data, struct drm_file *file_priv);
223223 int drm_mode_rmfb_ioctl(struct drm_device *dev,
224224 void *data, struct drm_file *file_priv);
225+int drm_mode_closefb_ioctl(struct drm_device *dev,
226+ void *data, struct drm_file *file_priv);
225227 int drm_mode_getfb(struct drm_device *dev,
226228 void *data, struct drm_file *file_priv);
227229 int drm_mode_getfb2_ioctl(struct drm_device *dev,
@@ -251,7 +253,7 @@ int drm_atomic_set_property(struct drm_atomic_state *state, · 23 unmodified lines
251253 struct drm_file *file_priv,
252254 struct drm_mode_object *obj,
253255 struct drm_property *prop,
254− uint64_t prop_value);
256+ u64 prop_value, bool async_flip);
255257 int drm_atomic_get_property(struct drm_mode_object *obj,
256258 struct drm_property *property, uint64_t *val);
257259
drivers/gpu/drm/drm_damage_helper.c+2−1
@@ -241,7 +241,8 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, · 240 unmodified lines
241241 iter->plane_src.x2 = (src.x2 >> 16) + !!(src.x2 & 0xFFFF);
242242 iter->plane_src.y2 = (src.y2 >> 16) + !!(src.y2 & 0xFFFF);
243243
244− if (!iter->clips || !drm_rect_equals(&state->src, &old_state->src)) {
244+ if (!iter->clips || state->ignore_damage_clips ||
245+ !drm_rect_equals(&state->src, &old_state->src)) {
245246 iter->clips = NULL;
246247 iter->num_clips = 0;
247248 iter->full_update = true;
drivers/gpu/drm/drm_debugfs.c+62−3
@@ -314,10 +314,8 @@ void drm_debugfs_dev_register(struct drm_device *dev) · 313 unmodified lines
314314 drm_framebuffer_debugfs_init(dev);
315315 drm_client_debugfs_init(dev);
316316 }
317− if (drm_drv_uses_atomic_modeset(dev)) {
317+ if (drm_drv_uses_atomic_modeset(dev))
318318 drm_atomic_debugfs_init(dev);
319− drm_bridge_debugfs_init(dev);
320− }
321319 }
322320
323321 int drm_debugfs_register(struct drm_minor *minor, int minor_id,
@@ -589,4 +587,65 @@ void drm_debugfs_crtc_remove(struct drm_crtc *crtc) · 265 unmodified lines
589587 crtc->debugfs_entry = NULL;
590588 }
591589
590+static int bridges_show(struct seq_file *m, void *data)
591+{
592+ struct drm_encoder *encoder = m->private;
593+ struct drm_printer p = drm_seq_file_printer(m);
594+ struct drm_bridge *bridge;
595+ unsigned int idx = 0;
596+
597+ drm_for_each_bridge_in_chain(encoder, bridge) {
598+ drm_printf(&p, "bridge[%d]: %ps\n", idx++, bridge->funcs);
599+ drm_printf(&p, "\ttype: [%d] %s\n",
600+ bridge->type,
601+ drm_get_connector_type_name(bridge->type));
602+#ifdef CONFIG_OF
603+ if (bridge->of_node)
604+ drm_printf(&p, "\tOF: %pOFfc\n", bridge->of_node);
605+#endif
606+ drm_printf(&p, "\tops: [0x%x]", bridge->ops);
607+ if (bridge->ops & DRM_BRIDGE_OP_DETECT)
608+ drm_puts(&p, " detect");
609+ if (bridge->ops & DRM_BRIDGE_OP_EDID)
610+ drm_puts(&p, " edid");
611+ if (bridge->ops & DRM_BRIDGE_OP_HPD)
612+ drm_puts(&p, " hpd");
613+ if (bridge->ops & DRM_BRIDGE_OP_MODES)
614+ drm_puts(&p, " modes");
615+ drm_puts(&p, "\n");
616+ }
617+
618+ return 0;
619+}
620+DEFINE_SHOW_ATTRIBUTE(bridges);
621+
622+void drm_debugfs_encoder_add(struct drm_encoder *encoder)
623+{
624+ struct drm_minor *minor = encoder->dev->primary;
625+ struct dentry *root;
626+ char *name;
627+
628+ name = kasprintf(GFP_KERNEL, "encoder-%d", encoder->index);
629+ if (!name)
630+ return;
631+
632+ root = debugfs_create_dir(name, minor->debugfs_root);
633+ kfree(name);
634+
635+ encoder->debugfs_entry = root;
636+
637+ /* bridges list */
638+ debugfs_create_file("bridges", 0444, root, encoder,
639+ &bridges_fops);
640+
641+ if (encoder->funcs && encoder->funcs->debugfs_init)
642+ encoder->funcs->debugfs_init(encoder, root);
643+}
644+
645+void drm_debugfs_encoder_remove(struct drm_encoder *encoder)
646+{
647+ debugfs_remove_recursive(encoder->debugfs_entry);
648+ encoder->debugfs_entry = NULL;
649+}
650+
592651 #endif /* CONFIG_DEBUG_FS */
drivers/gpu/drm/drm_dma.c+0−178
@@ -1,178 +0,0 @@
1−/*
2− * \file drm_dma.c
3− * DMA IOCTL and function support
4− *
5− * \author Rickard E. (Rik) Faith <faith@valinux.com>
6− * \author Gareth Hughes <gareth@valinux.com>
7− */
8−
9−/*
10− * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
11− *
12− * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13− * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14− * All Rights Reserved.
15− *
16− * Permission is hereby granted, free of charge, to any person obtaining a
17− * copy of this software and associated documentation files (the "Software"),
18− * to deal in the Software without restriction, including without limitation
19− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20− * and/or sell copies of the Software, and to permit persons to whom the
21− * Software is furnished to do so, subject to the following conditions:
22− *
23− * The above copyright notice and this permission notice (including the next
24− * paragraph) shall be included in all copies or substantial portions of the
25− * Software.
26− *
27− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28− * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30− * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31− * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32− * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33− * OTHER DEALINGS IN THE SOFTWARE.
34− */
35−
36−#include <linux/export.h>
37−#include <linux/pci.h>
38−
39−#include <drm/drm_drv.h>
40−#include <drm/drm_print.h>
41−
42−#include "drm_legacy.h"
43−
44−/**
45− * drm_legacy_dma_setup() - Initialize the DMA data.
46− *
47− * @dev: DRM device.
48− * Return: zero on success or a negative value on failure.
49− *
50− * Allocate and initialize a drm_device_dma structure.
51− */
52−int drm_legacy_dma_setup(struct drm_device *dev)
53−{
54− int i;
55−
56− if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
57− !drm_core_check_feature(dev, DRIVER_LEGACY))
58− return 0;
59−
60− dev->buf_use = 0;
61− atomic_set(&dev->buf_alloc, 0);
62−
63− dev->dma = kzalloc(sizeof(*dev->dma), GFP_KERNEL);
64− if (!dev->dma)
65− return -ENOMEM;
66−
67− for (i = 0; i <= DRM_MAX_ORDER; i++)
68− memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
69−
70− return 0;
71−}
72−
73−/**
74− * drm_legacy_dma_takedown() - Cleanup the DMA resources.
75− *
76− * @dev: DRM device.
77− *
78− * Free all pages associated with DMA buffers, the buffers and pages lists, and
79− * finally the drm_device::dma structure itself.
80− */
81−void drm_legacy_dma_takedown(struct drm_device *dev)
82−{
83− struct drm_device_dma *dma = dev->dma;
84− drm_dma_handle_t *dmah;
85− int i, j;
86−
87− if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
88− !drm_core_check_feature(dev, DRIVER_LEGACY))
89− return;
90−
91− if (!dma)
92− return;
93−
94− /* Clear dma buffers */
95− for (i = 0; i <= DRM_MAX_ORDER; i++) {
96− if (dma->bufs[i].seg_count) {
97− DRM_DEBUG("order %d: buf_count = %d,"
98− " seg_count = %d\n",
99− i,
100− dma->bufs[i].buf_count,
101− dma->bufs[i].seg_count);
102− for (j = 0; j < dma->bufs[i].seg_count; j++) {
103− if (dma->bufs[i].seglist[j]) {
104− dmah = dma->bufs[i].seglist[j];
105− dma_free_coherent(dev->dev,
106− dmah->size,
107− dmah->vaddr,
108− dmah->busaddr);
109− kfree(dmah);
110− }
111− }
112− kfree(dma->bufs[i].seglist);
113− }
114− if (dma->bufs[i].buf_count) {
115− for (j = 0; j < dma->bufs[i].buf_count; j++) {
116− kfree(dma->bufs[i].buflist[j].dev_private);
117− }
118− kfree(dma->bufs[i].buflist);
119− }
120− }
121−
122− kfree(dma->buflist);
123− kfree(dma->pagelist);
124− kfree(dev->dma);
125− dev->dma = NULL;
126−}
127−
128−/**
129− * drm_legacy_free_buffer() - Free a buffer.
130− *
131− * @dev: DRM device.
132− * @buf: buffer to free.
133− *
134− * Resets the fields of \p buf.
135− */
136−void drm_legacy_free_buffer(struct drm_device *dev, struct drm_buf * buf)
137−{
138− if (!buf)
139− return;
140−
141− buf->waiting = 0;
142− buf->pending = 0;
143− buf->file_priv = NULL;
144− buf->used = 0;
145−}
146−
147−/**
148− * drm_legacy_reclaim_buffers() - Reclaim the buffers.
149− *
150− * @dev: DRM device.
151− * @file_priv: DRM file private.
152− *
153− * Frees each buffer associated with \p file_priv not already on the hardware.
154− */
155−void drm_legacy_reclaim_buffers(struct drm_device *dev,
156− struct drm_file *file_priv)
157−{
158− struct drm_device_dma *dma = dev->dma;
159− int i;
160−
161− if (!dma)
162− return;
163− for (i = 0; i < dma->buf_count; i++) {
164− if (dma->buflist[i]->file_priv == file_priv) {
165− switch (dma->buflist[i]->list) {
166− case DRM_LIST_NONE:
167− drm_legacy_free_buffer(dev, dma->buflist[i]);
168− break;
169− case DRM_LIST_WAIT:
170− dma->buflist[i]->list = DRM_LIST_RECLAIM;
171− break;
172− default:
173− /* Buffer already on hardware. */
174− break;
175− }
176− }
177− }
178−}
drivers/gpu/drm/drm_drv.c+8−19
@@ -48,7 +48,6 @@ · 47 unmodified lines
4848
4949 #include "drm_crtc_internal.h"
5050 #include "drm_internal.h"
51−#include "drm_legacy.h"
5251
5352 MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
5453 MODULE_DESCRIPTION("DRM shared core routines");
@@ -585,8 +584,6 @@ static void drm_fs_inode_free(struct inode *inode) · 530 unmodified lines
585584
586585 static void drm_dev_init_release(struct drm_device *dev, void *res)
587586 {
588− drm_legacy_ctxbitmap_cleanup(dev);
589− drm_legacy_remove_map_hash(dev);
590587 drm_fs_inode_free(dev->anon_inode);
591588
592589 put_device(dev->dev);
@@ -597,7 +594,6 @@ static void drm_dev_init_release(struct drm_device *dev, void *res) · 4 unmodified lines
597594 mutex_destroy(&dev->clientlist_mutex);
598595 mutex_destroy(&dev->filelist_mutex);
599596 mutex_destroy(&dev->struct_mutex);
600− drm_legacy_destroy_members(dev);
601597 }
602598
603599 static int drm_dev_init(struct drm_device *dev,
@@ -632,7 +628,6 @@ static int drm_dev_init(struct drm_device *dev, · 28 unmodified lines
632628 return -EINVAL;
633629 }
634630
635− drm_legacy_init_members(dev);
636631 INIT_LIST_HEAD(&dev->filelist);
637632 INIT_LIST_HEAD(&dev->filelist_internal);
638633 INIT_LIST_HEAD(&dev->clientlist);
@@ -673,12 +668,6 @@ static int drm_dev_init(struct drm_device *dev, · 34 unmodified lines
673668 goto err;
674669 }
675670
676− ret = drm_legacy_create_map_hash(dev);
677− if (ret)
678− goto err;
679−
680− drm_legacy_ctxbitmap_init(dev);
681−
682671 if (drm_core_check_feature(dev, DRIVER_GEM)) {
683672 ret = drm_gem_init(dev);
684673 if (ret) {
@@ -949,8 +938,11 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) · 264 unmodified lines
949938 goto err_minors;
950939 }
951940
952− if (drm_core_check_feature(dev, DRIVER_MODESET))
953− drm_modeset_register_all(dev);
941+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
942+ ret = drm_modeset_register_all(dev);
943+ if (ret)
944+ goto err_unload;
945+ }
954946
955947 DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
956948 driver->name, driver->major, driver->minor,
@@ -960,6 +952,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) · 3 unmodified lines
960952
961953 goto out_unlock;
962954
955+err_unload:
956+ if (dev->driver->unload)
957+ dev->driver->unload(dev);
963958 err_minors:
964959 remove_compat_control_link(dev);
965960 drm_minor_unregister(dev, DRM_MINOR_ACCEL);
@@ -990,9 +985,6 @@ EXPORT_SYMBOL(drm_dev_register); · 24 unmodified lines
990985 */
991986 void drm_dev_unregister(struct drm_device *dev)
992987 {
993− if (drm_core_check_feature(dev, DRIVER_LEGACY))
994− drm_lastclose(dev);
995−
996988 dev->registered = false;
997989
998990 drm_client_dev_unregister(dev);
@@ -1003,9 +995,6 @@ void drm_dev_unregister(struct drm_device *dev) · 4 unmodified lines
1003995 if (dev->driver->unload)
1004996 dev->driver->unload(dev);
1005997
1006− drm_legacy_pci_agp_destroy(dev);
1007− drm_legacy_rmmaps(dev);
1008−
1009998 remove_compat_control_link(dev);
1010999 drm_minor_unregister(dev, DRM_MINOR_ACCEL);
10111000 drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drivers/gpu/drm/drm_edid.c+31−12
@@ -41,10 +41,12 @@ · 40 unmodified lines
4141 #include <drm/drm_displayid.h>
4242 #include <drm/drm_drv.h>
4343 #include <drm/drm_edid.h>
44+#include <drm/drm_eld.h>
4445 #include <drm/drm_encoder.h>
4546 #include <drm/drm_print.h>
4647
4748 #include "drm_crtc_internal.h"
49+#include "drm_internal.h"
4850
4951 static int oui(u8 first, u8 second, u8 third)
5052 {
@@ -5509,6 +5511,27 @@ static void clear_eld(struct drm_connector *connector) · 5458 unmodified lines
55095511 connector->audio_latency[1] = 0;
55105512 }
55115513
5514+/*
5515+ * Get 3-byte SAD buffer from struct cea_sad.
5516+ */
5517+void drm_edid_cta_sad_get(const struct cea_sad *cta_sad, u8 *sad)
5518+{
5519+ sad[0] = cta_sad->format << 3 | cta_sad->channels;
5520+ sad[1] = cta_sad->freq;
5521+ sad[2] = cta_sad->byte2;
5522+}
5523+
5524+/*
5525+ * Set struct cea_sad from 3-byte SAD buffer.
5526+ */
5527+void drm_edid_cta_sad_set(struct cea_sad *cta_sad, const u8 *sad)
5528+{
5529+ cta_sad->format = (sad[0] & 0x78) >> 3;
5530+ cta_sad->channels = sad[0] & 0x07;
5531+ cta_sad->freq = sad[1] & 0x7f;
5532+ cta_sad->byte2 = sad[2];
5533+}
5534+
55125535 /*
55135536 * drm_edid_to_eld - build ELD from EDID
55145537 * @connector: connector corresponding to the HDMI/DP sink
@@ -5593,7 +5616,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, · 78 unmodified lines
55935616 }
55945617
55955618 static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
5596− struct cea_sad **sads)
5619+ struct cea_sad **psads)
55975620 {
55985621 const struct cea_db *db;
55995622 struct cea_db_iter iter;
@@ -5602,20 +5625,16 @@ static int _drm_edid_to_sad(const struct drm_edid *drm_edid, · 2 unmodified lines
56025625 cea_db_iter_edid_begin(drm_edid, &iter);
56035626 cea_db_iter_for_each(db, &iter) {
56045627 if (cea_db_tag(db) == CTA_DB_AUDIO) {
5605− int j;
5628+ struct cea_sad *sads;
5629+ int i;
56065630
56075631 count = cea_db_payload_len(db) / 3; /* SAD is 3B */
5608− *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL);
5609− if (!*sads)
5632+ sads = kcalloc(count, sizeof(*sads), GFP_KERNEL);
5633+ *psads = sads;
5634+ if (!sads)
56105635 return -ENOMEM;
5611− for (j = 0; j < count; j++) {
5612− const u8 *sad = &db->data[j * 3];
5613−
5614− (*sads)[j].format = (sad[0] & 0x78) >> 3;
5615− (*sads)[j].channels = sad[0] & 0x7;
5616− (*sads)[j].freq = sad[1] & 0x7F;
5617− (*sads)[j].byte2 = sad[2];
5618− }
5636+ for (i = 0; i < count; i++)
5637+ drm_edid_cta_sad_set(&sads[i], &db->data[i * 3]);
56195638 break;
56205639 }
56215640 }
drivers/gpu/drm/drm_edid_load.c+0−16
@@ -23,22 +23,6 @@ module_param_string(edid_firmware, edid_firmware, sizeof(edid_firmware), 0644); · 22 unmodified lines
2323 MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob "
2424 "from built-in data or /lib/firmware instead. ");
2525
26−/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
27−int __drm_set_edid_firmware_path(const char *path)
28−{
29− scnprintf(edid_firmware, sizeof(edid_firmware), "%s", path);
30−
31− return 0;
32−}
33−EXPORT_SYMBOL(__drm_set_edid_firmware_path);
34−
35−/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
36−int __drm_get_edid_firmware_path(char *buf, size_t bufsize)
37−{
38− return scnprintf(buf, bufsize, "%s", edid_firmware);
39−}
40−EXPORT_SYMBOL(__drm_get_edid_firmware_path);
41−
4226 #define GENERIC_EDIDS 6
4327 static const char * const generic_edid_name[GENERIC_EDIDS] = {
4428 "edid/800x600.bin",
drivers/gpu/drm/drm_eld.c+55−0
@@ -0,0 +1,55 @@
1+// SPDX-License-Identifier: MIT
2+/*
3+ * Copyright © 2023 Intel Corporation
4+ */
5+
6+#include <drm/drm_edid.h>
7+#include <drm/drm_eld.h>
8+
9+#include "drm_internal.h"
10+
11+/**
12+ * drm_eld_sad_get - get SAD from ELD to struct cea_sad
13+ * @eld: ELD buffer
14+ * @sad_index: SAD index
15+ * @cta_sad: destination struct cea_sad
16+ *
17+ * @return: 0 on success, or negative on errors
18+ */
19+int drm_eld_sad_get(const u8 *eld, int sad_index, struct cea_sad *cta_sad)
20+{
21+ const u8 *sad;
22+
23+ if (sad_index >= drm_eld_sad_count(eld))
24+ return -EINVAL;
25+
26+ sad = eld + DRM_ELD_CEA_SAD(drm_eld_mnl(eld), sad_index);
27+
28+ drm_edid_cta_sad_set(cta_sad, sad);
29+
30+ return 0;
31+}
32+EXPORT_SYMBOL(drm_eld_sad_get);
33+
34+/**
35+ * drm_eld_sad_set - set SAD to ELD from struct cea_sad
36+ * @eld: ELD buffer
37+ * @sad_index: SAD index
38+ * @cta_sad: source struct cea_sad
39+ *
40+ * @return: 0 on success, or negative on errors
41+ */
42+int drm_eld_sad_set(u8 *eld, int sad_index, const struct cea_sad *cta_sad)
43+{
44+ u8 *sad;
45+
46+ if (sad_index >= drm_eld_sad_count(eld))
47+ return -EINVAL;
48+
49+ sad = eld + DRM_ELD_CEA_SAD(drm_eld_mnl(eld), sad_index);
50+
51+ drm_edid_cta_sad_get(cta_sad, sad);
52+
53+ return 0;
54+}
55+EXPORT_SYMBOL(drm_eld_sad_set);
drivers/gpu/drm/drm_encoder.c+4−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030 #include <drm/drm_print.h>
3131
3232 #include "drm_crtc_internal.h"
33+#include "drm_internal.h"
3334
3435 /**
3536 * DOC: overview
@@ -74,6 +75,8 @@ int drm_encoder_register_all(struct drm_device *dev) · 38 unmodified lines
7475 int ret = 0;
7576
7677 drm_for_each_encoder(encoder, dev) {
78+ drm_debugfs_encoder_add(encoder);
79+
7780 if (encoder->funcs && encoder->funcs->late_register)
7881 ret = encoder->funcs->late_register(encoder);
7982 if (ret)
@@ -90,6 +93,7 @@ void drm_encoder_unregister_all(struct drm_device *dev) · 10 unmodified lines
9093 drm_for_each_encoder(encoder, dev) {
9194 if (encoder->funcs && encoder->funcs->early_unregister)
9295 encoder->funcs->early_unregister(encoder);
96+ drm_debugfs_encoder_remove(encoder);
9397 }
9498 }
9599
drivers/gpu/drm/drm_file.c+4−64
@@ -47,21 +47,12 @@ · 46 unmodified lines
4747
4848 #include "drm_crtc_internal.h"
4949 #include "drm_internal.h"
50−#include "drm_legacy.h"
5150
5251 /* from BKL pushdown */
5352 DEFINE_MUTEX(drm_global_mutex);
5453
5554 bool drm_dev_needs_global_mutex(struct drm_device *dev)
5655 {
57− /*
58− * Legacy drivers rely on all kinds of BKL locking semantics, don't
59− * bother. They also still need BKL locking for their ioctls, so better
60− * safe than sorry.
61− */
62− if (drm_core_check_feature(dev, DRIVER_LEGACY))
63− return true;
64−
6556 /*
6657 * The deprecated ->load callback must be called after the driver is
6758 * already registered. This means such drivers rely on the BKL to make
@@ -107,9 +98,7 @@ bool drm_dev_needs_global_mutex(struct drm_device *dev) · 39 unmodified lines
10798 * drm_send_event() as the main starting points.
10899 *
109100 * The memory mapping implementation will vary depending on how the driver
110− * manages memory. Legacy drivers will use the deprecated drm_legacy_mmap()
111− * function, modern drivers should use one of the provided memory-manager
112− * specific implementations. For GEM-based drivers this is drm_gem_mmap().
101+ * manages memory. For GEM-based drivers this is drm_gem_mmap().
113102 *
114103 * No other file operations are supported by the DRM userspace API. Overall the
115104 * following is an example &file_operations structure::
@@ -254,18 +243,6 @@ void drm_file_free(struct drm_file *file) · 138 unmodified lines
254243 (long)old_encode_dev(file->minor->kdev->devt),
255244 atomic_read(&dev->open_count));
256245
257−#ifdef CONFIG_DRM_LEGACY
258− if (drm_core_check_feature(dev, DRIVER_LEGACY) &&
259− dev->driver->preclose)
260− dev->driver->preclose(dev, file);
261−#endif
262−
263− if (drm_core_check_feature(dev, DRIVER_LEGACY))
264− drm_legacy_lock_release(dev, file->filp);
265−
266− if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
267− drm_legacy_reclaim_buffers(dev, file);
268−
269246 drm_events_release(file);
270247
271248 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -279,8 +256,6 @@ void drm_file_free(struct drm_file *file) · 7 unmodified lines
279256 if (drm_core_check_feature(dev, DRIVER_GEM))
280257 drm_gem_release(dev, file);
281258
282− drm_legacy_ctxbitmap_flush(dev, file);
283−
284259 if (drm_is_primary_client(file))
285260 drm_master_release(file);
286261
@@ -367,29 +342,6 @@ int drm_open_helper(struct file *filp, struct drm_minor *minor) · 80 unmodified lines
367342 list_add(&priv->lhead, &dev->filelist);
368343 mutex_unlock(&dev->filelist_mutex);
369344
370−#ifdef CONFIG_DRM_LEGACY
371−#ifdef __alpha__
372− /*
373− * Default the hose
374− */
375− if (!dev->hose) {
376− struct pci_dev *pci_dev;
377−
378− pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
379− if (pci_dev) {
380− dev->hose = pci_dev->sysdata;
381− pci_dev_put(pci_dev);
382− }
383− if (!dev->hose) {
384− struct pci_bus *b = list_entry(pci_root_buses.next,
385− struct pci_bus, node);
386− if (b)
387− dev->hose = b->sysdata;
388− }
389− }
390−#endif
391−#endif
392−
393345 return 0;
394346 }
395347
@@ -411,7 +363,6 @@ int drm_open(struct inode *inode, struct file *filp) · 15 unmodified lines
411363 struct drm_device *dev;
412364 struct drm_minor *minor;
413365 int retcode;
414− int need_setup = 0;
415366
416367 minor = drm_minor_acquire(iminor(inode));
417368 if (IS_ERR(minor))
@@ -421,8 +372,7 @@ int drm_open(struct inode *inode, struct file *filp) · 3 unmodified lines
421372 if (drm_dev_needs_global_mutex(dev))
422373 mutex_lock(&drm_global_mutex);
423374
424− if (!atomic_fetch_inc(&dev->open_count))
425− need_setup = 1;
375+ atomic_fetch_inc(&dev->open_count);
426376
427377 /* share address_space across all char-devs of a single device */
428378 filp->f_mapping = dev->anon_inode->i_mapping;
@@ -430,13 +380,6 @@ int drm_open(struct inode *inode, struct file *filp) · 1 unmodified line
430380 retcode = drm_open_helper(filp, minor);
431381 if (retcode)
432382 goto err_undo;
433− if (need_setup) {
434− retcode = drm_legacy_setup(dev);
435− if (retcode) {
436− drm_close_helper(filp);
437− goto err_undo;
438− }
439− }
440383
441384 if (drm_dev_needs_global_mutex(dev))
442385 mutex_unlock(&drm_global_mutex);
@@ -460,9 +403,6 @@ void drm_lastclose(struct drm_device * dev) · 17 unmodified lines
460403 dev->driver->lastclose(dev);
461404 drm_dbg_core(dev, "driver lastclose completed\n");
462405
463− if (drm_core_check_feature(dev, DRIVER_LEGACY))
464− drm_legacy_dev_reinit(dev);
465−
466406 drm_client_dev_restore(dev);
467407 }
468408
@@ -913,7 +853,7 @@ static void print_size(struct drm_printer *p, const char *stat, · 444 unmodified lines
913853 unsigned u;
914854
915855 for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
916− if (sz < SZ_1K)
856+ if (sz == 0 || !IS_ALIGNED(sz, SZ_1K))
917857 break;
918858 sz = div_u64(sz, SZ_1K);
919859 }
@@ -958,7 +898,7 @@ void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file) · 38 unmodified lines
958898 {
959899 struct drm_gem_object *obj;
960900 struct drm_memory_stats status = {};
961− enum drm_gem_object_status supported_status;
901+ enum drm_gem_object_status supported_status = 0;
962902 int id;
963903
964904 spin_lock(&file->table_lock);
drivers/gpu/drm/drm_flip_work.c+7−20
@@ -27,14 +27,12 @@ · 26 unmodified lines
2727 #include <drm/drm_print.h>
2828 #include <drm/drm_util.h>
2929
30−/**
31− * drm_flip_work_allocate_task - allocate a flip-work task
32− * @data: data associated to the task
33− * @flags: allocator flags
34− *
35− * Allocate a drm_flip_task object and attach private data to it.
36− */
37−struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags)
30+struct drm_flip_task {
31+ struct list_head node;
32+ void *data;
33+};
34+
35+static struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags)
3836 {
3937 struct drm_flip_task *task;
4038
@@ -44,18 +42,8 @@ struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags) · 3 unmodified lines
4442
4543 return task;
4644 }
47−EXPORT_SYMBOL(drm_flip_work_allocate_task);
4845
49−/**
50− * drm_flip_work_queue_task - queue a specific task
51− * @work: the flip-work
52− * @task: the task to handle
53− *
54− * Queues task, that will later be run (passed back to drm_flip_func_t
55− * func) on a work queue after drm_flip_work_commit() is called.
56− */
57−void drm_flip_work_queue_task(struct drm_flip_work *work,
58− struct drm_flip_task *task)
46+static void drm_flip_work_queue_task(struct drm_flip_work *work, struct drm_flip_task *task)
5947 {
6048 unsigned long flags;
6149
@@ -63,7 +51,6 @@ void drm_flip_work_queue_task(struct drm_flip_work *work, · 1 unmodified line
6351 list_add_tail(&task->node, &work->queued);
6452 spin_unlock_irqrestore(&work->lock, flags);
6553 }
66−EXPORT_SYMBOL(drm_flip_work_queue_task);
6754
6855 /**
6956 * drm_flip_work_queue - queue work
drivers/gpu/drm/drm_format_helper.c+162−53
@@ -20,6 +20,97 @@ · 19 unmodified lines
2020 #include <drm/drm_print.h>
2121 #include <drm/drm_rect.h>
2222
23+/**
24+ * drm_format_conv_state_init - Initialize format-conversion state
25+ * @state: The state to initialize
26+ *
27+ * Clears all fields in struct drm_format_conv_state. The state will
28+ * be empty with no preallocated resources.
29+ */
30+void drm_format_conv_state_init(struct drm_format_conv_state *state)
31+{
32+ state->tmp.mem = NULL;
33+ state->tmp.size = 0;
34+ state->tmp.preallocated = false;
35+}
36+EXPORT_SYMBOL(drm_format_conv_state_init);
37+
38+/**
39+ * drm_format_conv_state_copy - Copy format-conversion state
40+ * @state: Destination state
41+ * @old_state: Source state
42+ *
43+ * Copies format-conversion state from @old_state to @state; except for
44+ * temporary storage.
45+ */
46+void drm_format_conv_state_copy(struct drm_format_conv_state *state,
47+ const struct drm_format_conv_state *old_state)
48+{
49+ /*
50+ * So far, there's only temporary storage here, which we don't
51+ * duplicate. Just clear the fields.
52+ */
53+ state->tmp.mem = NULL;
54+ state->tmp.size = 0;
55+ state->tmp.preallocated = false;
56+}
57+EXPORT_SYMBOL(drm_format_conv_state_copy);
58+
59+/**
60+ * drm_format_conv_state_reserve - Allocates storage for format conversion
61+ * @state: The format-conversion state
62+ * @new_size: The minimum allocation size
63+ * @flags: Flags for kmalloc()
64+ *
65+ * Allocates at least @new_size bytes and returns a pointer to the memory
66+ * range. After calling this function, previously returned memory blocks
67+ * are invalid. It's best to collect all memory requirements of a format
68+ * conversion and call this function once to allocate the range.
69+ *
70+ * Returns:
71+ * A pointer to the allocated memory range, or NULL otherwise.
72+ */
73+void *drm_format_conv_state_reserve(struct drm_format_conv_state *state,
74+ size_t new_size, gfp_t flags)
75+{
76+ void *mem;
77+
78+ if (new_size <= state->tmp.size)
79+ goto out;
80+ else if (state->tmp.preallocated)
81+ return NULL;
82+
83+ mem = krealloc(state->tmp.mem, new_size, flags);
84+ if (!mem)
85+ return NULL;
86+
87+ state->tmp.mem = mem;
88+ state->tmp.size = new_size;
89+
90+out:
91+ return state->tmp.mem;
92+}
93+EXPORT_SYMBOL(drm_format_conv_state_reserve);
94+
95+/**
96+ * drm_format_conv_state_release - Releases an format-conversion storage
97+ * @state: The format-conversion state
98+ *
99+ * Releases the memory range references by the format-conversion state.
100+ * After this call, all pointers to the memory are invalid. Prefer
101+ * drm_format_conv_state_init() for cleaning up and unloading a driver.
102+ */
103+void drm_format_conv_state_release(struct drm_format_conv_state *state)
104+{
105+ if (state->tmp.preallocated)
106+ return;
107+
108+ kfree(state->tmp.mem);
109+ state->tmp.mem = NULL;
110+ state->tmp.size = 0;
111+}
112+EXPORT_SYMBOL(drm_format_conv_state_release);
113+
23114 static unsigned int clip_offset(const struct drm_rect *clip, unsigned int pitch, unsigned int cpp)
24115 {
25116 return clip->y1 * pitch + clip->x1 * cpp;
@@ -45,6 +136,7 @@ EXPORT_SYMBOL(drm_fb_clip_offset); · 19 unmodified lines
45136 static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize,
46137 const void *vaddr, const struct drm_framebuffer *fb,
47138 const struct drm_rect *clip, bool vaddr_cached_hint,
139+ struct drm_format_conv_state *state,
48140 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))
49141 {
50142 unsigned long linepixels = drm_rect_width(clip);
@@ -60,7 +152,7 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p · 9 unmodified lines
60152 * one line at a time.
61153 */
62154 if (!vaddr_cached_hint) {
63− stmp = kmalloc(sbuf_len, GFP_KERNEL);
155+ stmp = drm_format_conv_state_reserve(state, sbuf_len, GFP_KERNEL);
64156 if (!stmp)
65157 return -ENOMEM;
66158 }
@@ -79,8 +171,6 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p · 12 unmodified lines
79171 dst += dst_pitch;
80172 }
81173
82− kfree(stmp);
83−
84174 return 0;
85175 }
86176
@@ -88,6 +178,7 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p · 1 unmodified line
88178 static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned long dst_pixsize,
89179 const void *vaddr, const struct drm_framebuffer *fb,
90180 const struct drm_rect *clip, bool vaddr_cached_hint,
181+ struct drm_format_conv_state *state,
91182 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))
92183 {
93184 unsigned long linepixels = drm_rect_width(clip);
@@ -101,9 +192,9 @@ static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsign · 7 unmodified lines
101192 void *dbuf;
102193
103194 if (vaddr_cached_hint) {
104− dbuf = kmalloc(dbuf_len, GFP_KERNEL);
195+ dbuf = drm_format_conv_state_reserve(state, dbuf_len, GFP_KERNEL);
105196 } else {
106− dbuf = kmalloc(stmp_off + sbuf_len, GFP_KERNEL);
197+ dbuf = drm_format_conv_state_reserve(state, stmp_off + sbuf_len, GFP_KERNEL);
107198 stmp = dbuf + stmp_off;
108199 }
109200 if (!dbuf)
@@ -124,8 +215,6 @@ static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsign · 14 unmodified lines
124215 dst += dst_pitch;
125216 }
126217
127− kfree(dbuf);
128−
129218 return 0;
130219 }
131220
@@ -134,6 +223,7 @@ static int drm_fb_xfrm(struct iosys_map *dst, · 2 unmodified lines
134223 const unsigned int *dst_pitch, const u8 *dst_pixsize,
135224 const struct iosys_map *src, const struct drm_framebuffer *fb,
136225 const struct drm_rect *clip, bool vaddr_cached_hint,
226+ struct drm_format_conv_state *state,
137227 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))
138228 {
139229 static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
@@ -146,10 +236,12 @@ static int drm_fb_xfrm(struct iosys_map *dst, · 6 unmodified lines
146236 /* TODO: handle src in I/O memory here */
147237 if (dst[0].is_iomem)
148238 return __drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], dst_pixsize[0],
149− src[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line);
239+ src[0].vaddr, fb, clip, vaddr_cached_hint, state,
240+ xfrm_line);
150241 else
151242 return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0],
152− src[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line);
243+ src[0].vaddr, fb, clip, vaddr_cached_hint, state,
244+ xfrm_line);
153245 }
154246
155247 /**
@@ -235,6 +327,7 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels · 79 unmodified lines
235327 * @fb: DRM framebuffer
236328 * @clip: Clip rectangle area to copy
237329 * @cached: Source buffer is mapped cached (eg. not write-combined)
330+ * @state: Transform and conversion state
238331 *
239332 * This function copies parts of a framebuffer to display memory and swaps per-pixel
240333 * bytes during the process. Destination and framebuffer formats must match. The
@@ -249,7 +342,8 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels · 8 unmodified lines
249342 */
250343 void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch,
251344 const struct iosys_map *src, const struct drm_framebuffer *fb,
252− const struct drm_rect *clip, bool cached)
345+ const struct drm_rect *clip, bool cached,
346+ struct drm_format_conv_state *state)
253347 {
254348 const struct drm_format_info *format = fb->format;
255349 u8 cpp = DIV_ROUND_UP(drm_format_info_bpp(format, 0), 8);
@@ -268,7 +362,7 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, · 12 unmodified lines
268362 return;
269363 }
270364
271− drm_fb_xfrm(dst, dst_pitch, &cpp, src, fb, clip, cached, swab_line);
365+ drm_fb_xfrm(dst, dst_pitch, &cpp, src, fb, clip, cached, state, swab_line);
272366 }
273367 EXPORT_SYMBOL(drm_fb_swab);
274368
@@ -295,6 +389,7 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne · 20 unmodified lines
295389 * @src: Array of XRGB8888 source buffers
296390 * @fb: DRM framebuffer
297391 * @clip: Clip rectangle area to copy
392+ * @state: Transform and conversion state
298393 *
299394 * This function copies parts of a framebuffer to display memory and converts the
300395 * color format during the process. Destination and framebuffer formats must match. The
@@ -309,13 +404,13 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne · 8 unmodified lines
309404 */
310405 void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch,
311406 const struct iosys_map *src, const struct drm_framebuffer *fb,
312− const struct drm_rect *clip)
407+ const struct drm_rect *clip, struct drm_format_conv_state *state)
313408 {
314409 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
315410 1,
316411 };
317412
318− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
413+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
319414 drm_fb_xrgb8888_to_rgb332_line);
320415 }
321416 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332);
@@ -364,6 +459,7 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf, · 42 unmodified lines
364459 * @src: Array of XRGB8888 source buffer
365460 * @fb: DRM framebuffer
366461 * @clip: Clip rectangle area to copy
462+ * @state: Transform and conversion state
367463 * @swab: Swap bytes
368464 *
369465 * This function copies parts of a framebuffer to display memory and converts the
@@ -379,7 +475,8 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf, · 9 unmodified lines
379475 */
380476 void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch,
381477 const struct iosys_map *src, const struct drm_framebuffer *fb,
382− const struct drm_rect *clip, bool swab)
478+ const struct drm_rect *clip, struct drm_format_conv_state *state,
479+ bool swab)
383480 {
384481 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
385482 2,
@@ -392,7 +489,7 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi · 6 unmodified lines
392489 else
393490 xfrm_line = drm_fb_xrgb8888_to_rgb565_line;
394491
395− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, xfrm_line);
492+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, xfrm_line);
396493 }
397494 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565);
398495
@@ -421,6 +518,7 @@ static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsig · 22 unmodified lines
421518 * @src: Array of XRGB8888 source buffer
422519 * @fb: DRM framebuffer
423520 * @clip: Clip rectangle area to copy
521+ * @state: Transform and conversion state
424522 *
425523 * This function copies parts of a framebuffer to display memory and converts
426524 * the color format during the process. The parameters @dst, @dst_pitch and
@@ -436,13 +534,13 @@ static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsig · 9 unmodified lines
436534 */
437535 void drm_fb_xrgb8888_to_xrgb1555(struct iosys_map *dst, const unsigned int *dst_pitch,
438536 const struct iosys_map *src, const struct drm_framebuffer *fb,
439− const struct drm_rect *clip)
537+ const struct drm_rect *clip, struct drm_format_conv_state *state)
440538 {
441539 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
442540 2,
443541 };
444542
445− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
543+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
446544 drm_fb_xrgb8888_to_xrgb1555_line);
447545 }
448546 EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb1555);
@@ -473,6 +571,7 @@ static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsig · 24 unmodified lines
473571 * @src: Array of XRGB8888 source buffer
474572 * @fb: DRM framebuffer
475573 * @clip: Clip rectangle area to copy
574+ * @state: Transform and conversion state
476575 *
477576 * This function copies parts of a framebuffer to display memory and converts
478577 * the color format during the process. The parameters @dst, @dst_pitch and
@@ -488,13 +587,13 @@ static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsig · 9 unmodified lines
488587 */
489588 void drm_fb_xrgb8888_to_argb1555(struct iosys_map *dst, const unsigned int *dst_pitch,
490589 const struct iosys_map *src, const struct drm_framebuffer *fb,
491− const struct drm_rect *clip)
590+ const struct drm_rect *clip, struct drm_format_conv_state *state)
492591 {
493592 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
494593 2,
495594 };
496595
497− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
596+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
498597 drm_fb_xrgb8888_to_argb1555_line);
499598 }
500599 EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb1555);
@@ -525,6 +624,7 @@ static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsig · 24 unmodified lines
525624 * @src: Array of XRGB8888 source buffer
526625 * @fb: DRM framebuffer
527626 * @clip: Clip rectangle area to copy
627+ * @state: Transform and conversion state
528628 *
529629 * This function copies parts of a framebuffer to display memory and converts
530630 * the color format during the process. The parameters @dst, @dst_pitch and
@@ -540,13 +640,13 @@ static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsig · 9 unmodified lines
540640 */
541641 void drm_fb_xrgb8888_to_rgba5551(struct iosys_map *dst, const unsigned int *dst_pitch,
542642 const struct iosys_map *src, const struct drm_framebuffer *fb,
543− const struct drm_rect *clip)
643+ const struct drm_rect *clip, struct drm_format_conv_state *state)
544644 {
545645 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
546646 2,
547647 };
548648
549− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
649+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
550650 drm_fb_xrgb8888_to_rgba5551_line);
551651 }
552652 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgba5551);
@@ -575,6 +675,7 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne · 22 unmodified lines
575675 * @src: Array of XRGB8888 source buffers
576676 * @fb: DRM framebuffer
577677 * @clip: Clip rectangle area to copy
678+ * @state: Transform and conversion state
578679 *
579680 * This function copies parts of a framebuffer to display memory and converts the
580681 * color format during the process. Destination and framebuffer formats must match. The
@@ -590,13 +691,13 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne · 9 unmodified lines
590691 */
591692 void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch,
592693 const struct iosys_map *src, const struct drm_framebuffer *fb,
593− const struct drm_rect *clip)
694+ const struct drm_rect *clip, struct drm_format_conv_state *state)
594695 {
595696 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
596697 3,
597698 };
598699
599− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
700+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
600701 drm_fb_xrgb8888_to_rgb888_line);
601702 }
602703 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888);
@@ -623,6 +724,7 @@ static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsig · 20 unmodified lines
623724 * @src: Array of XRGB8888 source buffer
624725 * @fb: DRM framebuffer
625726 * @clip: Clip rectangle area to copy
727+ * @state: Transform and conversion state
626728 *
627729 * This function copies parts of a framebuffer to display memory and converts the
628730 * color format during the process. The parameters @dst, @dst_pitch and @src refer
@@ -638,13 +740,13 @@ static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsig · 9 unmodified lines
638740 */
639741 void drm_fb_xrgb8888_to_argb8888(struct iosys_map *dst, const unsigned int *dst_pitch,
640742 const struct iosys_map *src, const struct drm_framebuffer *fb,
641− const struct drm_rect *clip)
743+ const struct drm_rect *clip, struct drm_format_conv_state *state)
642744 {
643745 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
644746 4,
645747 };
646748
647− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
749+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
648750 drm_fb_xrgb8888_to_argb8888_line);
649751 }
650752 EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb8888);
@@ -669,13 +771,14 @@ static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsig · 18 unmodified lines
669771 static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,
670772 const struct iosys_map *src,
671773 const struct drm_framebuffer *fb,
672− const struct drm_rect *clip)
774+ const struct drm_rect *clip,
775+ struct drm_format_conv_state *state)
673776 {
674777 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
675778 4,
676779 };
677780
678− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
781+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
679782 drm_fb_xrgb8888_to_abgr8888_line);
680783 }
681784
@@ -699,13 +802,14 @@ static void drm_fb_xrgb8888_to_xbgr8888_line(void *dbuf, const void *sbuf, unsig · 17 unmodified lines
699802 static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,
700803 const struct iosys_map *src,
701804 const struct drm_framebuffer *fb,
702− const struct drm_rect *clip)
805+ const struct drm_rect *clip,
806+ struct drm_format_conv_state *state)
703807 {
704808 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
705809 4,
706810 };
707811
708− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
812+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
709813 drm_fb_xrgb8888_to_xbgr8888_line);
710814 }
711815
@@ -735,6 +839,7 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un · 23 unmodified lines
735839 * @src: Array of XRGB8888 source buffers
736840 * @fb: DRM framebuffer
737841 * @clip: Clip rectangle area to copy
842+ * @state: Transform and conversion state
738843 *
739844 * This function copies parts of a framebuffer to display memory and converts the
740845 * color format during the process. Destination and framebuffer formats must match. The
@@ -750,13 +855,14 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un · 9 unmodified lines
750855 */
751856 void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch,
752857 const struct iosys_map *src, const struct drm_framebuffer *fb,
753− const struct drm_rect *clip)
858+ const struct drm_rect *clip,
859+ struct drm_format_conv_state *state)
754860 {
755861 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
756862 4,
757863 };
758864
759− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
865+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
760866 drm_fb_xrgb8888_to_xrgb2101010_line);
761867 }
762868 EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010);
@@ -788,6 +894,7 @@ static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, un · 25 unmodified lines
788894 * @src: Array of XRGB8888 source buffers
789895 * @fb: DRM framebuffer
790896 * @clip: Clip rectangle area to copy
897+ * @state: Transform and conversion state
791898 *
792899 * This function copies parts of a framebuffer to display memory and converts
793900 * the color format during the process. The parameters @dst, @dst_pitch and
@@ -803,13 +910,14 @@ static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, un · 9 unmodified lines
803910 */
804911 void drm_fb_xrgb8888_to_argb2101010(struct iosys_map *dst, const unsigned int *dst_pitch,
805912 const struct iosys_map *src, const struct drm_framebuffer *fb,
806− const struct drm_rect *clip)
913+ const struct drm_rect *clip,
914+ struct drm_format_conv_state *state)
807915 {
808916 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
809917 4,
810918 };
811919
812− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
920+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
813921 drm_fb_xrgb8888_to_argb2101010_line);
814922 }
815923 EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb2101010);
@@ -839,6 +947,7 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned · 23 unmodified lines
839947 * @src: Array of XRGB8888 source buffers
840948 * @fb: DRM framebuffer
841949 * @clip: Clip rectangle area to copy
950+ * @state: Transform and conversion state
842951 *
843952 * This function copies parts of a framebuffer to display memory and converts the
844953 * color format during the process. Destination and framebuffer formats must match. The
@@ -858,13 +967,13 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned · 13 unmodified lines
858967 */
859968 void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch,
860969 const struct iosys_map *src, const struct drm_framebuffer *fb,
861− const struct drm_rect *clip)
970+ const struct drm_rect *clip, struct drm_format_conv_state *state)
862971 {
863972 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {
864973 1,
865974 };
866975
867− drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false,
976+ drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,
868977 drm_fb_xrgb8888_to_gray8_line);
869978 }
870979 EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8);
@@ -878,6 +987,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); · 7 unmodified lines
878987 * @src: The framebuffer memory to copy from
879988 * @fb: The framebuffer to copy from
880989 * @clip: Clip rectangle area to copy
990+ * @state: Transform and conversion state
881991 *
882992 * This function copies parts of a framebuffer to display memory. If the
883993 * formats of the display and the framebuffer mismatch, the blit function
@@ -896,7 +1006,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); · 12 unmodified lines
8961006 */
8971007 int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format,
8981008 const struct iosys_map *src, const struct drm_framebuffer *fb,
899− const struct drm_rect *clip)
1009+ const struct drm_rect *clip, struct drm_format_conv_state *state)
9001010 {
9011011 uint32_t fb_format = fb->format->format;
9021012
@@ -904,44 +1014,44 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d · 1 unmodified line
9041014 drm_fb_memcpy(dst, dst_pitch, src, fb, clip);
9051015 return 0;
9061016 } else if (fb_format == (dst_format | DRM_FORMAT_BIG_ENDIAN)) {
907− drm_fb_swab(dst, dst_pitch, src, fb, clip, false);
1017+ drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state);
9081018 return 0;
9091019 } else if (fb_format == (dst_format & ~DRM_FORMAT_BIG_ENDIAN)) {
910− drm_fb_swab(dst, dst_pitch, src, fb, clip, false);
1020+ drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state);
9111021 return 0;
9121022 } else if (fb_format == DRM_FORMAT_XRGB8888) {
9131023 if (dst_format == DRM_FORMAT_RGB565) {
914− drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, false);
1024+ drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, state, false);
9151025 return 0;
9161026 } else if (dst_format == DRM_FORMAT_XRGB1555) {
917− drm_fb_xrgb8888_to_xrgb1555(dst, dst_pitch, src, fb, clip);
1027+ drm_fb_xrgb8888_to_xrgb1555(dst, dst_pitch, src, fb, clip, state);
9181028 return 0;
9191029 } else if (dst_format == DRM_FORMAT_ARGB1555) {
920− drm_fb_xrgb8888_to_argb1555(dst, dst_pitch, src, fb, clip);
1030+ drm_fb_xrgb8888_to_argb1555(dst, dst_pitch, src, fb, clip, state);
9211031 return 0;
9221032 } else if (dst_format == DRM_FORMAT_RGBA5551) {
923− drm_fb_xrgb8888_to_rgba5551(dst, dst_pitch, src, fb, clip);
1033+ drm_fb_xrgb8888_to_rgba5551(dst, dst_pitch, src, fb, clip, state);
9241034 return 0;
9251035 } else if (dst_format == DRM_FORMAT_RGB888) {
926− drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, src, fb, clip);
1036+ drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, src, fb, clip, state);
9271037 return 0;
9281038 } else if (dst_format == DRM_FORMAT_ARGB8888) {
929− drm_fb_xrgb8888_to_argb8888(dst, dst_pitch, src, fb, clip);
1039+ drm_fb_xrgb8888_to_argb8888(dst, dst_pitch, src, fb, clip, state);
9301040 return 0;
9311041 } else if (dst_format == DRM_FORMAT_XBGR8888) {
932− drm_fb_xrgb8888_to_xbgr8888(dst, dst_pitch, src, fb, clip);
1042+ drm_fb_xrgb8888_to_xbgr8888(dst, dst_pitch, src, fb, clip, state);
9331043 return 0;
9341044 } else if (dst_format == DRM_FORMAT_ABGR8888) {
935− drm_fb_xrgb8888_to_abgr8888(dst, dst_pitch, src, fb, clip);
1045+ drm_fb_xrgb8888_to_abgr8888(dst, dst_pitch, src, fb, clip, state);
9361046 return 0;
9371047 } else if (dst_format == DRM_FORMAT_XRGB2101010) {
938− drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, src, fb, clip);
1048+ drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, src, fb, clip, state);
9391049 return 0;
9401050 } else if (dst_format == DRM_FORMAT_ARGB2101010) {
941− drm_fb_xrgb8888_to_argb2101010(dst, dst_pitch, src, fb, clip);
1051+ drm_fb_xrgb8888_to_argb2101010(dst, dst_pitch, src, fb, clip, state);
9421052 return 0;
9431053 } else if (dst_format == DRM_FORMAT_BGRX8888) {
944− drm_fb_swab(dst, dst_pitch, src, fb, clip, false);
1054+ drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state);
9451055 return 0;
9461056 }
9471057 }
@@ -978,6 +1088,7 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int · 30 unmodified lines
9781088 * @src: Array of XRGB8888 source buffers
9791089 * @fb: DRM framebuffer
9801090 * @clip: Clip rectangle area to copy
1091+ * @state: Transform and conversion state
9811092 *
9821093 * This function copies parts of a framebuffer to display memory and converts the
9831094 * color format during the process. Destination and framebuffer formats must match. The
@@ -1002,7 +1113,7 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int · 18 unmodified lines
10021113 */
10031114 void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch,
10041115 const struct iosys_map *src, const struct drm_framebuffer *fb,
1005− const struct drm_rect *clip)
1116+ const struct drm_rect *clip, struct drm_format_conv_state *state)
10061117 {
10071118 static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
10081119 0, 0, 0, 0
@@ -1042,7 +1153,7 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc · 33 unmodified lines
10421153 * Allocate a buffer to be used for both copying from the cma
10431154 * memory and to store the intermediate grayscale line pixels.
10441155 */
1045− src32 = kmalloc(len_src32 + linepixels, GFP_KERNEL);
1156+ src32 = drm_format_conv_state_reserve(state, len_src32 + linepixels, GFP_KERNEL);
10461157 if (!src32)
10471158 return;
10481159
@@ -1056,8 +1167,6 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc · 7 unmodified lines
10561167 vaddr += fb->pitches[0];
10571168 mono += dst_pitch_0;
10581169 }
1059−
1060− kfree(src32);
10611170 }
10621171 EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono);
10631172
drivers/gpu/drm/drm_framebuffer.c+54−23
@@ -394,6 +394,31 @@ static void drm_mode_rmfb_work_fn(struct work_struct *w) · 393 unmodified lines
394394 }
395395 }
396396
397+static int drm_mode_closefb(struct drm_framebuffer *fb,
398+ struct drm_file *file_priv)
399+{
400+ struct drm_framebuffer *fbl;
401+ bool found = false;
402+
403+ mutex_lock(&file_priv->fbs_lock);
404+ list_for_each_entry(fbl, &file_priv->fbs, filp_head)
405+ if (fb == fbl)
406+ found = true;
407+
408+ if (!found) {
409+ mutex_unlock(&file_priv->fbs_lock);
410+ return -ENOENT;
411+ }
412+
413+ list_del_init(&fb->filp_head);
414+ mutex_unlock(&file_priv->fbs_lock);
415+
416+ /* Drop the reference that was stored in the fbs list */
417+ drm_framebuffer_put(fb);
418+
419+ return 0;
420+}
421+
397422 /**
398423 * drm_mode_rmfb - remove an FB from the configuration
399424 * @dev: drm device
@@ -410,9 +435,8 @@ static void drm_mode_rmfb_work_fn(struct work_struct *w) · 10 unmodified lines
410435 int drm_mode_rmfb(struct drm_device *dev, u32 fb_id,
411436 struct drm_file *file_priv)
412437 {
413− struct drm_framebuffer *fb = NULL;
414− struct drm_framebuffer *fbl = NULL;
415− int found = 0;
438+ struct drm_framebuffer *fb;
439+ int ret;
416440
417441 if (!drm_core_check_feature(dev, DRIVER_MODESET))
418442 return -EOPNOTSUPP;
@@ -421,24 +445,13 @@ int drm_mode_rmfb(struct drm_device *dev, u32 fb_id, · 2 unmodified lines
421445 if (!fb)
422446 return -ENOENT;
423447
424− mutex_lock(&file_priv->fbs_lock);
425− list_for_each_entry(fbl, &file_priv->fbs, filp_head)
426− if (fb == fbl)
427− found = 1;
428− if (!found) {
429− mutex_unlock(&file_priv->fbs_lock);
430− goto fail_unref;
448+ ret = drm_mode_closefb(fb, file_priv);
449+ if (ret != 0) {
450+ drm_framebuffer_put(fb);
451+ return ret;
431452 }
432453
433− list_del_init(&fb->filp_head);
434− mutex_unlock(&file_priv->fbs_lock);
435−
436− /* drop the reference we picked up in framebuffer lookup */
437− drm_framebuffer_put(fb);
438−
439454 /*
440− * we now own the reference that was stored in the fbs list
441− *
442455 * drm_framebuffer_remove may fail with -EINTR on pending signals,
443456 * so run this in a separate stack as there's no way to correctly
444457 * handle this after the fb is already removed from the lookup table.
@@ -457,10 +470,6 @@ int drm_mode_rmfb(struct drm_device *dev, u32 fb_id, · 12 unmodified lines
457470 drm_framebuffer_put(fb);
458471
459472 return 0;
460−
461−fail_unref:
462− drm_framebuffer_put(fb);
463− return -ENOENT;
464473 }
465474
466475 int drm_mode_rmfb_ioctl(struct drm_device *dev,
@@ -471,6 +480,28 @@ int drm_mode_rmfb_ioctl(struct drm_device *dev, · 4 unmodified lines
471480 return drm_mode_rmfb(dev, *fb_id, file_priv);
472481 }
473482
483+int drm_mode_closefb_ioctl(struct drm_device *dev,
484+ void *data, struct drm_file *file_priv)
485+{
486+ struct drm_mode_closefb *r = data;
487+ struct drm_framebuffer *fb;
488+ int ret;
489+
490+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
491+ return -EOPNOTSUPP;
492+
493+ if (r->pad)
494+ return -EINVAL;
495+
496+ fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
497+ if (!fb)
498+ return -ENOENT;
499+
500+ ret = drm_mode_closefb(fb, file_priv);
501+ drm_framebuffer_put(fb);
502+ return ret;
503+}
504+
474505 /**
475506 * drm_mode_getfb - get FB info
476507 * @dev: drm device for the ioctl
@@ -552,7 +583,7 @@ int drm_mode_getfb2_ioctl(struct drm_device *dev, · 75 unmodified lines
552583 struct drm_mode_fb_cmd2 *r = data;
553584 struct drm_framebuffer *fb;
554585 unsigned int i;
555− int ret;
586+ int ret = 0;
556587
557588 if (!drm_core_check_feature(dev, DRIVER_MODESET))
558589 return -EINVAL;
drivers/gpu/drm/drm_gem_atomic_helper.c+9−0
@@ -218,7 +218,14 @@ void · 217 unmodified lines
218218 __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane,
219219 struct drm_shadow_plane_state *new_shadow_plane_state)
220220 {
221+ struct drm_plane_state *plane_state = plane->state;
222+ struct drm_shadow_plane_state *shadow_plane_state =
223+ to_drm_shadow_plane_state(plane_state);
224+
221225 __drm_atomic_helper_plane_duplicate_state(plane, &new_shadow_plane_state->base);
226+
227+ drm_format_conv_state_copy(&shadow_plane_state->fmtcnv_state,
228+ &new_shadow_plane_state->fmtcnv_state);
222229 }
223230 EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state);
224231
@@ -266,6 +273,7 @@ EXPORT_SYMBOL(drm_gem_duplicate_shadow_plane_state); · 41 unmodified lines
266273 */
267274 void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state)
268275 {
276+ drm_format_conv_state_release(&shadow_plane_state->fmtcnv_state);
269277 __drm_atomic_helper_plane_destroy_state(&shadow_plane_state->base);
270278 }
271279 EXPORT_SYMBOL(__drm_gem_destroy_shadow_plane_state);
@@ -302,6 +310,7 @@ void __drm_gem_reset_shadow_plane(struct drm_plane *plane, · 30 unmodified lines
302310 struct drm_shadow_plane_state *shadow_plane_state)
303311 {
304312 __drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base);
313+ drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state);
305314 }
306315 EXPORT_SYMBOL(__drm_gem_reset_shadow_plane);
307316
drivers/gpu/drm/drm_gpuvm.c+1097−71
@@ -61,6 +61,42 @@ · 60 unmodified lines
6161 * contained within struct drm_gpuva already. Hence, for inserting &drm_gpuva
6262 * entries from within dma-fence signalling critical sections it is enough to
6363 * pre-allocate the &drm_gpuva structures.
64+ *
65+ * &drm_gem_objects which are private to a single VM can share a common
66+ * &dma_resv in order to improve locking efficiency (e.g. with &drm_exec).
67+ * For this purpose drivers must pass a &drm_gem_object to drm_gpuvm_init(), in
68+ * the following called 'resv object', which serves as the container of the
69+ * GPUVM's shared &dma_resv. This resv object can be a driver specific
70+ * &drm_gem_object, such as the &drm_gem_object containing the root page table,
71+ * but it can also be a 'dummy' object, which can be allocated with
72+ * drm_gpuvm_resv_object_alloc().
73+ *
74+ * In order to connect a struct drm_gpuva its backing &drm_gem_object each
75+ * &drm_gem_object maintains a list of &drm_gpuvm_bo structures, and each
76+ * &drm_gpuvm_bo contains a list of &drm_gpuva structures.
77+ *
78+ * A &drm_gpuvm_bo is an abstraction that represents a combination of a
79+ * &drm_gpuvm and a &drm_gem_object. Every such combination should be unique.
80+ * This is ensured by the API through drm_gpuvm_bo_obtain() and
81+ * drm_gpuvm_bo_obtain_prealloc() which first look into the corresponding
82+ * &drm_gem_object list of &drm_gpuvm_bos for an existing instance of this
83+ * particular combination. If not existent a new instance is created and linked
84+ * to the &drm_gem_object.
85+ *
86+ * &drm_gpuvm_bo structures, since unique for a given &drm_gpuvm, are also used
87+ * as entry for the &drm_gpuvm's lists of external and evicted objects. Those
88+ * lists are maintained in order to accelerate locking of dma-resv locks and
89+ * validation of evicted objects bound in a &drm_gpuvm. For instance, all
90+ * &drm_gem_object's &dma_resv of a given &drm_gpuvm can be locked by calling
91+ * drm_gpuvm_exec_lock(). Once locked drivers can call drm_gpuvm_validate() in
92+ * order to validate all evicted &drm_gem_objects. It is also possible to lock
93+ * additional &drm_gem_objects by providing the corresponding parameters to
94+ * drm_gpuvm_exec_lock() as well as open code the &drm_exec loop while making
95+ * use of helper functions such as drm_gpuvm_prepare_range() or
96+ * drm_gpuvm_prepare_objects().
97+ *
98+ * Every bound &drm_gem_object is treated as external object when its &dma_resv
99+ * structure is different than the &drm_gpuvm's common &dma_resv structure.
64100 */
65101
66102 /**
@@ -386,21 +422,42 @@ · 319 unmodified lines
386422 /**
387423 * DOC: Locking
388424 *
389− * Generally, the GPU VA manager does not take care of locking itself, it is
390− * the drivers responsibility to take care about locking. Drivers might want to
391− * protect the following operations: inserting, removing and iterating
392− * &drm_gpuva objects as well as generating all kinds of operations, such as
393− * split / merge or prefetch.
394− *
395− * The GPU VA manager also does not take care of the locking of the backing
396− * &drm_gem_object buffers GPU VA lists by itself; drivers are responsible to
397− * enforce mutual exclusion using either the GEMs dma_resv lock or alternatively
398− * a driver specific external lock. For the latter see also
399− * drm_gem_gpuva_set_lock().
400− *
401− * However, the GPU VA manager contains lockdep checks to ensure callers of its
402− * API hold the corresponding lock whenever the &drm_gem_objects GPU VA list is
403− * accessed by functions such as drm_gpuva_link() or drm_gpuva_unlink().
425+ * In terms of managing &drm_gpuva entries DRM GPUVM does not take care of
426+ * locking itself, it is the drivers responsibility to take care about locking.
427+ * Drivers might want to protect the following operations: inserting, removing
428+ * and iterating &drm_gpuva objects as well as generating all kinds of
429+ * operations, such as split / merge or prefetch.
430+ *
431+ * DRM GPUVM also does not take care of the locking of the backing
432+ * &drm_gem_object buffers GPU VA lists and &drm_gpuvm_bo abstractions by
433+ * itself; drivers are responsible to enforce mutual exclusion using either the
434+ * GEMs dma_resv lock or alternatively a driver specific external lock. For the
435+ * latter see also drm_gem_gpuva_set_lock().
436+ *
437+ * However, DRM GPUVM contains lockdep checks to ensure callers of its API hold
438+ * the corresponding lock whenever the &drm_gem_objects GPU VA list is accessed
439+ * by functions such as drm_gpuva_link() or drm_gpuva_unlink(), but also
440+ * drm_gpuvm_bo_obtain() and drm_gpuvm_bo_put().
441+ *
442+ * The latter is required since on creation and destruction of a &drm_gpuvm_bo
443+ * the &drm_gpuvm_bo is attached / removed from the &drm_gem_objects gpuva list.
444+ * Subsequent calls to drm_gpuvm_bo_obtain() for the same &drm_gpuvm and
445+ * &drm_gem_object must be able to observe previous creations and destructions
446+ * of &drm_gpuvm_bos in order to keep instances unique.
447+ *
448+ * The &drm_gpuvm's lists for keeping track of external and evicted objects are
449+ * protected against concurrent insertion / removal and iteration internally.
450+ *
451+ * However, drivers still need ensure to protect concurrent calls to functions
452+ * iterating those lists, namely drm_gpuvm_prepare_objects() and
453+ * drm_gpuvm_validate().
454+ *
455+ * Alternatively, drivers can set the &DRM_GPUVM_RESV_PROTECTED flag to indicate
456+ * that the corresponding &dma_resv locks are held in order to protect the
457+ * lists. If &DRM_GPUVM_RESV_PROTECTED is set, internal locking is disabled and
458+ * the corresponding lockdep checks are enabled. This is an optimization for
459+ * drivers which are capable of taking the corresponding &dma_resv locks and
460+ * hence do not require internal locking.
404461 */
405462
406463 /**
@@ -430,6 +487,7 @@ · 23 unmodified lines
430487 * {
431488 * struct drm_gpuva_ops *ops;
432489 * struct drm_gpuva_op *op
490+ * struct drm_gpuvm_bo *vm_bo;
433491 *
434492 * driver_lock_va_space();
435493 * ops = drm_gpuvm_sm_map_ops_create(gpuvm, addr, range,
@@ -437,6 +495,10 @@ · 1 unmodified line
437495 * if (IS_ERR(ops))
438496 * return PTR_ERR(ops);
439497 *
498+ * vm_bo = drm_gpuvm_bo_obtain(gpuvm, obj);
499+ * if (IS_ERR(vm_bo))
500+ * return PTR_ERR(vm_bo);
501+ *
440502 * drm_gpuva_for_each_op(op, ops) {
441503 * struct drm_gpuva *va;
442504 *
@@ -449,7 +511,7 @@ · 6 unmodified lines
449511 *
450512 * driver_vm_map();
451513 * drm_gpuva_map(gpuvm, va, &op->map);
452− * drm_gpuva_link(va);
514+ * drm_gpuva_link(va, vm_bo);
453515 *
454516 * break;
455517 * case DRM_GPUVA_OP_REMAP: {
@@ -476,11 +538,11 @@ · 20 unmodified lines
476538 * driver_vm_remap();
477539 * drm_gpuva_remap(prev, next, &op->remap);
478540 *
479− * drm_gpuva_unlink(va);
480541 * if (prev)
481− * drm_gpuva_link(prev);
542+ * drm_gpuva_link(prev, va->vm_bo);
482543 * if (next)
483− * drm_gpuva_link(next);
544+ * drm_gpuva_link(next, va->vm_bo);
545+ * drm_gpuva_unlink(va);
484546 *
485547 * break;
486548 * }
@@ -496,6 +558,7 @@ · 9 unmodified lines
496558 * break;
497559 * }
498560 * }
561+ * drm_gpuvm_bo_put(vm_bo);
499562 * driver_unlock_va_space();
500563 *
501564 * return 0;
@@ -505,6 +568,7 @@ · 3 unmodified lines
505568 *
506569 * struct driver_context {
507570 * struct drm_gpuvm *gpuvm;
571+ * struct drm_gpuvm_bo *vm_bo;
508572 * struct drm_gpuva *new_va;
509573 * struct drm_gpuva *prev_va;
510574 * struct drm_gpuva *next_va;
@@ -525,6 +589,7 @@ · 14 unmodified lines
525589 * struct drm_gem_object *obj, u64 offset)
526590 * {
527591 * struct driver_context ctx;
592+ * struct drm_gpuvm_bo *vm_bo;
528593 * struct drm_gpuva_ops *ops;
529594 * struct drm_gpuva_op *op;
530595 * int ret = 0;
@@ -534,16 +599,23 @@ · 3 unmodified lines
534599 * ctx.new_va = kzalloc(sizeof(*ctx.new_va), GFP_KERNEL);
535600 * ctx.prev_va = kzalloc(sizeof(*ctx.prev_va), GFP_KERNEL);
536601 * ctx.next_va = kzalloc(sizeof(*ctx.next_va), GFP_KERNEL);
537− * if (!ctx.new_va || !ctx.prev_va || !ctx.next_va) {
602+ * ctx.vm_bo = drm_gpuvm_bo_create(gpuvm, obj);
603+ * if (!ctx.new_va || !ctx.prev_va || !ctx.next_va || !vm_bo) {
538604 * ret = -ENOMEM;
539605 * goto out;
540606 * }
541607 *
608+ * // Typically protected with a driver specific GEM gpuva lock
609+ * // used in the fence signaling path for drm_gpuva_link() and
610+ * // drm_gpuva_unlink(), hence pre-allocate.
611+ * ctx.vm_bo = drm_gpuvm_bo_obtain_prealloc(ctx.vm_bo);
612+ *
542613 * driver_lock_va_space();
543614 * ret = drm_gpuvm_sm_map(gpuvm, &ctx, addr, range, obj, offset);
544615 * driver_unlock_va_space();
545616 *
546617 * out:
618+ * drm_gpuvm_bo_put(ctx.vm_bo);
547619 * kfree(ctx.new_va);
548620 * kfree(ctx.prev_va);
549621 * kfree(ctx.next_va);
@@ -556,7 +628,7 @@ · 6 unmodified lines
556628 *
557629 * drm_gpuva_map(ctx->vm, ctx->new_va, &op->map);
558630 *
559− * drm_gpuva_link(ctx->new_va);
631+ * drm_gpuva_link(ctx->new_va, ctx->vm_bo);
560632 *
561633 * // prevent the new GPUVA from being freed in
562634 * // driver_mapping_create()
@@ -568,22 +640,23 @@ · 5 unmodified lines
568640 * int driver_gpuva_remap(struct drm_gpuva_op *op, void *__ctx)
569641 * {
570642 * struct driver_context *ctx = __ctx;
643+ * struct drm_gpuva *va = op->remap.unmap->va;
571644 *
572645 * drm_gpuva_remap(ctx->prev_va, ctx->next_va, &op->remap);
573646 *
574− * drm_gpuva_unlink(op->remap.unmap->va);
575− * kfree(op->remap.unmap->va);
576− *
577647 * if (op->remap.prev) {
578− * drm_gpuva_link(ctx->prev_va);
648+ * drm_gpuva_link(ctx->prev_va, va->vm_bo);
579649 * ctx->prev_va = NULL;
580650 * }
581651 *
582652 * if (op->remap.next) {
583− * drm_gpuva_link(ctx->next_va);
653+ * drm_gpuva_link(ctx->next_va, va->vm_bo);
584654 * ctx->next_va = NULL;
585655 * }
586656 *
657+ * drm_gpuva_unlink(va);
658+ * kfree(va);
659+ *
587660 * return 0;
588661 * }
589662 *
@@ -597,6 +670,201 @@ · 7 unmodified lines
597670 * }
598671 */
599672
673+/**
674+ * get_next_vm_bo_from_list() - get the next vm_bo element
675+ * @__gpuvm: the &drm_gpuvm
676+ * @__list_name: the name of the list we're iterating on
677+ * @__local_list: a pointer to the local list used to store already iterated items
678+ * @__prev_vm_bo: the previous element we got from get_next_vm_bo_from_list()
679+ *
680+ * This helper is here to provide lockless list iteration. Lockless as in, the
681+ * iterator releases the lock immediately after picking the first element from
682+ * the list, so list insertion deletion can happen concurrently.
683+ *
684+ * Elements popped from the original list are kept in a local list, so removal
685+ * and is_empty checks can still happen while we're iterating the list.
686+ */
687+#define get_next_vm_bo_from_list(__gpuvm, __list_name, __local_list, __prev_vm_bo) \
688+ ({ \
689+ struct drm_gpuvm_bo *__vm_bo = NULL; \
690+ \
691+ drm_gpuvm_bo_put(__prev_vm_bo); \
692+ \
693+ spin_lock(&(__gpuvm)->__list_name.lock); \
694+ if (!(__gpuvm)->__list_name.local_list) \
695+ (__gpuvm)->__list_name.local_list = __local_list; \
696+ else \
697+ drm_WARN_ON((__gpuvm)->drm, \
698+ (__gpuvm)->__list_name.local_list != __local_list); \
699+ \
700+ while (!list_empty(&(__gpuvm)->__list_name.list)) { \
701+ __vm_bo = list_first_entry(&(__gpuvm)->__list_name.list, \
702+ struct drm_gpuvm_bo, \
703+ list.entry.__list_name); \
704+ if (kref_get_unless_zero(&__vm_bo->kref)) { \
705+ list_move_tail(&(__vm_bo)->list.entry.__list_name, \
706+ __local_list); \
707+ break; \
708+ } else { \
709+ list_del_init(&(__vm_bo)->list.entry.__list_name); \
710+ __vm_bo = NULL; \
711+ } \
712+ } \
713+ spin_unlock(&(__gpuvm)->__list_name.lock); \
714+ \
715+ __vm_bo; \
716+ })
717+
718+/**
719+ * for_each_vm_bo_in_list() - internal vm_bo list iterator
720+ * @__gpuvm: the &drm_gpuvm
721+ * @__list_name: the name of the list we're iterating on
722+ * @__local_list: a pointer to the local list used to store already iterated items
723+ * @__vm_bo: the struct drm_gpuvm_bo to assign in each iteration step
724+ *
725+ * This helper is here to provide lockless list iteration. Lockless as in, the
726+ * iterator releases the lock immediately after picking the first element from the
727+ * list, hence list insertion and deletion can happen concurrently.
728+ *
729+ * It is not allowed to re-assign the vm_bo pointer from inside this loop.
730+ *
731+ * Typical use:
732+ *
733+ * struct drm_gpuvm_bo *vm_bo;
734+ * LIST_HEAD(my_local_list);
735+ *
736+ * ret = 0;
737+ * for_each_vm_bo_in_list(gpuvm, <list_name>, &my_local_list, vm_bo) {
738+ * ret = do_something_with_vm_bo(..., vm_bo);
739+ * if (ret)
740+ * break;
741+ * }
742+ * // Drop ref in case we break out of the loop.
743+ * drm_gpuvm_bo_put(vm_bo);
744+ * restore_vm_bo_list(gpuvm, <list_name>, &my_local_list);
745+ *
746+ *
747+ * Only used for internal list iterations, not meant to be exposed to the outside
748+ * world.
749+ */
750+#define for_each_vm_bo_in_list(__gpuvm, __list_name, __local_list, __vm_bo) \
751+ for (__vm_bo = get_next_vm_bo_from_list(__gpuvm, __list_name, \
752+ __local_list, NULL); \
753+ __vm_bo; \
754+ __vm_bo = get_next_vm_bo_from_list(__gpuvm, __list_name, \
755+ __local_list, __vm_bo))
756+
757+static void
758+__restore_vm_bo_list(struct drm_gpuvm *gpuvm, spinlock_t *lock,
759+ struct list_head *list, struct list_head **local_list)
760+{
761+ /* Merge back the two lists, moving local list elements to the
762+ * head to preserve previous ordering, in case it matters.
763+ */
764+ spin_lock(lock);
765+ if (*local_list) {
766+ list_splice(*local_list, list);
767+ *local_list = NULL;
768+ }
769+ spin_unlock(lock);
770+}
771+
772+/**
773+ * restore_vm_bo_list() - move vm_bo elements back to their original list
774+ * @__gpuvm: the &drm_gpuvm
775+ * @__list_name: the name of the list we're iterating on
776+ *
777+ * When we're done iterating a vm_bo list, we should call restore_vm_bo_list()
778+ * to restore the original state and let new iterations take place.
779+ */
780+#define restore_vm_bo_list(__gpuvm, __list_name) \
781+ __restore_vm_bo_list((__gpuvm), &(__gpuvm)->__list_name.lock, \
782+ &(__gpuvm)->__list_name.list, \
783+ &(__gpuvm)->__list_name.local_list)
784+
785+static void
786+cond_spin_lock(spinlock_t *lock, bool cond)
787+{
788+ if (cond)
789+ spin_lock(lock);
790+}
791+
792+static void
793+cond_spin_unlock(spinlock_t *lock, bool cond)
794+{
795+ if (cond)
796+ spin_unlock(lock);
797+}
798+
799+static void
800+__drm_gpuvm_bo_list_add(struct drm_gpuvm *gpuvm, spinlock_t *lock,
801+ struct list_head *entry, struct list_head *list)
802+{
803+ cond_spin_lock(lock, !!lock);
804+ if (list_empty(entry))
805+ list_add_tail(entry, list);
806+ cond_spin_unlock(lock, !!lock);
807+}
808+
809+/**
810+ * drm_gpuvm_bo_list_add() - insert a vm_bo into the given list
811+ * @__vm_bo: the &drm_gpuvm_bo
812+ * @__list_name: the name of the list to insert into
813+ * @__lock: whether to lock with the internal spinlock
814+ *
815+ * Inserts the given @__vm_bo into the list specified by @__list_name.
816+ */
817+#define drm_gpuvm_bo_list_add(__vm_bo, __list_name, __lock) \
818+ __drm_gpuvm_bo_list_add((__vm_bo)->vm, \
819+ __lock ? &(__vm_bo)->vm->__list_name.lock : \
820+ NULL, \
821+ &(__vm_bo)->list.entry.__list_name, \
822+ &(__vm_bo)->vm->__list_name.list)
823+
824+static void
825+__drm_gpuvm_bo_list_del(struct drm_gpuvm *gpuvm, spinlock_t *lock,
826+ struct list_head *entry, bool init)
827+{
828+ cond_spin_lock(lock, !!lock);
829+ if (init) {
830+ if (!list_empty(entry))
831+ list_del_init(entry);
832+ } else {
833+ list_del(entry);
834+ }
835+ cond_spin_unlock(lock, !!lock);
836+}
837+
838+/**
839+ * drm_gpuvm_bo_list_del_init() - remove a vm_bo from the given list
840+ * @__vm_bo: the &drm_gpuvm_bo
841+ * @__list_name: the name of the list to insert into
842+ * @__lock: whether to lock with the internal spinlock
843+ *
844+ * Removes the given @__vm_bo from the list specified by @__list_name.
845+ */
846+#define drm_gpuvm_bo_list_del_init(__vm_bo, __list_name, __lock) \
847+ __drm_gpuvm_bo_list_del((__vm_bo)->vm, \
848+ __lock ? &(__vm_bo)->vm->__list_name.lock : \
849+ NULL, \
850+ &(__vm_bo)->list.entry.__list_name, \
851+ true)
852+
853+/**
854+ * drm_gpuvm_bo_list_del() - remove a vm_bo from the given list
855+ * @__vm_bo: the &drm_gpuvm_bo
856+ * @__list_name: the name of the list to insert into
857+ * @__lock: whether to lock with the internal spinlock
858+ *
859+ * Removes the given @__vm_bo from the list specified by @__list_name.
860+ */
861+#define drm_gpuvm_bo_list_del(__vm_bo, __list_name, __lock) \
862+ __drm_gpuvm_bo_list_del((__vm_bo)->vm, \
863+ __lock ? &(__vm_bo)->vm->__list_name.lock : \
864+ NULL, \
865+ &(__vm_bo)->list.entry.__list_name, \
866+ false)
867+
600868 #define to_drm_gpuva(__node) container_of((__node), struct drm_gpuva, rb.node)
601869
602870 #define GPUVA_START(node) ((node)->va.addr)
@@ -618,8 +886,14 @@ drm_gpuvm_check_overflow(u64 addr, u64 range) · 15 unmodified lines
618886 {
619887 u64 end;
620888
621− return WARN(check_add_overflow(addr, range, &end),
622− "GPUVA address limited to %zu bytes.\n", sizeof(end));
889+ return check_add_overflow(addr, range, &end);
890+}
891+
892+static bool
893+drm_gpuvm_warn_check_overflow(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
894+{
895+ return drm_WARN(gpuvm->drm, drm_gpuvm_check_overflow(addr, range),
896+ "GPUVA address limited to %zu bytes.\n", sizeof(addr));
623897 }
624898
625899 static bool
@@ -643,7 +917,18 @@ drm_gpuvm_in_kernel_node(struct drm_gpuvm *gpuvm, u64 addr, u64 range) · 17 unmodified lines
643917 return krange && addr < kend && kstart < end;
644918 }
645919
646−static bool
920+/**
921+ * drm_gpuvm_range_valid() - checks whether the given range is valid for the
922+ * given &drm_gpuvm
923+ * @gpuvm: the GPUVM to check the range for
924+ * @addr: the base address
925+ * @range: the range starting from the base address
926+ *
927+ * Checks whether the range is within the GPUVM's managed boundaries.
928+ *
929+ * Returns: true for a valid range, false otherwise
930+ */
931+bool
647932 drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm,
648933 u64 addr, u64 range)
649934 {
@@ -651,11 +936,52 @@ drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm, · 1 unmodified line
651936 drm_gpuvm_in_mm_range(gpuvm, addr, range) &&
652937 !drm_gpuvm_in_kernel_node(gpuvm, addr, range);
653938 }
939+EXPORT_SYMBOL_GPL(drm_gpuvm_range_valid);
940+
941+static void
942+drm_gpuvm_gem_object_free(struct drm_gem_object *obj)
943+{
944+ drm_gem_object_release(obj);
945+ kfree(obj);
946+}
947+
948+static const struct drm_gem_object_funcs drm_gpuvm_object_funcs = {
949+ .free = drm_gpuvm_gem_object_free,
950+};
951+
952+/**
953+ * drm_gpuvm_resv_object_alloc() - allocate a dummy &drm_gem_object
954+ * @drm: the drivers &drm_device
955+ *
956+ * Allocates a dummy &drm_gem_object which can be passed to drm_gpuvm_init() in
957+ * order to serve as root GEM object providing the &drm_resv shared across
958+ * &drm_gem_objects local to a single GPUVM.
959+ *
960+ * Returns: the &drm_gem_object on success, NULL on failure
961+ */
962+struct drm_gem_object *
963+drm_gpuvm_resv_object_alloc(struct drm_device *drm)
964+{
965+ struct drm_gem_object *obj;
966+
967+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
968+ if (!obj)
969+ return NULL;
970+
971+ obj->funcs = &drm_gpuvm_object_funcs;
972+ drm_gem_private_object_init(drm, obj, 0);
973+
974+ return obj;
975+}
976+EXPORT_SYMBOL_GPL(drm_gpuvm_resv_object_alloc);
654977
655978 /**
656979 * drm_gpuvm_init() - initialize a &drm_gpuvm
657980 * @gpuvm: pointer to the &drm_gpuvm to initialize
658981 * @name: the name of the GPU VA space
982+ * @flags: the &drm_gpuvm_flags for this GPUVM
983+ * @drm: the &drm_device this VM resides in
984+ * @r_obj: the resv &drm_gem_object providing the GPUVM's common &dma_resv
659985 * @start_offset: the start offset of the GPU VA space
660986 * @range: the size of the GPU VA space
661987 * @reserve_offset: the start of the kernel reserved GPU VA area
@@ -668,8 +994,10 @@ drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm, · 6 unmodified lines
668994 * &name is expected to be managed by the surrounding driver structures.
669995 */
670996 void
671−drm_gpuvm_init(struct drm_gpuvm *gpuvm,
672− const char *name,
997+drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
998+ enum drm_gpuvm_flags flags,
999+ struct drm_device *drm,
1000+ struct drm_gem_object *r_obj,
6731001 u64 start_offset, u64 range,
6741002 u64 reserve_offset, u64 reserve_range,
6751003 const struct drm_gpuvm_ops *ops)
@@ -677,45 +1005,713 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, · 1 unmodified line
6771005 gpuvm->rb.tree = RB_ROOT_CACHED;
6781006 INIT_LIST_HEAD(&gpuvm->rb.list);
6791007
680− drm_gpuvm_check_overflow(start_offset, range);
681− gpuvm->mm_start = start_offset;
682− gpuvm->mm_range = range;
1008+ INIT_LIST_HEAD(&gpuvm->extobj.list);
1009+ spin_lock_init(&gpuvm->extobj.lock);
1010+
1011+ INIT_LIST_HEAD(&gpuvm->evict.list);
1012+ spin_lock_init(&gpuvm->evict.lock);
1013+
1014+ kref_init(&gpuvm->kref);
6831015
6841016 gpuvm->name = name ? name : "unknown";
1017+ gpuvm->flags = flags;
6851018 gpuvm->ops = ops;
1019+ gpuvm->drm = drm;
1020+ gpuvm->r_obj = r_obj;
6861021
687− memset(&gpuvm->kernel_alloc_node, 0, sizeof(struct drm_gpuva));
1022+ drm_gem_object_get(r_obj);
1023+
1024+ drm_gpuvm_warn_check_overflow(gpuvm, start_offset, range);
1025+ gpuvm->mm_start = start_offset;
1026+ gpuvm->mm_range = range;
6881027
1028+ memset(&gpuvm->kernel_alloc_node, 0, sizeof(struct drm_gpuva));
6891029 if (reserve_range) {
6901030 gpuvm->kernel_alloc_node.va.addr = reserve_offset;
6911031 gpuvm->kernel_alloc_node.va.range = reserve_range;
6921032
693− if (likely(!drm_gpuvm_check_overflow(reserve_offset,
694− reserve_range)))
1033+ if (likely(!drm_gpuvm_warn_check_overflow(gpuvm, reserve_offset,
1034+ reserve_range)))
6951035 __drm_gpuva_insert(gpuvm, &gpuvm->kernel_alloc_node);
6961036 }
6971037 }
6981038 EXPORT_SYMBOL_GPL(drm_gpuvm_init);
6991039
1040+static void
1041+drm_gpuvm_fini(struct drm_gpuvm *gpuvm)
1042+{
1043+ gpuvm->name = NULL;
1044+
1045+ if (gpuvm->kernel_alloc_node.va.range)
1046+ __drm_gpuva_remove(&gpuvm->kernel_alloc_node);
1047+
1048+ drm_WARN(gpuvm->drm, !RB_EMPTY_ROOT(&gpuvm->rb.tree.rb_root),
1049+ "GPUVA tree is not empty, potentially leaking memory.\n");
1050+
1051+ drm_WARN(gpuvm->drm, !list_empty(&gpuvm->extobj.list),
1052+ "Extobj list should be empty.\n");
1053+ drm_WARN(gpuvm->drm, !list_empty(&gpuvm->evict.list),
1054+ "Evict list should be empty.\n");
1055+
1056+ drm_gem_object_put(gpuvm->r_obj);
1057+}
1058+
1059+static void
1060+drm_gpuvm_free(struct kref *kref)
1061+{
1062+ struct drm_gpuvm *gpuvm = container_of(kref, struct drm_gpuvm, kref);
1063+
1064+ drm_gpuvm_fini(gpuvm);
1065+
1066+ if (drm_WARN_ON(gpuvm->drm, !gpuvm->ops->vm_free))
1067+ return;
1068+
1069+ gpuvm->ops->vm_free(gpuvm);
1070+}
1071+
7001072 /**
701− * drm_gpuvm_destroy() - cleanup a &drm_gpuvm
702− * @gpuvm: pointer to the &drm_gpuvm to clean up
1073+ * drm_gpuvm_put() - drop a struct drm_gpuvm reference
1074+ * @gpuvm: the &drm_gpuvm to release the reference of
1075+ *
1076+ * This releases a reference to @gpuvm.
7031077 *
704− * Note that it is a bug to call this function on a manager that still
705− * holds GPU VA mappings.
1078+ * This function may be called from atomic context.
7061079 */
7071080 void
708−drm_gpuvm_destroy(struct drm_gpuvm *gpuvm)
1081+drm_gpuvm_put(struct drm_gpuvm *gpuvm)
7091082 {
710− gpuvm->name = NULL;
1083+ if (gpuvm)
1084+ kref_put(&gpuvm->kref, drm_gpuvm_free);
1085+}
1086+EXPORT_SYMBOL_GPL(drm_gpuvm_put);
7111087
712− if (gpuvm->kernel_alloc_node.va.range)
713− __drm_gpuva_remove(&gpuvm->kernel_alloc_node);
1088+static int
1089+exec_prepare_obj(struct drm_exec *exec, struct drm_gem_object *obj,
1090+ unsigned int num_fences)
1091+{
1092+ return num_fences ? drm_exec_prepare_obj(exec, obj, num_fences) :
1093+ drm_exec_lock_obj(exec, obj);
1094+}
7141095
715− WARN(!RB_EMPTY_ROOT(&gpuvm->rb.tree.rb_root),
716− "GPUVA tree is not empty, potentially leaking memory.");
1096+/**
1097+ * drm_gpuvm_prepare_vm() - prepare the GPUVMs common dma-resv
1098+ * @gpuvm: the &drm_gpuvm
1099+ * @exec: the &drm_exec context
1100+ * @num_fences: the amount of &dma_fences to reserve
1101+ *
1102+ * Calls drm_exec_prepare_obj() for the GPUVMs dummy &drm_gem_object; if
1103+ * @num_fences is zero drm_exec_lock_obj() is called instead.
1104+ *
1105+ * Using this function directly, it is the drivers responsibility to call
1106+ * drm_exec_init() and drm_exec_fini() accordingly.
1107+ *
1108+ * Returns: 0 on success, negative error code on failure.
1109+ */
1110+int
1111+drm_gpuvm_prepare_vm(struct drm_gpuvm *gpuvm,
1112+ struct drm_exec *exec,
1113+ unsigned int num_fences)
1114+{
1115+ return exec_prepare_obj(exec, gpuvm->r_obj, num_fences);
1116+}
1117+EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_vm);
1118+
1119+static int
1120+__drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
1121+ struct drm_exec *exec,
1122+ unsigned int num_fences)
1123+{
1124+ struct drm_gpuvm_bo *vm_bo;
1125+ LIST_HEAD(extobjs);
1126+ int ret = 0;
1127+
1128+ for_each_vm_bo_in_list(gpuvm, extobj, &extobjs, vm_bo) {
1129+ ret = exec_prepare_obj(exec, vm_bo->obj, num_fences);
1130+ if (ret)
1131+ break;
1132+ }
1133+ /* Drop ref in case we break out of the loop. */
1134+ drm_gpuvm_bo_put(vm_bo);
1135+ restore_vm_bo_list(gpuvm, extobj);
1136+
1137+ return ret;
7171138 }
718−EXPORT_SYMBOL_GPL(drm_gpuvm_destroy);
1139+
1140+static int
1141+drm_gpuvm_prepare_objects_locked(struct drm_gpuvm *gpuvm,
1142+ struct drm_exec *exec,
1143+ unsigned int num_fences)
1144+{
1145+ struct drm_gpuvm_bo *vm_bo;
1146+ int ret = 0;
1147+
1148+ drm_gpuvm_resv_assert_held(gpuvm);
1149+ list_for_each_entry(vm_bo, &gpuvm->extobj.list, list.entry.extobj) {
1150+ ret = exec_prepare_obj(exec, vm_bo->obj, num_fences);
1151+ if (ret)
1152+ break;
1153+
1154+ if (vm_bo->evicted)
1155+ drm_gpuvm_bo_list_add(vm_bo, evict, false);
1156+ }
1157+
1158+ return ret;
1159+}
1160+
1161+/**
1162+ * drm_gpuvm_prepare_objects() - prepare all assoiciated BOs
1163+ * @gpuvm: the &drm_gpuvm
1164+ * @exec: the &drm_exec locking context
1165+ * @num_fences: the amount of &dma_fences to reserve
1166+ *
1167+ * Calls drm_exec_prepare_obj() for all &drm_gem_objects the given
1168+ * &drm_gpuvm contains mappings of; if @num_fences is zero drm_exec_lock_obj()
1169+ * is called instead.
1170+ *
1171+ * Using this function directly, it is the drivers responsibility to call
1172+ * drm_exec_init() and drm_exec_fini() accordingly.
1173+ *
1174+ * Note: This function is safe against concurrent insertion and removal of
1175+ * external objects, however it is not safe against concurrent usage itself.
1176+ *
1177+ * Drivers need to make sure to protect this case with either an outer VM lock
1178+ * or by calling drm_gpuvm_prepare_vm() before this function within the
1179+ * drm_exec_until_all_locked() loop, such that the GPUVM's dma-resv lock ensures
1180+ * mutual exclusion.
1181+ *
1182+ * Returns: 0 on success, negative error code on failure.
1183+ */
1184+int
1185+drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
1186+ struct drm_exec *exec,
1187+ unsigned int num_fences)
1188+{
1189+ if (drm_gpuvm_resv_protected(gpuvm))
1190+ return drm_gpuvm_prepare_objects_locked(gpuvm, exec,
1191+ num_fences);
1192+ else
1193+ return __drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
1194+}
1195+EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_objects);
1196+
1197+/**
1198+ * drm_gpuvm_prepare_range() - prepare all BOs mapped within a given range
1199+ * @gpuvm: the &drm_gpuvm
1200+ * @exec: the &drm_exec locking context
1201+ * @addr: the start address within the VA space
1202+ * @range: the range to iterate within the VA space
1203+ * @num_fences: the amount of &dma_fences to reserve
1204+ *
1205+ * Calls drm_exec_prepare_obj() for all &drm_gem_objects mapped between @addr
1206+ * and @addr + @range; if @num_fences is zero drm_exec_lock_obj() is called
1207+ * instead.
1208+ *
1209+ * Returns: 0 on success, negative error code on failure.
1210+ */
1211+int
1212+drm_gpuvm_prepare_range(struct drm_gpuvm *gpuvm, struct drm_exec *exec,
1213+ u64 addr, u64 range, unsigned int num_fences)
1214+{
1215+ struct drm_gpuva *va;
1216+ u64 end = addr + range;
1217+ int ret;
1218+
1219+ drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) {
1220+ struct drm_gem_object *obj = va->gem.obj;
1221+
1222+ ret = exec_prepare_obj(exec, obj, num_fences);
1223+ if (ret)
1224+ return ret;
1225+ }
1226+
1227+ return 0;
1228+}
1229+EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_range);
1230+
1231+/**
1232+ * drm_gpuvm_exec_lock() - lock all dma-resv of all assoiciated BOs
1233+ * @vm_exec: the &drm_gpuvm_exec wrapper
1234+ *
1235+ * Acquires all dma-resv locks of all &drm_gem_objects the given
1236+ * &drm_gpuvm contains mappings of.
1237+ *
1238+ * Addionally, when calling this function with struct drm_gpuvm_exec::extra
1239+ * being set the driver receives the given @fn callback to lock additional
1240+ * dma-resv in the context of the &drm_gpuvm_exec instance. Typically, drivers
1241+ * would call drm_exec_prepare_obj() from within this callback.
1242+ *
1243+ * Returns: 0 on success, negative error code on failure.
1244+ */
1245+int
1246+drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec)
1247+{
1248+ struct drm_gpuvm *gpuvm = vm_exec->vm;
1249+ struct drm_exec *exec = &vm_exec->exec;
1250+ unsigned int num_fences = vm_exec->num_fences;
1251+ int ret;
1252+
1253+ drm_exec_init(exec, vm_exec->flags);
1254+
1255+ drm_exec_until_all_locked(exec) {
1256+ ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences);
1257+ drm_exec_retry_on_contention(exec);
1258+ if (ret)
1259+ goto err;
1260+
1261+ ret = drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
1262+ drm_exec_retry_on_contention(exec);
1263+ if (ret)
1264+ goto err;
1265+
1266+ if (vm_exec->extra.fn) {
1267+ ret = vm_exec->extra.fn(vm_exec);
1268+ drm_exec_retry_on_contention(exec);
1269+ if (ret)
1270+ goto err;
1271+ }
1272+ }
1273+
1274+ return 0;
1275+
1276+err:
1277+ drm_exec_fini(exec);
1278+ return ret;
1279+}
1280+EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock);
1281+
1282+static int
1283+fn_lock_array(struct drm_gpuvm_exec *vm_exec)
1284+{
1285+ struct {
1286+ struct drm_gem_object **objs;
1287+ unsigned int num_objs;
1288+ } *args = vm_exec->extra.priv;
1289+
1290+ return drm_exec_prepare_array(&vm_exec->exec, args->objs,
1291+ args->num_objs, vm_exec->num_fences);
1292+}
1293+
1294+/**
1295+ * drm_gpuvm_exec_lock_array() - lock all dma-resv of all assoiciated BOs
1296+ * @vm_exec: the &drm_gpuvm_exec wrapper
1297+ * @objs: additional &drm_gem_objects to lock
1298+ * @num_objs: the number of additional &drm_gem_objects to lock
1299+ *
1300+ * Acquires all dma-resv locks of all &drm_gem_objects the given &drm_gpuvm
1301+ * contains mappings of, plus the ones given through @objs.
1302+ *
1303+ * Returns: 0 on success, negative error code on failure.
1304+ */
1305+int
1306+drm_gpuvm_exec_lock_array(struct drm_gpuvm_exec *vm_exec,
1307+ struct drm_gem_object **objs,
1308+ unsigned int num_objs)
1309+{
1310+ struct {
1311+ struct drm_gem_object **objs;
1312+ unsigned int num_objs;
1313+ } args;
1314+
1315+ args.objs = objs;
1316+ args.num_objs = num_objs;
1317+
1318+ vm_exec->extra.fn = fn_lock_array;
1319+ vm_exec->extra.priv = &args;
1320+
1321+ return drm_gpuvm_exec_lock(vm_exec);
1322+}
1323+EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock_array);
1324+
1325+/**
1326+ * drm_gpuvm_exec_lock_range() - prepare all BOs mapped within a given range
1327+ * @vm_exec: the &drm_gpuvm_exec wrapper
1328+ * @addr: the start address within the VA space
1329+ * @range: the range to iterate within the VA space
1330+ *
1331+ * Acquires all dma-resv locks of all &drm_gem_objects mapped between @addr and
1332+ * @addr + @range.
1333+ *
1334+ * Returns: 0 on success, negative error code on failure.
1335+ */
1336+int
1337+drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
1338+ u64 addr, u64 range)
1339+{
1340+ struct drm_gpuvm *gpuvm = vm_exec->vm;
1341+ struct drm_exec *exec = &vm_exec->exec;
1342+ int ret;
1343+
1344+ drm_exec_init(exec, vm_exec->flags);
1345+
1346+ drm_exec_until_all_locked(exec) {
1347+ ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range,
1348+ vm_exec->num_fences);
1349+ drm_exec_retry_on_contention(exec);
1350+ if (ret)
1351+ goto err;
1352+ }
1353+
1354+ return ret;
1355+
1356+err:
1357+ drm_exec_fini(exec);
1358+ return ret;
1359+}
1360+EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock_range);
1361+
1362+static int
1363+__drm_gpuvm_validate(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1364+{
1365+ const struct drm_gpuvm_ops *ops = gpuvm->ops;
1366+ struct drm_gpuvm_bo *vm_bo;
1367+ LIST_HEAD(evict);
1368+ int ret = 0;
1369+
1370+ for_each_vm_bo_in_list(gpuvm, evict, &evict, vm_bo) {
1371+ ret = ops->vm_bo_validate(vm_bo, exec);
1372+ if (ret)
1373+ break;
1374+ }
1375+ /* Drop ref in case we break out of the loop. */
1376+ drm_gpuvm_bo_put(vm_bo);
1377+ restore_vm_bo_list(gpuvm, evict);
1378+
1379+ return ret;
1380+}
1381+
1382+static int
1383+drm_gpuvm_validate_locked(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1384+{
1385+ const struct drm_gpuvm_ops *ops = gpuvm->ops;
1386+ struct drm_gpuvm_bo *vm_bo, *next;
1387+ int ret = 0;
1388+
1389+ drm_gpuvm_resv_assert_held(gpuvm);
1390+
1391+ list_for_each_entry_safe(vm_bo, next, &gpuvm->evict.list,
1392+ list.entry.evict) {
1393+ ret = ops->vm_bo_validate(vm_bo, exec);
1394+ if (ret)
1395+ break;
1396+
1397+ dma_resv_assert_held(vm_bo->obj->resv);
1398+ if (!vm_bo->evicted)
1399+ drm_gpuvm_bo_list_del_init(vm_bo, evict, false);
1400+ }
1401+
1402+ return ret;
1403+}
1404+
1405+/**
1406+ * drm_gpuvm_validate() - validate all BOs marked as evicted
1407+ * @gpuvm: the &drm_gpuvm to validate evicted BOs
1408+ * @exec: the &drm_exec instance used for locking the GPUVM
1409+ *
1410+ * Calls the &drm_gpuvm_ops::vm_bo_validate callback for all evicted buffer
1411+ * objects being mapped in the given &drm_gpuvm.
1412+ *
1413+ * Returns: 0 on success, negative error code on failure.
1414+ */
1415+int
1416+drm_gpuvm_validate(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1417+{
1418+ const struct drm_gpuvm_ops *ops = gpuvm->ops;
1419+
1420+ if (unlikely(!ops || !ops->vm_bo_validate))
1421+ return -EOPNOTSUPP;
1422+
1423+ if (drm_gpuvm_resv_protected(gpuvm))
1424+ return drm_gpuvm_validate_locked(gpuvm, exec);
1425+ else
1426+ return __drm_gpuvm_validate(gpuvm, exec);
1427+}
1428+EXPORT_SYMBOL_GPL(drm_gpuvm_validate);
1429+
1430+/**
1431+ * drm_gpuvm_resv_add_fence - add fence to private and all extobj
1432+ * dma-resv
1433+ * @gpuvm: the &drm_gpuvm to add a fence to
1434+ * @exec: the &drm_exec locking context
1435+ * @fence: fence to add
1436+ * @private_usage: private dma-resv usage
1437+ * @extobj_usage: extobj dma-resv usage
1438+ */
1439+void
1440+drm_gpuvm_resv_add_fence(struct drm_gpuvm *gpuvm,
1441+ struct drm_exec *exec,
1442+ struct dma_fence *fence,
1443+ enum dma_resv_usage private_usage,
1444+ enum dma_resv_usage extobj_usage)
1445+{
1446+ struct drm_gem_object *obj;
1447+ unsigned long index;
1448+
1449+ drm_exec_for_each_locked_object(exec, index, obj) {
1450+ dma_resv_assert_held(obj->resv);
1451+ dma_resv_add_fence(obj->resv, fence,
1452+ drm_gpuvm_is_extobj(gpuvm, obj) ?
1453+ extobj_usage : private_usage);
1454+ }
1455+}
1456+EXPORT_SYMBOL_GPL(drm_gpuvm_resv_add_fence);
1457+
1458+/**
1459+ * drm_gpuvm_bo_create() - create a new instance of struct drm_gpuvm_bo
1460+ * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1461+ * @obj: The &drm_gem_object being mapped in the @gpuvm.
1462+ *
1463+ * If provided by the driver, this function uses the &drm_gpuvm_ops
1464+ * vm_bo_alloc() callback to allocate.
1465+ *
1466+ * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure
1467+ */
1468+struct drm_gpuvm_bo *
1469+drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
1470+ struct drm_gem_object *obj)
1471+{
1472+ const struct drm_gpuvm_ops *ops = gpuvm->ops;
1473+ struct drm_gpuvm_bo *vm_bo;
1474+
1475+ if (ops && ops->vm_bo_alloc)
1476+ vm_bo = ops->vm_bo_alloc();
1477+ else
1478+ vm_bo = kzalloc(sizeof(*vm_bo), GFP_KERNEL);
1479+
1480+ if (unlikely(!vm_bo))
1481+ return NULL;
1482+
1483+ vm_bo->vm = drm_gpuvm_get(gpuvm);
1484+ vm_bo->obj = obj;
1485+ drm_gem_object_get(obj);
1486+
1487+ kref_init(&vm_bo->kref);
1488+ INIT_LIST_HEAD(&vm_bo->list.gpuva);
1489+ INIT_LIST_HEAD(&vm_bo->list.entry.gem);
1490+
1491+ INIT_LIST_HEAD(&vm_bo->list.entry.extobj);
1492+ INIT_LIST_HEAD(&vm_bo->list.entry.evict);
1493+
1494+ return vm_bo;
1495+}
1496+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create);
1497+
1498+static void
1499+drm_gpuvm_bo_destroy(struct kref *kref)
1500+{
1501+ struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
1502+ kref);
1503+ struct drm_gpuvm *gpuvm = vm_bo->vm;
1504+ const struct drm_gpuvm_ops *ops = gpuvm->ops;
1505+ struct drm_gem_object *obj = vm_bo->obj;
1506+ bool lock = !drm_gpuvm_resv_protected(gpuvm);
1507+
1508+ if (!lock)
1509+ drm_gpuvm_resv_assert_held(gpuvm);
1510+
1511+ drm_gpuvm_bo_list_del(vm_bo, extobj, lock);
1512+ drm_gpuvm_bo_list_del(vm_bo, evict, lock);
1513+
1514+ drm_gem_gpuva_assert_lock_held(obj);
1515+ list_del(&vm_bo->list.entry.gem);
1516+
1517+ if (ops && ops->vm_bo_free)
1518+ ops->vm_bo_free(vm_bo);
1519+ else
1520+ kfree(vm_bo);
1521+
1522+ drm_gpuvm_put(gpuvm);
1523+ drm_gem_object_put(obj);
1524+}
1525+
1526+/**
1527+ * drm_gpuvm_bo_put() - drop a struct drm_gpuvm_bo reference
1528+ * @vm_bo: the &drm_gpuvm_bo to release the reference of
1529+ *
1530+ * This releases a reference to @vm_bo.
1531+ *
1532+ * If the reference count drops to zero, the &gpuvm_bo is destroyed, which
1533+ * includes removing it from the GEMs gpuva list. Hence, if a call to this
1534+ * function can potentially let the reference count drop to zero the caller must
1535+ * hold the dma-resv or driver specific GEM gpuva lock.
1536+ *
1537+ * This function may only be called from non-atomic context.
1538+ *
1539+ * Returns: true if vm_bo was destroyed, false otherwise.
1540+ */
1541+bool
1542+drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo)
1543+{
1544+ might_sleep();
1545+
1546+ if (vm_bo)
1547+ return !!kref_put(&vm_bo->kref, drm_gpuvm_bo_destroy);
1548+
1549+ return false;
1550+}
1551+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put);
1552+
1553+static struct drm_gpuvm_bo *
1554+__drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
1555+ struct drm_gem_object *obj)
1556+{
1557+ struct drm_gpuvm_bo *vm_bo;
1558+
1559+ drm_gem_gpuva_assert_lock_held(obj);
1560+ drm_gem_for_each_gpuvm_bo(vm_bo, obj)
1561+ if (vm_bo->vm == gpuvm)
1562+ return vm_bo;
1563+
1564+ return NULL;
1565+}
1566+
1567+/**
1568+ * drm_gpuvm_bo_find() - find the &drm_gpuvm_bo for the given
1569+ * &drm_gpuvm and &drm_gem_object
1570+ * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1571+ * @obj: The &drm_gem_object being mapped in the @gpuvm.
1572+ *
1573+ * Find the &drm_gpuvm_bo representing the combination of the given
1574+ * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1575+ * count of the &drm_gpuvm_bo accordingly.
1576+ *
1577+ * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure
1578+ */
1579+struct drm_gpuvm_bo *
1580+drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
1581+ struct drm_gem_object *obj)
1582+{
1583+ struct drm_gpuvm_bo *vm_bo = __drm_gpuvm_bo_find(gpuvm, obj);
1584+
1585+ return vm_bo ? drm_gpuvm_bo_get(vm_bo) : NULL;
1586+}
1587+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_find);
1588+
1589+/**
1590+ * drm_gpuvm_bo_obtain() - obtains and instance of the &drm_gpuvm_bo for the
1591+ * given &drm_gpuvm and &drm_gem_object
1592+ * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1593+ * @obj: The &drm_gem_object being mapped in the @gpuvm.
1594+ *
1595+ * Find the &drm_gpuvm_bo representing the combination of the given
1596+ * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1597+ * count of the &drm_gpuvm_bo accordingly. If not found, allocates a new
1598+ * &drm_gpuvm_bo.
1599+ *
1600+ * A new &drm_gpuvm_bo is added to the GEMs gpuva list.
1601+ *
1602+ * Returns: a pointer to the &drm_gpuvm_bo on success, an ERR_PTR on failure
1603+ */
1604+struct drm_gpuvm_bo *
1605+drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm,
1606+ struct drm_gem_object *obj)
1607+{
1608+ struct drm_gpuvm_bo *vm_bo;
1609+
1610+ vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
1611+ if (vm_bo)
1612+ return vm_bo;
1613+
1614+ vm_bo = drm_gpuvm_bo_create(gpuvm, obj);
1615+ if (!vm_bo)
1616+ return ERR_PTR(-ENOMEM);
1617+
1618+ drm_gem_gpuva_assert_lock_held(obj);
1619+ list_add_tail(&vm_bo->list.entry.gem, &obj->gpuva.list);
1620+
1621+ return vm_bo;
1622+}
1623+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain);
1624+
1625+/**
1626+ * drm_gpuvm_bo_obtain_prealloc() - obtains and instance of the &drm_gpuvm_bo
1627+ * for the given &drm_gpuvm and &drm_gem_object
1628+ * @__vm_bo: A pre-allocated struct drm_gpuvm_bo.
1629+ *
1630+ * Find the &drm_gpuvm_bo representing the combination of the given
1631+ * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1632+ * count of the found &drm_gpuvm_bo accordingly, while the @__vm_bo reference
1633+ * count is decreased. If not found @__vm_bo is returned without further
1634+ * increase of the reference count.
1635+ *
1636+ * A new &drm_gpuvm_bo is added to the GEMs gpuva list.
1637+ *
1638+ * Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing
1639+ * &drm_gpuvm_bo was found
1640+ */
1641+struct drm_gpuvm_bo *
1642+drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *__vm_bo)
1643+{
1644+ struct drm_gpuvm *gpuvm = __vm_bo->vm;
1645+ struct drm_gem_object *obj = __vm_bo->obj;
1646+ struct drm_gpuvm_bo *vm_bo;
1647+
1648+ vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
1649+ if (vm_bo) {
1650+ drm_gpuvm_bo_put(__vm_bo);
1651+ return vm_bo;
1652+ }
1653+
1654+ drm_gem_gpuva_assert_lock_held(obj);
1655+ list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list);
1656+
1657+ return __vm_bo;
1658+}
1659+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_prealloc);
1660+
1661+/**
1662+ * drm_gpuvm_bo_extobj_add() - adds the &drm_gpuvm_bo to its &drm_gpuvm's
1663+ * extobj list
1664+ * @vm_bo: The &drm_gpuvm_bo to add to its &drm_gpuvm's the extobj list.
1665+ *
1666+ * Adds the given @vm_bo to its &drm_gpuvm's extobj list if not on the list
1667+ * already and if the corresponding &drm_gem_object is an external object,
1668+ * actually.
1669+ */
1670+void
1671+drm_gpuvm_bo_extobj_add(struct drm_gpuvm_bo *vm_bo)
1672+{
1673+ struct drm_gpuvm *gpuvm = vm_bo->vm;
1674+ bool lock = !drm_gpuvm_resv_protected(gpuvm);
1675+
1676+ if (!lock)
1677+ drm_gpuvm_resv_assert_held(gpuvm);
1678+
1679+ if (drm_gpuvm_is_extobj(gpuvm, vm_bo->obj))
1680+ drm_gpuvm_bo_list_add(vm_bo, extobj, lock);
1681+}
1682+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_extobj_add);
1683+
1684+/**
1685+ * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to / from the &drm_gpuvms
1686+ * evicted list
1687+ * @vm_bo: the &drm_gpuvm_bo to add or remove
1688+ * @evict: indicates whether the object is evicted
1689+ *
1690+ * Adds a &drm_gpuvm_bo to or removes it from the &drm_gpuvms evicted list.
1691+ */
1692+void
1693+drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
1694+{
1695+ struct drm_gpuvm *gpuvm = vm_bo->vm;
1696+ struct drm_gem_object *obj = vm_bo->obj;
1697+ bool lock = !drm_gpuvm_resv_protected(gpuvm);
1698+
1699+ dma_resv_assert_held(obj->resv);
1700+ vm_bo->evicted = evict;
1701+
1702+ /* Can't add external objects to the evicted list directly if not using
1703+ * internal spinlocks, since in this case the evicted list is protected
1704+ * with the VM's common dma-resv lock.
1705+ */
1706+ if (drm_gpuvm_is_extobj(gpuvm, obj) && !lock)
1707+ return;
1708+
1709+ if (evict)
1710+ drm_gpuvm_bo_list_add(vm_bo, evict, lock);
1711+ else
1712+ drm_gpuvm_bo_list_del_init(vm_bo, evict, lock);
1713+}
1714+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_evict);
7191715
7201716 static int
7211717 __drm_gpuva_insert(struct drm_gpuvm *gpuvm,
@@ -764,11 +1760,21 @@ drm_gpuva_insert(struct drm_gpuvm *gpuvm, · 42 unmodified lines
7641760 {
7651761 u64 addr = va->va.addr;
7661762 u64 range = va->va.range;
1763+ int ret;
7671764
7681765 if (unlikely(!drm_gpuvm_range_valid(gpuvm, addr, range)))
7691766 return -EINVAL;
7701767
771− return __drm_gpuva_insert(gpuvm, va);
1768+ ret = __drm_gpuva_insert(gpuvm, va);
1769+ if (likely(!ret))
1770+ /* Take a reference of the GPUVM for the successfully inserted
1771+ * drm_gpuva. We can't take the reference in
1772+ * __drm_gpuva_insert() itself, since we don't want to increse
1773+ * the reference count for the GPUVM's kernel_alloc_node.
1774+ */
1775+ drm_gpuvm_get(gpuvm);
1776+
1777+ return ret;
7721778 }
7731779 EXPORT_SYMBOL_GPL(drm_gpuva_insert);
7741780
@@ -795,35 +1801,46 @@ drm_gpuva_remove(struct drm_gpuva *va) · 20 unmodified lines
7951801 struct drm_gpuvm *gpuvm = va->vm;
7961802
7971803 if (unlikely(va == &gpuvm->kernel_alloc_node)) {
798− WARN(1, "Can't destroy kernel reserved node.\n");
1804+ drm_WARN(gpuvm->drm, 1,
1805+ "Can't destroy kernel reserved node.\n");
7991806 return;
8001807 }
8011808
8021809 __drm_gpuva_remove(va);
1810+ drm_gpuvm_put(va->vm);
8031811 }
8041812 EXPORT_SYMBOL_GPL(drm_gpuva_remove);
8051813
8061814 /**
8071815 * drm_gpuva_link() - link a &drm_gpuva
8081816 * @va: the &drm_gpuva to link
1817+ * @vm_bo: the &drm_gpuvm_bo to add the &drm_gpuva to
8091818 *
810− * This adds the given &va to the GPU VA list of the &drm_gem_object it is
811− * associated with.
1819+ * This adds the given &va to the GPU VA list of the &drm_gpuvm_bo and the
1820+ * &drm_gpuvm_bo to the &drm_gem_object it is associated with.
1821+ *
1822+ * For every &drm_gpuva entry added to the &drm_gpuvm_bo an additional
1823+ * reference of the latter is taken.
8121824 *
8131825 * This function expects the caller to protect the GEM's GPUVA list against
814− * concurrent access using the GEMs dma_resv lock.
1826+ * concurrent access using either the GEMs dma_resv lock or a driver specific
1827+ * lock set through drm_gem_gpuva_set_lock().
8151828 */
8161829 void
817−drm_gpuva_link(struct drm_gpuva *va)
1830+drm_gpuva_link(struct drm_gpuva *va, struct drm_gpuvm_bo *vm_bo)
8181831 {
8191832 struct drm_gem_object *obj = va->gem.obj;
1833+ struct drm_gpuvm *gpuvm = va->vm;
8201834
8211835 if (unlikely(!obj))
8221836 return;
8231837
824− drm_gem_gpuva_assert_lock_held(obj);
1838+ drm_WARN_ON(gpuvm->drm, obj != vm_bo->obj);
8251839
826− list_add_tail(&va->gem.entry, &obj->gpuva.list);
1840+ va->vm_bo = drm_gpuvm_bo_get(vm_bo);
1841+
1842+ drm_gem_gpuva_assert_lock_held(obj);
1843+ list_add_tail(&va->gem.entry, &vm_bo->list.gpuva);
8271844 }
8281845 EXPORT_SYMBOL_GPL(drm_gpuva_link);
8291846
@@ -834,20 +1851,31 @@ EXPORT_SYMBOL_GPL(drm_gpuva_link); · 4 unmodified lines
8341851 * This removes the given &va from the GPU VA list of the &drm_gem_object it is
8351852 * associated with.
8361853 *
1854+ * This removes the given &va from the GPU VA list of the &drm_gpuvm_bo and
1855+ * the &drm_gpuvm_bo from the &drm_gem_object it is associated with in case
1856+ * this call unlinks the last &drm_gpuva from the &drm_gpuvm_bo.
1857+ *
1858+ * For every &drm_gpuva entry removed from the &drm_gpuvm_bo a reference of
1859+ * the latter is dropped.
1860+ *
8371861 * This function expects the caller to protect the GEM's GPUVA list against
838− * concurrent access using the GEMs dma_resv lock.
1862+ * concurrent access using either the GEMs dma_resv lock or a driver specific
1863+ * lock set through drm_gem_gpuva_set_lock().
8391864 */
8401865 void
8411866 drm_gpuva_unlink(struct drm_gpuva *va)
8421867 {
8431868 struct drm_gem_object *obj = va->gem.obj;
1869+ struct drm_gpuvm_bo *vm_bo = va->vm_bo;
8441870
8451871 if (unlikely(!obj))
8461872 return;
8471873
8481874 drm_gem_gpuva_assert_lock_held(obj);
849−
8501875 list_del_init(&va->gem.entry);
1876+
1877+ va->vm_bo = NULL;
1878+ drm_gpuvm_bo_put(vm_bo);
8511879 }
8521880 EXPORT_SYMBOL_GPL(drm_gpuva_unlink);
8531881
@@ -992,10 +2020,10 @@ drm_gpuva_remap(struct drm_gpuva *prev, · 138 unmodified lines
9922020 struct drm_gpuva *next,
9932021 struct drm_gpuva_op_remap *op)
9942022 {
995− struct drm_gpuva *curr = op->unmap->va;
996− struct drm_gpuvm *gpuvm = curr->vm;
2023+ struct drm_gpuva *va = op->unmap->va;
2024+ struct drm_gpuvm *gpuvm = va->vm;
9972025
998− drm_gpuva_remove(curr);
2026+ drm_gpuva_remove(va);
9992027
10002028 if (op->prev) {
10012029 drm_gpuva_init_from_op(prev, op->prev);
@@ -1637,9 +2665,8 @@ err_free_ops: · 635 unmodified lines
16372665 EXPORT_SYMBOL_GPL(drm_gpuvm_prefetch_ops_create);
16382666
16392667 /**
1640− * drm_gpuvm_gem_unmap_ops_create() - creates the &drm_gpuva_ops to unmap a GEM
1641− * @gpuvm: the &drm_gpuvm representing the GPU VA space
1642− * @obj: the &drm_gem_object to unmap
2668+ * drm_gpuvm_bo_unmap_ops_create() - creates the &drm_gpuva_ops to unmap a GEM
2669+ * @vm_bo: the &drm_gpuvm_bo abstraction
16432670 *
16442671 * This function creates a list of operations to perform unmapping for every
16452672 * GPUVA attached to a GEM.
@@ -1656,15 +2683,14 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_prefetch_ops_create); · 10 unmodified lines
16562683 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
16572684 */
16582685 struct drm_gpuva_ops *
1659−drm_gpuvm_gem_unmap_ops_create(struct drm_gpuvm *gpuvm,
1660− struct drm_gem_object *obj)
2686+drm_gpuvm_bo_unmap_ops_create(struct drm_gpuvm_bo *vm_bo)
16612687 {
16622688 struct drm_gpuva_ops *ops;
16632689 struct drm_gpuva_op *op;
16642690 struct drm_gpuva *va;
16652691 int ret;
16662692
1667− drm_gem_gpuva_assert_lock_held(obj);
2693+ drm_gem_gpuva_assert_lock_held(vm_bo->obj);
16682694
16692695 ops = kzalloc(sizeof(*ops), GFP_KERNEL);
16702696 if (!ops)
@@ -1672,8 +2698,8 @@ drm_gpuvm_gem_unmap_ops_create(struct drm_gpuvm *gpuvm, · 1 unmodified line
16722698
16732699 INIT_LIST_HEAD(&ops->list);
16742700
1675− drm_gem_for_each_gpuva(va, obj) {
1676− op = gpuva_op_alloc(gpuvm);
2701+ drm_gpuvm_bo_for_each_va(va, vm_bo) {
2702+ op = gpuva_op_alloc(vm_bo->vm);
16772703 if (!op) {
16782704 ret = -ENOMEM;
16792705 goto err_free_ops;
@@ -1687,10 +2713,10 @@ drm_gpuvm_gem_unmap_ops_create(struct drm_gpuvm *gpuvm, · 7 unmodified lines
16872713 return ops;
16882714
16892715 err_free_ops:
1690− drm_gpuva_ops_free(gpuvm, ops);
2716+ drm_gpuva_ops_free(vm_bo->vm, ops);
16912717 return ERR_PTR(ret);
16922718 }
1693−EXPORT_SYMBOL_GPL(drm_gpuvm_gem_unmap_ops_create);
2719+EXPORT_SYMBOL_GPL(drm_gpuvm_bo_unmap_ops_create);
16942720
16952721 /**
16962722 * drm_gpuva_ops_free() - free the given &drm_gpuva_ops
drivers/gpu/drm/drm_hashtab.c+0−203
@@ -1,203 +0,0 @@
1−/**************************************************************************
2− *
3− * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
4− * All Rights Reserved.
5− *
6− * Permission is hereby granted, free of charge, to any person obtaining a
7− * copy of this software and associated documentation files (the
8− * "Software"), to deal in the Software without restriction, including
9− * without limitation the rights to use, copy, modify, merge, publish,
10− * distribute, sub license, and/or sell copies of the Software, and to
11− * permit persons to whom the Software is furnished to do so, subject to
12− * the following conditions:
13− *
14− * The above copyright notice and this permission notice (including the
15− * next paragraph) shall be included in all copies or substantial portions
16− * of the Software.
17− *
18− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19− * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20− * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21− * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22− * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23− * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24− * USE OR OTHER DEALINGS IN THE SOFTWARE.
25− *
26− *
27− **************************************************************************/
28−/*
29− * Simple open hash tab implementation.
30− *
31− * Authors:
32− * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
33− */
34−
35−#include <linux/hash.h>
36−#include <linux/mm.h>
37−#include <linux/rculist.h>
38−#include <linux/slab.h>
39−#include <linux/vmalloc.h>
40−
41−#include <drm/drm_print.h>
42−
43−#include "drm_legacy.h"
44−
45−int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
46−{
47− unsigned int size = 1 << order;
48−
49− ht->order = order;
50− ht->table = NULL;
51− if (size <= PAGE_SIZE / sizeof(*ht->table))
52− ht->table = kcalloc(size, sizeof(*ht->table), GFP_KERNEL);
53− else
54− ht->table = vzalloc(array_size(size, sizeof(*ht->table)));
55− if (!ht->table) {
56− DRM_ERROR("Out of memory for hash table\n");
57− return -ENOMEM;
58− }
59− return 0;
60−}
61−
62−void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key)
63−{
64− struct drm_hash_item *entry;
65− struct hlist_head *h_list;
66− unsigned int hashed_key;
67− int count = 0;
68−
69− hashed_key = hash_long(key, ht->order);
70− DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key);
71− h_list = &ht->table[hashed_key];
72− hlist_for_each_entry(entry, h_list, head)
73− DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key);
74−}
75−
76−static struct hlist_node *drm_ht_find_key(struct drm_open_hash *ht,
77− unsigned long key)
78−{
79− struct drm_hash_item *entry;
80− struct hlist_head *h_list;
81− unsigned int hashed_key;
82−
83− hashed_key = hash_long(key, ht->order);
84− h_list = &ht->table[hashed_key];
85− hlist_for_each_entry(entry, h_list, head) {
86− if (entry->key == key)
87− return &entry->head;
88− if (entry->key > key)
89− break;
90− }
91− return NULL;
92−}
93−
94−static struct hlist_node *drm_ht_find_key_rcu(struct drm_open_hash *ht,
95− unsigned long key)
96−{
97− struct drm_hash_item *entry;
98− struct hlist_head *h_list;
99− unsigned int hashed_key;
100−
101− hashed_key = hash_long(key, ht->order);
102− h_list = &ht->table[hashed_key];
103− hlist_for_each_entry_rcu(entry, h_list, head) {
104− if (entry->key == key)
105− return &entry->head;
106− if (entry->key > key)
107− break;
108− }
109− return NULL;
110−}
111−
112−int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item)
113−{
114− struct drm_hash_item *entry;
115− struct hlist_head *h_list;
116− struct hlist_node *parent;
117− unsigned int hashed_key;
118− unsigned long key = item->key;
119−

84 more lines aren’t shown here.

drivers/gpu/drm/drm_internal.h+16−7

This diff is large: its 66 lines aren’t shown here.

drivers/gpu/drm/drm_ioc32.c+2−611

This diff is large: its 656 lines aren’t shown here.

drivers/gpu/drm/drm_ioctl.c+21−75

This diff is large: its 165 lines aren’t shown here.

drivers/gpu/drm/drm_irq.c+0−204

This diff is large: its 205 lines aren’t shown here.

drivers/gpu/drm/drm_kms_helper_common.c+0−32

This diff is large: its 39 lines aren’t shown here.

drivers/gpu/drm/drm_legacy.h+0−290

This diff is large: its 291 lines aren’t shown here.

drivers/gpu/drm/drm_legacy_misc.c+0−105

This diff is large: its 106 lines aren’t shown here.

drivers/gpu/drm/drm_lock.c+0−373

This diff is large: its 374 lines aren’t shown here.

drivers/gpu/drm/drm_memory.c+0−138

This diff is large: its 139 lines aren’t shown here.

drivers/gpu/drm/drm_mipi_dbi.c+12−7

This diff is large: its 70 lines aren’t shown here.

drivers/gpu/drm/drm_mipi_dsi.c+15−2

This diff is large: its 45 lines aren’t shown here.

drivers/gpu/drm/drm_mode_object.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/drm_panel_orientation_quirks.c+6−0

This diff is large: its 13 lines aren’t shown here.

drivers/gpu/drm/drm_pci.c+1−203

This diff is large: its 220 lines aren’t shown here.

drivers/gpu/drm/drm_plane.c+148−2

This diff is large: its 185 lines aren’t shown here.

drivers/gpu/drm/drm_plane_helper.c+0−32

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/drm_scatter.c+0−220

This diff is large: its 221 lines aren’t shown here.

drivers/gpu/drm/drm_syncobj.c+51−13

This diff is large: its 152 lines aren’t shown here.

drivers/gpu/drm/drm_vblank.c+0−101

This diff is large: its 136 lines aren’t shown here.

drivers/gpu/drm/drm_vm.c+0−665

This diff is large: its 666 lines aren’t shown here.

drivers/gpu/drm/etnaviv/etnaviv_drv.c+2−4

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/etnaviv/etnaviv_gpu.c+3−4

This diff is large: its 30 lines aren’t shown here.

drivers/gpu/drm/etnaviv/etnaviv_sched.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/exynos/exynos_drm_gsc.c+5−4

This diff is large: its 39 lines aren’t shown here.

drivers/gpu/drm/gud/gud_pipe.c+18−12

This diff is large: its 104 lines aren’t shown here.

drivers/gpu/drm/i915/Kconfig+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/Makefile+97−83

This diff is large: its 299 lines aren’t shown here.

drivers/gpu/drm/i915/display/g4x_dp.c+39−7

This diff is large: its 97 lines aren’t shown here.

drivers/gpu/drm/i915/display/g4x_hdmi.c+37−29

This diff is large: its 147 lines aren’t shown here.

drivers/gpu/drm/i915/display/hsw_ips.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/i915/display/i9xx_wm.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/display/icl_dsi.c+5−5

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_atomic.c+0−3

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_atomic_plane.c+47−36

This diff is large: its 126 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_audio.c+9−8

This diff is large: its 51 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_backlight.c+5−4

This diff is large: its 25 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_bios.c+27−5

This diff is large: its 68 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_cdclk.c+3−2

This diff is large: its 12 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_color.c+35−35

This diff is large: its 112 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_crt.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_crtc_state_dump.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_cx0_phy.c+125−35

This diff is large: its 229 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_cx0_phy.h+8−8

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_ddi.c+134−43

This diff is large: its 361 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_ddi.h+5−0

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display.c+219−341

This diff is large: its 960 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display.h+3−6

This diff is large: its 37 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_core.h+11−9

This diff is large: its 48 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_debugfs.c+98−0

This diff is large: its 147 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_debugfs_params.c+176−0

This diff is large: its 177 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_debugfs_params.h+13−0

This diff is large: its 14 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_device.c+11−2

This diff is large: its 39 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_device.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_driver.c+7−0

This diff is large: its 14 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_params.c+217−0

This diff is large: its 218 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_params.h+61−0

This diff is large: its 62 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_power.c+7−7

This diff is large: its 51 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_power_well.c+9−14

This diff is large: its 71 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_reset.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_display_types.h+17−14

This diff is large: its 90 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dp.c+392−110

This diff is large: its 859 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dp.h+23−3

This diff is large: its 62 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dp_aux.c+62−37

This diff is large: its 276 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dp_aux_regs.h+8−6

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dp_mst.c+557−105

This diff is large: its 957 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dp_mst.h+5−0

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpio_phy.c+94−77

This diff is large: its 448 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpio_phy.h+5−0

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpll.c+220−50

This diff is large: its 475 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpll.h+7−2

This diff is large: its 23 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpll_mgr.c+95−92

This diff is large: its 313 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpll_mgr.h+6−0

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpt.c+0−24

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpt.h+0−2

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpt_common.c+34−0

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dpt_common.h+13−0

This diff is large: its 14 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dsb.c+36−62

This diff is large: its 255 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dsb_buffer.c+82−0

This diff is large: its 83 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dsb_buffer.h+29−0

This diff is large: its 30 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_dsi_vbt.c+135−218

This diff is large: its 511 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_fb.c+4−4

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_fbc.c+48−9

This diff is large: its 121 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_fdi.c+6−2

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_frontbuffer.c+0−2

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_hdcp.c+29−8

This diff is large: its 79 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_hdcp.h+4−4

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_hdmi.c+0−10

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_hotplug_irq.c+16−0

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_link_bw.c+22−8

This diff is large: its 97 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_link_bw.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_lvds.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_modeset_setup.c+6−0

This diff is large: its 13 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_modeset_verify.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_opregion.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_panel.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_pch_display.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_pps.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_psr.c+274−95

This diff is large: its 728 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_psr.h+7−0

This diff is large: its 14 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_psr_regs.h+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_qp_tables.c+0−3

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_sdvo.c+18−6

This diff is large: its 68 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_sprite.c+6−1

This diff is large: its 21 lines aren’t shown here.

drivers/gpu/drm/i915/display/intel_vdsc.c+22−7

This diff is large: its 79 lines aren’t shown here.

drivers/gpu/drm/i915/display/skl_universal_plane.c+14−14

This diff is large: its 66 lines aren’t shown here.

drivers/gpu/drm/i915/display/skl_watermark.c+3−2

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/i915/display/vlv_dsi.c+12−9

This diff is large: its 63 lines aren’t shown here.

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/gt/intel_engine_pm.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/gt/intel_gt.c+0−11

This diff is large: its 25 lines aren’t shown here.

drivers/gpu/drm/i915/gt/intel_gt.h+14−0

This diff is large: its 21 lines aren’t shown here.

drivers/gpu/drm/i915/gt/intel_gt_engines_debugfs.c+1−1

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/i915/gvt/cmd_parser.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/gvt/fb_decoder.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/gpu/drm/i915/gvt/handlers.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/i915/i915_debugfs.c+3−1

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/i915/i915_driver.c+3−9

This diff is large: its 44 lines aren’t shown here.

drivers/gpu/drm/i915/i915_drv.h+1−19

This diff is large: its 41 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem.c+0−2

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gpu_error.c+4−1

This diff is large: its 33 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gpu_error.h+2−0

This diff is large: its 16 lines aren’t shown here.

drivers/gpu/drm/i915/i915_params.c+0−89

This diff is large: its 129 lines aren’t shown here.

drivers/gpu/drm/i915/i915_params.h+0−22

This diff is large: its 46 lines aren’t shown here.

drivers/gpu/drm/i915/i915_reg.h+0−2

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/i915_utils.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/intel_runtime_pm.h+0−2

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/selftests/intel_uncore.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/soc/intel_gmch.c+14−13

This diff is large: its 87 lines aren’t shown here.

drivers/gpu/drm/i915/vlv_sideband.c+6−23

This diff is large: its 57 lines aren’t shown here.

drivers/gpu/drm/i915/vlv_sideband.h+3−6

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/imagination/Kconfig+18−0

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/imagination/Makefile+35−0

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_ccb.c+645−0

This diff is large: its 646 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_ccb.h+71−0

This diff is large: its 72 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_cccb.c+267−0

This diff is large: its 268 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_cccb.h+110−0

This diff is large: its 111 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_context.c+464−0

This diff is large: its 465 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_context.h+205−0

This diff is large: its 206 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_debugfs.c+53−0

This diff is large: its 54 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_debugfs.h+29−0

This diff is large: its 30 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_device.c+658−0

This diff is large: its 659 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_device.h+721−0

This diff is large: its 722 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_device_info.c+255−0

This diff is large: its 256 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_device_info.h+186−0

This diff is large: its 187 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_drv.c+1501−0

This diff is large: its 1502 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_drv.h+129−0

This diff is large: its 130 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_free_list.c+625−0

This diff is large: its 626 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_free_list.h+195−0

This diff is large: its 196 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw.c+1489−0

This diff is large: its 1490 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw.h+509−0

This diff is large: its 510 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_info.h+135−0

This diff is large: its 136 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_meta.c+555−0

This diff is large: its 556 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_meta.h+14−0

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_mips.c+252−0

This diff is large: its 253 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_mips.h+48−0

This diff is large: its 49 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_startstop.c+306−0

This diff is large: its 307 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_startstop.h+13−0

This diff is large: its 14 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_trace.c+471−0

This diff is large: its 472 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_fw_trace.h+78−0

This diff is large: its 79 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_gem.c+414−0

This diff is large: its 415 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_gem.h+170−0

This diff is large: its 171 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_hwrt.c+549−0

This diff is large: its 550 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_hwrt.h+166−0

This diff is large: its 167 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_job.c+786−0

This diff is large: its 787 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_job.h+161−0

This diff is large: its 162 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_mmu.c+2640−0

This diff is large: its 2641 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_mmu.h+108−0

This diff is large: its 109 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_params.c+147−0

This diff is large: its 148 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_params.h+72−0

This diff is large: its 73 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_power.c+433−0

This diff is large: its 434 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_power.h+41−0

This diff is large: its 42 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_queue.c+1432−0

This diff is large: its 1433 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_queue.h+169−0

This diff is large: its 170 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h+6193−0

This diff is large: its 6194 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_cr_defs_client.h+159−0

This diff is large: its 160 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_defs.h+179−0

This diff is large: its 180 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif.h+2188−0

This diff is large: its 2189 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_check.h+493−0

This diff is large: its 494 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_client.h+373−0

This diff is large: its 374 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_client_check.h+133−0

This diff is large: its 134 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_common.h+60−0

This diff is large: its 61 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_dev_info.h+113−0

This diff is large: its 114 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_resetframework.h+28−0

This diff is large: its 29 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h+1648−0

This diff is large: its 1649 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_shared.h+258−0

This diff is large: its 259 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_shared_check.h+108−0

This diff is large: its 109 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_fwif_stream.h+78−0

This diff is large: its 79 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_heap_config.h+113−0

This diff is large: its 114 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_meta.h+356−0

This diff is large: its 357 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_mips.h+335−0

This diff is large: its 336 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_mips_check.h+58−0

This diff is large: its 59 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_rogue_mmu_defs.h+136−0

This diff is large: its 137 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_stream.c+285−0

This diff is large: its 286 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_stream.h+75−0

This diff is large: its 76 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_stream_defs.c+351−0

This diff is large: its 352 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_stream_defs.h+16−0

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_sync.c+289−0

This diff is large: its 290 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_sync.h+84−0

This diff is large: its 85 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_vm.c+1092−0

This diff is large: its 1093 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_vm.h+66−0

This diff is large: its 67 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_vm_mips.c+237−0

This diff is large: its 238 lines aren’t shown here.

drivers/gpu/drm/imagination/pvr_vm_mips.h+22−0

This diff is large: its 23 lines aren’t shown here.

drivers/gpu/drm/imx/dcss/dcss-drv.c+2−4

This diff is large: its 27 lines aren’t shown here.

drivers/gpu/drm/imx/ipuv3/imx-ldb.c+4−5

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/imx/lcdc/imx-lcdc.c+2−13

This diff is large: its 47 lines aren’t shown here.

drivers/gpu/drm/kmb/kmb_drv.c+2−3

This diff is large: its 26 lines aren’t shown here.

drivers/gpu/drm/lima/lima_device.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/lima/lima_sched.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/loongson/Kconfig+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/loongson/lsdc_plane.c+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c+2−3

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/mediatek/mtk_ethdr.c+2−3

This diff is large: its 21 lines aren’t shown here.

drivers/gpu/drm/meson/meson_dw_mipi_dsi.c+2−4

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/adreno_device.c+4−2

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c+1−2

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/msm/dp/dp_display.c+10−5

This diff is large: its 29 lines aren’t shown here.

drivers/gpu/drm/msm/dp/dp_drm.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/msm/msm_drv.c+0−2

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/msm/msm_gem_submit.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/msm/msm_gpu.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/msm/msm_ringbuffer.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/mxsfb/mxsfb_drv.c+3−7

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/nouveau/dispnv50/disp.c+6−4

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/nouveau/include/nvkm/core/event.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_abi16.c+6−13

This diff is large: its 37 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_abi16.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_bo.c+12−3

This diff is large: its 48 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_bo.h+5−0

This diff is large: its 12 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_display.c+5−0

This diff is large: its 12 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_drm.c+25−11

This diff is large: its 84 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_drv.h+9−10

This diff is large: its 48 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_exec.c+21−47

This diff is large: its 132 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_exec.h+1−5

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_gem.c+8−2

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_platform.c+2−3

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_sched.c+116−91

This diff is large: its 315 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_sched.h+17−26

This diff is large: its 92 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_uvmm.c+198−182

This diff is large: its 680 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_uvmm.h+1−11

This diff is large: its 40 lines aren’t shown here.

drivers/gpu/drm/nouveau/nv04_fence.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nvkm/core/event.c+6−6

This diff is large: its 40 lines aren’t shown here.

drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c+3−3

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/omapdrm/dss/dispc.c+2−2

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/omapdrm/dss/dss.c+3−2

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/omapdrm/omap_drv.c+4−5

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/omapdrm/omap_gem.c+10−4

This diff is large: its 47 lines aren’t shown here.

drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c+5−4

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/panel/panel-edp.c+127−11

This diff is large: its 241 lines aren’t shown here.

drivers/gpu/drm/panel/panel-elida-kd35t133.c+3−34

This diff is large: its 107 lines aren’t shown here.

drivers/gpu/drm/panel/panel-himax-hx8394.c+152−28

This diff is large: its 280 lines aren’t shown here.

drivers/gpu/drm/panel/panel-ilitek-ili9881c.c+225−0

This diff is large: its 258 lines aren’t shown here.

drivers/gpu/drm/panel/panel-newvision-nv3051d.c+46−11

This diff is large: its 93 lines aren’t shown here.

drivers/gpu/drm/panel/panel-novatek-nt35510.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/panel/panel-simple.c+69−6

This diff is large: its 118 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_device.c+77−4

This diff is large: its 104 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_device.h+23−0

This diff is large: its 50 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_drv.c+4−1

This diff is large: its 33 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_dump.c+2−10

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_gpu.c+86−33

This diff is large: its 188 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_gpu.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_job.c+24−6

This diff is large: its 72 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_job.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_mmu.c+24−8

This diff is large: its 65 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_mmu.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/panfrost/panfrost_regs.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/qxl/qxl_display.c+6−8

This diff is large: its 49 lines aren’t shown here.

drivers/gpu/drm/qxl/qxl_drv.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/qxl/qxl_drv.h+0−7

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_audio.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_drv.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/rockchip/rk3066_hdmi.c+18−27

This diff is large: its 93 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_vop.c+11−3

This diff is large: its 34 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_vop2.c+5−0

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_vop2_reg.c+2−0

This diff is large: its 11 lines aren’t shown here.

drivers/gpu/drm/scheduler/gpu_scheduler_trace.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/scheduler/sched_entity.c+11−7

This diff is large: its 40 lines aren’t shown here.

drivers/gpu/drm/scheduler/sched_main.c+344−148

This diff is large: its 801 lines aren’t shown here.

drivers/gpu/drm/solomon/ssd130x.c+32−6

This diff is large: its 108 lines aren’t shown here.

drivers/gpu/drm/solomon/ssd130x.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/sprd/sprd_dpu.c+2−4

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/sprd/sprd_drm.c+2−3

This diff is large: its 21 lines aren’t shown here.

drivers/gpu/drm/sprd/sprd_dsi.c+2−4

This diff is large: its 21 lines aren’t shown here.

drivers/gpu/drm/tegra/hdmi.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/tegra/sor.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/tests/Makefile+3−2

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/tests/drm_buddy_test.c+0−465

This diff is large: its 508 lines aren’t shown here.

drivers/gpu/drm/tests/drm_dp_mst_helper_test.c+163−3

This diff is large: its 206 lines aren’t shown here.

drivers/gpu/drm/tests/drm_format_helper_test.c+44−28

This diff is large: its 265 lines aren’t shown here.

drivers/gpu/drm/tests/drm_gem_shmem_test.c+383−0

This diff is large: its 384 lines aren’t shown here.

drivers/gpu/drm/tests/drm_mm_test.c+56−1960

This diff is large: its 2107 lines aren’t shown here.

drivers/gpu/drm/tidss/tidss_crtc.c+4−8

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/tidss/tidss_dispc.c+131−7

This diff is large: its 210 lines aren’t shown here.

drivers/gpu/drm/tidss/tidss_dispc.h+3−0

This diff is large: its 23 lines aren’t shown here.

drivers/gpu/drm/tidss/tidss_drv.c+13−3

This diff is large: its 66 lines aren’t shown here.

drivers/gpu/drm/tidss/tidss_irq.c+8−46

This diff is large: its 81 lines aren’t shown here.

drivers/gpu/drm/tidss/tidss_kms.c+1−5

This diff is large: its 29 lines aren’t shown here.

drivers/gpu/drm/tilcdc/tilcdc_drv.c+5−6

This diff is large: its 41 lines aren’t shown here.

drivers/gpu/drm/tiny/arcpgu.c+2−4

This diff is large: its 25 lines aren’t shown here.

drivers/gpu/drm/tiny/cirrus.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/tiny/ili9225.c+6−4

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/tiny/ofdrm.c+15−2

This diff is large: its 46 lines aren’t shown here.

drivers/gpu/drm/tiny/repaper.c+7−3

This diff is large: its 37 lines aren’t shown here.

drivers/gpu/drm/tiny/simpledrm.c+41−3

This diff is large: its 77 lines aren’t shown here.

drivers/gpu/drm/tiny/st7586.c+11−8

This diff is large: its 75 lines aren’t shown here.

drivers/gpu/drm/ttm/ttm_bo.c+7−1

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/ttm/ttm_device.c+4−2

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/udl/udl_modeset.c+17−2

This diff is large: its 40 lines aren’t shown here.

drivers/gpu/drm/v3d/Makefile+3−1

This diff is large: its 11 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_bo.c+51−0

This diff is large: its 76 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_debugfs.c+101−77

This diff is large: its 245 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_drv.c+49−1

This diff is large: its 115 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_drv.h+155−10

This diff is large: its 250 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_gem.c+9−770

This diff is large: its 816 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_irq.c+74−19

This diff is large: its 172 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_regs.h+54−40

This diff is large: its 235 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_sched.c+375−22

This diff is large: its 555 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_submit.c+1320−0

This diff is large: its 1321 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_sysfs.c+69−0

This diff is large: its 70 lines aren’t shown here.

drivers/gpu/drm/v3d/v3d_trace.h+57−0

This diff is large: its 64 lines aren’t shown here.

drivers/gpu/drm/vboxvideo/vbox_drv.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/vboxvideo/vbox_mode.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/gpu/drm/virtio/virtgpu_drv.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/virtio/virtgpu_drv.h+5−0

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/virtio/virtgpu_ioctl.c+33−8

This diff is large: its 77 lines aren’t shown here.

drivers/gpu/drm/virtio/virtgpu_plane.c+14−4

This diff is large: its 45 lines aren’t shown here.

drivers/gpu/drm/vkms/vkms_writeback.c+15−10

This diff is large: its 66 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_drv.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c+13−7

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/xlnx/zynqmp_kms.c+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/hid/hid-apple.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/hid/hid-asus.c+23−4

This diff is large: its 69 lines aren’t shown here.

drivers/hid/hid-core.c+10−2

This diff is large: its 33 lines aren’t shown here.

drivers/hid/hid-debug.c+3−0

This diff is large: its 17 lines aren’t shown here.

drivers/hid/hid-glorious.c+14−2

This diff is large: its 46 lines aren’t shown here.

drivers/hid/hid-ids.h+7−5

This diff is large: its 40 lines aren’t shown here.

drivers/hid/hid-logitech-dj.c+3−8

This diff is large: its 27 lines aren’t shown here.

drivers/hid/hid-mcp2221.c+3−1

This diff is large: its 23 lines aren’t shown here.

drivers/hid/hid-multitouch.c+5−0

This diff is large: its 12 lines aren’t shown here.

drivers/hid/hid-picolcd_fb.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/hid/hid-quirks.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/i2c/busses/i2c-designware-common.c+8−8

This diff is large: its 58 lines aren’t shown here.

drivers/i2c/busses/i2c-ocores.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/i2c/busses/i2c-pxa.c+68−8

This diff is large: its 117 lines aren’t shown here.

drivers/irqchip/irq-gic-v3-its.c+10−6

This diff is large: its 41 lines aren’t shown here.

drivers/md/bcache/bcache.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/md/bcache/btree.c+10−1

This diff is large: its 39 lines aren’t shown here.

drivers/md/bcache/super.c+3−1

This diff is large: its 18 lines aren’t shown here.

drivers/md/bcache/sysfs.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/md/bcache/writeback.c+18−6

This diff is large: its 75 lines aren’t shown here.

drivers/md/dm-bufio.c+62−25

This diff is large: its 205 lines aren’t shown here.

drivers/md/dm-crypt.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/md/dm-delay.c+52−60

This diff is large: its 215 lines aren’t shown here.

drivers/md/dm-verity-fec.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/md/dm-verity-target.c+12−11

This diff is large: its 78 lines aren’t shown here.

drivers/md/dm-verity.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/md/md.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/media/pci/ivtv/Kconfig+1−3

This diff is large: its 11 lines aren’t shown here.

drivers/media/pci/ivtv/ivtvfb.c+3−3

This diff is large: its 21 lines aren’t shown here.

drivers/net/bonding/bond_main.c+6−0

This diff is large: its 20 lines aren’t shown here.

drivers/net/ethernet/amd/pds_core/adminq.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/ethernet/amd/pds_core/core.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/ethernet/amd/pds_core/dev.c+6−2

This diff is large: its 17 lines aren’t shown here.

drivers/net/ethernet/amd/pds_core/devlink.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/ethernet/amd/xgbe/xgbe-drv.c+14−0

This diff is large: its 25 lines aren’t shown here.

drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c+8−3

This diff is large: its 19 lines aren’t shown here.

drivers/net/ethernet/amd/xgbe/xgbe-mdio.c+13−1

This diff is large: its 21 lines aren’t shown here.

drivers/net/ethernet/broadcom/tg3.c+36−6

This diff is large: its 92 lines aren’t shown here.

drivers/net/ethernet/broadcom/tg3.h+2−2

This diff is large: its 25 lines aren’t shown here.

drivers/net/ethernet/cortina/gemini.c+29−16

This diff is large: its 91 lines aren’t shown here.

drivers/net/ethernet/cortina/gemini.h+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/net/ethernet/google/gve/gve_main.c+7−1

This diff is large: its 25 lines aren’t shown here.

drivers/net/ethernet/google/gve/gve_rx.c+0−4

This diff is large: its 11 lines aren’t shown here.

drivers/net/ethernet/google/gve/gve_tx.c+0−4

This diff is large: its 11 lines aren’t shown here.

drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c+6−3

This diff is large: its 18 lines aren’t shown here.

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c+25−8

This diff is large: its 123 lines aren’t shown here.

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c+22−3

This diff is large: its 74 lines aren’t shown here.

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c+7−0

This diff is large: its 21 lines aren’t shown here.

drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c+9−7

This diff is large: its 40 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_ddp.c+100−3

This diff is large: its 130 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_dpll.c+9−12

This diff is large: its 71 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_dpll.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_main.c+3−9

This diff is large: its 26 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_ptp.c+78−66

This diff is large: its 244 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_ptp.h+2−3

This diff is large: its 19 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_ptp_hw.c+54−0

This diff is large: its 58 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_ptp_hw.h+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_txrx.c+0−3

This diff is large: its 10 lines aren’t shown here.

drivers/net/ethernet/intel/ice/ice_txrx.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/net/ethernet/marvell/mvneta.c+20−8

This diff is large: its 59 lines aren’t shown here.

drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c+19−1

This diff is large: its 41 lines aren’t shown here.

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c+16−4

This diff is large: its 58 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c+2−2

This diff is large: its 22 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c+14−16

This diff is large: its 96 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c+9−4

This diff is large: its 22 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/en_rep.c+8−4

This diff is large: its 22 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c+32−28

This diff is large: its 124 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/en_tx.c+2−2

This diff is large: its 23 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/eq.c+19−6

This diff is large: its 48 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c+0−42

This diff is large: its 46 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c+6−1

This diff is large: its 14 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c+3−3

This diff is large: its 20 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c+13−102

This diff is large: its 198 lines aren’t shown here.

drivers/net/ethernet/realtek/r8169_main.c+32−14

This diff is large: its 132 lines aren’t shown here.

drivers/net/ethernet/stmicro/stmmac/Kconfig+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+2−1

This diff is large: its 20 lines aren’t shown here.

drivers/net/ethernet/ti/icssg/icssg_prueth.c+10−5

This diff is large: its 43 lines aren’t shown here.

drivers/net/ethernet/wangxun/libwx/wx_hw.c+5−3

This diff is large: its 16 lines aren’t shown here.

drivers/net/ethernet/wangxun/ngbe/ngbe_main.c+1−3

This diff is large: its 12 lines aren’t shown here.

drivers/net/ethernet/wangxun/txgbe/txgbe_main.c+1−3

This diff is large: its 12 lines aren’t shown here.

drivers/net/ethernet/xilinx/xilinx_axienet_main.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/hyperv/netvsc_drv.c+45−21

This diff is large: its 135 lines aren’t shown here.

drivers/net/ipa/reg/gsi_reg-v5.0.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/ipvlan/ipvlan_core.c+25−16

This diff is large: its 75 lines aren’t shown here.

drivers/net/macvlan.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/net/netkit.c+20−2

This diff is large: its 76 lines aren’t shown here.

drivers/net/ppp/ppp_synctty.c+5−1

This diff is large: its 20 lines aren’t shown here.

drivers/net/usb/aqc111.c+4−4

This diff is large: its 22 lines aren’t shown here.

drivers/net/usb/ax88179_178a.c+2−2

This diff is large: its 14 lines aren’t shown here.

drivers/net/usb/qmi_wwan.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/net/veth.c+13−33

This diff is large: its 103 lines aren’t shown here.

drivers/net/vrf.c+10−28

This diff is large: its 104 lines aren’t shown here.

drivers/net/wireguard/device.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/net/wireguard/receive.c+6−6

This diff is large: its 27 lines aren’t shown here.

drivers/net/wireguard/send.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/nfc/virtual_ncidev.c+6−1

This diff is large: its 32 lines aren’t shown here.

drivers/nvme/host/auth.c+3−2

This diff is large: its 23 lines aren’t shown here.

drivers/nvme/host/core.c+14−7

This diff is large: its 69 lines aren’t shown here.

drivers/nvme/host/fabrics.c+2−0

This diff is large: its 11 lines aren’t shown here.

drivers/nvme/host/fc.c+8−11

This diff is large: its 56 lines aren’t shown here.

drivers/nvme/host/rdma.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/nvme/host/tcp.c+15−17

This diff is large: its 115 lines aren’t shown here.

drivers/nvme/target/Kconfig+2−2

This diff is large: its 19 lines aren’t shown here.

drivers/nvme/target/configfs.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/nvme/target/fabrics-cmd.c+4−0

This diff is large: its 18 lines aren’t shown here.

drivers/nvme/target/tcp.c+3−1

This diff is large: its 20 lines aren’t shown here.

drivers/parisc/power.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/phy/Kconfig+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/phy/Makefile+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/phy/qualcomm/Kconfig+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/phy/qualcomm/phy-qcom-qmp-combo.c+2−42

This diff is large: its 72 lines aren’t shown here.

drivers/phy/realtek/Kconfig+0−32

This diff is large: its 33 lines aren’t shown here.

drivers/phy/realtek/Makefile+0−3

This diff is large: its 4 lines aren’t shown here.

drivers/phy/realtek/phy-rtk-usb2.c+0−1325

This diff is large: its 1326 lines aren’t shown here.

drivers/phy/realtek/phy-rtk-usb3.c+0−761

This diff is large: its 762 lines aren’t shown here.

drivers/platform/x86/amd/pmc/pmc.c+2−29

This diff is large: its 45 lines aren’t shown here.

drivers/platform/x86/hp/hp-bioscfg/bioscfg.c+11−15

This diff is large: its 72 lines aren’t shown here.

drivers/platform/x86/ideapad-laptop.c+5−6

This diff is large: its 24 lines aren’t shown here.

drivers/platform/x86/intel/telemetry/core.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/ptp/ptp_chardev.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/ptp/ptp_clock.c+3−2

This diff is large: its 14 lines aren’t shown here.

drivers/ptp/ptp_private.h+6−2

This diff is large: its 16 lines aren’t shown here.

drivers/ptp/ptp_sysfs.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/s390/block/dasd.c+13−11

This diff is large: its 32 lines aren’t shown here.

drivers/s390/block/dasd_int.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/s390/net/Kconfig+2−1

This diff is large: its 13 lines aren’t shown here.

drivers/s390/net/ism_drv.c+46−47

This diff is large: its 154 lines aren’t shown here.

drivers/scsi/qla2xxx/qla_os.c+10−2

This diff is large: its 19 lines aren’t shown here.

drivers/scsi/scsi_debug.c+1−8

This diff is large: its 33 lines aren’t shown here.

drivers/scsi/sd.c+23−30

This diff is large: its 105 lines aren’t shown here.

drivers/soc/qcom/Kconfig+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/soc/qcom/pmic_glink_altmode.c+9−24

This diff is large: its 69 lines aren’t shown here.

drivers/staging/sm750fb/sm750.c+52−13

This diff is large: its 98 lines aren’t shown here.

drivers/thunderbolt/switch.c+3−3

This diff is large: its 37 lines aren’t shown here.

drivers/thunderbolt/tb.c+11−1

This diff is large: its 19 lines aren’t shown here.

drivers/ufs/core/ufs-mcq.c+4−1

This diff is large: its 28 lines aren’t shown here.

drivers/usb/cdns3/cdnsp-ring.c+3−0

This diff is large: its 24 lines aren’t shown here.

drivers/usb/core/config.c+2−1

This diff is large: its 17 lines aren’t shown here.

drivers/usb/core/hub.c+0−23

This diff is large: its 30 lines aren’t shown here.

drivers/usb/dwc2/hcd_intr.c+7−8

This diff is large: its 44 lines aren’t shown here.

drivers/usb/dwc3/core.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/usb/dwc3/drd.c+1−1

This diff is large: its 16 lines aren’t shown here.

drivers/usb/dwc3/dwc3-qcom.c+47−22

This diff is large: its 163 lines aren’t shown here.

drivers/usb/dwc3/dwc3-rtk.c+7−1

This diff is large: its 25 lines aren’t shown here.

drivers/usb/host/xhci-mtk-sch.c+10−3

This diff is large: its 27 lines aren’t shown here.

drivers/usb/host/xhci-mtk.h+2−0

This diff is large: its 16 lines aren’t shown here.

drivers/usb/host/xhci-plat.c+30−20

This diff is large: its 78 lines aren’t shown here.

drivers/usb/misc/onboard_usb_hub.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/usb/misc/onboard_usb_hub.h+7−0

This diff is large: its 21 lines aren’t shown here.

drivers/usb/misc/usb-ljca.c+4−13

This diff is large: its 42 lines aren’t shown here.

drivers/usb/serial/option.c+8−3

This diff is large: its 46 lines aren’t shown here.

drivers/usb/typec/mux/Kconfig+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/usb/typec/mux/nb7vpq904m.c+2−42

This diff is large: its 72 lines aren’t shown here.

drivers/usb/typec/tcpm/Kconfig+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c+6−35

This diff is large: its 80 lines aren’t shown here.

drivers/usb/typec/tcpm/tcpm.c+11−1

This diff is large: its 26 lines aren’t shown here.

drivers/usb/typec/tipd/core.c+9−5

This diff is large: its 42 lines aren’t shown here.

drivers/vdpa/vdpa_sim/vdpa_sim_blk.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/vhost/vdpa.c+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/video/fbdev/Kconfig+12−38

This diff is large: its 129 lines aren’t shown here.

drivers/video/fbdev/acornfb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/amba-clcd.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/arcfb.c+27−87

This diff is large: its 151 lines aren’t shown here.

drivers/video/fbdev/au1100fb.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/au1200fb.c+6−5

This diff is large: its 36 lines aren’t shown here.

drivers/video/fbdev/clps711x-fb.c+1−3

This diff is large: its 15 lines aren’t shown here.

drivers/video/fbdev/core/Kconfig+3−4

This diff is large: its 37 lines aren’t shown here.

drivers/video/fbdev/core/Makefile+1−1

This diff is large: its 8 lines aren’t shown here.

drivers/video/fbdev/core/cfbcopyarea.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/video/fbdev/core/cfbfillrect.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/video/fbdev/core/cfbimgblt.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/video/fbdev/core/fb_chrdev.c+13−55

This diff is large: its 103 lines aren’t shown here.

drivers/video/fbdev/core/fb_defio.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/core/fb_io_fops.c+36−0

This diff is large: its 56 lines aren’t shown here.

drivers/video/fbdev/core/fb_sys_fops.c+6−0

This diff is large: its 20 lines aren’t shown here.

drivers/video/fbdev/core/syscopyarea.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/video/fbdev/core/sysfillrect.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/video/fbdev/core/sysimgblt.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/video/fbdev/cyber2000fb.c+1−8

This diff is large: its 23 lines aren’t shown here.

drivers/video/fbdev/ep93xx-fb.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/gbefb.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/omap/omapfb_main.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/omap2/omapfb/omapfb-main.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/ps3fb.c+5−6

This diff is large: its 36 lines aren’t shown here.

drivers/video/fbdev/sa1100fb.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/sbuslib.c+3−2

This diff is large: its 26 lines aren’t shown here.

drivers/video/fbdev/sh_mobile_lcdcfb.c+9−7

This diff is large: its 59 lines aren’t shown here.

drivers/video/fbdev/simplefb.c+127−5

This diff is large: its 196 lines aren’t shown here.

drivers/video/fbdev/sm712fb.c+2−4

This diff is large: its 19 lines aren’t shown here.

drivers/video/fbdev/smscufx.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/udlfb.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/vermilion/vermilion.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/vfb.c+5−5

This diff is large: its 35 lines aren’t shown here.

drivers/video/fbdev/vt8500lcdfb.c+3−1

This diff is large: its 25 lines aren’t shown here.

drivers/video/fbdev/wm8505fb.c+2−0

This diff is large: its 16 lines aren’t shown here.

drivers/virtio/virtio_pci_common.c+3−3

This diff is large: its 22 lines aren’t shown here.

drivers/virtio/virtio_pci_modern_dev.c+4−3

This diff is large: its 14 lines aren’t shown here.

drivers/xen/events/events_2l.c+4−4

This diff is large: its 26 lines aren’t shown here.

drivers/xen/events/events_base.c+279−297

This diff is large: its 1254 lines aren’t shown here.

drivers/xen/events/events_internal.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/xen/pcpu.c+22−0

This diff is large: its 34 lines aren’t shown here.

drivers/xen/privcmd.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/xen/swiotlb-xen.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/xen/xen-front-pgdir-shbuf.c+17−17

This diff is large: its 153 lines aren’t shown here.

fs/afs/dynroot.c+2−2

This diff is large: its 11 lines aren’t shown here.

fs/afs/internal.h+1−0

This diff is large: its 8 lines aren’t shown here.

fs/afs/server_list.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/afs/super.c+4−0

This diff is large: its 11 lines aren’t shown here.

fs/afs/vl_rotate.c+10−0

This diff is large: its 31 lines aren’t shown here.

fs/autofs/inode.c+21−35

This diff is large: its 88 lines aren’t shown here.

fs/bcachefs/backpointers.c+5−5

This diff is large: its 23 lines aren’t shown here.

fs/bcachefs/bcachefs.h+1−1

This diff is large: its 9 lines aren’t shown here.

fs/bcachefs/btree_iter.c+0−2

This diff is large: its 9 lines aren’t shown here.

fs/bcachefs/btree_key_cache.c+19−18

This diff is large: its 130 lines aren’t shown here.

fs/bcachefs/btree_key_cache_types.h+34−0

This diff is large: its 35 lines aren’t shown here.

fs/bcachefs/btree_trans_commit.c+93−76

This diff is large: its 251 lines aren’t shown here.

fs/bcachefs/btree_types.h+2−33

This diff is large: its 81 lines aren’t shown here.

fs/bcachefs/btree_update_interior.c+0−30

This diff is large: its 65 lines aren’t shown here.

fs/bcachefs/btree_update_interior.h+0−1

This diff is large: its 8 lines aren’t shown here.

fs/bcachefs/data_update.c+28−0

This diff is large: its 35 lines aren’t shown here.

fs/bcachefs/disk_groups.c+3−1

This diff is large: its 25 lines aren’t shown here.

fs/bcachefs/ec.c+14−2

This diff is large: its 37 lines aren’t shown here.

fs/bcachefs/fs-io-pagecache.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/bcachefs/fs-io-pagecache.h+1−1

This diff is large: its 9 lines aren’t shown here.

fs/bcachefs/fs.c+1−7

This diff is large: its 24 lines aren’t shown here.

fs/bcachefs/fsck.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/bcachefs/inode.c+5−3

This diff is large: its 22 lines aren’t shown here.

fs/bcachefs/io_write.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/bcachefs/journal.c+0−31

This diff is large: its 45 lines aren’t shown here.

fs/bcachefs/journal.h+0−98

This diff is large: its 105 lines aren’t shown here.

fs/bcachefs/journal_io.c+7−0

This diff is large: its 21 lines aren’t shown here.

fs/bcachefs/journal_reclaim.c+15−27

This diff is large: its 89 lines aren’t shown here.

fs/bcachefs/journal_types.h+0−26

This diff is large: its 47 lines aren’t shown here.

fs/bcachefs/six.c+5−2

This diff is large: its 14 lines aren’t shown here.

fs/bcachefs/subvolume_types.h+1−1

This diff is large: its 9 lines aren’t shown here.

fs/bcachefs/trace.h+2−9

This diff is large: its 45 lines aren’t shown here.

fs/bcachefs/xattr.c+9−0

This diff is large: its 23 lines aren’t shown here.

fs/btrfs/ctree.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/btrfs/delayed-ref.c+2−2

This diff is large: its 18 lines aren’t shown here.

fs/btrfs/extent-tree.c+17−8

This diff is large: its 102 lines aren’t shown here.

fs/btrfs/extent-tree.h+2−1

This diff is large: its 10 lines aren’t shown here.

fs/btrfs/inode.c+7−0

This diff is large: its 16 lines aren’t shown here.

fs/btrfs/ioctl.c+5−5

This diff is large: its 38 lines aren’t shown here.

fs/btrfs/qgroup.c+8−2

This diff is large: its 30 lines aren’t shown here.

fs/btrfs/raid-stripe-tree.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/btrfs/scrub.c+7−3

This diff is large: its 38 lines aren’t shown here.

fs/btrfs/volumes.c+3−3

This diff is large: its 17 lines aren’t shown here.

fs/btrfs/zoned.c+0−7

This diff is large: its 14 lines aren’t shown here.

fs/ecryptfs/inode.c+10−2

This diff is large: its 26 lines aren’t shown here.

fs/erofs/Kconfig+1−1

This diff is large: its 9 lines aren’t shown here.

fs/erofs/data.c+3−2

This diff is large: its 19 lines aren’t shown here.

fs/erofs/inode.c+35−63

This diff is large: its 167 lines aren’t shown here.

fs/inode.c+2−0

This diff is large: its 9 lines aren’t shown here.

fs/libfs.c+11−3

This diff is large: its 49 lines aren’t shown here.

fs/nfsd/cache.h+2−2

This diff is large: its 11 lines aren’t shown here.

fs/nfsd/nfs4state.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/nfsd/nfscache.c+51−36

This diff is large: its 133 lines aren’t shown here.

fs/nfsd/nfssvc.c+12−2

This diff is large: its 49 lines aren’t shown here.

fs/overlayfs/inode.c+5−5

This diff is large: its 31 lines aren’t shown here.

fs/overlayfs/overlayfs.h+8−0

This diff is large: its 15 lines aren’t shown here.

fs/overlayfs/params.c+5−6

This diff is large: its 48 lines aren’t shown here.

fs/overlayfs/util.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/smb/client/cifs_spnego.c+2−2

This diff is large: its 11 lines aren’t shown here.

fs/smb/client/cifsglob.h+11−3

This diff is large: its 35 lines aren’t shown here.

fs/smb/client/cifspdu.h+2−2

This diff is large: its 18 lines aren’t shown here.

fs/smb/client/cifsproto.h+13−1

This diff is large: its 35 lines aren’t shown here.

fs/smb/client/cifssmb.c+77−116

This diff is large: its 214 lines aren’t shown here.

fs/smb/client/connect.c+6−0

This diff is large: its 13 lines aren’t shown here.

fs/smb/client/inode.c+60−14

This diff is large: its 127 lines aren’t shown here.

fs/smb/client/readdir.c+5−1

This diff is large: its 20 lines aren’t shown here.

fs/smb/client/sess.c+14−10

This diff is large: its 43 lines aren’t shown here.

fs/smb/client/smb1ops.c+32−121

This diff is large: its 202 lines aren’t shown here.

fs/smb/client/smb2inode.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/smb/client/smb2ops.c+112−115

This diff is large: its 357 lines aren’t shown here.

fs/smb/client/smb2transport.c+2−3

This diff is large: its 19 lines aren’t shown here.

fs/stat.c+5−1

This diff is large: its 20 lines aren’t shown here.

fs/tracefs/event_inode.c+26−39

This diff is large: its 180 lines aren’t shown here.

fs/tracefs/inode.c+4−9

This diff is large: its 25 lines aren’t shown here.

fs/xfs/Kconfig+1−1

This diff is large: its 9 lines aren’t shown here.

fs/xfs/libxfs/xfs_alloc.c+24−3

This diff is large: its 41 lines aren’t shown here.

fs/xfs/libxfs/xfs_defer.c+18−10

This diff is large: its 68 lines aren’t shown here.

fs/xfs/libxfs/xfs_defer.h+1−1

This diff is large: its 9 lines aren’t shown here.

fs/xfs/libxfs/xfs_inode_buf.c+3−0

This diff is large: its 10 lines aren’t shown here.

fs/xfs/xfs_dquot.c+3−2

This diff is large: its 19 lines aren’t shown here.

fs/xfs/xfs_dquot_item_recover.c+18−3

This diff is large: its 58 lines aren’t shown here.

fs/xfs/xfs_inode.h+8−0

This diff is large: its 15 lines aren’t shown here.

fs/xfs/xfs_inode_item_recover.c+30−16

This diff is large: its 71 lines aren’t shown here.

fs/xfs/xfs_ioctl.c+20−10

This diff is large: its 51 lines aren’t shown here.

fs/xfs/xfs_iops.c+7−0

This diff is large: its 14 lines aren’t shown here.

fs/xfs/xfs_log.c+12−11

This diff is large: its 50 lines aren’t shown here.

fs/xfs/xfs_log_recover.c+1−1

This diff is large: its 9 lines aren’t shown here.

fs/xfs/xfs_reflink.c+1−0

This diff is large: its 8 lines aren’t shown here.

include/acpi/acpi_bus.h+1−0

This diff is large: its 8 lines aren’t shown here.

include/asm-generic/qspinlock.h+1−1

This diff is large: its 9 lines aren’t shown here.

include/drm/bridge/aux-bridge.h+37−0

This diff is large: its 38 lines aren’t shown here.

include/drm/display/drm_dp.h+28−0

This diff is large: its 70 lines aren’t shown here.

include/drm/display/drm_dp_helper.h+32−0

This diff is large: its 58 lines aren’t shown here.

include/drm/display/drm_dp_mst_helper.h+12−4

This diff is large: its 52 lines aren’t shown here.

include/drm/drm_atomic_helper.h+2−3

This diff is large: its 12 lines aren’t shown here.

include/drm/drm_auth.h+0−22

This diff is large: its 36 lines aren’t shown here.

include/drm/drm_bridge.h+1−3

This diff is large: its 16 lines aren’t shown here.

include/drm/drm_color_mgmt.h+8−11

This diff is large: its 29 lines aren’t shown here.

include/drm/drm_device.h+2−69

This diff is large: its 92 lines aren’t shown here.

include/drm/drm_drv.h+9−19

This diff is large: its 42 lines aren’t shown here.

include/drm/drm_edid.h+0−153

This diff is large: its 174 lines aren’t shown here.

include/drm/drm_eld.h+164−0

This diff is large: its 165 lines aren’t shown here.

include/drm/drm_encoder.h+15−1

This diff is large: its 37 lines aren’t shown here.

include/drm/drm_file.h+12−5

This diff is large: its 31 lines aren’t shown here.

include/drm/drm_flip_work.h+3−17

This diff is large: its 42 lines aren’t shown here.

include/drm/drm_format_helper.h+68−13

This diff is large: its 121 lines aren’t shown here.

include/drm/drm_framebuffer.h+0−12

This diff is large: its 19 lines aren’t shown here.

include/drm/drm_gem.h+16−16

This diff is large: its 53 lines aren’t shown here.

include/drm/drm_gem_atomic_helper.h+10−0

This diff is large: its 24 lines aren’t shown here.

include/drm/drm_gpuvm.h+527−5

This diff is large: its 637 lines aren’t shown here.

include/drm/drm_ioctl.h+0−11

This diff is large: its 18 lines aren’t shown here.

include/drm/drm_legacy.h+0−331

This diff is large: its 332 lines aren’t shown here.

include/drm/drm_mipi_dbi.h+3−1

This diff is large: its 18 lines aren’t shown here.

include/drm/drm_mipi_dsi.h+2−0

This diff is large: its 16 lines aren’t shown here.

include/drm/drm_modeset_helper_vtables.h+10−0

This diff is large: its 24 lines aren’t shown here.

include/drm/drm_plane.h+24−0

This diff is large: its 45 lines aren’t shown here.

include/drm/drm_plane_helper.h+0−2

This diff is large: its 16 lines aren’t shown here.

include/drm/drm_print.h+1−1

This diff is large: its 9 lines aren’t shown here.

include/drm/gpu_scheduler.h+41−15

This diff is large: its 150 lines aren’t shown here.

include/linux/blk-pm.h+0−1

This diff is large: its 8 lines aren’t shown here.

include/linux/bpf.h+7−3

This diff is large: its 26 lines aren’t shown here.

include/linux/bpf_verifier.h+16−0

This diff is large: its 37 lines aren’t shown here.

include/linux/cpuhotplug.h+1−0

This diff is large: its 8 lines aren’t shown here.

include/linux/dma-buf.h+7−4

This diff is large: its 24 lines aren’t shown here.

include/linux/export-internal.h+1−3

This diff is large: its 11 lines aren’t shown here.

include/linux/fb.h+14−2

This diff is large: its 42 lines aren’t shown here.

include/linux/hid.h+3−0

This diff is large: its 17 lines aren’t shown here.

include/linux/hrtimer.h+2−2

This diff is large: its 12 lines aren’t shown here.

include/linux/iosys-map.h+22−22

This diff is large: its 81 lines aren’t shown here.

include/linux/mdio.h+1−1

This diff is large: its 9 lines aren’t shown here.

include/linux/netdevice.h+26−4

This diff is large: its 58 lines aren’t shown here.

include/linux/pagemap.h+17−0

This diff is large: its 31 lines aren’t shown here.

include/linux/perf_event.h+8−5

This diff is large: its 27 lines aren’t shown here.

include/linux/sizes.h+9−0

This diff is large: its 18 lines aren’t shown here.

include/linux/stackleak.h+6−0

This diff is large: its 20 lines aren’t shown here.

include/linux/usb/phy.h+0−13

This diff is large: its 27 lines aren’t shown here.

include/linux/virtio_pci_modern.h+0−7

This diff is large: its 14 lines aren’t shown here.

include/net/netfilter/nf_tables.h+2−2

This diff is large: its 12 lines aren’t shown here.

include/net/netkit.h+6−0

This diff is large: its 19 lines aren’t shown here.

include/net/tc_act/tc_ct.h+9−0

This diff is large: its 23 lines aren’t shown here.

include/trace/events/rxrpc.h+1−1

This diff is large: its 9 lines aren’t shown here.

include/uapi/drm/drm.h+71−1

This diff is large: its 121 lines aren’t shown here.

include/uapi/drm/drm_mode.h+19−0

This diff is large: its 33 lines aren’t shown here.

include/uapi/drm/ivpu_accel.h+1−1

This diff is large: its 9 lines aren’t shown here.

include/uapi/drm/pvr_drm.h+1295−0

This diff is large: its 1296 lines aren’t shown here.

include/uapi/drm/qaic_accel.h+3−2

This diff is large: its 12 lines aren’t shown here.

include/uapi/drm/v3d_drm.h+244−1

This diff is large: its 294 lines aren’t shown here.

include/uapi/drm/virtgpu_drm.h+2−0

This diff is large: its 16 lines aren’t shown here.

include/uapi/linux/btrfs_tree.h+16−8

This diff is large: its 38 lines aren’t shown here.

include/uapi/linux/fcntl.h+3−0

This diff is large: its 9 lines aren’t shown here.

include/uapi/linux/sync_file.h+22−0

This diff is large: its 35 lines aren’t shown here.

include/uapi/linux/virtio_pci.h+11−0

This diff is large: its 18 lines aren’t shown here.

include/xen/events.h+2−6

This diff is large: its 29 lines aren’t shown here.

io_uring/fdinfo.c+2−7

This diff is large: its 16 lines aren’t shown here.

io_uring/fs.c+1−1

This diff is large: its 9 lines aren’t shown here.

io_uring/rsrc.c+1−1

This diff is large: its 9 lines aren’t shown here.

io_uring/sqpoll.c+10−2

This diff is large: its 42 lines aren’t shown here.

kernel/audit_watch.c+1−1

This diff is large: its 9 lines aren’t shown here.

kernel/bpf/core.c+3−5

This diff is large: its 22 lines aren’t shown here.

kernel/bpf/verifier.c+329−160

This diff is large: its 859 lines aren’t shown here.

kernel/cgroup/cgroup.c+0−12

This diff is large: its 47 lines aren’t shown here.

kernel/cpu.c+7−1

This diff is large: its 22 lines aren’t shown here.

kernel/events/core.c+17−0

This diff is large: its 45 lines aren’t shown here.

kernel/futex/core.c+6−3

This diff is large: its 23 lines aren’t shown here.

kernel/locking/lockdep.c+2−1

This diff is large: its 10 lines aren’t shown here.

kernel/sched/fair.c+135−26

This diff is large: its 214 lines aren’t shown here.

kernel/sys.c+4−0

This diff is large: its 11 lines aren’t shown here.

kernel/time/hrtimer.c+12−21

This diff is large: its 58 lines aren’t shown here.

lib/errname.c+0−6

This diff is large: its 20 lines aren’t shown here.

lib/iov_iter.c+1−1

This diff is large: its 9 lines aren’t shown here.

lib/zstd/common/fse_decompress.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/damon/core.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/damon/sysfs-schemes.c+5−0

This diff is large: its 19 lines aren’t shown here.

mm/damon/sysfs.c+4−2

This diff is large: its 21 lines aren’t shown here.

mm/filemap.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/huge_memory.c+9−7

This diff is large: its 23 lines aren’t shown here.

mm/ksm.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/memcontrol.c+2−1

This diff is large: its 10 lines aren’t shown here.

mm/page-writeback.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/userfaultfd.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/util.c+10−0

This diff is large: its 24 lines aren’t shown here.

net/bridge/netfilter/nf_conntrack_bridge.c+1−1

This diff is large: its 9 lines aren’t shown here.

net/core/dev.c+59−2

This diff is large: its 98 lines aren’t shown here.

net/core/filter.c+14−5

This diff is large: its 46 lines aren’t shown here.

net/core/gso_test.c+5−9

This diff is large: its 36 lines aren’t shown here.

net/ipv4/inet_diag.c+1−0

This diff is large: its 7 lines aren’t shown here.

net/ipv4/inet_hashtables.c+1−1

This diff is large: its 14 lines aren’t shown here.

net/ipv4/raw_diag.c+1−0

This diff is large: its 7 lines aren’t shown here.

net/ipv4/route.c+1−1

This diff is large: its 9 lines aren’t shown here.

net/ipv4/tcp_diag.c+1−0

This diff is large: its 6 lines aren’t shown here.

net/ipv4/udp_diag.c+1−0

This diff is large: its 7 lines aren’t shown here.

net/mptcp/mptcp_diag.c+1−0

This diff is large: its 6 lines aren’t shown here.

net/mptcp/pm_netlink.c+3−2

This diff is large: its 12 lines aren’t shown here.

net/mptcp/protocol.c+8−3

This diff is large: its 33 lines aren’t shown here.

net/mptcp/sockopt.c+3−0

This diff is large: its 12 lines aren’t shown here.

net/ncsi/ncsi-aen.c+0−5

This diff is large: its 12 lines aren’t shown here.

net/netfilter/ipset/ip_set_core.c+7−7

This diff is large: its 37 lines aren’t shown here.

net/netfilter/nf_tables_api.c+33−27

This diff is large: its 97 lines aren’t shown here.

net/netfilter/nft_byteorder.c+3−2

This diff is large: its 25 lines aren’t shown here.

net/netfilter/nft_meta.c+1−1

This diff is large: its 9 lines aren’t shown here.

net/netfilter/nft_set_rbtree.c+0−2

This diff is large: its 15 lines aren’t shown here.

net/packet/diag.c+1−0

This diff is large: its 6 lines aren’t shown here.

net/rxrpc/conn_client.c+4−3

This diff is large: its 42 lines aren’t shown here.

net/rxrpc/input.c+29−32

This diff is large: its 118 lines aren’t shown here.

net/sched/act_ct.c+3−0

This diff is large: its 10 lines aren’t shown here.

net/sctp/diag.c+1−0

This diff is large: its 6 lines aren’t shown here.

net/smc/af_smc.c+6−2

This diff is large: its 15 lines aren’t shown here.

net/smc/smc_diag.c+1−0

This diff is large: its 7 lines aren’t shown here.

net/tipc/diag.c+1−0

This diff is large: its 6 lines aren’t shown here.

net/tipc/netlink_compat.c+1−0

This diff is large: its 8 lines aren’t shown here.

net/tls/tls_sw.c+3−0

This diff is large: its 15 lines aren’t shown here.

net/unix/af_unix.c+5−4

This diff is large: its 21 lines aren’t shown here.

net/unix/diag.c+1−0

This diff is large: its 6 lines aren’t shown here.

net/vmw_vsock/diag.c+1−0

This diff is large: its 7 lines aren’t shown here.

net/xdp/xsk_diag.c+1−0

This diff is large: its 6 lines aren’t shown here.

scripts/Makefile.lib+2−2

This diff is large: its 17 lines aren’t shown here.

scripts/checkstack.pl+1−2

This diff is large: its 10 lines aren’t shown here.

scripts/gcc-plugins/latent_entropy_plugin.c+2−2

This diff is large: its 18 lines aren’t shown here.

scripts/gcc-plugins/randomize_layout_plugin.c+0−10

This diff is large: its 30 lines aren’t shown here.

scripts/kconfig/symbol.c+6−8

This diff is large: its 34 lines aren’t shown here.

scripts/mod/modpost.c+4−2

This diff is large: its 26 lines aren’t shown here.

sound/core/pcm_drm_eld.c+1−0

This diff is large: its 8 lines aren’t shown here.

sound/pci/hda/cs35l56_hda_i2c.c+4−0

This diff is large: its 11 lines aren’t shown here.

sound/pci/hda/hda_intel.c+3−0

This diff is large: its 10 lines aren’t shown here.

sound/pci/hda/patch_realtek.c+13−16

This diff is large: its 84 lines aren’t shown here.

sound/soc/codecs/hdac_hdmi.c+1−0

This diff is large: its 8 lines aren’t shown here.

sound/soc/codecs/hdmi-codec.c+1−0

This diff is large: its 8 lines aren’t shown here.

sound/x86/intel_hdmi_audio.c+1−0

This diff is large: its 8 lines aren’t shown here.

tools/arch/parisc/include/uapi/asm/errno.h+0−2

This diff is large: its 16 lines aren’t shown here.

tools/hv/hv_kvp_daemon.c+12−8

This diff is large: its 35 lines aren’t shown here.

tools/hv/hv_set_ifconfig.sh+2−2

This diff is large: its 18 lines aren’t shown here.

tools/net/ynl/Makefile.deps+1−1

This diff is large: its 6 lines aren’t shown here.

tools/net/ynl/generated/devlink-user.c+1−1

This diff is large: its 9 lines aren’t shown here.

tools/net/ynl/ynl-gen-c.py+6−0

This diff is large: its 13 lines aren’t shown here.

tools/power/pm-graph/sleepgraph.py+1−1

This diff is large: its 9 lines aren’t shown here.

tools/power/x86/turbostat/turbostat.c+1537−1537

This diff is large: its 4073 lines aren’t shown here.

tools/testing/selftests/arm64/fp/za-fork.c+1−1

This diff is large: its 9 lines aren’t shown here.

tools/testing/selftests/bpf/prog_tests/tc_redirect.c+190−127

This diff is large: its 498 lines aren’t shown here.

tools/testing/selftests/bpf/prog_tests/verifier.c+2−0

This diff is large: its 16 lines aren’t shown here.

tools/testing/selftests/bpf/progs/bpf_loop_bench.c+8−5

This diff is large: its 22 lines aren’t shown here.

tools/testing/selftests/bpf/progs/cb_refs.c+1−0

This diff is large: its 8 lines aren’t shown here.

tools/testing/selftests/bpf/progs/exceptions_fail.c+2−0

This diff is large: its 16 lines aren’t shown here.

tools/testing/selftests/bpf/progs/strobemeta.h+48−30

This diff is large: its 220 lines aren’t shown here.

tools/testing/selftests/bpf/progs/verifier_cfg.c+62−0

This diff is large: its 67 lines aren’t shown here.

tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c+242−0

This diff is large: its 243 lines aren’t shown here.

tools/testing/selftests/bpf/progs/verifier_loops1.c+6−3

This diff is large: its 24 lines aren’t shown here.

tools/testing/selftests/bpf/progs/verifier_precision.c+40−0

This diff is large: its 44 lines aren’t shown here.

tools/testing/selftests/bpf/progs/verifier_subprog_precision.c+72−14

This diff is large: its 132 lines aren’t shown here.

tools/testing/selftests/bpf/progs/xdp_synproxy_kern.c+52−32

This diff is large: its 148 lines aren’t shown here.

tools/testing/selftests/bpf/verifier/calls.c+3−3

This diff is large: its 27 lines aren’t shown here.

tools/testing/selftests/bpf/verifier/ld_imm64.c+4−4

This diff is large: its 22 lines aren’t shown here.

tools/testing/selftests/bpf/xskxceiver.c+12−7

This diff is large: its 50 lines aren’t shown here.

tools/testing/selftests/mm/.gitignore+1−0

This diff is large: its 5 lines aren’t shown here.

tools/testing/selftests/mm/pagemap_ioctl.c+12−11

This diff is large: its 89 lines aren’t shown here.

tools/testing/selftests/mm/run_vmtests.sh+3−0

This diff is large: its 13 lines aren’t shown here.

tools/testing/selftests/net/mptcp/mptcp_join.sh+1−1

This diff is large: its 9 lines aren’t shown here.

tools/testing/selftests/net/rtnetlink.sh+1−1

This diff is large: its 9 lines aren’t shown here.

tools/testing/vsock/vsock_test.c+13−6

This diff is large: its 65 lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t