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

Merge tag 'topic/drm-misc-2016-06-15' of git://anongit.freedesktop.org/drm-intel into drm-next

- best_encoder cleanup from Boris.
- drm_simple_display_pipe helpers from Noralf. Looks really neat imo, and
there's 2-3 in-flight drivers which look like they could/should use it.
Anyway, with this we have now helpers and everything in place to write
drivers for simple hw with fewer complexity in the driver than what
fbdev would need. That was the last complaint I've heard from embedded
folks after we made atomic happen. Mission accomplished!
- nonblocking commit helpers for atomic, plus a bunch of driver patches
for that.
- Prep patch from Laurent for cleaned up pixel format functions.
- More of Gustavo's cleanup for drm vblank functions.
- and a few oddball things in between

Plus the merge of docs-next to prep the docbook->sphinx conversion as
discussed. Jon cc'ed as fyi.

* tag 'topic/drm-misc-2016-06-15' of git://anongit.freedesktop.org/drm-intel: (108 commits)
drm/atomic-helpers: Clear up cleanup_done a bit
drm/atomic-helpers: Stall on the right commit
drm/vmwgfx: use *_32_bits() macros
drm/virtio: Don't reinvent a flipping wheel
drm/i915: Fix missing unlock on error in i915_ppgtt_info()
drm/gma500: use drm_crtc_vblank_{on,off}()
drm/radeon: use crtc directly in drm_crtc_vblank_put()
drm/amdgpu: use crtc directly in drm_crtc_vblank_put()
drm/radeon: use drm_crtc_vblank_{on,off}()
drm/amdgpu: use drm_crtc_vblank_{on,off}()
drm: make drm_vblank_{get,put}() static
drm: remove legacy drm_arm_vblank_event()
drm: remove legacy drm_send_vblank_event()
drm/nouveau: replace legacy vblank helpers
drm/prime: fix error path deadlock fail
drm/dsi: Add uevent callback
drm: fb: cma: fix memory leak
drm: i915: Rely on the default ->best_encoder() behavior where appropriate
drm: Add helper for simple display pipeline
drm/bridge: dw-hdmi: Use drm_atomic_helper_best_encoder()
...

+2928 -1633
+1
Documentation/.gitignore
··· 1 + output
+3 -4
Documentation/DocBook/Makefile
··· 33 33 PS_METHOD = $(prefer-db2x) 34 34 35 35 36 - ### 37 - # The targets that may be used. 38 - PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs 39 - 40 36 targets += $(DOCBOOKS) 41 37 BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) 42 38 xmldocs: $(BOOKS) ··· 58 62 find $(obj)/man -name '*.9.gz' -printf '%h %f\n' | \ 59 63 sort -k 2 -k 1 | uniq -f 1 | sed -e 's: :/:' | \ 60 64 xargs install -m 644 -t /usr/local/man/man9/ 65 + 66 + # no-op for the DocBook toolchain 67 + epubdocs: 61 68 62 69 ### 63 70 #External programs used
+11
Documentation/DocBook/gpu.tmpl
··· 1018 1018 </para> 1019 1019 </sect2> 1020 1020 <sect2> 1021 + <title>DRM Format Handling</title> 1022 + !Iinclude/drm/drm_fourcc.h 1023 + !Edrivers/gpu/drm/drm_fourcc.c 1024 + </sect2> 1025 + <sect2> 1021 1026 <title>Dumb Buffer Objects</title> 1022 1027 <para> 1023 1028 The KMS API doesn't standardize backing storage object creation and ··· 1687 1682 !Iinclude/drm/drm_panel.h 1688 1683 !Edrivers/gpu/drm/drm_panel.c 1689 1684 !Pdrivers/gpu/drm/drm_panel.c drm panel 1685 + </sect2> 1686 + <sect2> 1687 + <title>Simple KMS Helper Reference</title> 1688 + !Iinclude/drm/drm_simple_kms_helper.h 1689 + !Edrivers/gpu/drm/drm_simple_kms_helper.c 1690 + !Pdrivers/gpu/drm/drm_simple_kms_helper.c overview 1690 1691 </sect2> 1691 1692 </sect1> 1692 1693
+63
Documentation/Makefile.sphinx
··· 1 + # -*- makefile -*- 2 + # Makefile for Sphinx documentation 3 + # 4 + 5 + # You can set these variables from the command line. 6 + SPHINXBUILD = sphinx-build 7 + SPHINXOPTS = 8 + PAPER = 9 + BUILDDIR = $(obj)/output 10 + 11 + # User-friendly check for sphinx-build 12 + HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi) 13 + 14 + ifeq ($(HAVE_SPHINX),0) 15 + 16 + .DEFAULT: 17 + $(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.) 18 + @echo " SKIP Sphinx $@ target." 19 + 20 + else # HAVE_SPHINX 21 + 22 + # User-friendly check for rst2pdf 23 + HAVE_RST2PDF := $(shell if python -c "import rst2pdf" >/dev/null 2>&1; then echo 1; else echo 0; fi) 24 + 25 + # Internal variables. 26 + PAPEROPT_a4 = -D latex_paper_size=a4 27 + PAPEROPT_letter = -D latex_paper_size=letter 28 + KERNELDOC = $(srctree)/scripts/kernel-doc 29 + KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC) 30 + ALLSPHINXOPTS = -D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) 31 + # the i18n builder cannot share the environment and doctrees with the others 32 + I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 33 + 34 + quiet_cmd_sphinx = SPHINX $@ 35 + cmd_sphinx = $(SPHINXBUILD) -b $2 $(ALLSPHINXOPTS) $(BUILDDIR)/$2 36 + 37 + htmldocs: 38 + $(call cmd,sphinx,html) 39 + 40 + pdfdocs: 41 + ifeq ($(HAVE_RST2PDF),0) 42 + $(warning The Python 'rst2pdf' module was not found. Make sure you have the module installed to produce PDF output.) 43 + @echo " SKIP Sphinx $@ target." 44 + else # HAVE_RST2PDF 45 + $(call cmd,sphinx,pdf) 46 + endif # HAVE_RST2PDF 47 + 48 + epubdocs: 49 + $(call cmd,sphinx,epub) 50 + 51 + xmldocs: 52 + $(call cmd,sphinx,xml) 53 + 54 + # no-ops for the Sphinx toolchain 55 + sgmldocs: 56 + psdocs: 57 + mandocs: 58 + installmandocs: 59 + 60 + cleandocs: 61 + $(Q)rm -rf $(BUILDDIR) 62 + 63 + endif # HAVE_SPHINX
+414
Documentation/conf.py
··· 1 + # -*- coding: utf-8 -*- 2 + # 3 + # The Linux Kernel documentation build configuration file, created by 4 + # sphinx-quickstart on Fri Feb 12 13:51:46 2016. 5 + # 6 + # This file is execfile()d with the current directory set to its 7 + # containing dir. 8 + # 9 + # Note that not all possible configuration values are present in this 10 + # autogenerated file. 11 + # 12 + # All configuration values have a default; values that are commented out 13 + # serve to show the default. 14 + 15 + import sys 16 + import os 17 + 18 + # If extensions (or modules to document with autodoc) are in another directory, 19 + # add these directories to sys.path here. If the directory is relative to the 20 + # documentation root, use os.path.abspath to make it absolute, like shown here. 21 + sys.path.insert(0, os.path.abspath('sphinx')) 22 + 23 + # -- General configuration ------------------------------------------------ 24 + 25 + # If your documentation needs a minimal Sphinx version, state it here. 26 + #needs_sphinx = '1.0' 27 + 28 + # Add any Sphinx extension module names here, as strings. They can be 29 + # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 + # ones. 31 + extensions = ['kernel-doc'] 32 + 33 + # Gracefully handle missing rst2pdf. 34 + try: 35 + import rst2pdf 36 + extensions += ['rst2pdf.pdfbuilder'] 37 + except ImportError: 38 + pass 39 + 40 + # Add any paths that contain templates here, relative to this directory. 41 + templates_path = ['_templates'] 42 + 43 + # The suffix(es) of source filenames. 44 + # You can specify multiple suffix as a list of string: 45 + # source_suffix = ['.rst', '.md'] 46 + source_suffix = '.rst' 47 + 48 + # The encoding of source files. 49 + #source_encoding = 'utf-8-sig' 50 + 51 + # The master toctree document. 52 + master_doc = 'index' 53 + 54 + # General information about the project. 55 + project = 'The Linux Kernel' 56 + copyright = '2016, The kernel development community' 57 + author = 'The kernel development community' 58 + 59 + # The version info for the project you're documenting, acts as replacement for 60 + # |version| and |release|, also used in various other places throughout the 61 + # built documents. 62 + # 63 + # In a normal build, version and release are are set to KERNELVERSION and 64 + # KERNELRELEASE, respectively, from the Makefile via Sphinx command line 65 + # arguments. 66 + # 67 + # The following code tries to extract the information by reading the Makefile, 68 + # when Sphinx is run directly (e.g. by Read the Docs). 69 + try: 70 + makefile_version = None 71 + makefile_patchlevel = None 72 + for line in open('../Makefile'): 73 + key, val = [x.strip() for x in line.split('=', 2)] 74 + if key == 'VERSION': 75 + makefile_version = val 76 + elif key == 'PATCHLEVEL': 77 + makefile_patchlevel = val 78 + if makefile_version and makefile_patchlevel: 79 + break 80 + except: 81 + pass 82 + finally: 83 + if makefile_version and makefile_patchlevel: 84 + version = release = makefile_version + '.' + makefile_patchlevel 85 + else: 86 + sys.stderr.write('Warning: Could not extract kernel version\n') 87 + version = release = "unknown version" 88 + 89 + # The language for content autogenerated by Sphinx. Refer to documentation 90 + # for a list of supported languages. 91 + # 92 + # This is also used if you do content translation via gettext catalogs. 93 + # Usually you set "language" from the command line for these cases. 94 + language = None 95 + 96 + # There are two options for replacing |today|: either, you set today to some 97 + # non-false value, then it is used: 98 + #today = '' 99 + # Else, today_fmt is used as the format for a strftime call. 100 + #today_fmt = '%B %d, %Y' 101 + 102 + # List of patterns, relative to source directory, that match files and 103 + # directories to ignore when looking for source files. 104 + exclude_patterns = ['output'] 105 + 106 + # The reST default role (used for this markup: `text`) to use for all 107 + # documents. 108 + #default_role = None 109 + 110 + # If true, '()' will be appended to :func: etc. cross-reference text. 111 + #add_function_parentheses = True 112 + 113 + # If true, the current module name will be prepended to all description 114 + # unit titles (such as .. function::). 115 + #add_module_names = True 116 + 117 + # If true, sectionauthor and moduleauthor directives will be shown in the 118 + # output. They are ignored by default. 119 + #show_authors = False 120 + 121 + # The name of the Pygments (syntax highlighting) style to use. 122 + pygments_style = 'sphinx' 123 + 124 + # A list of ignored prefixes for module index sorting. 125 + #modindex_common_prefix = [] 126 + 127 + # If true, keep warnings as "system message" paragraphs in the built documents. 128 + #keep_warnings = False 129 + 130 + # If true, `todo` and `todoList` produce output, else they produce nothing. 131 + todo_include_todos = False 132 + 133 + primary_domain = 'C' 134 + highlight_language = 'C' 135 + 136 + # -- Options for HTML output ---------------------------------------------- 137 + 138 + # The theme to use for HTML and HTML Help pages. See the documentation for 139 + # a list of builtin themes. 140 + 141 + # The Read the Docs theme is available from 142 + # - https://github.com/snide/sphinx_rtd_theme 143 + # - https://pypi.python.org/pypi/sphinx_rtd_theme 144 + # - python-sphinx-rtd-theme package (on Debian) 145 + try: 146 + import sphinx_rtd_theme 147 + html_theme = 'sphinx_rtd_theme' 148 + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 149 + except ImportError: 150 + sys.stderr.write('Warning: The Sphinx \'sphinx_rtd_theme\' HTML theme was not found. Make sure you have the theme installed to produce pretty HTML output. Falling back to the default theme.\n') 151 + 152 + # Theme options are theme-specific and customize the look and feel of a theme 153 + # further. For a list of options available for each theme, see the 154 + # documentation. 155 + #html_theme_options = {} 156 + 157 + # Add any paths that contain custom themes here, relative to this directory. 158 + #html_theme_path = [] 159 + 160 + # The name for this set of Sphinx documents. If None, it defaults to 161 + # "<project> v<release> documentation". 162 + #html_title = None 163 + 164 + # A shorter title for the navigation bar. Default is the same as html_title. 165 + #html_short_title = None 166 + 167 + # The name of an image file (relative to this directory) to place at the top 168 + # of the sidebar. 169 + #html_logo = None 170 + 171 + # The name of an image file (within the static path) to use as favicon of the 172 + # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 173 + # pixels large. 174 + #html_favicon = None 175 + 176 + # Add any paths that contain custom static files (such as style sheets) here, 177 + # relative to this directory. They are copied after the builtin static files, 178 + # so a file named "default.css" will overwrite the builtin "default.css". 179 + #html_static_path = ['_static'] 180 + 181 + # Add any extra paths that contain custom files (such as robots.txt or 182 + # .htaccess) here, relative to this directory. These files are copied 183 + # directly to the root of the documentation. 184 + #html_extra_path = [] 185 + 186 + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 187 + # using the given strftime format. 188 + #html_last_updated_fmt = '%b %d, %Y' 189 + 190 + # If true, SmartyPants will be used to convert quotes and dashes to 191 + # typographically correct entities. 192 + #html_use_smartypants = True 193 + 194 + # Custom sidebar templates, maps document names to template names. 195 + #html_sidebars = {} 196 + 197 + # Additional templates that should be rendered to pages, maps page names to 198 + # template names. 199 + #html_additional_pages = {} 200 + 201 + # If false, no module index is generated. 202 + #html_domain_indices = True 203 + 204 + # If false, no index is generated. 205 + #html_use_index = True 206 + 207 + # If true, the index is split into individual pages for each letter. 208 + #html_split_index = False 209 + 210 + # If true, links to the reST sources are added to the pages. 211 + #html_show_sourcelink = True 212 + 213 + # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 214 + #html_show_sphinx = True 215 + 216 + # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 217 + #html_show_copyright = True 218 + 219 + # If true, an OpenSearch description file will be output, and all pages will 220 + # contain a <link> tag referring to it. The value of this option must be the 221 + # base URL from which the finished HTML is served. 222 + #html_use_opensearch = '' 223 + 224 + # This is the file name suffix for HTML files (e.g. ".xhtml"). 225 + #html_file_suffix = None 226 + 227 + # Language to be used for generating the HTML full-text search index. 228 + # Sphinx supports the following languages: 229 + # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' 230 + # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' 231 + #html_search_language = 'en' 232 + 233 + # A dictionary with options for the search language support, empty by default. 234 + # Now only 'ja' uses this config value 235 + #html_search_options = {'type': 'default'} 236 + 237 + # The name of a javascript file (relative to the configuration directory) that 238 + # implements a search results scorer. If empty, the default will be used. 239 + #html_search_scorer = 'scorer.js' 240 + 241 + # Output file base name for HTML help builder. 242 + htmlhelp_basename = 'TheLinuxKerneldoc' 243 + 244 + # -- Options for LaTeX output --------------------------------------------- 245 + 246 + latex_elements = { 247 + # The paper size ('letterpaper' or 'a4paper'). 248 + #'papersize': 'letterpaper', 249 + 250 + # The font size ('10pt', '11pt' or '12pt'). 251 + #'pointsize': '10pt', 252 + 253 + # Additional stuff for the LaTeX preamble. 254 + #'preamble': '', 255 + 256 + # Latex figure (float) alignment 257 + #'figure_align': 'htbp', 258 + } 259 + 260 + # Grouping the document tree into LaTeX files. List of tuples 261 + # (source start file, target name, title, 262 + # author, documentclass [howto, manual, or own class]). 263 + latex_documents = [ 264 + (master_doc, 'TheLinuxKernel.tex', 'The Linux Kernel Documentation', 265 + 'The kernel development community', 'manual'), 266 + ] 267 + 268 + # The name of an image file (relative to this directory) to place at the top of 269 + # the title page. 270 + #latex_logo = None 271 + 272 + # For "manual" documents, if this is true, then toplevel headings are parts, 273 + # not chapters. 274 + #latex_use_parts = False 275 + 276 + # If true, show page references after internal links. 277 + #latex_show_pagerefs = False 278 + 279 + # If true, show URL addresses after external links. 280 + #latex_show_urls = False 281 + 282 + # Documents to append as an appendix to all manuals. 283 + #latex_appendices = [] 284 + 285 + # If false, no module index is generated. 286 + #latex_domain_indices = True 287 + 288 + 289 + # -- Options for manual page output --------------------------------------- 290 + 291 + # One entry per manual page. List of tuples 292 + # (source start file, name, description, authors, manual section). 293 + man_pages = [ 294 + (master_doc, 'thelinuxkernel', 'The Linux Kernel Documentation', 295 + [author], 1) 296 + ] 297 + 298 + # If true, show URL addresses after external links. 299 + #man_show_urls = False 300 + 301 + 302 + # -- Options for Texinfo output ------------------------------------------- 303 + 304 + # Grouping the document tree into Texinfo files. List of tuples 305 + # (source start file, target name, title, author, 306 + # dir menu entry, description, category) 307 + texinfo_documents = [ 308 + (master_doc, 'TheLinuxKernel', 'The Linux Kernel Documentation', 309 + author, 'TheLinuxKernel', 'One line description of project.', 310 + 'Miscellaneous'), 311 + ] 312 + 313 + # Documents to append as an appendix to all manuals. 314 + #texinfo_appendices = [] 315 + 316 + # If false, no module index is generated. 317 + #texinfo_domain_indices = True 318 + 319 + # How to display URL addresses: 'footnote', 'no', or 'inline'. 320 + #texinfo_show_urls = 'footnote' 321 + 322 + # If true, do not generate a @detailmenu in the "Top" node's menu. 323 + #texinfo_no_detailmenu = False 324 + 325 + 326 + # -- Options for Epub output ---------------------------------------------- 327 + 328 + # Bibliographic Dublin Core info. 329 + epub_title = project 330 + epub_author = author 331 + epub_publisher = author 332 + epub_copyright = copyright 333 + 334 + # The basename for the epub file. It defaults to the project name. 335 + #epub_basename = project 336 + 337 + # The HTML theme for the epub output. Since the default themes are not 338 + # optimized for small screen space, using the same theme for HTML and epub 339 + # output is usually not wise. This defaults to 'epub', a theme designed to save 340 + # visual space. 341 + #epub_theme = 'epub' 342 + 343 + # The language of the text. It defaults to the language option 344 + # or 'en' if the language is not set. 345 + #epub_language = '' 346 + 347 + # The scheme of the identifier. Typical schemes are ISBN or URL. 348 + #epub_scheme = '' 349 + 350 + # The unique identifier of the text. This can be a ISBN number 351 + # or the project homepage. 352 + #epub_identifier = '' 353 + 354 + # A unique identification for the text. 355 + #epub_uid = '' 356 + 357 + # A tuple containing the cover image and cover page html template filenames. 358 + #epub_cover = () 359 + 360 + # A sequence of (type, uri, title) tuples for the guide element of content.opf. 361 + #epub_guide = () 362 + 363 + # HTML files that should be inserted before the pages created by sphinx. 364 + # The format is a list of tuples containing the path and title. 365 + #epub_pre_files = [] 366 + 367 + # HTML files that should be inserted after the pages created by sphinx. 368 + # The format is a list of tuples containing the path and title. 369 + #epub_post_files = [] 370 + 371 + # A list of files that should not be packed into the epub file. 372 + epub_exclude_files = ['search.html'] 373 + 374 + # The depth of the table of contents in toc.ncx. 375 + #epub_tocdepth = 3 376 + 377 + # Allow duplicate toc entries. 378 + #epub_tocdup = True 379 + 380 + # Choose between 'default' and 'includehidden'. 381 + #epub_tocscope = 'default' 382 + 383 + # Fix unsupported image types using the Pillow. 384 + #epub_fix_images = False 385 + 386 + # Scale large images. 387 + #epub_max_image_width = 0 388 + 389 + # How to display URL addresses: 'footnote', 'no', or 'inline'. 390 + #epub_show_urls = 'inline' 391 + 392 + # If false, no index is generated. 393 + #epub_use_index = True 394 + 395 + #======= 396 + # rst2pdf 397 + # 398 + # Grouping the document tree into PDF files. List of tuples 399 + # (source start file, target name, title, author, options). 400 + # 401 + # See the Sphinx chapter of http://ralsina.me/static/manual.pdf 402 + # 403 + # FIXME: Do not add the index file here; the result will be too big. Adding 404 + # multiple PDF files here actually tries to get the cross-referencing right 405 + # *between* PDF files. 406 + pdf_documents = [ 407 + ('index', u'Kernel', u'Kernel', u'J. Random Bozo'), 408 + ] 409 + 410 + # kernel-doc extension configuration for running Sphinx directly (e.g. by Read 411 + # the Docs). In a normal build, these are supplied from the Makefile via command 412 + # line arguments. 413 + kerneldoc_bin = '../scripts/kernel-doc' 414 + kerneldoc_srctree = '..'
+1 -1
Documentation/dmaengine/provider.txt
··· 323 323 * device_resume 324 324 - Resumes a transfer on the channel 325 325 - This command should operate synchronously on the channel, 326 - pausing right away the work of the given channel 326 + resuming right away the work of the given channel 327 327 328 328 * device_terminate_all 329 329 - Aborts all the pending and ongoing transfers on the channel
+23
Documentation/index.rst
··· 1 + .. The Linux Kernel documentation master file, created by 2 + sphinx-quickstart on Fri Feb 12 13:51:46 2016. 3 + You can adapt this file completely to your liking, but it should at least 4 + contain the root `toctree` directive. 5 + 6 + Welcome to The Linux Kernel's documentation! 7 + ============================================ 8 + 9 + Nothing for you to see here *yet*. Please move along. 10 + 11 + Contents: 12 + 13 + .. toctree:: 14 + :maxdepth: 2 15 + 16 + 17 + Indices and tables 18 + ================== 19 + 20 + * :ref:`genindex` 21 + * :ref:`modindex` 22 + * :ref:`search` 23 +
+3 -2
Documentation/kernel-parameters.txt
··· 3992 3992 3993 3993 trace_event=[event-list] 3994 3994 [FTRACE] Set and start specified trace events in order 3995 - to facilitate early boot debugging. 3996 - See also Documentation/trace/events.txt 3995 + to facilitate early boot debugging. The event-list is a 3996 + comma separated list of trace events to enable. See 3997 + also Documentation/trace/events.txt 3997 3998 3998 3999 trace_options=[option-list] 3999 4000 [FTRACE] Enable or disable tracer options at boot.
+2 -2
Documentation/mic/mpssd/mpssd.c
··· 1538 1538 1539 1539 len = snprintf(buffer, PATH_MAX, 1540 1540 "clocksource=tsc highres=off nohz=off "); 1541 - len += snprintf(buffer + len, PATH_MAX, 1541 + len += snprintf(buffer + len, PATH_MAX - len, 1542 1542 "cpufreq_on;corec6_off;pc3_off;pc6_off "); 1543 - len += snprintf(buffer + len, PATH_MAX, 1543 + len += snprintf(buffer + len, PATH_MAX - len, 1544 1544 "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0", 1545 1545 mic->id + 1); 1546 1546
+18 -10
Documentation/security/self-protection.txt
··· 183 183 ### Canaries, blinding, and other secrets 184 184 185 185 It should be noted that things like the stack canary discussed earlier 186 - are technically statistical defenses, since they rely on a (leakable) 187 - secret value. 186 + are technically statistical defenses, since they rely on a secret value, 187 + and such values may become discoverable through an information exposure 188 + flaw. 188 189 189 190 Blinding literal values for things like JITs, where the executable 190 191 contents may be partially under the control of userspace, need a similar ··· 200 199 Since the location of kernel memory is almost always instrumental in 201 200 mounting a successful attack, making the location non-deterministic 202 201 raises the difficulty of an exploit. (Note that this in turn makes 203 - the value of leaks higher, since they may be used to discover desired 204 - memory locations.) 202 + the value of information exposures higher, since they may be used to 203 + discover desired memory locations.) 205 204 206 205 #### Text and module base 207 206 ··· 223 222 Much of the kernel's dynamic memory (e.g. kmalloc, vmalloc, etc) ends up 224 223 being relatively deterministic in layout due to the order of early-boot 225 224 initializations. If the base address of these areas is not the same 226 - between boots, targeting them is frustrated, requiring a leak specific 227 - to the region. 225 + between boots, targeting them is frustrated, requiring an information 226 + exposure specific to the region. 227 + 228 + #### Structure layout 229 + 230 + By performing a per-build randomization of the layout of sensitive 231 + structures, attacks must either be tuned to known kernel builds or expose 232 + enough kernel memory to determine structure layouts before manipulating 233 + them. 228 234 229 235 230 - ## Preventing Leaks 236 + ## Preventing Information Exposures 231 237 232 238 Since the locations of sensitive structures are the primary target for 233 - attacks, it is important to defend against leaks of both kernel memory 239 + attacks, it is important to defend against exposure of both kernel memory 234 240 addresses and kernel memory contents (since they may contain kernel 235 241 addresses or other sensitive things like canary values). 236 242 ··· 258 250 When releasing memory, it is best to poison the contents (clear stack on 259 251 syscall return, wipe heap memory on a free), to avoid reuse attacks that 260 252 rely on the old contents of memory. This frustrates many uninitialized 261 - variable attacks, stack info leaks, heap info leaks, and use-after-free 262 - attacks. 253 + variable attacks, stack content exposures, heap content exposures, and 254 + use-after-free attacks. 263 255 264 256 ### Destination tracking 265 257
+18
Documentation/sphinx/convert_template.sed
··· 1 + # 2 + # Pandoc doesn't grok <function> or <structname>, so convert them 3 + # ahead of time. 4 + # 5 + # Use the following escapes to pass through pandoc: 6 + # $bq = "`" 7 + # $lt = "<" 8 + # $gt = ">" 9 + # 10 + s%<function>\([^<(]\+\)()</function>%:c:func:$bq\1()$bq%g 11 + s%<function>\([^<(]\+\)</function>%:c:func:$bq\1()$bq%g 12 + s%<structname>struct *\([^<]\+\)</structname>%:c:type:$bqstruct \1 $lt\1$gt$bq%g 13 + s%struct <structname>\([^<]\+\)</structname>%:c:type:$bqstruct \1 $lt\1$gt$bq%g 14 + s%<structname>\([^<]\+\)</structname>%:c:type:$bqstruct \1 $lt\1$gt$bq%g 15 + # 16 + # Wrap docproc directives in para and code blocks. 17 + # 18 + s%^\(!.*\)$%<para><code>DOCPROC: \1</code></para>%
+127
Documentation/sphinx/kernel-doc.py
··· 1 + # coding=utf-8 2 + # 3 + # Copyright © 2016 Intel Corporation 4 + # 5 + # Permission is hereby granted, free of charge, to any person obtaining a 6 + # copy of this software and associated documentation files (the "Software"), 7 + # to deal in the Software without restriction, including without limitation 8 + # the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 + # and/or sell copies of the Software, and to permit persons to whom the 10 + # Software is furnished to do so, subject to the following conditions: 11 + # 12 + # The above copyright notice and this permission notice (including the next 13 + # paragraph) shall be included in all copies or substantial portions of the 14 + # Software. 15 + # 16 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 + # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 + # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 + # IN THE SOFTWARE. 23 + # 24 + # Authors: 25 + # Jani Nikula <jani.nikula@intel.com> 26 + # 27 + # Please make sure this works on both python2 and python3. 28 + # 29 + 30 + import os 31 + import subprocess 32 + import sys 33 + import re 34 + 35 + from docutils import nodes, statemachine 36 + from docutils.statemachine import ViewList 37 + from docutils.parsers.rst import directives 38 + from sphinx.util.compat import Directive 39 + 40 + class KernelDocDirective(Directive): 41 + """Extract kernel-doc comments from the specified file""" 42 + required_argument = 1 43 + optional_arguments = 4 44 + option_spec = { 45 + 'doc': directives.unchanged_required, 46 + 'functions': directives.unchanged_required, 47 + 'export': directives.flag, 48 + 'internal': directives.flag, 49 + } 50 + has_content = False 51 + 52 + def run(self): 53 + env = self.state.document.settings.env 54 + cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] 55 + 56 + filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] 57 + 58 + # Tell sphinx of the dependency 59 + env.note_dependency(os.path.abspath(filename)) 60 + 61 + tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) 62 + source = filename 63 + 64 + # FIXME: make this nicer and more robust against errors 65 + if 'export' in self.options: 66 + cmd += ['-export'] 67 + elif 'internal' in self.options: 68 + cmd += ['-internal'] 69 + elif 'doc' in self.options: 70 + cmd += ['-function', str(self.options.get('doc'))] 71 + elif 'functions' in self.options: 72 + for f in str(self.options.get('functions')).split(' '): 73 + cmd += ['-function', f] 74 + 75 + cmd += [filename] 76 + 77 + try: 78 + env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) 79 + 80 + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) 81 + out, err = p.communicate() 82 + 83 + # python2 needs conversion to unicode. 84 + # python3 with universal_newlines=True returns strings. 85 + if sys.version_info.major < 3: 86 + out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') 87 + 88 + if p.returncode != 0: 89 + sys.stderr.write(err) 90 + 91 + env.app.warn('kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode)) 92 + return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] 93 + elif env.config.kerneldoc_verbosity > 0: 94 + sys.stderr.write(err) 95 + 96 + lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) 97 + result = ViewList() 98 + 99 + lineoffset = 0; 100 + line_regex = re.compile("^#define LINENO ([0-9]+)$") 101 + for line in lines: 102 + match = line_regex.search(line) 103 + if match: 104 + # sphinx counts lines from 0 105 + lineoffset = int(match.group(1)) - 1 106 + # we must eat our comments since the upset the markup 107 + else: 108 + result.append(line, source, lineoffset) 109 + lineoffset += 1 110 + 111 + node = nodes.section() 112 + node.document = self.state.document 113 + self.state.nested_parse(result, self.content_offset, node) 114 + 115 + return node.children 116 + 117 + except Exception as e: 118 + env.app.warn('kernel-doc \'%s\' processing failed with: %s' % 119 + (" ".join(cmd), str(e))) 120 + return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] 121 + 122 + def setup(app): 123 + app.add_config_value('kerneldoc_bin', None, 'env') 124 + app.add_config_value('kerneldoc_srctree', None, 'env') 125 + app.add_config_value('kerneldoc_verbosity', 1, 'env') 126 + 127 + app.add_directive('kernel-doc', KernelDocDirective)
+23
Documentation/sphinx/post_convert.sed
··· 1 + # 2 + # Unescape. 3 + # 4 + s/$bq/`/g 5 + s/$lt/</g 6 + s/$gt/>/g 7 + # 8 + # pandoc thinks that both "_" needs to be escaped. Remove the extra 9 + # backslashes. 10 + # 11 + s/\\_/_/g 12 + # 13 + # Unwrap docproc directives. 14 + # 15 + s/^``DOCPROC: !E\(.*\)``$/.. kernel-doc:: \1\n :export:/ 16 + s/^``DOCPROC: !I\(.*\)``$/.. kernel-doc:: \1\n :internal:/ 17 + s/^``DOCPROC: !F\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :functions: \2/ 18 + s/^``DOCPROC: !P\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :doc: \2/ 19 + s/^``DOCPROC: \(!.*\)``$/.. WARNING: DOCPROC directive not supported: \1/ 20 + # 21 + # Trim trailing whitespace. 22 + # 23 + s/[[:space:]]*$//
+19
Documentation/sphinx/tmplcvt
··· 1 + #!/bin/bash 2 + # 3 + # Convert a template file into something like RST 4 + # 5 + # fix <function> 6 + # feed to pandoc 7 + # fix \_ 8 + # title line? 9 + # 10 + 11 + in=$1 12 + rst=$2 13 + tmp=$rst.tmp 14 + 15 + cp $in $tmp 16 + sed --in-place -f convert_template.sed $tmp 17 + pandoc -s -S -f docbook -t rst -o $rst $tmp 18 + sed --in-place -f post_convert.sed $rst 19 + rm $tmp
+3 -3
Documentation/sync_file.txt
··· 6 6 7 7 This document serves as a guide for device drivers writers on what the 8 8 sync_file API is, and how drivers can support it. Sync file is the carrier of 9 - the fences(struct fence) that needs to synchronized between drivers or across 10 - process boundaries. 9 + the fences(struct fence) that are needed to synchronize between drivers or 10 + across process boundaries. 11 11 12 12 The sync_file API is meant to be used to send and receive fence information 13 13 to/from userspace. It enables userspace to do explicit fencing, where instead ··· 32 32 Sync files can go either to or from userspace. When a sync_file is sent from 33 33 the driver to userspace we call the fences it contains 'out-fences'. They are 34 34 related to a buffer that the driver is processing or is going to process, so 35 - the driver an create out-fence to be able to notify, through fence_signal(), 35 + the driver creates an out-fence to be able to notify, through fence_signal(), 36 36 when it has finished using (or processing) that buffer. Out-fences are fences 37 37 that the driver creates. 38 38
+341 -222
Documentation/zh_CN/CodingStyle
··· 24 24 25 25 Linux内核代码风格 26 26 27 - 这是一个简短的文档,描述了linux内核的首选代码风格。代码风格是因人而异的,而且我 28 - 不愿意把我的观点强加给任何人,不过这里所讲述的是我必须要维护的代码所遵守的风格, 29 - 并且我也希望绝大多数其他代码也能遵守这个风格。请在写代码时至少考虑一下本文所述的 30 - 风格。 27 + 这是一个简短的文档,描述了 linux 内核的首选代码风格。代码风格是因人而异的,而且我 28 + 不愿意把自己的观点强加给任何人,但这就像我去做任何事情都必须遵循的原则那样,我也 29 + 希望在绝大多数事上保持这种的态度。请(在写代码时)至少考虑一下这里的代码风格。 31 30 32 - 首先,我建议你打印一份GNU代码规范,然后不要读它。烧了它,这是一个具有重大象征性 33 - 意义的动作。 31 + 首先,我建议你打印一份 GNU 代码规范,然后不要读。烧了它,这是一个具有重大象征性意义 32 + 的动作。 34 33 35 34 不管怎样,现在我们开始: 36 35 37 36 38 - 第一章:缩进 37 + 第一章:缩进 39 38 40 - 制表符是8个字符,所以缩进也是8个字符。有些异端运动试图将缩进变为4(乃至2)个字符 41 - 深,这几乎相当于尝试将圆周率的值定义为3。 39 + 制表符是 8 个字符,所以缩进也是 8 个字符。有些异端运动试图将缩进变为 4(甚至 2!) 40 + 个字符深,这几乎相当于尝试将圆周率的值定义为 3。 42 41 43 42 理由:缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的屏幕 44 - 连续看了20小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。 43 + 连续看了 20 小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。 45 44 46 - 现在,有些人会抱怨8个字符的缩进会使代码向右边移动的太远,在80个字符的终端屏幕上 47 - 就很难读这样的代码。这个问题的答案是,如果你需要3级以上的缩进,不管用何种方式你 45 + 现在,有些人会抱怨 8 个字符的缩进会使代码向右边移动的太远,在 80 个字符的终端屏幕上 46 + 就很难读这样的代码。这个问题的答案是,如果你需要 3 级以上的缩进,不管用何种方式你 48 47 的代码已经有问题了,应该修正你的程序。 49 48 50 - 简而言之,8个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太深的 49 + 简而言之,8 个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太深的 51 50 时候可以给你警告。留心这个警告。 52 51 53 - 在switch语句中消除多级缩进的首选的方式是让“switch”和从属于它的“case”标签对齐于同 54 - 一列,而不要“两次缩进”“case”标签。比如: 52 + 在 switch 语句中消除多级缩进的首选的方式是让 “switch” 和从属于它的 “case” 标签 53 + 对齐于同一列,而不要 “两次缩进” “case” 标签。比如: 55 54 56 55 switch (suffix) { 57 56 case 'G': ··· 69 70 break; 70 71 } 71 72 72 - 73 73 不要把多个语句放在一行里,除非你有什么东西要隐藏: 74 74 75 75 if (condition) do_this; ··· 77 79 也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读的表 78 80 达式。 79 81 80 - 除了注释、文档和Kconfig之外,不要使用空格来缩进,前面的例子是例外,是有意为之。 82 + 除了注释、文档和 Kconfig 之外,不要使用空格来缩进,前面的例子是例外,是有意为之。 81 83 82 84 选用一个好的编辑器,不要在行尾留空格。 83 85 ··· 86 88 87 89 代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。 88 90 89 - 每一行的长度的限制是80列,我们强烈建议您遵守这个惯例。 91 + 每一行的长度的限制是 80 列,我们强烈建议您遵守这个惯例。 90 92 91 - 长于80列的语句要打散成有意义的片段。每个片段要明显短于原来的语句,而且放置的位置 92 - 也明显的靠右。同样的规则也适用于有很长参数列表的函数头。长字符串也要打散成较短的 93 - 字符串。唯一的例外是超过80列可以大幅度提高可读性并且不会隐藏信息的情况。 94 - 95 - void fun(int a, int b, int c) 96 - { 97 - if (condition) 98 - printk(KERN_WARNING "Warning this is a long printk with " 99 - "3 parameters a: %u b: %u " 100 - "c: %u \n", a, b, c); 101 - else 102 - next_statement; 103 - } 93 + 长于 80 列的语句要打散成有意义的片段。除非超过 80 列能显著增加可读性,并且不会隐藏 94 + 信息。子片段要明显短于母片段,并明显靠右。这同样适用于有着很长参数列表的函数头。 95 + 然而,绝对不要打散对用户可见的字符串,例如 printk 信息,因为这将导致无法 grep 这些 96 + 信息。 104 97 105 98 第三章:大括号和空格的放置 106 99 107 100 C语言风格中另外一个常见问题是大括号的放置。和缩进大小不同,选择或弃用某种放置策 108 - 略并没有多少技术上的原因,不过首选的方式,就像Kernighan和Ritchie展示给我们的,是 109 - 把起始大括号放在行尾,而把结束大括号放在行首,所以: 101 + 略并没有多少技术上的原因,不过首选的方式,就像 Kernighan 和 Ritchie 展示给我们的, 102 + 是把起始大括号放在行尾,而把结束大括号放在行首,所以: 110 103 111 104 if (x is true) { 112 105 we do y ··· 123 134 body of function 124 135 } 125 136 126 - 全世界的异端可能会抱怨这个不一致性是……呃……不一致的,不过所有思维健全的人都知道( 127 - a)K&R是_正确的_,并且(b)K&R是正确的。此外,不管怎样函数都是特殊的(在C语言中 128 - ,函数是不能嵌套的)。 137 + 全世界的异端可能会抱怨这个不一致性是……呃……不一致的,不过所有思维健全的人都知道 138 + (a) K&R 是 _正确的_,并且 (b) K&R 是正确的。此外,不管怎样函数都是特殊的(C 139 + 函数是不能嵌套的)。 129 140 130 - 注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是do语句中的 131 - “while”或者if语句中的“else”,像这样: 141 + 注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是 do 语句中的 142 + “while” 或者 if 语句中的 “else”,像这样: 132 143 133 144 do { 134 145 body of do-loop ··· 147 158 理由:K&R。 148 159 149 160 也请注意这种大括号的放置方式也能使空(或者差不多空的)行的数量最小化,同时不失可 150 - 读性。因此,由于你的屏幕上的新行是不可再生资源(想想25行的终端屏幕),你将会有更 161 + 读性。因此,由于你的屏幕上的新行是不可再生资源(想想 25 行的终端屏幕),你将会有更 151 162 多的空行来放置注释。 152 163 153 164 当只有一个单独的语句的时候,不用加不必要的大括号。 154 165 155 - if (condition) 156 - action(); 166 + if (condition) 167 + action(); 157 168 158 - 这点不适用于本身为某个条件语句的一个分支的单独语句。这时需要在两个分支里都使用大 159 - 括号。 169 + 160 170 161 - if (condition) { 162 - do_this(); 163 - do_that(); 164 - } else { 165 - otherwise(); 166 - } 171 + if (condition) 172 + do_this(); 173 + else 174 + do_that(); 175 + 176 + 这并不适用于只有一个条件分支是单语句的情况;这时所有分支都要使用大括号: 177 + 178 + if (condition) { 179 + do_this(); 180 + do_that(); 181 + } else { 182 + otherwise(); 183 + } 167 184 168 185 3.1:空格 169 186 170 - Linux内核的空格使用方式(主要)取决于它是用于函数还是关键字。(大多数)关键字后 171 - 要加一个空格。值得注意的例外是sizeof、typeof、alignof和__attribute__,这些关键字 172 - 某些程度上看起来更像函数(它们在Linux里也常常伴随小括号而使用,尽管在C语言里这样 173 - 的小括号不是必需的,就像“struct fileinfo info”声明过后的“sizeof info”)。 187 + Linux 内核的空格使用方式(主要)取决于它是用于函数还是关键字。(大多数)关键字后 188 + 要加一个空格。值得注意的例外是 sizeof、typeof、alignof 和 __attribute__,这些 189 + 关键字某些程度上看起来更像函数(它们在 Linux 里也常常伴随小括号而使用,尽管在 C 里 190 + 这样的小括号不是必需的,就像 “struct fileinfo info” 声明过后的 “sizeof info”)。 174 191 175 192 所以在这些关键字之后放一个空格: 193 + 176 194 if, switch, case, for, do, while 177 - 但是不要在sizeof、typeof、alignof或者__attribute__这些关键字之后放空格。例如, 195 + 196 + 但是不要在 sizeof、typeof、alignof 或者 __attribute__ 这些关键字之后放空格。例如, 197 + 178 198 s = sizeof(struct file); 179 199 180 200 不要在小括号里的表达式两侧加空格。这是一个反例: 181 201 182 202 s = sizeof( struct file ); 183 203 184 - 当声明指针类型或者返回指针类型的函数时,“*”的首选使用方式是使之靠近变量名或者函 204 + 当声明指针类型或者返回指针类型的函数时,“*” 的首选使用方式是使之靠近变量名或者函 185 205 数名,而不是靠近类型名。例子: 186 206 187 207 char *linux_banner; ··· 202 204 = + - < > * / % | & ^ <= >= == != ? : 203 205 204 206 但是一元操作符后不要加空格: 207 + 205 208 & * + - ~ ! sizeof typeof alignof __attribute__ defined 206 209 207 210 后缀自加和自减一元操作符前不加空格: 211 + 208 212 ++ -- 209 213 210 214 前缀自加和自减一元操作符后不加空格: 215 + 211 216 ++ -- 212 217 213 - “.”和“->”结构体成员操作符前后不加空格。 218 + ‘.’ 和 “->” 结构体成员操作符前后不加空格。 214 219 215 220 不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白,然后你 216 221 就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码,有些编辑器就不 ··· 226 225 227 226 第四章:命名 228 227 229 - C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal程序员不同,C程序员不使 230 - 用类似ThisVariableIsATemporaryCounter这样华丽的名字。C程序员会称那个变量为“tmp” 231 - ,这样写起来会更容易,而且至少不会令其难于理解。 228 + C是一个简朴的语言,你的命名也应该这样。和 Modula-2 和 Pascal 程序员不同,C 程序员 229 + 不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字。C 程序员会称那个变量 230 + 为 “tmp”,这样写起来会更容易,而且至少不会令其难于理解。 232 231 233 232 不过,虽然混用大小写的名字是不提倡使用的,但是全局变量还是需要一个具描述性的名字 234 - 。称一个全局函数为“foo”是一个难以饶恕的错误。 233 + 。称一个全局函数为 “foo” 是一个难以饶恕的错误。 235 234 236 235 全局变量(只有当你真正需要它们的时候再用它)需要有一个具描述性的名字,就像全局函 237 - 数。如果你有一个可以计算活动用户数量的函数,你应该叫它“count_active_users()”或者 238 - 类似的名字,你不应该叫它“cntuser()”。 236 + 数。如果你有一个可以计算活动用户数量的函数,你应该叫它 “count_active_users()” 237 + 或者类似的名字,你不应该叫它 “cntuser()”。 239 238 240 239 在函数名中包含函数类型(所谓的匈牙利命名法)是脑子出了问题——编译器知道那些类型而 241 240 且能够检查那些类型,这样做只能把程序员弄糊涂了。难怪微软总是制造出有问题的程序。 242 241 243 242 本地变量名应该简短,而且能够表达相关的含义。如果你有一些随机的整数型的循环计数器 244 - ,它应该被称为“i”。叫它“loop_counter”并无益处,如果它没有被误解的可能的话。类似 245 - 的,“tmp”可以用来称呼任意类型的临时变量。 243 + ,它应该被称为 “i”。叫它 “loop_counter” 并无益处,如果它没有被误解的可能的话。 244 + 类似的,“tmp” 可以用来称呼任意类型的临时变量。 246 245 247 246 如果你怕混淆了你的本地变量名,你就遇到另一个问题了,叫做函数增长荷尔蒙失衡综合症 248 247 。请看第六章(函数)。 ··· 250 249 251 250 第五章:Typedef 252 251 253 - 不要使用类似“vps_t”之类的东西。 252 + 不要使用类似 “vps_t” 之类的东西。 254 253 255 - 对结构体和指针使用typedef是一个错误。当你在代码里看到: 254 + 对结构体和指针使用 typedef 是一个错误。当你在代码里看到: 256 255 257 256 vps_t a; 258 257 ··· 262 261 263 262 struct virtual_container *a; 264 263 265 - 你就知道“a”是什么了。 264 + 你就知道 “a” 是什么了。 266 265 267 - 很多人认为typedef“能提高可读性”。实际不是这样的。它们只在下列情况下有用: 266 + 很多人认为 typedef “能提高可读性”。实际不是这样的。它们只在下列情况下有用: 268 267 269 - (a) 完全不透明的对象(这种情况下要主动使用typedef来隐藏这个对象实际上是什么)。 268 + (a) 完全不透明的对象(这种情况下要主动使用 typedef 来隐藏这个对象实际上是什么)。 270 269 271 - 例如:“pte_t”等不透明对象,你只能用合适的访问函数来访问它们。 270 + 例如:“pte_t” 等不透明对象,你只能用合适的访问函数来访问它们。 272 271 273 - 注意!不透明性和“访问函数”本身是不好的。我们使用pte_t等类型的原因在于真的是 272 + 注意!不透明性和“访问函数”本身是不好的。我们使用 pte_t 等类型的原因在于真的是 274 273 完全没有任何共用的可访问信息。 275 274 276 - (b) 清楚的整数类型,如此,这层抽象就可以帮助消除到底是“int”还是“long”的混淆。 275 + (b) 清楚的整数类型,如此,这层抽象就可以帮助消除到底是 “int” 还是 “long” 的混淆。 277 276 278 - u8/u16/u32是完全没有问题的typedef,不过它们更符合类别(d)而不是这里。 277 + u8/u16/u32 是完全没有问题的 typedef,不过它们更符合类别 (d) 而不是这里。 279 278 280 - 再次注意!要这样做,必须事出有因。如果某个变量是“unsigned long“,那么没有必要 279 + 再次注意!要这样做,必须事出有因。如果某个变量是 “unsigned long“,那么没有必要 281 280 282 281 typedef unsigned long myflags_t; 283 282 284 - 不过如果有一个明确的原因,比如它在某种情况下可能会是一个“unsigned int”而在 285 - 其他情况下可能为“unsigned long”,那么就不要犹豫,请务必使用typedef。 283 + 不过如果有一个明确的原因,比如它在某种情况下可能会是一个 “unsigned int” 而在 284 + 其他情况下可能为 “unsigned long”,那么就不要犹豫,请务必使用 typedef。 286 285 287 286 (c) 当你使用sparse按字面的创建一个新类型来做类型检查的时候。 288 287 289 288 (d) 和标准C99类型相同的类型,在某些例外的情况下。 290 289 291 - 虽然让眼睛和脑筋来适应新的标准类型比如“uint32_t”不需要花很多时间,可是有些 290 + 虽然让眼睛和脑筋来适应新的标准类型比如 “uint32_t” 不需要花很多时间,可是有些 292 291 人仍然拒绝使用它们。 293 292 294 - 因此,Linux特有的等同于标准类型的“u8/u16/u32/u64”类型和它们的有符号类型是被 293 + 因此,Linux 特有的等同于标准类型的 “u8/u16/u32/u64” 类型和它们的有符号类型是被 295 294 允许的——尽管在你自己的新代码中,它们不是强制要求要使用的。 296 295 297 296 当编辑已经使用了某个类型集的已有代码时,你应该遵循那些代码中已经做出的选择。 298 297 299 298 (e) 可以在用户空间安全使用的类型。 300 299 301 - 在某些用户空间可见的结构体里,我们不能要求C99类型而且不能用上面提到的“u32” 302 - 类型。因此,我们在与用户空间共享的所有结构体中使用__u32和类似的类型。 300 + 在某些用户空间可见的结构体里,我们不能要求C99类型而且不能用上面提到的 “u32” 301 + 类型。因此,我们在与用户空间共享的所有结构体中使用 __u32 和类似的类型。 303 302 304 - 可能还有其他的情况,不过基本的规则是永远不要使用typedef,除非你可以明确的应用上 303 + 可能还有其他的情况,不过基本的规则是永远不要使用 typedef,除非你可以明确的应用上 305 304 述某个规则中的一个。 306 305 307 306 总的来说,如果一个指针或者一个结构体里的元素可以合理的被直接访问到,那么它们就不 308 - 应该是一个typedef。 307 + 应该是一个 typedef。 309 308 310 309 311 310 第六章:函数 312 311 313 312 函数应该简短而漂亮,并且只完成一件事情。函数应该可以一屏或者两屏显示完(我们都知 314 - 道ISO/ANSI屏幕大小是80x24),只做一件事情,而且把它做好。 313 + 道 ISO/ANSI 屏幕大小是 80x24),只做一件事情,而且把它做好。 315 314 316 315 一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以,如果你有一个理论上 317 - 很简单的只有一个很长(但是简单)的case语句的函数,而且你需要在每个case里做很多很 318 - 小的事情,这样的函数尽管很长,但也是可以的。 316 + 很简单的只有一个很长(但是简单)的 case 语句的函数,而且你需要在每个 case 里做 317 + 很多很小的事情,这样的函数尽管很长,但也是可以的。 319 318 320 319 不过,如果你有一个复杂的函数,而且你怀疑一个天分不是很高的高中一年级学生可能甚至 321 320 搞不清楚这个函数的目的,你应该严格的遵守前面提到的长度限制。使用辅助函数,并为之 322 321 取个具描述性的名字(如果你觉得它们的性能很重要的话,可以让编译器内联它们,这样的 323 322 效果往往会比你写一个复杂函数的效果要好。) 324 323 325 - 函数的另外一个衡量标准是本地变量的数量。此数量不应超过5-10个,否则你的函数就有 324 + 函数的另外一个衡量标准是本地变量的数量。此数量不应超过 5-10 个,否则你的函数就有 326 325 问题了。重新考虑一下你的函数,把它分拆成更小的函数。人的大脑一般可以轻松的同时跟 327 - 踪7个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你2 328 - 个星期前做过的事情。 326 + 踪 7 个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你 327 + 2 个星期前做过的事情。 329 328 330 - 在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的EXPORT*宏应该紧贴 329 + 在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的 EXPORT* 宏应该紧贴 331 330 在它的结束大括号之下。比如: 332 331 333 - int system_is_up(void) 334 - { 335 - return system_state == SYSTEM_RUNNING; 336 - } 337 - EXPORT_SYMBOL(system_is_up); 332 + int system_is_up(void) 333 + { 334 + return system_state == SYSTEM_RUNNING; 335 + } 336 + EXPORT_SYMBOL(system_is_up); 338 337 339 - 在函数原型中,包含函数名和它们的数据类型。虽然C语言里没有这样的要求,在Linux里这 338 + 在函数原型中,包含函数名和它们的数据类型。虽然C语言里没有这样的要求,在 Linux 里这 340 339 是提倡的做法,因为这样可以很简单的给读者提供更多的有价值的信息。 341 340 342 341 343 342 第七章:集中的函数退出途径 344 343 345 - 虽然被某些人声称已经过时,但是goto语句的等价物还是经常被编译器所使用,具体形式是 344 + 虽然被某些人声称已经过时,但是 goto 语句的等价物还是经常被编译器所使用,具体形式是 346 345 无条件跳转指令。 347 346 348 - 当一个函数从多个位置退出并且需要做一些通用的清理工作的时候,goto的好处就显现出来 349 - 了。 347 + 当一个函数从多个位置退出,并且需要做一些类似清理的常见操作时,goto 语句就很方便了。 348 + 如果并不需要清理操作,那么直接 return 即可。 350 349 351 350 理由是: 352 351 ··· 355 354 - 可以避免由于修改时忘记更新某个单独的退出点而导致的错误 356 355 - 减轻了编译器的工作,无需删除冗余代码;) 357 356 358 - int fun(int a) 359 - { 360 - int result = 0; 361 - char *buffer = kmalloc(SIZE); 357 + int fun(int a) 358 + { 359 + int result = 0; 360 + char *buffer; 362 361 363 - if (buffer == NULL) 364 - return -ENOMEM; 362 + buffer = kmalloc(SIZE, GFP_KERNEL); 363 + if (!buffer) 364 + return -ENOMEM; 365 365 366 - if (condition1) { 367 - while (loop1) { 368 - ... 366 + if (condition1) { 367 + while (loop1) { 368 + ... 369 + } 370 + result = 1; 371 + goto out_buffer; 369 372 } 370 - result = 1; 371 - goto out; 373 + ... 374 + out_buffer: 375 + kfree(buffer); 376 + return result; 372 377 } 373 - ... 374 - out: 375 - kfree(buffer); 376 - return result; 377 - } 378 + 379 + 一个需要注意的常见错误是“一个 err 错误”,就像这样: 380 + 381 + err: 382 + kfree(foo->bar); 383 + kfree(foo); 384 + return ret; 385 + 386 + 这段代码的错误是,在某些退出路径上 “foo” 是 NULL。通常情况下,通过把它分离成两个 387 + 错误标签 “err_bar:” 和 “err_foo:” 来修复这个错误。 378 388 379 389 第八章:注释 380 390 ··· 398 386 加太多。你应该做的,是把注释放在函数的头部,告诉人们它做了什么,也可以加上它做这 399 387 些事情的原因。 400 388 401 - 当注释内核API函数时,请使用kernel-doc格式。请看 402 - Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc以获得详细信息。 389 + 当注释内核API函数时,请使用 kernel-doc 格式。请看 390 + Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc 以获得详细信息。 403 391 404 - Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ...”注释。 392 + Linux的注释风格是 C89 “/* ... */” 风格。不要使用 C99 风格 “// ...” 注释。 405 393 406 394 长(多行)的首选注释风格是: 407 395 ··· 414 402 * with beginning and ending almost-blank lines. 415 403 */ 416 404 405 + 对于在 net/ 和 drivers/net/ 的文件,首选的长(多行)注释风格有些不同。 406 + 407 + /* The preferred comment style for files in net/ and drivers/net 408 + * looks like this. 409 + * 410 + * It is nearly the same as the generally preferred comment style, 411 + * but there is no initial almost-blank line. 412 + */ 413 + 417 414 注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行应只 418 415 声明一个数据(不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据写一段 419 416 小注释来解释它们的用途了。 ··· 430 409 431 410 第九章:你已经把事情弄糟了 432 411 433 - 这没什么,我们都是这样。可能你的使用了很长时间Unix的朋友已经告诉你“GNU emacs”能 434 - 自动帮你格式化C源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们 435 - 想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在GNU emacs里打字永远不 436 - 会创造出一个好程序)(译注:请参考Infinite Monkey Theorem) 412 + 这没什么,我们都是这样。可能你的使用了很长时间 Unix 的朋友已经告诉你 “GNU emacs” 能 413 + 自动帮你格式化 C 源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们 414 + 想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在 GNU emacs 里打字永远不 415 + 会创造出一个好程序)(译注:请参考 Infinite Monkey Theorem) 437 416 438 - 所以你要么放弃GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,你可 439 - 以把下面这段粘贴到你的.emacs文件里。 417 + 所以你要么放弃 GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,你可 418 + 以把下面这段粘贴到你的 .emacs 文件里。 440 419 441 - (defun linux-c-mode () 442 - "C mode with adjusted defaults for use with the Linux kernel." 443 - (interactive) 444 - (c-mode) 445 - (c-set-style "K&R") 446 - (setq tab-width 8) 447 - (setq indent-tabs-mode t) 448 - (setq c-basic-offset 8)) 420 + (defun c-lineup-arglist-tabs-only (ignored) 421 + "Line up argument lists by tabs, not spaces" 422 + (let* ((anchor (c-langelem-pos c-syntactic-element)) 423 + (column (c-langelem-2nd-pos c-syntactic-element)) 424 + (offset (- (1+ column) anchor)) 425 + (steps (floor offset c-basic-offset))) 426 + (* (max steps 1) 427 + c-basic-offset))) 449 428 450 - 这样就定义了M-x linux-c-mode命令。当你hack一个模块的时候,如果你把字符串 451 - -*- linux-c -*-放在头两行的某个位置,这个模式将会被自动调用。如果你希望在你修改 452 - /usr/src/linux里的文件时魔术般自动打开linux-c-mode的话,你也可能需要添加 429 + (add-hook 'c-mode-common-hook 430 + (lambda () 431 + ;; Add kernel style 432 + (c-add-style 433 + "linux-tabs-only" 434 + '("linux" (c-offsets-alist 435 + (arglist-cont-nonempty 436 + c-lineup-gcc-asm-reg 437 + c-lineup-arglist-tabs-only)))))) 453 438 454 - (setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode) 455 - auto-mode-alist)) 439 + (add-hook 'c-mode-hook 440 + (lambda () 441 + (let ((filename (buffer-file-name))) 442 + ;; Enable kernel mode for the appropriate files 443 + (when (and filename 444 + (string-match (expand-file-name "~/src/linux-trees") 445 + filename)) 446 + (setq indent-tabs-mode t) 447 + (setq show-trailing-whitespace t) 448 + (c-set-style "linux-tabs-only"))))) 456 449 457 - 到你的.emacs文件里。 450 + 这会让 emacs 在 ~/src/linux-trees 目录下的 C 源文件获得更好的内核代码风格。 458 451 459 - 不过就算你尝试让emacs正确的格式化代码失败了,也并不意味着你失去了一切:还可以用“ 460 - indent”。 452 + 不过就算你尝试让 emacs 正确的格式化代码失败了,也并不意味着你失去了一切:还可以用 453 + “indent”。 461 454 462 - 不过,GNU indent也有和GNU emacs一样有问题的设定,所以你需要给它一些命令选项。不 463 - 过,这还不算太糟糕,因为就算是GNU indent的作者也认同K&R的权威性(GNU的人并不是坏 464 - 人,他们只是在这个问题上被严重的误导了),所以你只要给indent指定选项“-kr -i8” 465 - (代表“K&R,8个字符缩进”),或者使用“scripts/Lindent”,这样就可以以最时髦的方式 455 + 不过,GNU indent 也有和 GNU emacs 一样有问题的设定,所以你需要给它一些命令选项。不 456 + 过,这还不算太糟糕,因为就算是 GNU indent 的作者也认同 K&R 的权威性(GNU 的人并不是 457 + 坏人,他们只是在这个问题上被严重的误导了),所以你只要给 indent 指定选项 “-kr -i8” 458 + (代表 “K&R,8 个字符缩进”),或者使用 “scripts/Lindent”,这样就可以以最时髦的方式 466 459 缩进源代码。 467 460 468 - “indent”有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过 469 - 记住:“indent”不能修正坏的编程习惯。 461 + “indent” 有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过 462 + 记住:“indent” 不能修正坏的编程习惯。 470 463 471 464 472 - 第十章:Kconfig配置文件 465 + 第十章:Kconfig 配置文件 473 466 474 - 对于遍布源码树的所有Kconfig*配置文件来说,它们缩进方式与C代码相比有所不同。紧挨 475 - 在“config”定义下面的行缩进一个制表符,帮助信息则再多缩进2个空格。比如: 467 + 对于遍布源码树的所有 Kconfig* 配置文件来说,它们缩进方式与 C 代码相比有所不同。紧挨 468 + 在 “config” 定义下面的行缩进一个制表符,帮助信息则再多缩进 2 个空格。比如: 476 469 477 470 config AUDIT 478 471 bool "Auditing support" ··· 505 470 depends on ADFS_FS 506 471 ... 507 472 508 - 要查看配置文件的完整文档,请看Documentation/kbuild/kconfig-language.txt。 473 + 要查看配置文件的完整文档,请看 Documentation/kbuild/kconfig-language.txt。 509 474 510 475 511 476 第十一章:数据结构 ··· 524 489 很多数据结构实际上有2级引用计数,它们通常有不同“类”的用户。子类计数器统计子类用 525 490 户的数量,每当子类计数器减至零时,全局计数器减一。 526 491 527 - 这种“多级引用计数”的例子可以在内存管理(“struct mm_struct”:mm_users和mm_count) 492 + 这种“多级引用计数”的例子可以在内存管理(“struct mm_struct”:mm_users 和 mm_count) 528 493 和文件系统(“struct super_block”:s_count和s_active)中找到。 529 494 530 495 记住:如果另一个执行线索可以找到你的数据结构,但是这个数据结构没有引用计数器,这 531 - 里几乎肯定是一个bug。 496 + 里几乎肯定是一个 bug。 532 497 533 498 534 499 第十二章:宏,枚举和RTL ··· 543 508 544 509 一般的,如果能写成内联函数就不要写成像函数的宏。 545 510 546 - 含有多个语句的宏应该被包含在一个do-while代码块里: 511 + 含有多个语句的宏应该被包含在一个 do-while 代码块里: 547 512 548 - #define macrofun(a, b, c) \ 549 - do { \ 550 - if (a == 5) \ 551 - do_this(b, c); \ 552 - } while (0) 513 + #define macrofun(a, b, c) \ 514 + do { \ 515 + if (a == 5) \ 516 + do_this(b, c); \ 517 + } while (0) 553 518 554 519 使用宏的时候应避免的事情: 555 520 556 521 1) 影响控制流程的宏: 557 522 558 - #define FOO(x) \ 559 - do { \ 560 - if (blah(x) < 0) \ 561 - return -EBUGGERED; \ 562 - } while(0) 523 + #define FOO(x) \ 524 + do { \ 525 + if (blah(x) < 0) \ 526 + return -EBUGGERED; \ 527 + } while (0) 563 528 564 529 非常不好。它看起来像一个函数,不过却能导致“调用”它的函数退出;不要打乱读者大脑里 565 530 的语法分析器。 566 531 567 532 2) 依赖于一个固定名字的本地变量的宏: 568 533 569 - #define FOO(val) bar(index, val) 534 + #define FOO(val) bar(index, val) 570 535 571 536 可能看起来像是个不错的东西,不过它非常容易把读代码的人搞糊涂,而且容易导致看起来 572 537 不相关的改动带来错误。 573 538 574 - 3) 作为左值的带参数的宏: FOO(x) = y;如果有人把FOO变成一个内联函数的话,这种用 539 + 3) 作为左值的带参数的宏: FOO(x) = y;如果有人把 FOO 变成一个内联函数的话,这种用 575 540 法就会出错了。 576 541 577 542 4) 忘记了优先级:使用表达式定义常量的宏必须将表达式置于一对小括号之内。带参数的 578 543 宏也要注意此类问题。 579 544 580 - #define CONSTANT 0x4000 581 - #define CONSTEXP (CONSTANT | 3) 545 + #define CONSTANT 0x4000 546 + #define CONSTEXP (CONSTANT | 3) 582 547 583 - cpp手册对宏的讲解很详细。Gcc internals手册也详细讲解了RTL(译注:register 548 + 5) 在宏里定义类似函数的本地变量时命名冲突: 549 + 550 + #define FOO(x) \ 551 + ({ \ 552 + typeof(x) ret; \ 553 + ret = calc_ret(x); \ 554 + (ret); \ 555 + }) 556 + 557 + ret 是本地变量的通用名字 - __foo_ret 更不容易与一个已存在的变量冲突。 558 + 559 + cpp 手册对宏的讲解很详细。gcc internals 手册也详细讲解了 RTL(译注:register 584 560 transfer language),内核里的汇编语言经常用到它。 585 561 586 562 587 563 第十三章:打印内核消息 588 564 589 565 内核开发者应该是受过良好教育的。请一定注意内核信息的拼写,以给人以好的印象。不要 590 - 用不规范的单词比如“dont”,而要用“do not”或者“don't”。保证这些信息简单、明了、无 591 - 歧义。 566 + 用不规范的单词比如 “dont”,而要用 “do not”或者 “don't”。保证这些信息简单、明了、 567 + 无歧义。 592 568 593 569 内核信息不必以句号(译注:英文句号,即点)结束。 594 570 595 - 在小括号里打印数字(%d)没有任何价值,应该避免这样做。 571 + 在小括号里打印数字 (%d) 没有任何价值,应该避免这样做。 596 572 597 - <linux/device.h>里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的 598 - 设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(), dev_warn(), 599 - dev_info()等等。对于那些不和某个特定设备相关连的信息,<linux/kernel.h>定义了 600 - pr_debug()和pr_info()。 573 + <linux/device.h> 里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的 574 + 设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(),dev_warn(), 575 + dev_info() 等等。对于那些不和某个特定设备相关连的信息,<linux/printk.h> 定义了 576 + pr_notice(),pr_info(),pr_warn(),pr_err() 和其他。 601 577 602 - 写出好的调试信息可以是一个很大的挑战;当你写出来之后,这些信息在远程除错的时候 603 - 就会成为极大的帮助。当DEBUG符号没有被定义的时候,这些信息不应该被编译进内核里 604 - (也就是说,默认地,它们不应该被包含在内)。如果你使用dev_dbg()或者pr_debug(), 605 - 就能自动达到这个效果。很多子系统拥有Kconfig选项来启用-DDEBUG。还有一个相关的惯例 606 - 是使用VERBOSE_DEBUG来添加dev_vdbg()消息到那些已经由DEBUG启用的消息之上。 578 + 写出好的调试信息可以是一个很大的挑战;一旦你写出后,这些信息在远程除错时能提供极大 579 + 的帮助。然而打印调试信息的处理方式同打印非调试信息不同。其他 pr_XXX() 函数能无条件地 580 + 打印,pr_debug() 却不;默认情况下它不会被编译,除非定义了 DEBUG 或设定了 581 + CONFIG_DYNAMIC_DEBUG。实际这同样是为了 dev_dbg(),一个相关约定是在一个已经开启了 582 + DEBUG 时,使用 VERBOSE_DEBUG 来添加 dev_vdbg()。 583 + 584 + 许多子系统拥有 Kconfig 调试选项来开启 -DDEBUG 在对应的 Makefile 里面;在其他 585 + 情况下,特殊文件使用 #define DEBUG。当一条调试信息需要被无条件打印时,例如,如果 586 + 已经包含一个调试相关的 #ifdef 条件,printk(KERN_DEBUG ...) 就可被使用。 607 587 608 588 609 589 第十四章:分配内存 610 590 611 - 内核提供了下面的一般用途的内存分配函数:kmalloc(),kzalloc(),kcalloc()和 612 - vmalloc()。请参考API文档以获取有关它们的详细信息。 591 + 内核提供了下面的一般用途的内存分配函数: 592 + kmalloc(),kzalloc(),kmalloc_array(),kcalloc(),vmalloc() 和 vzalloc()。 593 + 请参考 API 文档以获取有关它们的详细信息。 613 594 614 595 传递结构体大小的首选形式是这样的: 615 596 616 597 p = kmalloc(sizeof(*p), ...); 617 598 618 - 另外一种传递方式中,sizeof的操作数是结构体的名字,这样会降低可读性,并且可能会引 619 - 入bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的sizeof的结果不变。 599 + 另外一种传递方式中,sizeof 的操作数是结构体的名字,这样会降低可读性,并且可能会引 600 + 入 bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的 sizeof 的结果不变。 620 601 621 - 强制转换一个void指针返回值是多余的。C语言本身保证了从void指针到其他任何指针类型 602 + 强制转换一个 void 指针返回值是多余的。C 语言本身保证了从 void 指针到其他任何指针类型 622 603 的转换是没有问题的。 604 + 605 + 分配一个数组的首选形式是这样的: 606 + 607 + p = kmalloc_array(n, sizeof(...), ...); 608 + 609 + 分配一个零长数组的首选形式是这样的: 610 + 611 + p = kcalloc(n, sizeof(...), ...); 612 + 613 + 两种形式检查分配大小 n * sizeof(...) 的溢出,如果溢出返回 NULL。 623 614 624 615 625 616 第十五章:内联弊病 626 617 627 - 有一个常见的误解是内联函数是gcc提供的可以让代码运行更快的一个选项。虽然使用内联 618 + 有一个常见的误解是内联函数是 gcc 提供的可以让代码运行更快的一个选项。虽然使用内联 628 619 函数有时候是恰当的(比如作为一种替代宏的方式,请看第十二章),不过很多情况下不是 629 - 这样。inline关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核 620 + 这样。inline 关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核 630 621 会占用更多的指令高速缓存(译注:一级缓存通常是指令缓存和数据缓存分开的)而且会导 631 - 致pagecache的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址,将 632 - 耗时5毫秒。5毫秒的时间内CPU能执行很多很多指令。 622 + 致 pagecache 的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址, 623 + 将耗时 5 毫秒。5 毫秒的时间内 CPU 能执行很多很多指令。 633 624 634 - 一个基本的原则是如果一个函数有3行以上,就不要把它变成内联函数。这个原则的一个例 625 + 一个基本的原则是如果一个函数有 3 行以上,就不要把它变成内联函数。这个原则的一个例 635 626 外是,如果你知道某个参数是一个编译时常量,而且因为这个常量你确定编译器在编译时能 636 - 优化掉你的函数的大部分代码,那仍然可以给它加上inline关键字。kmalloc()内联函数就 627 + 优化掉你的函数的大部分代码,那仍然可以给它加上 inline 关键字。kmalloc() 内联函数就 637 628 是一个很好的例子。 638 629 639 - 人们经常主张给static的而且只用了一次的函数加上inline,如此不会有任何损失,因为没 640 - 有什么好权衡的。虽然从技术上说这是正确的,但是实际上这种情况下即使不加inline gcc 641 - 也可以自动使其内联。而且其他用户可能会要求移除inline,由此而来的争论会抵消inline 630 + 人们经常主张给 static 的而且只用了一次的函数加上 inline,如此不会有任何损失,因为没 631 + 有什么好权衡的。虽然从技术上说这是正确的,但是实际上这种情况下即使不加 inline gcc 632 + 也可以自动使其内联。而且其他用户可能会要求移除 inline,由此而来的争论会抵消 inline 642 633 自身的潜在价值,得不偿失。 643 634 644 635 ··· 674 613 的一个值可以表示为一个错误代码整数(-Exxx=失败,0=成功)或者一个“成功”布尔值( 675 614 0=失败,非0=成功)。 676 615 677 - 混合使用这两种表达方式是难于发现的bug的来源。如果C语言本身严格区分整形和布尔型变 678 - 量,那么编译器就能够帮我们发现这些错误……不过C语言不区分。为了避免产生这种bug,请 616 + 混合使用这两种表达方式是难于发现的 bug 的来源。如果 C 语言本身严格区分整形和布尔型变 617 + 量,那么编译器就能够帮我们发现这些错误……不过 C 语言不区分。为了避免产生这种 bug,请 679 618 遵循下面的惯例: 680 619 681 620 如果函数的名字是一个动作或者强制性的命令,那么这个函数应该返回错误代码整 682 621 数。如果是一个判断,那么函数应该返回一个“成功”布尔值。 683 622 684 - 比如,“add work”是一个命令,所以add_work()函数在成功时返回0,在失败时返回-EBUSY。 685 - 类似的,因为“PCI device present”是一个判断,所以pci_dev_present()函数在成功找到 686 - 一个匹配的设备时应该返回1,如果找不到时应该返回0。 623 + 比如,“add work” 是一个命令,所以 add_work() 函数在成功时返回 0,在失败时返回 -EBUSY。 624 + 类似的,因为 “PCI device present” 是一个判断,所以 pci_dev_present() 函数在成功找到 625 + 一个匹配的设备时应该返回 1,如果找不到时应该返回 0。 687 626 688 627 所有导出(译注:EXPORT)的函数都必须遵守这个惯例,所有的公共函数也都应该如此。私 689 628 有(static)函数不需要如此,但是我们也推荐这样做。 690 629 691 630 返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。一般的,他们 692 631 通过返回一些正常值范围之外的结果来表示出错。典型的例子是返回指针的函数,他们使用 693 - NULL或者ERR_PTR机制来报告错误。 632 + NULL 或者 ERR_PTR 机制来报告错误。 694 633 695 634 696 635 第十七章:不要重新发明内核宏 697 636 698 - 头文件include/linux/kernel.h包含了一些宏,你应该使用它们,而不要自己写一些它们的 637 + 头文件 include/linux/kernel.h 包含了一些宏,你应该使用它们,而不要自己写一些它们的 699 638 变种。比如,如果你需要计算一个数组的长度,使用这个宏 700 639 701 - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 640 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 702 641 703 642 类似的,如果你要计算某结构体成员的大小,使用 704 643 705 - #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) 644 + #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) 706 645 707 - 还有可以做严格的类型检查的min()和max()宏,如果你需要可以使用它们。你可以自己看看 646 + 还有可以做严格的类型检查的 min() 和 max() 宏,如果你需要可以使用它们。你可以自己看看 708 647 那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应在你的代码里 709 648 自己重新定义。 710 649 ··· 714 653 有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs 715 654 能够解释被标记成这样的行: 716 655 717 - -*- mode: c -*- 656 + -*- mode: c -*- 718 657 719 658 或者这样的: 720 659 721 - /* 722 - Local Variables: 723 - compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" 724 - End: 725 - */ 660 + /* 661 + Local Variables: 662 + compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" 663 + End: 664 + */ 726 665 727 - Vim能够解释这样的标记: 666 + Vim 能够解释这样的标记: 728 667 729 - /* vim:set sw=8 noet */ 668 + /* vim:set sw=8 noet */ 730 669 731 670 不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不应 732 671 该覆盖别人的配置。这包括有关缩进和模式配置的标记。人们可以使用他们自己定制的模 733 672 式,或者使用其他可以产生正确的缩进的巧妙方法。 734 673 735 674 675 + 第十九章:内联汇编 676 + 677 + 在特定架构的代码中,你也许需要内联汇编来使用 CPU 接口和平台相关功能。在需要 678 + 这么做时,不要犹豫。然而,当 C 可以完成工作时,不要无端地使用内联汇编。如果 679 + 可能,你可以并且应该用 C 和硬件交互。 680 + 681 + 考虑去写通用一点的内联汇编作为简明的辅助函数,而不是重复写下它们的细节。记住 682 + 内联汇编可以使用 C 参数。 683 + 684 + 大而特殊的汇编函数应该放在 .S 文件中,对应 C 的原型定义在 C 头文件中。汇编 685 + 函数的 C 原型应该使用 “asmlinkage”。 686 + 687 + 你可能需要将你的汇编语句标记为 volatile,来阻止 GCC 在没发现任何副作用后就 688 + 移除了它。你不必总是这样做,虽然,这样可以限制不必要的优化。 689 + 690 + 在写一个包含多条指令的单个内联汇编语句时,把每条指令用引号字符串分离,并写在 691 + 单独一行,在每个字符串结尾,除了 \n\t 结尾之外,在汇编输出中适当地缩进下 692 + 一条指令: 693 + 694 + asm ("magic %reg1, #42\n\t" 695 + "more_magic %reg2, %reg3" 696 + : /* outputs */ : /* inputs */ : /* clobbers */); 697 + 698 + 699 + 第二十章:条件编译 700 + 701 + 只要可能,就不要在 .c 文件里面使用预处理条件;这样做让代码更难阅读并且逻辑难以 702 + 跟踪。替代方案是,在头文件定义函数在这些 .c 文件中使用这类的条件表达式,提供空 703 + 操作的桩版本(译注:桩程序,是指用来替换一部分功能的程序段)在 #else 情况下, 704 + 再从 .c 文件中无条件地调用这些函数。编译器会避免生成任何桩调用的代码,产生一致 705 + 的结果,但逻辑将更加清晰。 706 + 707 + 宁可编译整个函数,而不是部分函数或部分表达式。而不是在一个表达式添加 ifdef, 708 + 解析部分或全部表达式到一个单独的辅助函数,并应用条件到该函数内。 709 + 710 + 如果你有一个在特定配置中可能是未使用的函数或变量,编译器将警告它定义了但未使用, 711 + 标记这个定义为 __maybe_unused 而不是将它包含在一个预处理条件中。(然而,如果 712 + 一个函数或变量总是未使用的,就直接删除它。) 713 + 714 + 在代码中,可能的情况下,使用 IS_ENABLED 宏来转化某个 Kconfig 标记为 C 的布尔 715 + 表达式,并在正常的 C 条件中使用它: 716 + 717 + if (IS_ENABLED(CONFIG_SOMETHING)) { 718 + ... 719 + } 720 + 721 + 编译器会无条件地做常数合并,就像使用 #ifdef 那样,包含或排除代码块,所以这不会 722 + 带来任何运行时开销。然而,这种方法依旧允许 C 编译器查看块内的代码,并检查它的正确 723 + 性(语法,类型,符号引用,等等)。因此,如果条件不满足,代码块内的引用符号将不存在, 724 + 你必须继续使用 #ifdef。 725 + 726 + 在任何有意义的 #if 或 #ifdef 块的末尾(超过几行),在 #endif 同一行的后面写下 727 + 注释,指出该条件表达式被使用。例如: 728 + 729 + #ifdef CONFIG_SOMETHING 730 + ... 731 + #endif /* CONFIG_SOMETHING */ 732 + 736 733 737 734 附录 I:参考 738 735 739 - The C Programming Language, 第二版, 作者Brian W. Kernighan和Denni 740 - M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (软皮), 741 - 0-13-110370-9 (硬皮). URL: http://cm.bell-labs.com/cm/cs/cbook/ 736 + The C Programming Language, 第二版 737 + 作者:Brian W. Kernighan 和 Denni M. Ritchie. 738 + Prentice Hall, Inc., 1988. 739 + ISBN 0-13-110362-8 (软皮), 0-13-110370-9 (硬皮). 742 740 743 - The Practice of Programming 作者Brian W. Kernighan和Rob Pike. Addison-Wesley, 744 - Inc., 1999. ISBN 0-201-61586-X. URL: http://cm.bell-labs.com/cm/cs/tpop/ 741 + The Practice of Programming 742 + 作者:Brian W. Kernighan 和 Rob Pike. 743 + Addison-Wesley, Inc., 1999. 744 + ISBN 0-201-61586-X. 745 745 746 - cpp,gcc,gcc internals和indent的GNU手册——和K&R及本文相符合的部分,全部可以在 747 - http://www.gnu.org/manual/找到 746 + GNU 手册 - 遵循 K&R 标准和此文本 - cpp, gcc, gcc internals and indent, 747 + 都可以从 http://www.gnu.org/manual/ 找到 748 748 749 749 WG14是C语言的国际标准化工作组,URL: http://www.open-std.org/JTC1/SC22/WG14/ 750 750 751 - Kernel CodingStyle,作者greg@kroah.com发表于OLS 2002: 751 + Kernel CodingStyle,作者 greg@kroah.com 发表于OLS 2002: 752 752 http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ 753 - 754 - -- 755 - 最后更新于2007年7月13日。
+4 -1
Makefile
··· 1412 1412 1413 1413 # Documentation targets 1414 1414 # --------------------------------------------------------------------------- 1415 - %docs: scripts_basic FORCE 1415 + DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs 1416 + PHONY += $(DOC_TARGETS) 1417 + $(DOC_TARGETS): scripts_basic FORCE 1416 1418 $(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype 1419 + $(Q)$(MAKE) $(build)=Documentation -f $(srctree)/Documentation/Makefile.sphinx $@ 1417 1420 $(Q)$(MAKE) $(build)=Documentation/DocBook $@ 1418 1421 1419 1422 else # KBUILD_EXTMOD
+3 -2
drivers/gpu/drm/Makefile
··· 8 8 drm_lock.o drm_memory.o drm_drv.o drm_vm.o \ 9 9 drm_scatter.o drm_pci.o \ 10 10 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ 11 - drm_crtc.o drm_modes.o drm_edid.o \ 11 + drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ 12 12 drm_info.o drm_debugfs.o drm_encoder_slave.o \ 13 13 drm_trace_points.o drm_global.o drm_prime.o \ 14 14 drm_rect.o drm_vma_manager.o drm_flip_work.o \ ··· 23 23 24 24 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 25 25 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ 26 - drm_kms_helper_common.o drm_dp_dual_mode_helper.o 26 + drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ 27 + drm_simple_kms_helper.o 27 28 28 29 drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 29 30 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
··· 268 268 return 0; 269 269 270 270 vblank_cleanup: 271 - drm_crtc_vblank_put(&amdgpu_crtc->base); 271 + drm_crtc_vblank_put(crtc); 272 272 273 273 pflip_cleanup: 274 274 if (unlikely(amdgpu_bo_reserve(new_rbo, false) != 0)) {
+2 -2
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
··· 2719 2719 type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); 2720 2720 amdgpu_irq_update(adev, &adev->crtc_irq, type); 2721 2721 amdgpu_irq_update(adev, &adev->pageflip_irq, type); 2722 - drm_vblank_on(dev, amdgpu_crtc->crtc_id); 2722 + drm_crtc_vblank_on(crtc); 2723 2723 dce_v10_0_crtc_load_lut(crtc); 2724 2724 break; 2725 2725 case DRM_MODE_DPMS_STANDBY: 2726 2726 case DRM_MODE_DPMS_SUSPEND: 2727 2727 case DRM_MODE_DPMS_OFF: 2728 - drm_vblank_off(dev, amdgpu_crtc->crtc_id); 2728 + drm_crtc_vblank_off(crtc); 2729 2729 if (amdgpu_crtc->enabled) { 2730 2730 dce_v10_0_vga_enable(crtc, true); 2731 2731 amdgpu_atombios_crtc_blank(crtc, ATOM_ENABLE);
+2 -2
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
··· 2730 2730 type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); 2731 2731 amdgpu_irq_update(adev, &adev->crtc_irq, type); 2732 2732 amdgpu_irq_update(adev, &adev->pageflip_irq, type); 2733 - drm_vblank_on(dev, amdgpu_crtc->crtc_id); 2733 + drm_crtc_vblank_on(crtc); 2734 2734 dce_v11_0_crtc_load_lut(crtc); 2735 2735 break; 2736 2736 case DRM_MODE_DPMS_STANDBY: 2737 2737 case DRM_MODE_DPMS_SUSPEND: 2738 2738 case DRM_MODE_DPMS_OFF: 2739 - drm_vblank_off(dev, amdgpu_crtc->crtc_id); 2739 + drm_crtc_vblank_off(crtc); 2740 2740 if (amdgpu_crtc->enabled) { 2741 2741 dce_v11_0_vga_enable(crtc, true); 2742 2742 amdgpu_atombios_crtc_blank(crtc, ATOM_ENABLE);
+2 -2
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
··· 2626 2626 type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); 2627 2627 amdgpu_irq_update(adev, &adev->crtc_irq, type); 2628 2628 amdgpu_irq_update(adev, &adev->pageflip_irq, type); 2629 - drm_vblank_on(dev, amdgpu_crtc->crtc_id); 2629 + drm_crtc_vblank_on(crtc); 2630 2630 dce_v8_0_crtc_load_lut(crtc); 2631 2631 break; 2632 2632 case DRM_MODE_DPMS_STANDBY: 2633 2633 case DRM_MODE_DPMS_SUSPEND: 2634 2634 case DRM_MODE_DPMS_OFF: 2635 - drm_vblank_off(dev, amdgpu_crtc->crtc_id); 2635 + drm_crtc_vblank_off(crtc); 2636 2636 if (amdgpu_crtc->enabled) { 2637 2637 dce_v8_0_vga_enable(crtc, true); 2638 2638 amdgpu_atombios_crtc_blank(crtc, ATOM_ENABLE);
-1
drivers/gpu/drm/arc/arcpgu.h
··· 22 22 struct clk *clk; 23 23 struct drm_fbdev_cma *fbdev; 24 24 struct drm_framebuffer *fb; 25 - struct list_head event_list; 26 25 struct drm_crtc crtc; 27 26 struct drm_plane *plane; 28 27 };
+5 -11
drivers/gpu/drm/arc/arcpgu_crtc.c
··· 145 145 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc, 146 146 struct drm_crtc_state *state) 147 147 { 148 - struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc); 149 - unsigned long flags; 148 + struct drm_pending_vblank_event *event = crtc->state->event; 150 149 151 - if (crtc->state->event) { 152 - struct drm_pending_vblank_event *event = crtc->state->event; 153 - 150 + if (event) { 154 151 crtc->state->event = NULL; 155 - event->pipe = drm_crtc_index(crtc); 156 152 157 - WARN_ON(drm_crtc_vblank_get(crtc) != 0); 158 - 159 - spin_lock_irqsave(&crtc->dev->event_lock, flags); 160 - list_add_tail(&event->base.link, &arcpgu->event_list); 161 - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 153 + spin_lock_irq(&crtc->dev->event_lock); 154 + drm_crtc_send_vblank_event(crtc, event); 155 + spin_unlock_irq(&crtc->dev->event_lock); 162 156 } 163 157 } 164 158
+1 -26
drivers/gpu/drm/arc/arcpgu_drv.c
··· 32 32 drm_fbdev_cma_hotplug_event(arcpgu->fbdev); 33 33 } 34 34 35 - static int arcpgu_atomic_commit(struct drm_device *dev, 36 - struct drm_atomic_state *state, bool async) 37 - { 38 - return drm_atomic_helper_commit(dev, state, false); 39 - } 40 - 41 35 static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { 42 36 .fb_create = drm_fb_cma_create, 43 37 .output_poll_changed = arcpgu_fb_output_poll_changed, 44 38 .atomic_check = drm_atomic_helper_check, 45 - .atomic_commit = arcpgu_atomic_commit, 39 + .atomic_commit = drm_atomic_helper_commit, 46 40 }; 47 41 48 42 static void arcpgu_setup_mode_config(struct drm_device *drm) ··· 75 81 .mmap = arcpgu_gem_mmap, 76 82 }; 77 83 78 - static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file) 79 - { 80 - struct arcpgu_drm_private *arcpgu = drm->dev_private; 81 - struct drm_pending_vblank_event *e, *t; 82 - unsigned long flags; 83 - 84 - spin_lock_irqsave(&drm->event_lock, flags); 85 - list_for_each_entry_safe(e, t, &arcpgu->event_list, base.link) { 86 - if (e->base.file_priv != file) 87 - continue; 88 - list_del(&e->base.link); 89 - kfree(&e->base); 90 - } 91 - spin_unlock_irqrestore(&drm->event_lock, flags); 92 - } 93 - 94 84 static void arcpgu_lastclose(struct drm_device *drm) 95 85 { 96 86 struct arcpgu_drm_private *arcpgu = drm->dev_private; ··· 99 121 arcpgu->clk = devm_clk_get(drm->dev, "pxlclk"); 100 122 if (IS_ERR(arcpgu->clk)) 101 123 return PTR_ERR(arcpgu->clk); 102 - 103 - INIT_LIST_HEAD(&arcpgu->event_list); 104 124 105 125 arcpgu_setup_mode_config(drm); 106 126 ··· 169 193 static struct drm_driver arcpgu_drm_driver = { 170 194 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | 171 195 DRIVER_ATOMIC, 172 - .preclose = arcpgu_preclose, 173 196 .lastclose = arcpgu_lastclose, 174 197 .name = "drm-arcpgu", 175 198 .desc = "ARC PGU Controller",
-18
drivers/gpu/drm/arc/arcpgu_hdmi.c
··· 46 46 return sfuncs->get_modes(&slave->base, connector); 47 47 } 48 48 49 - struct drm_encoder * 50 - arcpgu_drm_connector_best_encoder(struct drm_connector *connector) 51 - { 52 - struct drm_encoder_slave *slave; 53 - struct arcpgu_drm_connector *con = 54 - container_of(connector, struct arcpgu_drm_connector, connector); 55 - 56 - slave = con->encoder_slave; 57 - if (slave == NULL) { 58 - dev_err(connector->dev->dev, 59 - "connector_best_encoder: cannot find slave encoder for connector\n"); 60 - return NULL; 61 - } 62 - 63 - return &slave->base; 64 - } 65 - 66 49 static enum drm_connector_status 67 50 arcpgu_drm_connector_detect(struct drm_connector *connector, bool force) 68 51 { ··· 80 97 static const struct drm_connector_helper_funcs 81 98 arcpgu_drm_connector_helper_funcs = { 82 99 .get_modes = arcpgu_drm_connector_get_modes, 83 - .best_encoder = arcpgu_drm_connector_best_encoder, 84 100 }; 85 101 86 102 static const struct drm_connector_funcs arcpgu_drm_connector_funcs = {
+1 -7
drivers/gpu/drm/arm/hdlcd_drv.c
··· 106 106 drm_fbdev_cma_hotplug_event(hdlcd->fbdev); 107 107 } 108 108 109 - static int hdlcd_atomic_commit(struct drm_device *dev, 110 - struct drm_atomic_state *state, bool nonblock) 111 - { 112 - return drm_atomic_helper_commit(dev, state, false); 113 - } 114 - 115 109 static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = { 116 110 .fb_create = drm_fb_cma_create, 117 111 .output_poll_changed = hdlcd_fb_output_poll_changed, 118 112 .atomic_check = drm_atomic_helper_check, 119 - .atomic_commit = hdlcd_atomic_commit, 113 + .atomic_commit = drm_atomic_helper_commit, 120 114 }; 121 115 122 116 static void hdlcd_setup_mode_config(struct drm_device *drm)
+1 -1
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
··· 519 519 } 520 520 521 521 /* Swap the state, this is the point of no return. */ 522 - drm_atomic_helper_swap_state(dev, state); 522 + drm_atomic_helper_swap_state(state, true); 523 523 524 524 if (async) 525 525 queue_work(dc->wq, &commit->work);
-12
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
··· 113 113 return atmel_hlcdc_dc_mode_valid(rgb->dc, mode); 114 114 } 115 115 116 - 117 - 118 - static struct drm_encoder * 119 - atmel_hlcdc_rgb_best_encoder(struct drm_connector *connector) 120 - { 121 - struct atmel_hlcdc_rgb_output *rgb = 122 - drm_connector_to_atmel_hlcdc_rgb_output(connector); 123 - 124 - return &rgb->encoder; 125 - } 126 - 127 116 static const struct drm_connector_helper_funcs atmel_hlcdc_panel_connector_helper_funcs = { 128 117 .get_modes = atmel_hlcdc_panel_get_modes, 129 118 .mode_valid = atmel_hlcdc_rgb_mode_valid, 130 - .best_encoder = atmel_hlcdc_rgb_best_encoder, 131 119 }; 132 120 133 121 static enum drm_connector_status
-8
drivers/gpu/drm/bridge/analogix-anx78xx.c
··· 986 986 return num_modes; 987 987 } 988 988 989 - static struct drm_encoder *anx78xx_best_encoder(struct drm_connector *connector) 990 - { 991 - struct anx78xx *anx78xx = connector_to_anx78xx(connector); 992 - 993 - return anx78xx->bridge.encoder; 994 - } 995 - 996 989 static const struct drm_connector_helper_funcs anx78xx_connector_helper_funcs = { 997 990 .get_modes = anx78xx_get_modes, 998 - .best_encoder = anx78xx_best_encoder, 999 991 }; 1000 992 1001 993 static enum drm_connector_status anx78xx_detect(struct drm_connector *connector,
+1 -10
drivers/gpu/drm/bridge/dw-hdmi.c
··· 1476 1476 return mode_status; 1477 1477 } 1478 1478 1479 - static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector 1480 - *connector) 1481 - { 1482 - struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, 1483 - connector); 1484 - 1485 - return hdmi->encoder; 1486 - } 1487 - 1488 1479 static void dw_hdmi_connector_destroy(struct drm_connector *connector) 1489 1480 { 1490 1481 drm_connector_unregister(connector); ··· 1516 1525 static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { 1517 1526 .get_modes = dw_hdmi_connector_get_modes, 1518 1527 .mode_valid = dw_hdmi_connector_mode_valid, 1519 - .best_encoder = dw_hdmi_connector_best_encoder, 1528 + .best_encoder = drm_atomic_helper_best_encoder, 1520 1529 }; 1521 1530 1522 1531 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
-8
drivers/gpu/drm/bridge/nxp-ptn3460.c
··· 235 235 return num_modes; 236 236 } 237 237 238 - static struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector) 239 - { 240 - struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector); 241 - 242 - return ptn_bridge->bridge.encoder; 243 - } 244 - 245 238 static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = { 246 239 .get_modes = ptn3460_get_modes, 247 - .best_encoder = ptn3460_best_encoder, 248 240 }; 249 241 250 242 static enum drm_connector_status ptn3460_detect(struct drm_connector *connector,
-10
drivers/gpu/drm/bridge/parade-ps8622.c
··· 474 474 return drm_panel_get_modes(ps8622->panel); 475 475 } 476 476 477 - static struct drm_encoder *ps8622_best_encoder(struct drm_connector *connector) 478 - { 479 - struct ps8622_bridge *ps8622; 480 - 481 - ps8622 = connector_to_ps8622(connector); 482 - 483 - return ps8622->bridge.encoder; 484 - } 485 - 486 477 static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = { 487 478 .get_modes = ps8622_get_modes, 488 - .best_encoder = ps8622_best_encoder, 489 479 }; 490 480 491 481 static enum drm_connector_status ps8622_detect(struct drm_connector *connector,
+22
drivers/gpu/drm/drm_atomic.c
··· 33 33 34 34 #include "drm_crtc_internal.h" 35 35 36 + static void crtc_commit_free(struct kref *kref) 37 + { 38 + struct drm_crtc_commit *commit = 39 + container_of(kref, struct drm_crtc_commit, ref); 40 + 41 + kfree(commit); 42 + } 43 + 44 + void drm_crtc_commit_put(struct drm_crtc_commit *commit) 45 + { 46 + kref_put(&commit->ref, crtc_commit_free); 47 + } 48 + EXPORT_SYMBOL(drm_crtc_commit_put); 49 + 36 50 /** 37 51 * drm_atomic_state_default_release - 38 52 * release memory initialized by drm_atomic_state_init ··· 162 148 163 149 crtc->funcs->atomic_destroy_state(crtc, 164 150 state->crtcs[i].state); 151 + 152 + if (state->crtcs[i].commit) { 153 + kfree(state->crtcs[i].commit->event); 154 + state->crtcs[i].commit->event = NULL; 155 + drm_crtc_commit_put(state->crtcs[i].commit); 156 + } 157 + 158 + state->crtcs[i].commit = NULL; 165 159 state->crtcs[i].ptr = NULL; 166 160 state->crtcs[i].state = NULL; 167 161 }
+444 -47
drivers/gpu/drm/drm_atomic_helper.c
··· 465 465 * times for the same update, e.g. when the ->atomic_check functions depend upon 466 466 * the adjusted dotclock for fifo space allocation and watermark computation. 467 467 * 468 - * RETURNS 468 + * RETURNS: 469 469 * Zero for success or -errno 470 470 */ 471 471 int ··· 579 579 * It also sets crtc_state->planes_changed to indicate that a crtc has 580 580 * updated planes. 581 581 * 582 - * RETURNS 582 + * RETURNS: 583 583 * Zero for success or -errno 584 584 */ 585 585 int ··· 647 647 * ->atomic_check functions depend upon an updated adjusted_mode.clock to 648 648 * e.g. properly compute watermarks. 649 649 * 650 - * RETURNS 650 + * RETURNS: 651 651 * Zero for success or -errno 652 652 */ 653 653 int drm_atomic_helper_check(struct drm_device *dev, ··· 1120 1120 EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks); 1121 1121 1122 1122 /** 1123 - * drm_atomic_helper_commit - commit validated state object 1124 - * @dev: DRM device 1125 - * @state: the driver state object 1126 - * @nonblocking: whether nonblocking behavior is requested. 1123 + * drm_atomic_helper_commit_tail - commit atomic update to hardware 1124 + * @state: new modeset state to be committed 1127 1125 * 1128 - * This function commits a with drm_atomic_helper_check() pre-validated state 1129 - * object. This can still fail when e.g. the framebuffer reservation fails. For 1130 - * now this doesn't implement nonblocking commits. 1126 + * This is the default implemenation for the ->atomic_commit_tail() hook of the 1127 + * &drm_mode_config_helper_funcs vtable. 1131 1128 * 1132 - * Note that right now this function does not support nonblocking commits, hence 1133 - * driver writers must implement their own version for now. Also note that the 1134 - * default ordering of how the various stages are called is to match the legacy 1135 - * modeset helper library closest. One peculiarity of that is that it doesn't 1136 - * mesh well with runtime PM at all. 1129 + * Note that the default ordering of how the various stages are called is to 1130 + * match the legacy modeset helper library closest. One peculiarity of that is 1131 + * that it doesn't mesh well with runtime PM at all. 1137 1132 * 1138 - * For drivers supporting runtime PM the recommended sequence is 1133 + * For drivers supporting runtime PM the recommended sequence is instead :: 1139 1134 * 1140 1135 * drm_atomic_helper_commit_modeset_disables(dev, state); 1141 1136 * ··· 1138 1143 * 1139 1144 * drm_atomic_helper_commit_planes(dev, state, true); 1140 1145 * 1141 - * See the kerneldoc entries for these three functions for more details. 1146 + * for committing the atomic update to hardware. See the kerneldoc entries for 1147 + * these three functions for more details. 1148 + */ 1149 + void drm_atomic_helper_commit_tail(struct drm_atomic_state *state) 1150 + { 1151 + struct drm_device *dev = state->dev; 1152 + 1153 + drm_atomic_helper_commit_modeset_disables(dev, state); 1154 + 1155 + drm_atomic_helper_commit_planes(dev, state, false); 1156 + 1157 + drm_atomic_helper_commit_modeset_enables(dev, state); 1158 + 1159 + drm_atomic_helper_commit_hw_done(state); 1160 + 1161 + drm_atomic_helper_wait_for_vblanks(dev, state); 1162 + 1163 + drm_atomic_helper_cleanup_planes(dev, state); 1164 + } 1165 + EXPORT_SYMBOL(drm_atomic_helper_commit_tail); 1166 + 1167 + static void commit_tail(struct drm_atomic_state *state) 1168 + { 1169 + struct drm_device *dev = state->dev; 1170 + struct drm_mode_config_helper_funcs *funcs; 1171 + 1172 + funcs = dev->mode_config.helper_private; 1173 + 1174 + drm_atomic_helper_wait_for_fences(dev, state); 1175 + 1176 + drm_atomic_helper_wait_for_dependencies(state); 1177 + 1178 + if (funcs && funcs->atomic_commit_tail) 1179 + funcs->atomic_commit_tail(state); 1180 + else 1181 + drm_atomic_helper_commit_tail(state); 1182 + 1183 + drm_atomic_helper_commit_cleanup_done(state); 1184 + 1185 + drm_atomic_state_free(state); 1186 + } 1187 + 1188 + static void commit_work(struct work_struct *work) 1189 + { 1190 + struct drm_atomic_state *state = container_of(work, 1191 + struct drm_atomic_state, 1192 + commit_work); 1193 + commit_tail(state); 1194 + } 1195 + 1196 + /** 1197 + * drm_atomic_helper_commit - commit validated state object 1198 + * @dev: DRM device 1199 + * @state: the driver state object 1200 + * @nonblock: whether nonblocking behavior is requested. 1142 1201 * 1143 - * RETURNS 1202 + * This function commits a with drm_atomic_helper_check() pre-validated state 1203 + * object. This can still fail when e.g. the framebuffer reservation fails. This 1204 + * function implements nonblocking commits, using 1205 + * drm_atomic_helper_setup_commit() and related functions. 1206 + * 1207 + * Note that right now this function does not support nonblocking commits, hence 1208 + * driver writers must implement their own version for now. 1209 + * 1210 + * Committing the actual hardware state is done through the 1211 + * ->atomic_commit_tail() callback of the &drm_mode_config_helper_funcs vtable, 1212 + * or it's default implementation drm_atomic_helper_commit_tail(). 1213 + * 1214 + * RETURNS: 1144 1215 * Zero for success or -errno. 1145 1216 */ 1146 1217 int drm_atomic_helper_commit(struct drm_device *dev, ··· 1215 1154 { 1216 1155 int ret; 1217 1156 1218 - if (nonblock) 1219 - return -EBUSY; 1157 + ret = drm_atomic_helper_setup_commit(state, nonblock); 1158 + if (ret) 1159 + return ret; 1160 + 1161 + INIT_WORK(&state->commit_work, commit_work); 1220 1162 1221 1163 ret = drm_atomic_helper_prepare_planes(dev, state); 1222 1164 if (ret) ··· 1231 1167 * the software side now. 1232 1168 */ 1233 1169 1234 - drm_atomic_helper_swap_state(dev, state); 1170 + drm_atomic_helper_swap_state(state, true); 1235 1171 1236 1172 /* 1237 1173 * Everything below can be run asynchronously without the need to grab ··· 1247 1183 * update. Which is important since compositors need to figure out the 1248 1184 * composition of the next frame right after having submitted the 1249 1185 * current layout. 1186 + * 1187 + * NOTE: Commit work has multiple phases, first hardware commit, then 1188 + * cleanup. We want them to overlap, hence need system_unbound_wq to 1189 + * make sure work items don't artifically stall on each another. 1250 1190 */ 1251 1191 1252 - drm_atomic_helper_wait_for_fences(dev, state); 1253 - 1254 - drm_atomic_helper_commit_modeset_disables(dev, state); 1255 - 1256 - drm_atomic_helper_commit_planes(dev, state, false); 1257 - 1258 - drm_atomic_helper_commit_modeset_enables(dev, state); 1259 - 1260 - drm_atomic_helper_wait_for_vblanks(dev, state); 1261 - 1262 - drm_atomic_helper_cleanup_planes(dev, state); 1263 - 1264 - drm_atomic_state_free(state); 1192 + if (nonblock) 1193 + queue_work(system_unbound_wq, &state->commit_work); 1194 + else 1195 + commit_tail(state); 1265 1196 1266 1197 return 0; 1267 1198 } ··· 1265 1206 /** 1266 1207 * DOC: implementing nonblocking commit 1267 1208 * 1268 - * For now the atomic helpers don't support nonblocking commit directly. If 1269 - * there is real need it could be added though, using the dma-buf fence 1270 - * infrastructure for generic synchronization with outstanding rendering. 1271 - * 1272 - * For now drivers have to implement nonblocking commit themselves, with the 1273 - * following sequence being the recommended one: 1209 + * Nonblocking atomic commits have to be implemented in the following sequence: 1274 1210 * 1275 1211 * 1. Run drm_atomic_helper_prepare_planes() first. This is the only function 1276 1212 * which commit needs to call which can fail, so we want to run it first and ··· 1277 1223 * cancelled updates. Note that it is important to ensure that the framebuffer 1278 1224 * cleanup is still done when cancelling. 1279 1225 * 1280 - * For sufficient parallelism it is recommended to have a work item per crtc 1281 - * (for updates which don't touch global state) and a global one. Then we only 1282 - * need to synchronize with the crtc work items for changed crtcs and the global 1283 - * work item, which allows nice concurrent updates on disjoint sets of crtcs. 1226 + * Asynchronous workers need to have sufficient parallelism to be able to run 1227 + * different atomic commits on different CRTCs in parallel. The simplest way to 1228 + * achive this is by running them on the &system_unbound_wq work queue. Note 1229 + * that drivers are not required to split up atomic commits and run an 1230 + * individual commit in parallel - userspace is supposed to do that if it cares. 1231 + * But it might be beneficial to do that for modesets, since those necessarily 1232 + * must be done as one global operation, and enabling or disabling a CRTC can 1233 + * take a long time. But even that is not required. 1284 1234 * 1285 1235 * 3. The software state is updated synchronously with 1286 1236 * drm_atomic_helper_swap_state(). Doing this under the protection of all modeset ··· 1297 1239 * commit helpers: a) pre-plane commit b) plane commit c) post-plane commit and 1298 1240 * then cleaning up the framebuffers after the old framebuffer is no longer 1299 1241 * being displayed. 1242 + * 1243 + * The above scheme is implemented in the atomic helper libraries in 1244 + * drm_atomic_helper_commit() using a bunch of helper functions. See 1245 + * drm_atomic_helper_setup_commit() for a starting point. 1300 1246 */ 1247 + 1248 + static int stall_checks(struct drm_crtc *crtc, bool nonblock) 1249 + { 1250 + struct drm_crtc_commit *commit, *stall_commit = NULL; 1251 + bool completed = true; 1252 + int i; 1253 + long ret = 0; 1254 + 1255 + spin_lock(&crtc->commit_lock); 1256 + i = 0; 1257 + list_for_each_entry(commit, &crtc->commit_list, commit_entry) { 1258 + if (i == 0) { 1259 + completed = try_wait_for_completion(&commit->flip_done); 1260 + /* Userspace is not allowed to get ahead of the previous 1261 + * commit with nonblocking ones. */ 1262 + if (!completed && nonblock) { 1263 + spin_unlock(&crtc->commit_lock); 1264 + return -EBUSY; 1265 + } 1266 + } else if (i == 1) { 1267 + stall_commit = commit; 1268 + drm_crtc_commit_get(stall_commit); 1269 + break; 1270 + } 1271 + 1272 + i++; 1273 + } 1274 + spin_unlock(&crtc->commit_lock); 1275 + 1276 + if (!stall_commit) 1277 + return 0; 1278 + 1279 + /* We don't want to let commits get ahead of cleanup work too much, 1280 + * stalling on 2nd previous commit means triple-buffer won't ever stall. 1281 + */ 1282 + ret = wait_for_completion_interruptible_timeout(&stall_commit->cleanup_done, 1283 + 10*HZ); 1284 + if (ret == 0) 1285 + DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n", 1286 + crtc->base.id, crtc->name); 1287 + 1288 + drm_crtc_commit_put(stall_commit); 1289 + 1290 + return ret < 0 ? ret : 0; 1291 + } 1292 + 1293 + /** 1294 + * drm_atomic_helper_setup_commit - setup possibly nonblocking commit 1295 + * @state: new modeset state to be committed 1296 + * @nonblock: whether nonblocking behavior is requested. 1297 + * 1298 + * This function prepares @state to be used by the atomic helper's support for 1299 + * nonblocking commits. Drivers using the nonblocking commit infrastructure 1300 + * should always call this function from their ->atomic_commit hook. 1301 + * 1302 + * To be able to use this support drivers need to use a few more helper 1303 + * functions. drm_atomic_helper_wait_for_dependencies() must be called before 1304 + * actually committing the hardware state, and for nonblocking commits this call 1305 + * must be placed in the async worker. See also drm_atomic_helper_swap_state() 1306 + * and it's stall parameter, for when a driver's commit hooks look at the 1307 + * ->state pointers of struct &drm_crtc, &drm_plane or &drm_connector directly. 1308 + * 1309 + * Completion of the hardware commit step must be signalled using 1310 + * drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed 1311 + * to read or change any permanent software or hardware modeset state. The only 1312 + * exception is state protected by other means than &drm_modeset_lock locks. 1313 + * Only the free standing @state with pointers to the old state structures can 1314 + * be inspected, e.g. to clean up old buffers using 1315 + * drm_atomic_helper_cleanup_planes(). 1316 + * 1317 + * At the very end, before cleaning up @state drivers must call 1318 + * drm_atomic_helper_commit_cleanup_done(). 1319 + * 1320 + * This is all implemented by in drm_atomic_helper_commit(), giving drivers a 1321 + * complete and esay-to-use default implementation of the atomic_commit() hook. 1322 + * 1323 + * The tracking of asynchronously executed and still pending commits is done 1324 + * using the core structure &drm_crtc_commit. 1325 + * 1326 + * By default there's no need to clean up resources allocated by this function 1327 + * explicitly: drm_atomic_state_default_clear() will take care of that 1328 + * automatically. 1329 + * 1330 + * Returns: 1331 + * 1332 + * 0 on success. -EBUSY when userspace schedules nonblocking commits too fast, 1333 + * -ENOMEM on allocation failures and -EINTR when a signal is pending. 1334 + */ 1335 + int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, 1336 + bool nonblock) 1337 + { 1338 + struct drm_crtc *crtc; 1339 + struct drm_crtc_state *crtc_state; 1340 + struct drm_crtc_commit *commit; 1341 + int i, ret; 1342 + 1343 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 1344 + commit = kzalloc(sizeof(*commit), GFP_KERNEL); 1345 + if (!commit) 1346 + return -ENOMEM; 1347 + 1348 + init_completion(&commit->flip_done); 1349 + init_completion(&commit->hw_done); 1350 + init_completion(&commit->cleanup_done); 1351 + INIT_LIST_HEAD(&commit->commit_entry); 1352 + kref_init(&commit->ref); 1353 + commit->crtc = crtc; 1354 + 1355 + state->crtcs[i].commit = commit; 1356 + 1357 + ret = stall_checks(crtc, nonblock); 1358 + if (ret) 1359 + return ret; 1360 + 1361 + /* Drivers only send out events when at least either current or 1362 + * new CRTC state is active. Complete right away if everything 1363 + * stays off. */ 1364 + if (!crtc->state->active && !crtc_state->active) { 1365 + complete_all(&commit->flip_done); 1366 + continue; 1367 + } 1368 + 1369 + /* Legacy cursor updates are fully unsynced. */ 1370 + if (state->legacy_cursor_update) { 1371 + complete_all(&commit->flip_done); 1372 + continue; 1373 + } 1374 + 1375 + if (!crtc_state->event) { 1376 + commit->event = kzalloc(sizeof(*commit->event), 1377 + GFP_KERNEL); 1378 + if (!commit->event) 1379 + return -ENOMEM; 1380 + 1381 + crtc_state->event = commit->event; 1382 + } 1383 + 1384 + crtc_state->event->base.completion = &commit->flip_done; 1385 + } 1386 + 1387 + return 0; 1388 + } 1389 + EXPORT_SYMBOL(drm_atomic_helper_setup_commit); 1390 + 1391 + 1392 + static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc) 1393 + { 1394 + struct drm_crtc_commit *commit; 1395 + int i = 0; 1396 + 1397 + list_for_each_entry(commit, &crtc->commit_list, commit_entry) { 1398 + /* skip the first entry, that's the current commit */ 1399 + if (i == 1) 1400 + return commit; 1401 + i++; 1402 + } 1403 + 1404 + return NULL; 1405 + } 1406 + 1407 + /** 1408 + * drm_atomic_helper_wait_for_dependencies - wait for required preceeding commits 1409 + * @state: new modeset state to be committed 1410 + * 1411 + * This function waits for all preceeding commits that touch the same CRTC as 1412 + * @state to both be committed to the hardware (as signalled by 1413 + * drm_atomic_helper_commit_hw_done) and executed by the hardware (as signalled 1414 + * by calling drm_crtc_vblank_send_event on the event member of 1415 + * &drm_crtc_state). 1416 + * 1417 + * This is part of the atomic helper support for nonblocking commits, see 1418 + * drm_atomic_helper_setup_commit() for an overview. 1419 + */ 1420 + void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state) 1421 + { 1422 + struct drm_crtc *crtc; 1423 + struct drm_crtc_state *crtc_state; 1424 + struct drm_crtc_commit *commit; 1425 + int i; 1426 + long ret; 1427 + 1428 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 1429 + spin_lock(&crtc->commit_lock); 1430 + commit = preceeding_commit(crtc); 1431 + if (commit) 1432 + drm_crtc_commit_get(commit); 1433 + spin_unlock(&crtc->commit_lock); 1434 + 1435 + if (!commit) 1436 + continue; 1437 + 1438 + ret = wait_for_completion_timeout(&commit->hw_done, 1439 + 10*HZ); 1440 + if (ret == 0) 1441 + DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n", 1442 + crtc->base.id, crtc->name); 1443 + 1444 + /* Currently no support for overwriting flips, hence 1445 + * stall for previous one to execute completely. */ 1446 + ret = wait_for_completion_timeout(&commit->flip_done, 1447 + 10*HZ); 1448 + if (ret == 0) 1449 + DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", 1450 + crtc->base.id, crtc->name); 1451 + 1452 + drm_crtc_commit_put(commit); 1453 + } 1454 + } 1455 + EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); 1456 + 1457 + /** 1458 + * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit 1459 + * @state: new modeset state to be committed 1460 + * 1461 + * This function is used to signal completion of the hardware commit step. After 1462 + * this step the driver is not allowed to read or change any permanent software 1463 + * or hardware modeset state. The only exception is state protected by other 1464 + * means than &drm_modeset_lock locks. 1465 + * 1466 + * Drivers should try to postpone any expensive or delayed cleanup work after 1467 + * this function is called. 1468 + * 1469 + * This is part of the atomic helper support for nonblocking commits, see 1470 + * drm_atomic_helper_setup_commit() for an overview. 1471 + */ 1472 + void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state) 1473 + { 1474 + struct drm_crtc *crtc; 1475 + struct drm_crtc_state *crtc_state; 1476 + struct drm_crtc_commit *commit; 1477 + int i; 1478 + 1479 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 1480 + commit = state->crtcs[i].commit; 1481 + if (!commit) 1482 + continue; 1483 + 1484 + /* backend must have consumed any event by now */ 1485 + WARN_ON(crtc->state->event); 1486 + spin_lock(&crtc->commit_lock); 1487 + complete_all(&commit->hw_done); 1488 + spin_unlock(&crtc->commit_lock); 1489 + } 1490 + } 1491 + EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done); 1492 + 1493 + /** 1494 + * drm_atomic_helper_commit_cleanup_done - signal completion of commit 1495 + * @state: new modeset state to be committed 1496 + * 1497 + * This signals completion of the atomic update @state, including any cleanup 1498 + * work. If used, it must be called right before calling 1499 + * drm_atomic_state_free(). 1500 + * 1501 + * This is part of the atomic helper support for nonblocking commits, see 1502 + * drm_atomic_helper_setup_commit() for an overview. 1503 + */ 1504 + void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state) 1505 + { 1506 + struct drm_crtc *crtc; 1507 + struct drm_crtc_state *crtc_state; 1508 + struct drm_crtc_commit *commit; 1509 + int i; 1510 + long ret; 1511 + 1512 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 1513 + commit = state->crtcs[i].commit; 1514 + if (WARN_ON(!commit)) 1515 + continue; 1516 + 1517 + spin_lock(&crtc->commit_lock); 1518 + complete_all(&commit->cleanup_done); 1519 + WARN_ON(!try_wait_for_completion(&commit->hw_done)); 1520 + 1521 + /* commit_list borrows our reference, need to remove before we 1522 + * clean up our drm_atomic_state. But only after it actually 1523 + * completed, otherwise subsequent commits won't stall properly. */ 1524 + if (try_wait_for_completion(&commit->flip_done)) 1525 + goto del_commit; 1526 + 1527 + spin_unlock(&crtc->commit_lock); 1528 + 1529 + /* We must wait for the vblank event to signal our completion 1530 + * before releasing our reference, since the vblank work does 1531 + * not hold a reference of its own. */ 1532 + ret = wait_for_completion_timeout(&commit->flip_done, 1533 + 10*HZ); 1534 + if (ret == 0) 1535 + DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", 1536 + crtc->base.id, crtc->name); 1537 + 1538 + spin_lock(&crtc->commit_lock); 1539 + del_commit: 1540 + list_del(&commit->commit_entry); 1541 + spin_unlock(&crtc->commit_lock); 1542 + } 1543 + } 1544 + EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done); 1301 1545 1302 1546 /** 1303 1547 * drm_atomic_helper_prepare_planes - prepare plane resources before commit ··· 1898 1538 1899 1539 /** 1900 1540 * drm_atomic_helper_swap_state - store atomic state into current sw state 1901 - * @dev: DRM device 1902 1541 * @state: atomic state 1542 + * @stall: stall for proceeding commits 1903 1543 * 1904 1544 * This function stores the atomic state into the current state pointers in all 1905 1545 * driver objects. It should be called after all failing steps have been done ··· 1920 1560 * 1921 1561 * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3 1922 1562 * contains the old state. Also do any other cleanup required with that state. 1563 + * 1564 + * @stall must be set when nonblocking commits for this driver directly access 1565 + * the ->state pointer of &drm_plane, &drm_crtc or &drm_connector. With the 1566 + * current atomic helpers this is almost always the case, since the helpers 1567 + * don't pass the right state structures to the callbacks. 1923 1568 */ 1924 - void drm_atomic_helper_swap_state(struct drm_device *dev, 1925 - struct drm_atomic_state *state) 1569 + void drm_atomic_helper_swap_state(struct drm_atomic_state *state, 1570 + bool stall) 1926 1571 { 1927 1572 int i; 1573 + long ret; 1928 1574 struct drm_connector *connector; 1929 1575 struct drm_connector_state *conn_state; 1930 1576 struct drm_crtc *crtc; 1931 1577 struct drm_crtc_state *crtc_state; 1932 1578 struct drm_plane *plane; 1933 1579 struct drm_plane_state *plane_state; 1580 + struct drm_crtc_commit *commit; 1581 + 1582 + if (stall) { 1583 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 1584 + spin_lock(&crtc->commit_lock); 1585 + commit = list_first_entry_or_null(&crtc->commit_list, 1586 + struct drm_crtc_commit, commit_entry); 1587 + if (commit) 1588 + drm_crtc_commit_get(commit); 1589 + spin_unlock(&crtc->commit_lock); 1590 + 1591 + if (!commit) 1592 + continue; 1593 + 1594 + ret = wait_for_completion_timeout(&commit->hw_done, 1595 + 10*HZ); 1596 + if (ret == 0) 1597 + DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n", 1598 + crtc->base.id, crtc->name); 1599 + drm_crtc_commit_put(commit); 1600 + } 1601 + } 1934 1602 1935 1603 for_each_connector_in_state(state, connector, conn_state, i) { 1936 1604 connector->state->state = state; ··· 1970 1582 crtc->state->state = state; 1971 1583 swap(state->crtcs[i].state, crtc->state); 1972 1584 crtc->state->state = NULL; 1585 + 1586 + if (state->crtcs[i].commit) { 1587 + spin_lock(&crtc->commit_lock); 1588 + list_add(&state->crtcs[i].commit->commit_entry, 1589 + &crtc->commit_list); 1590 + spin_unlock(&crtc->commit_lock); 1591 + 1592 + state->crtcs[i].commit->event = NULL; 1593 + } 1973 1594 } 1974 1595 1975 1596 for_each_plane_in_state(state, plane, plane_state, i) {
+3 -289
drivers/gpu/drm/drm_crtc.c
··· 239 239 } 240 240 EXPORT_SYMBOL(drm_get_subpixel_order_name); 241 241 242 - static char printable_char(int c) 243 - { 244 - return isascii(c) && isprint(c) ? c : '?'; 245 - } 246 - 247 - /** 248 - * drm_get_format_name - return a string for drm fourcc format 249 - * @format: format to compute name of 250 - * 251 - * Note that the buffer used by this function is globally shared and owned by 252 - * the function itself. 253 - * 254 - * FIXME: This isn't really multithreading safe. 255 - */ 256 - const char *drm_get_format_name(uint32_t format) 257 - { 258 - static char buf[32]; 259 - 260 - snprintf(buf, sizeof(buf), 261 - "%c%c%c%c %s-endian (0x%08x)", 262 - printable_char(format & 0xff), 263 - printable_char((format >> 8) & 0xff), 264 - printable_char((format >> 16) & 0xff), 265 - printable_char((format >> 24) & 0x7f), 266 - format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", 267 - format); 268 - 269 - return buf; 270 - } 271 - EXPORT_SYMBOL(drm_get_format_name); 272 - 273 242 /* 274 243 * Internal function to assign a slot in the object idr and optionally 275 244 * register the object into the idr. ··· 637 668 638 669 crtc->dev = dev; 639 670 crtc->funcs = funcs; 671 + 672 + INIT_LIST_HEAD(&crtc->commit_list); 673 + spin_lock_init(&crtc->commit_lock); 640 674 641 675 drm_modeset_lock_init(&crtc->mutex); 642 676 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); ··· 5473 5501 5474 5502 return dev->driver->dumb_destroy(file_priv, dev, args->handle); 5475 5503 } 5476 - 5477 - /** 5478 - * drm_fb_get_bpp_depth - get the bpp/depth values for format 5479 - * @format: pixel format (DRM_FORMAT_*) 5480 - * @depth: storage for the depth value 5481 - * @bpp: storage for the bpp value 5482 - * 5483 - * This only supports RGB formats here for compat with code that doesn't use 5484 - * pixel formats directly yet. 5485 - */ 5486 - void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, 5487 - int *bpp) 5488 - { 5489 - switch (format) { 5490 - case DRM_FORMAT_C8: 5491 - case DRM_FORMAT_RGB332: 5492 - case DRM_FORMAT_BGR233: 5493 - *depth = 8; 5494 - *bpp = 8; 5495 - break; 5496 - case DRM_FORMAT_XRGB1555: 5497 - case DRM_FORMAT_XBGR1555: 5498 - case DRM_FORMAT_RGBX5551: 5499 - case DRM_FORMAT_BGRX5551: 5500 - case DRM_FORMAT_ARGB1555: 5501 - case DRM_FORMAT_ABGR1555: 5502 - case DRM_FORMAT_RGBA5551: 5503 - case DRM_FORMAT_BGRA5551: 5504 - *depth = 15; 5505 - *bpp = 16; 5506 - break; 5507 - case DRM_FORMAT_RGB565: 5508 - case DRM_FORMAT_BGR565: 5509 - *depth = 16; 5510 - *bpp = 16; 5511 - break; 5512 - case DRM_FORMAT_RGB888: 5513 - case DRM_FORMAT_BGR888: 5514 - *depth = 24; 5515 - *bpp = 24; 5516 - break; 5517 - case DRM_FORMAT_XRGB8888: 5518 - case DRM_FORMAT_XBGR8888: 5519 - case DRM_FORMAT_RGBX8888: 5520 - case DRM_FORMAT_BGRX8888: 5521 - *depth = 24; 5522 - *bpp = 32; 5523 - break; 5524 - case DRM_FORMAT_XRGB2101010: 5525 - case DRM_FORMAT_XBGR2101010: 5526 - case DRM_FORMAT_RGBX1010102: 5527 - case DRM_FORMAT_BGRX1010102: 5528 - case DRM_FORMAT_ARGB2101010: 5529 - case DRM_FORMAT_ABGR2101010: 5530 - case DRM_FORMAT_RGBA1010102: 5531 - case DRM_FORMAT_BGRA1010102: 5532 - *depth = 30; 5533 - *bpp = 32; 5534 - break; 5535 - case DRM_FORMAT_ARGB8888: 5536 - case DRM_FORMAT_ABGR8888: 5537 - case DRM_FORMAT_RGBA8888: 5538 - case DRM_FORMAT_BGRA8888: 5539 - *depth = 32; 5540 - *bpp = 32; 5541 - break; 5542 - default: 5543 - DRM_DEBUG_KMS("unsupported pixel format %s\n", 5544 - drm_get_format_name(format)); 5545 - *depth = 0; 5546 - *bpp = 0; 5547 - break; 5548 - } 5549 - } 5550 - EXPORT_SYMBOL(drm_fb_get_bpp_depth); 5551 - 5552 - /** 5553 - * drm_format_num_planes - get the number of planes for format 5554 - * @format: pixel format (DRM_FORMAT_*) 5555 - * 5556 - * Returns: 5557 - * The number of planes used by the specified pixel format. 5558 - */ 5559 - int drm_format_num_planes(uint32_t format) 5560 - { 5561 - switch (format) { 5562 - case DRM_FORMAT_YUV410: 5563 - case DRM_FORMAT_YVU410: 5564 - case DRM_FORMAT_YUV411: 5565 - case DRM_FORMAT_YVU411: 5566 - case DRM_FORMAT_YUV420: 5567 - case DRM_FORMAT_YVU420: 5568 - case DRM_FORMAT_YUV422: 5569 - case DRM_FORMAT_YVU422: 5570 - case DRM_FORMAT_YUV444: 5571 - case DRM_FORMAT_YVU444: 5572 - return 3; 5573 - case DRM_FORMAT_NV12: 5574 - case DRM_FORMAT_NV21: 5575 - case DRM_FORMAT_NV16: 5576 - case DRM_FORMAT_NV61: 5577 - case DRM_FORMAT_NV24: 5578 - case DRM_FORMAT_NV42: 5579 - return 2; 5580 - default: 5581 - return 1; 5582 - } 5583 - } 5584 - EXPORT_SYMBOL(drm_format_num_planes); 5585 - 5586 - /** 5587 - * drm_format_plane_cpp - determine the bytes per pixel value 5588 - * @format: pixel format (DRM_FORMAT_*) 5589 - * @plane: plane index 5590 - * 5591 - * Returns: 5592 - * The bytes per pixel value for the specified plane. 5593 - */ 5594 - int drm_format_plane_cpp(uint32_t format, int plane) 5595 - { 5596 - unsigned int depth; 5597 - int bpp; 5598 - 5599 - if (plane >= drm_format_num_planes(format)) 5600 - return 0; 5601 - 5602 - switch (format) { 5603 - case DRM_FORMAT_YUYV: 5604 - case DRM_FORMAT_YVYU: 5605 - case DRM_FORMAT_UYVY: 5606 - case DRM_FORMAT_VYUY: 5607 - return 2; 5608 - case DRM_FORMAT_NV12: 5609 - case DRM_FORMAT_NV21: 5610 - case DRM_FORMAT_NV16: 5611 - case DRM_FORMAT_NV61: 5612 - case DRM_FORMAT_NV24: 5613 - case DRM_FORMAT_NV42: 5614 - return plane ? 2 : 1; 5615 - case DRM_FORMAT_YUV410: 5616 - case DRM_FORMAT_YVU410: 5617 - case DRM_FORMAT_YUV411: 5618 - case DRM_FORMAT_YVU411: 5619 - case DRM_FORMAT_YUV420: 5620 - case DRM_FORMAT_YVU420: 5621 - case DRM_FORMAT_YUV422: 5622 - case DRM_FORMAT_YVU422: 5623 - case DRM_FORMAT_YUV444: 5624 - case DRM_FORMAT_YVU444: 5625 - return 1; 5626 - default: 5627 - drm_fb_get_bpp_depth(format, &depth, &bpp); 5628 - return bpp >> 3; 5629 - } 5630 - } 5631 - EXPORT_SYMBOL(drm_format_plane_cpp); 5632 - 5633 - /** 5634 - * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor 5635 - * @format: pixel format (DRM_FORMAT_*) 5636 - * 5637 - * Returns: 5638 - * The horizontal chroma subsampling factor for the 5639 - * specified pixel format. 5640 - */ 5641 - int drm_format_horz_chroma_subsampling(uint32_t format) 5642 - { 5643 - switch (format) { 5644 - case DRM_FORMAT_YUV411: 5645 - case DRM_FORMAT_YVU411: 5646 - case DRM_FORMAT_YUV410: 5647 - case DRM_FORMAT_YVU410: 5648 - return 4; 5649 - case DRM_FORMAT_YUYV: 5650 - case DRM_FORMAT_YVYU: 5651 - case DRM_FORMAT_UYVY: 5652 - case DRM_FORMAT_VYUY: 5653 - case DRM_FORMAT_NV12: 5654 - case DRM_FORMAT_NV21: 5655 - case DRM_FORMAT_NV16: 5656 - case DRM_FORMAT_NV61: 5657 - case DRM_FORMAT_YUV422: 5658 - case DRM_FORMAT_YVU422: 5659 - case DRM_FORMAT_YUV420: 5660 - case DRM_FORMAT_YVU420: 5661 - return 2; 5662 - default: 5663 - return 1; 5664 - } 5665 - } 5666 - EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); 5667 - 5668 - /** 5669 - * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor 5670 - * @format: pixel format (DRM_FORMAT_*) 5671 - * 5672 - * Returns: 5673 - * The vertical chroma subsampling factor for the 5674 - * specified pixel format. 5675 - */ 5676 - int drm_format_vert_chroma_subsampling(uint32_t format) 5677 - { 5678 - switch (format) { 5679 - case DRM_FORMAT_YUV410: 5680 - case DRM_FORMAT_YVU410: 5681 - return 4; 5682 - case DRM_FORMAT_YUV420: 5683 - case DRM_FORMAT_YVU420: 5684 - case DRM_FORMAT_NV12: 5685 - case DRM_FORMAT_NV21: 5686 - return 2; 5687 - default: 5688 - return 1; 5689 - } 5690 - } 5691 - EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); 5692 - 5693 - /** 5694 - * drm_format_plane_width - width of the plane given the first plane 5695 - * @width: width of the first plane 5696 - * @format: pixel format 5697 - * @plane: plane index 5698 - * 5699 - * Returns: 5700 - * The width of @plane, given that the width of the first plane is @width. 5701 - */ 5702 - int drm_format_plane_width(int width, uint32_t format, int plane) 5703 - { 5704 - if (plane >= drm_format_num_planes(format)) 5705 - return 0; 5706 - 5707 - if (plane == 0) 5708 - return width; 5709 - 5710 - return width / drm_format_horz_chroma_subsampling(format); 5711 - } 5712 - EXPORT_SYMBOL(drm_format_plane_width); 5713 - 5714 - /** 5715 - * drm_format_plane_height - height of the plane given the first plane 5716 - * @height: height of the first plane 5717 - * @format: pixel format 5718 - * @plane: plane index 5719 - * 5720 - * Returns: 5721 - * The height of @plane, given that the height of the first plane is @height. 5722 - */ 5723 - int drm_format_plane_height(int height, uint32_t format, int plane) 5724 - { 5725 - if (plane >= drm_format_num_planes(format)) 5726 - return 0; 5727 - 5728 - if (plane == 0) 5729 - return height; 5730 - 5731 - return height / drm_format_vert_chroma_subsampling(format); 5732 - } 5733 - EXPORT_SYMBOL(drm_format_plane_height); 5734 5504 5735 5505 /** 5736 5506 * drm_rotation_simplify() - Try to simplify the rotation
-2
drivers/gpu/drm/drm_drv.c
··· 605 605 ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL); 606 606 if (ret) 607 607 goto err_minors; 608 - 609 - WARN_ON(driver->suspend || driver->resume); 610 608 } 611 609 612 610 if (drm_core_check_feature(dev, DRIVER_RENDER)) {
+1
drivers/gpu/drm/drm_fb_cma_helper.c
··· 346 346 fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); 347 347 if (!fbdefio || !fbops) { 348 348 kfree(fbdefio); 349 + kfree(fbops); 349 350 return -ENOMEM; 350 351 } 351 352
+2 -4
drivers/gpu/drm/drm_fb_helper.c
··· 385 385 386 386 drm_warn_on_modeset_not_all_locked(dev); 387 387 388 - if (fb_helper->atomic) 388 + if (dev->mode_config.funcs->atomic_commit) 389 389 return restore_fbdev_mode_atomic(fb_helper); 390 390 391 391 drm_for_each_plane(plane, dev) { ··· 715 715 fb_helper->crtc_info[i].mode_set.crtc = crtc; 716 716 i++; 717 717 } 718 - 719 - fb_helper->atomic = !!drm_core_check_feature(dev, DRIVER_ATOMIC); 720 718 721 719 return 0; 722 720 out_free: ··· 1342 1344 return -EBUSY; 1343 1345 } 1344 1346 1345 - if (fb_helper->atomic) { 1347 + if (dev->mode_config.funcs->atomic_commit) { 1346 1348 ret = pan_display_atomic(var, info); 1347 1349 goto unlock; 1348 1350 }
+6
drivers/gpu/drm/drm_fops.c
··· 797 797 { 798 798 assert_spin_locked(&dev->event_lock); 799 799 800 + if (e->completion) { 801 + /* ->completion might disappear as soon as it signalled. */ 802 + complete_all(e->completion); 803 + e->completion = NULL; 804 + } 805 + 800 806 if (e->fence) { 801 807 fence_signal(e->fence); 802 808 fence_put(e->fence);
+320
drivers/gpu/drm/drm_fourcc.c
··· 1 + /* 2 + * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 3 + * 4 + * DRM core format related functions 5 + * 6 + * Permission to use, copy, modify, distribute, and sell this software and its 7 + * documentation for any purpose is hereby granted without fee, provided that 8 + * the above copyright notice appear in all copies and that both that copyright 9 + * notice and this permission notice appear in supporting documentation, and 10 + * that the name of the copyright holders not be used in advertising or 11 + * publicity pertaining to distribution of the software without specific, 12 + * written prior permission. The copyright holders make no representations 13 + * about the suitability of this software for any purpose. It is provided "as 14 + * is" without express or implied warranty. 15 + * 16 + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18 + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20 + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21 + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 + * OF THIS SOFTWARE. 23 + */ 24 + 25 + #include <linux/bug.h> 26 + #include <linux/ctype.h> 27 + #include <linux/export.h> 28 + #include <linux/kernel.h> 29 + 30 + #include <drm/drmP.h> 31 + #include <drm/drm_fourcc.h> 32 + 33 + static char printable_char(int c) 34 + { 35 + return isascii(c) && isprint(c) ? c : '?'; 36 + } 37 + 38 + /** 39 + * drm_get_format_name - return a string for drm fourcc format 40 + * @format: format to compute name of 41 + * 42 + * Note that the buffer used by this function is globally shared and owned by 43 + * the function itself. 44 + * 45 + * FIXME: This isn't really multithreading safe. 46 + */ 47 + const char *drm_get_format_name(uint32_t format) 48 + { 49 + static char buf[32]; 50 + 51 + snprintf(buf, sizeof(buf), 52 + "%c%c%c%c %s-endian (0x%08x)", 53 + printable_char(format & 0xff), 54 + printable_char((format >> 8) & 0xff), 55 + printable_char((format >> 16) & 0xff), 56 + printable_char((format >> 24) & 0x7f), 57 + format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", 58 + format); 59 + 60 + return buf; 61 + } 62 + EXPORT_SYMBOL(drm_get_format_name); 63 + 64 + /** 65 + * drm_fb_get_bpp_depth - get the bpp/depth values for format 66 + * @format: pixel format (DRM_FORMAT_*) 67 + * @depth: storage for the depth value 68 + * @bpp: storage for the bpp value 69 + * 70 + * This only supports RGB formats here for compat with code that doesn't use 71 + * pixel formats directly yet. 72 + */ 73 + void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, 74 + int *bpp) 75 + { 76 + switch (format) { 77 + case DRM_FORMAT_C8: 78 + case DRM_FORMAT_RGB332: 79 + case DRM_FORMAT_BGR233: 80 + *depth = 8; 81 + *bpp = 8; 82 + break; 83 + case DRM_FORMAT_XRGB1555: 84 + case DRM_FORMAT_XBGR1555: 85 + case DRM_FORMAT_RGBX5551: 86 + case DRM_FORMAT_BGRX5551: 87 + case DRM_FORMAT_ARGB1555: 88 + case DRM_FORMAT_ABGR1555: 89 + case DRM_FORMAT_RGBA5551: 90 + case DRM_FORMAT_BGRA5551: 91 + *depth = 15; 92 + *bpp = 16; 93 + break; 94 + case DRM_FORMAT_RGB565: 95 + case DRM_FORMAT_BGR565: 96 + *depth = 16; 97 + *bpp = 16; 98 + break; 99 + case DRM_FORMAT_RGB888: 100 + case DRM_FORMAT_BGR888: 101 + *depth = 24; 102 + *bpp = 24; 103 + break; 104 + case DRM_FORMAT_XRGB8888: 105 + case DRM_FORMAT_XBGR8888: 106 + case DRM_FORMAT_RGBX8888: 107 + case DRM_FORMAT_BGRX8888: 108 + *depth = 24; 109 + *bpp = 32; 110 + break; 111 + case DRM_FORMAT_XRGB2101010: 112 + case DRM_FORMAT_XBGR2101010: 113 + case DRM_FORMAT_RGBX1010102: 114 + case DRM_FORMAT_BGRX1010102: 115 + case DRM_FORMAT_ARGB2101010: 116 + case DRM_FORMAT_ABGR2101010: 117 + case DRM_FORMAT_RGBA1010102: 118 + case DRM_FORMAT_BGRA1010102: 119 + *depth = 30; 120 + *bpp = 32; 121 + break; 122 + case DRM_FORMAT_ARGB8888: 123 + case DRM_FORMAT_ABGR8888: 124 + case DRM_FORMAT_RGBA8888: 125 + case DRM_FORMAT_BGRA8888: 126 + *depth = 32; 127 + *bpp = 32; 128 + break; 129 + default: 130 + DRM_DEBUG_KMS("unsupported pixel format %s\n", 131 + drm_get_format_name(format)); 132 + *depth = 0; 133 + *bpp = 0; 134 + break; 135 + } 136 + } 137 + EXPORT_SYMBOL(drm_fb_get_bpp_depth); 138 + 139 + /** 140 + * drm_format_num_planes - get the number of planes for format 141 + * @format: pixel format (DRM_FORMAT_*) 142 + * 143 + * Returns: 144 + * The number of planes used by the specified pixel format. 145 + */ 146 + int drm_format_num_planes(uint32_t format) 147 + { 148 + switch (format) { 149 + case DRM_FORMAT_YUV410: 150 + case DRM_FORMAT_YVU410: 151 + case DRM_FORMAT_YUV411: 152 + case DRM_FORMAT_YVU411: 153 + case DRM_FORMAT_YUV420: 154 + case DRM_FORMAT_YVU420: 155 + case DRM_FORMAT_YUV422: 156 + case DRM_FORMAT_YVU422: 157 + case DRM_FORMAT_YUV444: 158 + case DRM_FORMAT_YVU444: 159 + return 3; 160 + case DRM_FORMAT_NV12: 161 + case DRM_FORMAT_NV21: 162 + case DRM_FORMAT_NV16: 163 + case DRM_FORMAT_NV61: 164 + case DRM_FORMAT_NV24: 165 + case DRM_FORMAT_NV42: 166 + return 2; 167 + default: 168 + return 1; 169 + } 170 + } 171 + EXPORT_SYMBOL(drm_format_num_planes); 172 + 173 + /** 174 + * drm_format_plane_cpp - determine the bytes per pixel value 175 + * @format: pixel format (DRM_FORMAT_*) 176 + * @plane: plane index 177 + * 178 + * Returns: 179 + * The bytes per pixel value for the specified plane. 180 + */ 181 + int drm_format_plane_cpp(uint32_t format, int plane) 182 + { 183 + unsigned int depth; 184 + int bpp; 185 + 186 + if (plane >= drm_format_num_planes(format)) 187 + return 0; 188 + 189 + switch (format) { 190 + case DRM_FORMAT_YUYV: 191 + case DRM_FORMAT_YVYU: 192 + case DRM_FORMAT_UYVY: 193 + case DRM_FORMAT_VYUY: 194 + return 2; 195 + case DRM_FORMAT_NV12: 196 + case DRM_FORMAT_NV21: 197 + case DRM_FORMAT_NV16: 198 + case DRM_FORMAT_NV61: 199 + case DRM_FORMAT_NV24: 200 + case DRM_FORMAT_NV42: 201 + return plane ? 2 : 1; 202 + case DRM_FORMAT_YUV410: 203 + case DRM_FORMAT_YVU410: 204 + case DRM_FORMAT_YUV411: 205 + case DRM_FORMAT_YVU411: 206 + case DRM_FORMAT_YUV420: 207 + case DRM_FORMAT_YVU420: 208 + case DRM_FORMAT_YUV422: 209 + case DRM_FORMAT_YVU422: 210 + case DRM_FORMAT_YUV444: 211 + case DRM_FORMAT_YVU444: 212 + return 1; 213 + default: 214 + drm_fb_get_bpp_depth(format, &depth, &bpp); 215 + return bpp >> 3; 216 + } 217 + } 218 + EXPORT_SYMBOL(drm_format_plane_cpp); 219 + 220 + /** 221 + * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor 222 + * @format: pixel format (DRM_FORMAT_*) 223 + * 224 + * Returns: 225 + * The horizontal chroma subsampling factor for the 226 + * specified pixel format. 227 + */ 228 + int drm_format_horz_chroma_subsampling(uint32_t format) 229 + { 230 + switch (format) { 231 + case DRM_FORMAT_YUV411: 232 + case DRM_FORMAT_YVU411: 233 + case DRM_FORMAT_YUV410: 234 + case DRM_FORMAT_YVU410: 235 + return 4; 236 + case DRM_FORMAT_YUYV: 237 + case DRM_FORMAT_YVYU: 238 + case DRM_FORMAT_UYVY: 239 + case DRM_FORMAT_VYUY: 240 + case DRM_FORMAT_NV12: 241 + case DRM_FORMAT_NV21: 242 + case DRM_FORMAT_NV16: 243 + case DRM_FORMAT_NV61: 244 + case DRM_FORMAT_YUV422: 245 + case DRM_FORMAT_YVU422: 246 + case DRM_FORMAT_YUV420: 247 + case DRM_FORMAT_YVU420: 248 + return 2; 249 + default: 250 + return 1; 251 + } 252 + } 253 + EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); 254 + 255 + /** 256 + * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor 257 + * @format: pixel format (DRM_FORMAT_*) 258 + * 259 + * Returns: 260 + * The vertical chroma subsampling factor for the 261 + * specified pixel format. 262 + */ 263 + int drm_format_vert_chroma_subsampling(uint32_t format) 264 + { 265 + switch (format) { 266 + case DRM_FORMAT_YUV410: 267 + case DRM_FORMAT_YVU410: 268 + return 4; 269 + case DRM_FORMAT_YUV420: 270 + case DRM_FORMAT_YVU420: 271 + case DRM_FORMAT_NV12: 272 + case DRM_FORMAT_NV21: 273 + return 2; 274 + default: 275 + return 1; 276 + } 277 + } 278 + EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); 279 + 280 + /** 281 + * drm_format_plane_width - width of the plane given the first plane 282 + * @width: width of the first plane 283 + * @format: pixel format 284 + * @plane: plane index 285 + * 286 + * Returns: 287 + * The width of @plane, given that the width of the first plane is @width. 288 + */ 289 + int drm_format_plane_width(int width, uint32_t format, int plane) 290 + { 291 + if (plane >= drm_format_num_planes(format)) 292 + return 0; 293 + 294 + if (plane == 0) 295 + return width; 296 + 297 + return width / drm_format_horz_chroma_subsampling(format); 298 + } 299 + EXPORT_SYMBOL(drm_format_plane_width); 300 + 301 + /** 302 + * drm_format_plane_height - height of the plane given the first plane 303 + * @height: height of the first plane 304 + * @format: pixel format 305 + * @plane: plane index 306 + * 307 + * Returns: 308 + * The height of @plane, given that the height of the first plane is @height. 309 + */ 310 + int drm_format_plane_height(int height, uint32_t format, int plane) 311 + { 312 + if (plane >= drm_format_num_planes(format)) 313 + return 0; 314 + 315 + if (plane == 0) 316 + return height; 317 + 318 + return height / drm_format_vert_chroma_subsampling(format); 319 + } 320 + EXPORT_SYMBOL(drm_format_plane_height);
+16 -64
drivers/gpu/drm/drm_irq.c
··· 1001 1001 } 1002 1002 1003 1003 /** 1004 - * drm_arm_vblank_event - arm vblank event after pageflip 1005 - * @dev: DRM device 1006 - * @pipe: CRTC index 1007 - * @e: the event to prepare to send 1008 - * 1009 - * A lot of drivers need to generate vblank events for the very next vblank 1010 - * interrupt. For example when the page flip interrupt happens when the page 1011 - * flip gets armed, but not when it actually executes within the next vblank 1012 - * period. This helper function implements exactly the required vblank arming 1013 - * behaviour. 1014 - * 1015 - * Caller must hold event lock. Caller must also hold a vblank reference for 1016 - * the event @e, which will be dropped when the next vblank arrives. 1017 - * 1018 - * This is the legacy version of drm_crtc_arm_vblank_event(). 1019 - */ 1020 - void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe, 1021 - struct drm_pending_vblank_event *e) 1022 - { 1023 - assert_spin_locked(&dev->event_lock); 1024 - 1025 - e->pipe = pipe; 1026 - e->event.sequence = drm_vblank_count(dev, pipe); 1027 - list_add_tail(&e->base.link, &dev->vblank_event_list); 1028 - } 1029 - EXPORT_SYMBOL(drm_arm_vblank_event); 1030 - 1031 - /** 1032 1004 * drm_crtc_arm_vblank_event - arm vblank event after pageflip 1033 1005 * @crtc: the source CRTC of the vblank event 1034 1006 * @e: the event to send ··· 1013 1041 * 1014 1042 * Caller must hold event lock. Caller must also hold a vblank reference for 1015 1043 * the event @e, which will be dropped when the next vblank arrives. 1016 - * 1017 - * This is the native KMS version of drm_arm_vblank_event(). 1018 1044 */ 1019 1045 void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, 1020 1046 struct drm_pending_vblank_event *e) 1021 1047 { 1022 - drm_arm_vblank_event(crtc->dev, drm_crtc_index(crtc), e); 1048 + struct drm_device *dev = crtc->dev; 1049 + unsigned int pipe = drm_crtc_index(crtc); 1050 + 1051 + assert_spin_locked(&dev->event_lock); 1052 + 1053 + e->pipe = pipe; 1054 + e->event.sequence = drm_vblank_count(dev, pipe); 1055 + list_add_tail(&e->base.link, &dev->vblank_event_list); 1023 1056 } 1024 1057 EXPORT_SYMBOL(drm_crtc_arm_vblank_event); 1025 1058 1026 1059 /** 1027 - * drm_send_vblank_event - helper to send vblank event after pageflip 1028 - * @dev: DRM device 1029 - * @pipe: CRTC index 1060 + * drm_crtc_send_vblank_event - helper to send vblank event after pageflip 1061 + * @crtc: the source CRTC of the vblank event 1030 1062 * @e: the event to send 1031 1063 * 1032 1064 * Updates sequence # and timestamp on event, and sends it to userspace. 1033 1065 * Caller must hold event lock. 1034 - * 1035 - * This is the legacy version of drm_crtc_send_vblank_event(). 1036 1066 */ 1037 - void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe, 1038 - struct drm_pending_vblank_event *e) 1067 + void drm_crtc_send_vblank_event(struct drm_crtc *crtc, 1068 + struct drm_pending_vblank_event *e) 1039 1069 { 1070 + struct drm_device *dev = crtc->dev; 1071 + unsigned int seq, pipe = drm_crtc_index(crtc); 1040 1072 struct timeval now; 1041 - unsigned int seq; 1042 1073 1043 1074 if (dev->num_crtcs > 0) { 1044 1075 seq = drm_vblank_count_and_time(dev, pipe, &now); ··· 1052 1077 } 1053 1078 e->pipe = pipe; 1054 1079 send_vblank_event(dev, e, seq, &now); 1055 - } 1056 - EXPORT_SYMBOL(drm_send_vblank_event); 1057 - 1058 - /** 1059 - * drm_crtc_send_vblank_event - helper to send vblank event after pageflip 1060 - * @crtc: the source CRTC of the vblank event 1061 - * @e: the event to send 1062 - * 1063 - * Updates sequence # and timestamp on event, and sends it to userspace. 1064 - * Caller must hold event lock. 1065 - * 1066 - * This is the native KMS version of drm_send_vblank_event(). 1067 - */ 1068 - void drm_crtc_send_vblank_event(struct drm_crtc *crtc, 1069 - struct drm_pending_vblank_event *e) 1070 - { 1071 - drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), e); 1072 1080 } 1073 1081 EXPORT_SYMBOL(drm_crtc_send_vblank_event); 1074 1082 ··· 1108 1150 * Returns: 1109 1151 * Zero on success or a negative error code on failure. 1110 1152 */ 1111 - int drm_vblank_get(struct drm_device *dev, unsigned int pipe) 1153 + static int drm_vblank_get(struct drm_device *dev, unsigned int pipe) 1112 1154 { 1113 1155 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 1114 1156 unsigned long irqflags; ··· 1134 1176 1135 1177 return ret; 1136 1178 } 1137 - EXPORT_SYMBOL(drm_vblank_get); 1138 1179 1139 1180 /** 1140 1181 * drm_crtc_vblank_get - get a reference count on vblank events ··· 1141 1184 * 1142 1185 * Acquire a reference count on vblank events to avoid having them disabled 1143 1186 * while in use. 1144 - * 1145 - * This is the native kms version of drm_vblank_get(). 1146 1187 * 1147 1188 * Returns: 1148 1189 * Zero on success or a negative error code on failure. ··· 1161 1206 * 1162 1207 * This is the legacy version of drm_crtc_vblank_put(). 1163 1208 */ 1164 - void drm_vblank_put(struct drm_device *dev, unsigned int pipe) 1209 + static void drm_vblank_put(struct drm_device *dev, unsigned int pipe) 1165 1210 { 1166 1211 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 1167 1212 ··· 1182 1227 jiffies + ((drm_vblank_offdelay * HZ)/1000)); 1183 1228 } 1184 1229 } 1185 - EXPORT_SYMBOL(drm_vblank_put); 1186 1230 1187 1231 /** 1188 1232 * drm_crtc_vblank_put - give up ownership of vblank events ··· 1189 1235 * 1190 1236 * Release ownership of a given vblank counter, turning off interrupts 1191 1237 * if possible. Disable interrupts after drm_vblank_offdelay milliseconds. 1192 - * 1193 - * This is the native kms version of drm_vblank_put(). 1194 1238 */ 1195 1239 void drm_crtc_vblank_put(struct drm_crtc *crtc) 1196 1240 {
+16
drivers/gpu/drm/drm_mipi_dsi.c
··· 60 60 return 0; 61 61 } 62 62 63 + static int mipi_dsi_uevent(struct device *dev, struct kobj_uevent_env *env) 64 + { 65 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 66 + int err; 67 + 68 + err = of_device_uevent_modalias(dev, env); 69 + if (err != -ENODEV) 70 + return err; 71 + 72 + add_uevent_var(env, "MODALIAS=%s%s", MIPI_DSI_MODULE_PREFIX, 73 + dsi->name); 74 + 75 + return 0; 76 + } 77 + 63 78 static const struct dev_pm_ops mipi_dsi_device_pm_ops = { 64 79 .runtime_suspend = pm_generic_runtime_suspend, 65 80 .runtime_resume = pm_generic_runtime_resume, ··· 89 74 static struct bus_type mipi_dsi_bus_type = { 90 75 .name = "mipi-dsi", 91 76 .match = mipi_dsi_device_match, 77 + .uevent = mipi_dsi_uevent, 92 78 .pm = &mipi_dsi_device_pm_ops, 93 79 }; 94 80
+6 -4
drivers/gpu/drm/drm_prime.c
··· 593 593 get_dma_buf(dma_buf); 594 594 } 595 595 596 - /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */ 596 + /* _handle_create_tail unconditionally unlocks dev->object_name_lock. */ 597 597 ret = drm_gem_handle_create_tail(file_priv, obj, handle); 598 598 drm_gem_object_unreference_unlocked(obj); 599 599 if (ret) ··· 601 601 602 602 ret = drm_prime_add_buf_handle(&file_priv->prime, 603 603 dma_buf, *handle); 604 + mutex_unlock(&file_priv->prime.lock); 604 605 if (ret) 605 606 goto fail; 606 - 607 - mutex_unlock(&file_priv->prime.lock); 608 607 609 608 dma_buf_put(dma_buf); 610 609 ··· 614 615 * to detach.. which seems ok.. 615 616 */ 616 617 drm_gem_handle_delete(file_priv, *handle); 618 + dma_buf_put(dma_buf); 619 + return ret; 620 + 617 621 out_unlock: 618 622 mutex_unlock(&dev->object_name_lock); 619 623 out_put: 620 - dma_buf_put(dma_buf); 621 624 mutex_unlock(&file_priv->prime.lock); 625 + dma_buf_put(dma_buf); 622 626 return ret; 623 627 } 624 628 EXPORT_SYMBOL(drm_gem_prime_fd_to_handle);
+205
drivers/gpu/drm/drm_simple_kms_helper.c
··· 1 + /* 2 + * Copyright (C) 2016 Noralf Trønnes 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + */ 9 + 10 + #include <drm/drmP.h> 11 + #include <drm/drm_atomic.h> 12 + #include <drm/drm_atomic_helper.h> 13 + #include <drm/drm_crtc_helper.h> 14 + #include <drm/drm_plane_helper.h> 15 + #include <drm/drm_simple_kms_helper.h> 16 + #include <linux/slab.h> 17 + 18 + /** 19 + * DOC: overview 20 + * 21 + * This helper library provides helpers for drivers for simple display 22 + * hardware. 23 + * 24 + * drm_simple_display_pipe_init() initializes a simple display pipeline 25 + * which has only one full-screen scanout buffer feeding one output. The 26 + * pipeline is represented by struct &drm_simple_display_pipe and binds 27 + * together &drm_plane, &drm_crtc and &drm_encoder structures into one fixed 28 + * entity. Some flexibility for code reuse is provided through a separately 29 + * allocated &drm_connector object and supporting optional &drm_bridge 30 + * encoder drivers. 31 + */ 32 + 33 + static const struct drm_encoder_funcs drm_simple_kms_encoder_funcs = { 34 + .destroy = drm_encoder_cleanup, 35 + }; 36 + 37 + static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc) 38 + { 39 + struct drm_simple_display_pipe *pipe; 40 + 41 + pipe = container_of(crtc, struct drm_simple_display_pipe, crtc); 42 + if (!pipe->funcs || !pipe->funcs->enable) 43 + return; 44 + 45 + pipe->funcs->enable(pipe, crtc->state); 46 + } 47 + 48 + static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc) 49 + { 50 + struct drm_simple_display_pipe *pipe; 51 + 52 + pipe = container_of(crtc, struct drm_simple_display_pipe, crtc); 53 + if (!pipe->funcs || !pipe->funcs->disable) 54 + return; 55 + 56 + pipe->funcs->disable(pipe); 57 + } 58 + 59 + static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = { 60 + .disable = drm_simple_kms_crtc_disable, 61 + .enable = drm_simple_kms_crtc_enable, 62 + }; 63 + 64 + static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = { 65 + .reset = drm_atomic_helper_crtc_reset, 66 + .destroy = drm_crtc_cleanup, 67 + .set_config = drm_atomic_helper_set_config, 68 + .page_flip = drm_atomic_helper_page_flip, 69 + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 70 + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 71 + }; 72 + 73 + static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane, 74 + struct drm_plane_state *plane_state) 75 + { 76 + struct drm_rect src = { 77 + .x1 = plane_state->src_x, 78 + .y1 = plane_state->src_y, 79 + .x2 = plane_state->src_x + plane_state->src_w, 80 + .y2 = plane_state->src_y + plane_state->src_h, 81 + }; 82 + struct drm_rect dest = { 83 + .x1 = plane_state->crtc_x, 84 + .y1 = plane_state->crtc_y, 85 + .x2 = plane_state->crtc_x + plane_state->crtc_w, 86 + .y2 = plane_state->crtc_y + plane_state->crtc_h, 87 + }; 88 + struct drm_rect clip = { 0 }; 89 + struct drm_simple_display_pipe *pipe; 90 + struct drm_crtc_state *crtc_state; 91 + bool visible; 92 + int ret; 93 + 94 + pipe = container_of(plane, struct drm_simple_display_pipe, plane); 95 + crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state, 96 + &pipe->crtc); 97 + if (crtc_state->enable != !!plane_state->crtc) 98 + return -EINVAL; /* plane must match crtc enable state */ 99 + 100 + if (!crtc_state->enable) 101 + return 0; /* nothing to check when disabling or disabled */ 102 + 103 + clip.x2 = crtc_state->adjusted_mode.hdisplay; 104 + clip.y2 = crtc_state->adjusted_mode.vdisplay; 105 + ret = drm_plane_helper_check_update(plane, &pipe->crtc, 106 + plane_state->fb, 107 + &src, &dest, &clip, 108 + DRM_PLANE_HELPER_NO_SCALING, 109 + DRM_PLANE_HELPER_NO_SCALING, 110 + false, true, &visible); 111 + if (ret) 112 + return ret; 113 + 114 + if (!visible) 115 + return -EINVAL; 116 + 117 + if (!pipe->funcs || !pipe->funcs->check) 118 + return 0; 119 + 120 + return pipe->funcs->check(pipe, plane_state, crtc_state); 121 + } 122 + 123 + static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane, 124 + struct drm_plane_state *pstate) 125 + { 126 + struct drm_simple_display_pipe *pipe; 127 + 128 + pipe = container_of(plane, struct drm_simple_display_pipe, plane); 129 + if (!pipe->funcs || !pipe->funcs->update) 130 + return; 131 + 132 + pipe->funcs->update(pipe, pstate); 133 + } 134 + 135 + static const struct drm_plane_helper_funcs drm_simple_kms_plane_helper_funcs = { 136 + .atomic_check = drm_simple_kms_plane_atomic_check, 137 + .atomic_update = drm_simple_kms_plane_atomic_update, 138 + }; 139 + 140 + static const struct drm_plane_funcs drm_simple_kms_plane_funcs = { 141 + .update_plane = drm_atomic_helper_update_plane, 142 + .disable_plane = drm_atomic_helper_disable_plane, 143 + .destroy = drm_plane_cleanup, 144 + .reset = drm_atomic_helper_plane_reset, 145 + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 146 + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 147 + }; 148 + 149 + /** 150 + * drm_simple_display_pipe_init - Initialize a simple display pipeline 151 + * @dev: DRM device 152 + * @pipe: simple display pipe object to initialize 153 + * @funcs: callbacks for the display pipe (optional) 154 + * @formats: array of supported formats (%DRM_FORMAT_*) 155 + * @format_count: number of elements in @formats 156 + * @connector: connector to attach and register 157 + * 158 + * Sets up a display pipeline which consist of a really simple 159 + * plane-crtc-encoder pipe coupled with the provided connector. 160 + * Teardown of a simple display pipe is all handled automatically by the drm 161 + * core through calling drm_mode_config_cleanup(). Drivers afterwards need to 162 + * release the memory for the structure themselves. 163 + * 164 + * Returns: 165 + * Zero on success, negative error code on failure. 166 + */ 167 + int drm_simple_display_pipe_init(struct drm_device *dev, 168 + struct drm_simple_display_pipe *pipe, 169 + const struct drm_simple_display_pipe_funcs *funcs, 170 + const uint32_t *formats, unsigned int format_count, 171 + struct drm_connector *connector) 172 + { 173 + struct drm_encoder *encoder = &pipe->encoder; 174 + struct drm_plane *plane = &pipe->plane; 175 + struct drm_crtc *crtc = &pipe->crtc; 176 + int ret; 177 + 178 + pipe->connector = connector; 179 + pipe->funcs = funcs; 180 + 181 + drm_plane_helper_add(plane, &drm_simple_kms_plane_helper_funcs); 182 + ret = drm_universal_plane_init(dev, plane, 0, 183 + &drm_simple_kms_plane_funcs, 184 + formats, format_count, 185 + DRM_PLANE_TYPE_PRIMARY, NULL); 186 + if (ret) 187 + return ret; 188 + 189 + drm_crtc_helper_add(crtc, &drm_simple_kms_crtc_helper_funcs); 190 + ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, 191 + &drm_simple_kms_crtc_funcs, NULL); 192 + if (ret) 193 + return ret; 194 + 195 + encoder->possible_crtcs = 1 << drm_crtc_index(crtc); 196 + ret = drm_encoder_init(dev, encoder, &drm_simple_kms_encoder_funcs, 197 + DRM_MODE_ENCODER_NONE, NULL); 198 + if (ret) 199 + return ret; 200 + 201 + return drm_mode_connector_attach_encoder(connector, encoder); 202 + } 203 + EXPORT_SYMBOL(drm_simple_display_pipe_init); 204 + 205 + MODULE_LICENSE("GPL");
-71
drivers/gpu/drm/drm_sysfs.c
··· 32 32 33 33 struct class *drm_class; 34 34 35 - /** 36 - * __drm_class_suspend - internal DRM class suspend routine 37 - * @dev: Linux device to suspend 38 - * @state: power state to enter 39 - * 40 - * Just figures out what the actual struct drm_device associated with 41 - * @dev is and calls its suspend hook, if present. 42 - */ 43 - static int __drm_class_suspend(struct device *dev, pm_message_t state) 44 - { 45 - if (dev->type == &drm_sysfs_device_minor) { 46 - struct drm_minor *drm_minor = to_drm_minor(dev); 47 - struct drm_device *drm_dev = drm_minor->dev; 48 - 49 - if (drm_minor->type == DRM_MINOR_LEGACY && 50 - !drm_core_check_feature(drm_dev, DRIVER_MODESET) && 51 - drm_dev->driver->suspend) 52 - return drm_dev->driver->suspend(drm_dev, state); 53 - } 54 - return 0; 55 - } 56 - 57 - /** 58 - * drm_class_suspend - internal DRM class suspend hook. Simply calls 59 - * __drm_class_suspend() with the correct pm state. 60 - * @dev: Linux device to suspend 61 - */ 62 - static int drm_class_suspend(struct device *dev) 63 - { 64 - return __drm_class_suspend(dev, PMSG_SUSPEND); 65 - } 66 - 67 - /** 68 - * drm_class_freeze - internal DRM class freeze hook. Simply calls 69 - * __drm_class_suspend() with the correct pm state. 70 - * @dev: Linux device to freeze 71 - */ 72 - static int drm_class_freeze(struct device *dev) 73 - { 74 - return __drm_class_suspend(dev, PMSG_FREEZE); 75 - } 76 - 77 - /** 78 - * drm_class_resume - DRM class resume hook 79 - * @dev: Linux device to resume 80 - * 81 - * Just figures out what the actual struct drm_device associated with 82 - * @dev is and calls its resume hook, if present. 83 - */ 84 - static int drm_class_resume(struct device *dev) 85 - { 86 - if (dev->type == &drm_sysfs_device_minor) { 87 - struct drm_minor *drm_minor = to_drm_minor(dev); 88 - struct drm_device *drm_dev = drm_minor->dev; 89 - 90 - if (drm_minor->type == DRM_MINOR_LEGACY && 91 - !drm_core_check_feature(drm_dev, DRIVER_MODESET) && 92 - drm_dev->driver->resume) 93 - return drm_dev->driver->resume(drm_dev); 94 - } 95 - return 0; 96 - } 97 - 98 - static const struct dev_pm_ops drm_class_dev_pm_ops = { 99 - .suspend = drm_class_suspend, 100 - .resume = drm_class_resume, 101 - .freeze = drm_class_freeze, 102 - }; 103 - 104 35 static char *drm_devnode(struct device *dev, umode_t *mode) 105 36 { 106 37 return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); ··· 61 130 drm_class = class_create(THIS_MODULE, "drm"); 62 131 if (IS_ERR(drm_class)) 63 132 return PTR_ERR(drm_class); 64 - 65 - drm_class->pm = &drm_class_dev_pm_ops; 66 133 67 134 err = class_create_file(drm_class, &class_attr_version.attr); 68 135 if (err) {
-9
drivers/gpu/drm/exynos/exynos_drm_dpi.c
··· 93 93 return 0; 94 94 } 95 95 96 - static struct drm_encoder * 97 - exynos_dpi_best_encoder(struct drm_connector *connector) 98 - { 99 - struct exynos_dpi *ctx = connector_to_dpi(connector); 100 - 101 - return &ctx->encoder; 102 - } 103 - 104 96 static const struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = { 105 97 .get_modes = exynos_dpi_get_modes, 106 - .best_encoder = exynos_dpi_best_encoder, 107 98 }; 108 99 109 100 static int exynos_dpi_create_connector(struct drm_encoder *encoder)
+1 -1
drivers/gpu/drm/exynos/exynos_drm_drv.c
··· 299 299 priv->pending |= commit->crtcs; 300 300 spin_unlock(&priv->lock); 301 301 302 - drm_atomic_helper_swap_state(dev, state); 302 + drm_atomic_helper_swap_state(state, true); 303 303 304 304 if (nonblock) 305 305 schedule_work(&commit->work);
-9
drivers/gpu/drm/exynos/exynos_drm_dsi.c
··· 1566 1566 return 0; 1567 1567 } 1568 1568 1569 - static struct drm_encoder * 1570 - exynos_dsi_best_encoder(struct drm_connector *connector) 1571 - { 1572 - struct exynos_dsi *dsi = connector_to_dsi(connector); 1573 - 1574 - return &dsi->encoder; 1575 - } 1576 - 1577 1569 static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = { 1578 1570 .get_modes = exynos_dsi_get_modes, 1579 - .best_encoder = exynos_dsi_best_encoder, 1580 1571 }; 1581 1572 1582 1573 static int exynos_dsi_create_connector(struct drm_encoder *encoder)
+1 -1
drivers/gpu/drm/exynos/exynos_drm_plane.c
··· 242 242 state->v_ratio == (1 << 15)) 243 243 height_ok = true; 244 244 245 - if (width_ok & height_ok) 245 + if (width_ok && height_ok) 246 246 return 0; 247 247 248 248 DRM_DEBUG_KMS("scaling mode is not supported");
-8
drivers/gpu/drm/exynos/exynos_drm_vidi.c
··· 378 378 return drm_add_edid_modes(connector, edid); 379 379 } 380 380 381 - static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector) 382 - { 383 - struct vidi_context *ctx = ctx_from_connector(connector); 384 - 385 - return &ctx->encoder; 386 - } 387 - 388 381 static const struct drm_connector_helper_funcs vidi_connector_helper_funcs = { 389 382 .get_modes = vidi_get_modes, 390 - .best_encoder = vidi_best_encoder, 391 383 }; 392 384 393 385 static int vidi_create_connector(struct drm_encoder *encoder)
-8
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 937 937 return MODE_OK; 938 938 } 939 939 940 - static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector) 941 - { 942 - struct hdmi_context *hdata = connector_to_hdmi(connector); 943 - 944 - return &hdata->encoder; 945 - } 946 - 947 940 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = { 948 941 .get_modes = hdmi_get_modes, 949 942 .mode_valid = hdmi_mode_valid, 950 - .best_encoder = hdmi_best_encoder, 951 943 }; 952 944 953 945 static int hdmi_create_connector(struct drm_encoder *encoder)
+12 -13
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
··· 22 22 #include "fsl_dcu_drm_drv.h" 23 23 #include "fsl_dcu_drm_plane.h" 24 24 25 - static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc, 26 - struct drm_crtc_state *old_crtc_state) 27 - { 28 - } 29 - 30 - static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc, 31 - struct drm_crtc_state *state) 32 - { 33 - return 0; 34 - } 35 - 36 25 static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc, 37 26 struct drm_crtc_state *old_crtc_state) 38 27 { 28 + struct drm_pending_vblank_event *event = crtc->state->event; 29 + 30 + if (event) { 31 + crtc->state->event = NULL; 32 + 33 + spin_lock_irq(&crtc->dev->event_lock); 34 + if (drm_crtc_vblank_get(crtc) == 0) 35 + drm_crtc_arm_vblank_event(crtc, event); 36 + else 37 + drm_crtc_send_vblank_event(crtc, event); 38 + spin_unlock_irq(&crtc->dev->event_lock); 39 + } 39 40 } 40 41 41 42 static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc) ··· 118 117 } 119 118 120 119 static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = { 121 - .atomic_begin = fsl_dcu_drm_crtc_atomic_begin, 122 - .atomic_check = fsl_dcu_drm_crtc_atomic_check, 123 120 .atomic_flush = fsl_dcu_drm_crtc_atomic_flush, 124 121 .disable = fsl_dcu_drm_disable_crtc, 125 122 .enable = fsl_dcu_drm_crtc_enable,
-9
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
··· 102 102 .reset = drm_atomic_helper_connector_reset, 103 103 }; 104 104 105 - static struct drm_encoder * 106 - fsl_dcu_drm_connector_best_encoder(struct drm_connector *connector) 107 - { 108 - struct fsl_dcu_drm_connector *fsl_con = to_fsl_dcu_connector(connector); 109 - 110 - return fsl_con->encoder; 111 - } 112 - 113 105 static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector) 114 106 { 115 107 struct fsl_dcu_drm_connector *fsl_connector; ··· 128 136 } 129 137 130 138 static const struct drm_connector_helper_funcs connector_helper_funcs = { 131 - .best_encoder = fsl_dcu_drm_connector_best_encoder, 132 139 .get_modes = fsl_dcu_drm_connector_get_modes, 133 140 .mode_valid = fsl_dcu_drm_connector_mode_valid, 134 141 };
+1 -1
drivers/gpu/drm/gma500/gma_display.c
··· 282 282 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 283 283 284 284 /* Turn off vblank interrupts */ 285 - drm_vblank_off(dev, pipe); 285 + drm_crtc_vblank_off(crtc); 286 286 287 287 /* Wait for vblank for the disable to take effect */ 288 288 gma_wait_for_vblank(dev);
+12 -8
drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
··· 502 502 acrtc->enable = false; 503 503 } 504 504 505 - static int ade_crtc_atomic_check(struct drm_crtc *crtc, 506 - struct drm_crtc_state *state) 507 - { 508 - /* do nothing */ 509 - return 0; 510 - } 511 - 512 505 static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc) 513 506 { 514 507 struct ade_crtc *acrtc = to_ade_crtc(crtc); ··· 530 537 { 531 538 struct ade_crtc *acrtc = to_ade_crtc(crtc); 532 539 struct ade_hw_ctx *ctx = acrtc->ctx; 540 + struct drm_pending_vblank_event *event = crtc->state->event; 533 541 void __iomem *base = ctx->base; 534 542 535 543 /* only crtc is enabled regs take effect */ ··· 539 545 /* flush ade registers */ 540 546 writel(ADE_ENABLE, base + ADE_EN); 541 547 } 548 + 549 + if (event) { 550 + crtc->state->event = NULL; 551 + 552 + spin_lock_irq(&crtc->dev->event_lock); 553 + if (drm_crtc_vblank_get(crtc) == 0) 554 + drm_crtc_arm_vblank_event(crtc, event); 555 + else 556 + drm_crtc_send_vblank_event(crtc, event); 557 + spin_unlock_irq(&crtc->dev->event_lock); 558 + } 542 559 } 543 560 544 561 static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = { 545 562 .enable = ade_crtc_enable, 546 563 .disable = ade_crtc_disable, 547 - .atomic_check = ade_crtc_atomic_check, 548 564 .mode_set_nofb = ade_crtc_mode_set_nofb, 549 565 .atomic_begin = ade_crtc_atomic_begin, 550 566 .atomic_flush = ade_crtc_atomic_flush,
+2 -2
drivers/gpu/drm/i915/i915_debugfs.c
··· 2393 2393 task = get_pid_task(file->pid, PIDTYPE_PID); 2394 2394 if (!task) { 2395 2395 ret = -ESRCH; 2396 - goto out_put; 2396 + goto out_unlock; 2397 2397 } 2398 2398 seq_printf(m, "\nproc: %s\n", task->comm); 2399 2399 put_task_struct(task); 2400 2400 idr_for_each(&file_priv->context_idr, per_file_ctx, 2401 2401 (void *)(unsigned long)m); 2402 2402 } 2403 + out_unlock: 2403 2404 mutex_unlock(&dev->filelist_mutex); 2404 2405 2405 - out_put: 2406 2406 intel_runtime_pm_put(dev_priv); 2407 2407 mutex_unlock(&dev->struct_mutex); 2408 2408
-1
drivers/gpu/drm/i915/intel_crt.c
··· 753 753 static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { 754 754 .mode_valid = intel_crt_mode_valid, 755 755 .get_modes = intel_crt_get_modes, 756 - .best_encoder = intel_best_encoder, 757 756 }; 758 757 759 758 static const struct drm_encoder_funcs intel_crt_enc_funcs = {
+1 -9
drivers/gpu/drm/i915/intel_display.c
··· 13726 13726 return ret; 13727 13727 } 13728 13728 13729 - drm_atomic_helper_swap_state(dev, state); 13729 + drm_atomic_helper_swap_state(state, true); 13730 13730 dev_priv->wm.distrust_bios_wm = false; 13731 13731 dev_priv->wm.skl_results = intel_state->wm_results; 13732 13732 intel_shared_dpll_commit(state); ··· 16265 16265 intel_cleanup_gt_powersave(dev_priv); 16266 16266 16267 16267 intel_teardown_gmbus(dev); 16268 - } 16269 - 16270 - /* 16271 - * Return which encoder is currently attached for connector. 16272 - */ 16273 - struct drm_encoder *intel_best_encoder(struct drm_connector *connector) 16274 - { 16275 - return &intel_attached_encoder(connector)->base; 16276 16268 } 16277 16269 16278 16270 void intel_connector_attach_encoder(struct intel_connector *connector,
-1
drivers/gpu/drm/i915/intel_dp.c
··· 4580 4580 static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { 4581 4581 .get_modes = intel_dp_get_modes, 4582 4582 .mode_valid = intel_dp_mode_valid, 4583 - .best_encoder = intel_best_encoder, 4584 4583 }; 4585 4584 4586 4585 static const struct drm_encoder_funcs intel_dp_enc_funcs = {
-1
drivers/gpu/drm/i915/intel_drv.h
··· 1154 1154 bool intel_connector_get_hw_state(struct intel_connector *connector); 1155 1155 void intel_connector_attach_encoder(struct intel_connector *connector, 1156 1156 struct intel_encoder *encoder); 1157 - struct drm_encoder *intel_best_encoder(struct drm_connector *connector); 1158 1157 struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, 1159 1158 struct drm_crtc *crtc); 1160 1159 enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
-1
drivers/gpu/drm/i915/intel_dsi.c
··· 1379 1379 static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = { 1380 1380 .get_modes = intel_dsi_get_modes, 1381 1381 .mode_valid = intel_dsi_mode_valid, 1382 - .best_encoder = intel_best_encoder, 1383 1382 }; 1384 1383 1385 1384 static const struct drm_connector_funcs intel_dsi_connector_funcs = {
-1
drivers/gpu/drm/i915/intel_dvo.c
··· 351 351 static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { 352 352 .mode_valid = intel_dvo_mode_valid, 353 353 .get_modes = intel_dvo_get_modes, 354 - .best_encoder = intel_best_encoder, 355 354 }; 356 355 357 356 static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
-2
drivers/gpu/drm/i915/intel_fbdev.c
··· 724 724 return ret; 725 725 } 726 726 727 - ifbdev->helper.atomic = true; 728 - 729 727 dev_priv->fbdev = ifbdev; 730 728 INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker); 731 729
-1
drivers/gpu/drm/i915/intel_hdmi.c
··· 1782 1782 static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { 1783 1783 .get_modes = intel_hdmi_get_modes, 1784 1784 .mode_valid = intel_hdmi_mode_valid, 1785 - .best_encoder = intel_best_encoder, 1786 1785 }; 1787 1786 1788 1787 static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
-1
drivers/gpu/drm/i915/intel_lvds.c
··· 547 547 static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { 548 548 .get_modes = intel_lvds_get_modes, 549 549 .mode_valid = intel_lvds_mode_valid, 550 - .best_encoder = intel_best_encoder, 551 550 }; 552 551 553 552 static const struct drm_connector_funcs intel_lvds_connector_funcs = {
-1
drivers/gpu/drm/i915/intel_sdvo.c
··· 2191 2191 static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { 2192 2192 .get_modes = intel_sdvo_get_modes, 2193 2193 .mode_valid = intel_sdvo_mode_valid, 2194 - .best_encoder = intel_best_encoder, 2195 2194 }; 2196 2195 2197 2196 static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
-1
drivers/gpu/drm/i915/intel_tv.c
··· 1512 1512 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { 1513 1513 .mode_valid = intel_tv_mode_valid, 1514 1514 .get_modes = intel_tv_get_modes, 1515 - .best_encoder = intel_best_encoder, 1516 1515 }; 1517 1516 1518 1517 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
+1 -1
drivers/gpu/drm/mediatek/mtk_drm_drv.c
··· 91 91 mutex_lock(&private->commit.lock); 92 92 flush_work(&private->commit.work); 93 93 94 - drm_atomic_helper_swap_state(drm, state); 94 + drm_atomic_helper_swap_state(state, true); 95 95 96 96 if (async) 97 97 mtk_atomic_schedule(private, state);
-9
drivers/gpu/drm/mediatek/mtk_dsi.c
··· 575 575 return drm_panel_get_modes(dsi->panel); 576 576 } 577 577 578 - static struct drm_encoder *mtk_dsi_connector_best_encoder( 579 - struct drm_connector *connector) 580 - { 581 - struct mtk_dsi *dsi = connector_to_dsi(connector); 582 - 583 - return &dsi->encoder; 584 - } 585 - 586 578 static const struct drm_encoder_helper_funcs mtk_dsi_encoder_helper_funcs = { 587 579 .mode_fixup = mtk_dsi_encoder_mode_fixup, 588 580 .mode_set = mtk_dsi_encoder_mode_set, ··· 595 603 static const struct drm_connector_helper_funcs 596 604 mtk_dsi_connector_helper_funcs = { 597 605 .get_modes = mtk_dsi_connector_get_modes, 598 - .best_encoder = mtk_dsi_connector_best_encoder, 599 606 }; 600 607 601 608 static int mtk_drm_attach_bridge(struct drm_bridge *bridge,
-10
drivers/gpu/drm/msm/edp/edp_connector.c
··· 91 91 return MODE_OK; 92 92 } 93 93 94 - static struct drm_encoder * 95 - edp_connector_best_encoder(struct drm_connector *connector) 96 - { 97 - struct edp_connector *edp_connector = to_edp_connector(connector); 98 - 99 - DBG(""); 100 - return edp_connector->edp->encoder; 101 - } 102 - 103 94 static const struct drm_connector_funcs edp_connector_funcs = { 104 95 .dpms = drm_atomic_helper_connector_dpms, 105 96 .detect = edp_connector_detect, ··· 104 113 static const struct drm_connector_helper_funcs edp_connector_helper_funcs = { 105 114 .get_modes = edp_connector_get_modes, 106 115 .mode_valid = edp_connector_mode_valid, 107 - .best_encoder = edp_connector_best_encoder, 108 116 }; 109 117 110 118 /* initialize connector */
-8
drivers/gpu/drm/msm/hdmi/hdmi_connector.c
··· 406 406 return 0; 407 407 } 408 408 409 - static struct drm_encoder * 410 - msm_hdmi_connector_best_encoder(struct drm_connector *connector) 411 - { 412 - struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector); 413 - return hdmi_connector->hdmi->encoder; 414 - } 415 - 416 409 static const struct drm_connector_funcs hdmi_connector_funcs = { 417 410 .dpms = drm_atomic_helper_connector_dpms, 418 411 .detect = hdmi_connector_detect, ··· 419 426 static const struct drm_connector_helper_funcs msm_hdmi_connector_helper_funcs = { 420 427 .get_modes = msm_hdmi_connector_get_modes, 421 428 .mode_valid = msm_hdmi_connector_mode_valid, 422 - .best_encoder = msm_hdmi_connector_best_encoder, 423 429 }; 424 430 425 431 /* initialize connector */
-9
drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
··· 90 90 return MODE_OK; 91 91 } 92 92 93 - static struct drm_encoder * 94 - mdp4_lvds_connector_best_encoder(struct drm_connector *connector) 95 - { 96 - struct mdp4_lvds_connector *mdp4_lvds_connector = 97 - to_mdp4_lvds_connector(connector); 98 - return mdp4_lvds_connector->encoder; 99 - } 100 - 101 93 static const struct drm_connector_funcs mdp4_lvds_connector_funcs = { 102 94 .dpms = drm_atomic_helper_connector_dpms, 103 95 .detect = mdp4_lvds_connector_detect, ··· 103 111 static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs = { 104 112 .get_modes = mdp4_lvds_connector_get_modes, 105 113 .mode_valid = mdp4_lvds_connector_mode_valid, 106 - .best_encoder = mdp4_lvds_connector_best_encoder, 107 114 }; 108 115 109 116 /* initialize connector */
+1 -1
drivers/gpu/drm/msm/msm_atomic.c
··· 238 238 * the software side now. 239 239 */ 240 240 241 - drm_atomic_helper_swap_state(dev, state); 241 + drm_atomic_helper_swap_state(state, true); 242 242 243 243 /* 244 244 * Everything below can be run asynchronously without the need to grab
+11 -11
drivers/gpu/drm/nouveau/nouveau_display.c
··· 760 760 761 761 /* Initialize a page flip struct */ 762 762 *s = (struct nouveau_page_flip_state) 763 - { { }, event, nouveau_crtc(crtc)->index, 764 - fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y, 763 + { { }, event, crtc, fb->bits_per_pixel, fb->pitches[0], 765 764 new_bo->bo.offset }; 766 765 767 766 /* Keep vblanks on during flip, for the target crtc of this flip */ 768 - drm_vblank_get(dev, nouveau_crtc(crtc)->index); 767 + drm_crtc_vblank_get(crtc); 769 768 770 769 /* Emit a page flip */ 771 770 if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { ··· 809 810 return 0; 810 811 811 812 fail_unreserve: 812 - drm_vblank_put(dev, nouveau_crtc(crtc)->index); 813 + drm_crtc_vblank_put(crtc); 813 814 ttm_bo_unreserve(&old_bo->bo); 814 815 fail_unpin: 815 816 mutex_unlock(&cli->mutex); ··· 841 842 s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 842 843 if (s->event) { 843 844 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 844 - drm_arm_vblank_event(dev, s->crtc, s->event); 845 + drm_crtc_arm_vblank_event(s->crtc, s->event); 845 846 } else { 846 - drm_send_vblank_event(dev, s->crtc, s->event); 847 + drm_crtc_send_vblank_event(s->crtc, s->event); 847 848 848 849 /* Give up ownership of vblank for page-flipped crtc */ 849 - drm_vblank_put(dev, s->crtc); 850 + drm_crtc_vblank_put(s->crtc); 850 851 } 851 852 } 852 853 else { 853 854 /* Give up ownership of vblank for page-flipped crtc */ 854 - drm_vblank_put(dev, s->crtc); 855 + drm_crtc_vblank_put(s->crtc); 855 856 } 856 857 857 858 list_del(&s->head); ··· 872 873 873 874 if (!nouveau_finish_page_flip(chan, &state)) { 874 875 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 875 - nv_set_crtc_base(drm->dev, state.crtc, state.offset + 876 - state.y * state.pitch + 877 - state.x * state.bpp / 8); 876 + nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc), 877 + state.offset + state.crtc->y * 878 + state.pitch + state.crtc->x * 879 + state.bpp / 8); 878 880 } 879 881 } 880 882
+2 -1
drivers/gpu/drm/nouveau/nouveau_display.h
··· 28 28 struct nouveau_page_flip_state { 29 29 struct list_head head; 30 30 struct drm_pending_vblank_event *event; 31 - int crtc, bpp, pitch, x, y; 31 + struct drm_crtc *crtc; 32 + int bpp, pitch; 32 33 u64 offset; 33 34 }; 34 35
-10
drivers/gpu/drm/omapdrm/omap_connector.c
··· 32 32 struct omap_connector { 33 33 struct drm_connector base; 34 34 struct omap_dss_device *dssdev; 35 - struct drm_encoder *encoder; 36 35 bool hdmi_mode; 37 36 }; 38 37 ··· 255 256 return ret; 256 257 } 257 258 258 - struct drm_encoder *omap_connector_attached_encoder( 259 - struct drm_connector *connector) 260 - { 261 - struct omap_connector *omap_connector = to_omap_connector(connector); 262 - return omap_connector->encoder; 263 - } 264 - 265 259 static const struct drm_connector_funcs omap_connector_funcs = { 266 260 .dpms = drm_atomic_helper_connector_dpms, 267 261 .reset = drm_atomic_helper_connector_reset, ··· 268 276 static const struct drm_connector_helper_funcs omap_connector_helper_funcs = { 269 277 .get_modes = omap_connector_get_modes, 270 278 .mode_valid = omap_connector_mode_valid, 271 - .best_encoder = omap_connector_attached_encoder, 272 279 }; 273 280 274 281 /* initialize connector */ ··· 287 296 goto fail; 288 297 289 298 omap_connector->dssdev = dssdev; 290 - omap_connector->encoder = encoder; 291 299 292 300 connector = &omap_connector->base; 293 301
+1 -1
drivers/gpu/drm/omapdrm/omap_drv.c
··· 174 174 spin_unlock(&priv->commit.lock); 175 175 176 176 /* Swap the state, this is the point of no return. */ 177 - drm_atomic_helper_swap_state(dev, state); 177 + drm_atomic_helper_swap_state(state, true); 178 178 179 179 if (nonblock) 180 180 schedule_work(&commit->work);
+2 -2
drivers/gpu/drm/radeon/atombios_crtc.c
··· 276 276 atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); 277 277 atombios_blank_crtc(crtc, ATOM_DISABLE); 278 278 if (dev->num_crtcs > radeon_crtc->crtc_id) 279 - drm_vblank_on(dev, radeon_crtc->crtc_id); 279 + drm_crtc_vblank_on(crtc); 280 280 radeon_crtc_load_lut(crtc); 281 281 break; 282 282 case DRM_MODE_DPMS_STANDBY: 283 283 case DRM_MODE_DPMS_SUSPEND: 284 284 case DRM_MODE_DPMS_OFF: 285 285 if (dev->num_crtcs > radeon_crtc->crtc_id) 286 - drm_vblank_off(dev, radeon_crtc->crtc_id); 286 + drm_crtc_vblank_off(crtc); 287 287 if (radeon_crtc->enabled) 288 288 atombios_blank_crtc(crtc, ATOM_ENABLE); 289 289 if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
+1 -1
drivers/gpu/drm/radeon/radeon_display.c
··· 627 627 return 0; 628 628 629 629 vblank_cleanup: 630 - drm_crtc_vblank_put(&radeon_crtc->base); 630 + drm_crtc_vblank_put(crtc); 631 631 632 632 pflip_cleanup: 633 633 if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) {
+2 -2
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
··· 332 332 WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); 333 333 } 334 334 if (dev->num_crtcs > radeon_crtc->crtc_id) 335 - drm_vblank_on(dev, radeon_crtc->crtc_id); 335 + drm_crtc_vblank_on(crtc); 336 336 radeon_crtc_load_lut(crtc); 337 337 break; 338 338 case DRM_MODE_DPMS_STANDBY: 339 339 case DRM_MODE_DPMS_SUSPEND: 340 340 case DRM_MODE_DPMS_OFF: 341 341 if (dev->num_crtcs > radeon_crtc->crtc_id) 342 - drm_vblank_off(dev, radeon_crtc->crtc_id); 342 + drm_crtc_vblank_off(crtc); 343 343 if (radeon_crtc->crtc_id) 344 344 WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); 345 345 else {
-12
drivers/gpu/drm/rcar-du/rcar_du_encoder.c
··· 27 27 #include "rcar_du_vgacon.h" 28 28 29 29 /* ----------------------------------------------------------------------------- 30 - * Common connector functions 31 - */ 32 - 33 - struct drm_encoder * 34 - rcar_du_connector_best_encoder(struct drm_connector *connector) 35 - { 36 - struct rcar_du_connector *rcon = to_rcar_connector(connector); 37 - 38 - return rcar_encoder_to_drm_encoder(rcon->encoder); 39 - } 40 - 41 - /* ----------------------------------------------------------------------------- 42 30 * Encoder 43 31 */ 44 32
-3
drivers/gpu/drm/rcar-du/rcar_du_encoder.h
··· 49 49 #define to_rcar_connector(c) \ 50 50 container_of(c, struct rcar_du_connector, connector) 51 51 52 - struct drm_encoder * 53 - rcar_du_connector_best_encoder(struct drm_connector *connector); 54 - 55 52 int rcar_du_encoder_init(struct rcar_du_device *rcdu, 56 53 enum rcar_du_encoder_type type, 57 54 enum rcar_du_output output,
-1
drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
··· 52 52 static const struct drm_connector_helper_funcs connector_helper_funcs = { 53 53 .get_modes = rcar_du_hdmi_connector_get_modes, 54 54 .mode_valid = rcar_du_hdmi_connector_mode_valid, 55 - .best_encoder = rcar_du_connector_best_encoder, 56 55 }; 57 56 58 57 static enum drm_connector_status
+1 -1
drivers/gpu/drm/rcar-du/rcar_du_kms.c
··· 327 327 } 328 328 329 329 /* Swap the state, this is the point of no return. */ 330 - drm_atomic_helper_swap_state(dev, state); 330 + drm_atomic_helper_swap_state(state, true); 331 331 332 332 if (nonblock) 333 333 schedule_work(&commit->work);
-1
drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
··· 59 59 60 60 static const struct drm_connector_helper_funcs connector_helper_funcs = { 61 61 .get_modes = rcar_du_lvds_connector_get_modes, 62 - .best_encoder = rcar_du_connector_best_encoder, 63 62 }; 64 63 65 64 static enum drm_connector_status
-3
drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
··· 28 28 29 29 static const struct drm_connector_helper_funcs connector_helper_funcs = { 30 30 .get_modes = rcar_du_vga_connector_get_modes, 31 - .best_encoder = rcar_du_connector_best_encoder, 32 31 }; 33 32 34 33 static enum drm_connector_status ··· 77 78 ret = drm_mode_connector_attach_encoder(connector, encoder); 78 79 if (ret < 0) 79 80 return ret; 80 - 81 - rcon->encoder = renc; 82 81 83 82 return 0; 84 83 }
+4 -13
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
··· 349 349 return 0; 350 350 } 351 351 352 - #ifdef CONFIG_PM_SLEEP 353 - static int rockchip_dp_suspend(struct device *dev) 354 - { 355 - return analogix_dp_suspend(dev); 356 - } 357 - 358 - static int rockchip_dp_resume(struct device *dev) 359 - { 360 - return analogix_dp_resume(dev); 361 - } 362 - #endif 363 - 364 352 static const struct dev_pm_ops rockchip_dp_pm_ops = { 365 - SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume) 353 + #ifdef CONFIG_PM_SLEEP 354 + .suspend = analogix_dp_suspend, 355 + .resume_early = analogix_dp_resume, 356 + #endif 366 357 }; 367 358 368 359 static const struct of_device_id rockchip_dp_dt_ids[] = {
-9
drivers/gpu/drm/rockchip/dw-mipi-dsi.c
··· 964 964 return mode_status; 965 965 } 966 966 967 - static struct drm_encoder *dw_mipi_dsi_connector_best_encoder( 968 - struct drm_connector *connector) 969 - { 970 - struct dw_mipi_dsi *dsi = con_to_dsi(connector); 971 - 972 - return &dsi->encoder; 973 - } 974 - 975 967 static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = { 976 968 .get_modes = dw_mipi_dsi_connector_get_modes, 977 969 .mode_valid = dw_mipi_dsi_mode_valid, 978 - .best_encoder = dw_mipi_dsi_connector_best_encoder, 979 970 }; 980 971 981 972 static enum drm_connector_status
-9
drivers/gpu/drm/rockchip/inno_hdmi.c
··· 579 579 return MODE_OK; 580 580 } 581 581 582 - static struct drm_encoder * 583 - inno_hdmi_connector_best_encoder(struct drm_connector *connector) 584 - { 585 - struct inno_hdmi *hdmi = to_inno_hdmi(connector); 586 - 587 - return &hdmi->encoder; 588 - } 589 - 590 582 static int 591 583 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector, 592 584 uint32_t maxX, uint32_t maxY) ··· 605 613 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = { 606 614 .get_modes = inno_hdmi_connector_get_modes, 607 615 .mode_valid = inno_hdmi_connector_mode_valid, 608 - .best_encoder = inno_hdmi_connector_best_encoder, 609 616 }; 610 617 611 618 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
+60 -134
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
··· 25 25 #include <linux/module.h> 26 26 #include <linux/of_graph.h> 27 27 #include <linux/component.h> 28 + #include <linux/console.h> 28 29 29 30 #include "rockchip_drm_drv.h" 30 31 #include "rockchip_drm_fb.h" ··· 39 38 #define DRIVER_MINOR 0 40 39 41 40 static bool is_support_iommu = true; 41 + static struct drm_driver rockchip_drm_driver; 42 42 43 43 /* 44 44 * Attach a (component) device to the shared drm dma mapping from master drm ··· 135 133 priv->crtc_funcs[pipe]->disable_vblank(crtc); 136 134 } 137 135 138 - static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags) 136 + static int rockchip_drm_bind(struct device *dev) 139 137 { 138 + struct drm_device *drm_dev; 140 139 struct rockchip_drm_private *private; 141 140 struct dma_iommu_mapping *mapping = NULL; 142 - struct device *dev = drm_dev->dev; 143 - struct drm_connector *connector; 144 141 int ret; 145 142 146 - private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL); 147 - if (!private) 143 + drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev); 144 + if (!drm_dev) 148 145 return -ENOMEM; 149 146 150 - mutex_init(&private->commit.lock); 151 - INIT_WORK(&private->commit.work, rockchip_drm_atomic_work); 147 + ret = drm_dev_register(drm_dev, 0); 148 + if (ret) 149 + goto err_free; 150 + 151 + dev_set_drvdata(dev, drm_dev); 152 + 153 + private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL); 154 + if (!private) { 155 + ret = -ENOMEM; 156 + goto err_unregister; 157 + } 152 158 153 159 drm_dev->dev_private = private; 154 160 ··· 197 187 if (ret) 198 188 goto err_detach_device; 199 189 200 - /* 201 - * All components are now added, we can publish the connector sysfs 202 - * entries to userspace. This will generate hotplug events and so 203 - * userspace will expect to be able to access DRM at this point. 204 - */ 205 - list_for_each_entry(connector, &drm_dev->mode_config.connector_list, 206 - head) { 207 - ret = drm_connector_register(connector); 208 - if (ret) { 209 - dev_err(drm_dev->dev, 210 - "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n", 211 - connector->base.id, 212 - connector->name, ret); 213 - goto err_unbind; 214 - } 190 + ret = drm_connector_register_all(drm_dev); 191 + if (ret) { 192 + dev_err(dev, "failed to register connectors\n"); 193 + goto err_unbind; 215 194 } 216 195 217 196 /* init kms poll for handling hpd */ ··· 240 241 err_config_cleanup: 241 242 drm_mode_config_cleanup(drm_dev); 242 243 drm_dev->dev_private = NULL; 244 + err_unregister: 245 + drm_dev_unregister(drm_dev); 246 + err_free: 247 + drm_dev_unref(drm_dev); 243 248 return ret; 244 249 } 245 250 246 - static int rockchip_drm_unload(struct drm_device *drm_dev) 251 + static void rockchip_drm_unbind(struct device *dev) 247 252 { 248 - struct device *dev = drm_dev->dev; 253 + struct drm_device *drm_dev = dev_get_drvdata(dev); 249 254 250 255 rockchip_drm_fbdev_fini(drm_dev); 251 256 drm_vblank_cleanup(drm_dev); ··· 259 256 arm_iommu_detach_device(dev); 260 257 drm_mode_config_cleanup(drm_dev); 261 258 drm_dev->dev_private = NULL; 262 - 263 - return 0; 264 - } 265 - 266 - static void rockchip_drm_crtc_cancel_pending_vblank(struct drm_crtc *crtc, 267 - struct drm_file *file_priv) 268 - { 269 - struct rockchip_drm_private *priv = crtc->dev->dev_private; 270 - int pipe = drm_crtc_index(crtc); 271 - 272 - if (pipe < ROCKCHIP_MAX_CRTC && 273 - priv->crtc_funcs[pipe] && 274 - priv->crtc_funcs[pipe]->cancel_pending_vblank) 275 - priv->crtc_funcs[pipe]->cancel_pending_vblank(crtc, file_priv); 276 - } 277 - 278 - static void rockchip_drm_preclose(struct drm_device *dev, 279 - struct drm_file *file_priv) 280 - { 281 - struct drm_crtc *crtc; 282 - 283 - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 284 - rockchip_drm_crtc_cancel_pending_vblank(crtc, file_priv); 259 + drm_dev_unregister(drm_dev); 260 + drm_dev_unref(drm_dev); 261 + dev_set_drvdata(dev, NULL); 285 262 } 286 263 287 264 void rockchip_drm_lastclose(struct drm_device *dev) ··· 287 304 static struct drm_driver rockchip_drm_driver = { 288 305 .driver_features = DRIVER_MODESET | DRIVER_GEM | 289 306 DRIVER_PRIME | DRIVER_ATOMIC, 290 - .load = rockchip_drm_load, 291 - .unload = rockchip_drm_unload, 292 - .preclose = rockchip_drm_preclose, 293 307 .lastclose = rockchip_drm_lastclose, 294 308 .get_vblank_counter = drm_vblank_no_hw_counter, 295 309 .enable_vblank = rockchip_drm_crtc_enable_vblank, ··· 313 333 }; 314 334 315 335 #ifdef CONFIG_PM_SLEEP 336 + void rockchip_drm_fb_suspend(struct drm_device *drm) 337 + { 338 + struct rockchip_drm_private *priv = drm->dev_private; 339 + 340 + console_lock(); 341 + drm_fb_helper_set_suspend(&priv->fbdev_helper, 1); 342 + console_unlock(); 343 + } 344 + 345 + void rockchip_drm_fb_resume(struct drm_device *drm) 346 + { 347 + struct rockchip_drm_private *priv = drm->dev_private; 348 + 349 + console_lock(); 350 + drm_fb_helper_set_suspend(&priv->fbdev_helper, 0); 351 + console_unlock(); 352 + } 353 + 316 354 static int rockchip_drm_sys_suspend(struct device *dev) 317 355 { 318 356 struct drm_device *drm = dev_get_drvdata(dev); 319 - struct drm_connector *connector; 357 + struct rockchip_drm_private *priv = drm->dev_private; 320 358 321 - if (!drm) 322 - return 0; 359 + drm_kms_helper_poll_disable(drm); 360 + rockchip_drm_fb_suspend(drm); 323 361 324 - drm_modeset_lock_all(drm); 325 - list_for_each_entry(connector, &drm->mode_config.connector_list, head) { 326 - int old_dpms = connector->dpms; 327 - 328 - if (connector->funcs->dpms) 329 - connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF); 330 - 331 - /* Set the old mode back to the connector for resume */ 332 - connector->dpms = old_dpms; 362 + priv->state = drm_atomic_helper_suspend(drm); 363 + if (IS_ERR(priv->state)) { 364 + rockchip_drm_fb_resume(drm); 365 + drm_kms_helper_poll_enable(drm); 366 + return PTR_ERR(priv->state); 333 367 } 334 - drm_modeset_unlock_all(drm); 335 368 336 369 return 0; 337 370 } ··· 352 359 static int rockchip_drm_sys_resume(struct device *dev) 353 360 { 354 361 struct drm_device *drm = dev_get_drvdata(dev); 355 - struct drm_connector *connector; 356 - enum drm_connector_status status; 357 - bool changed = false; 362 + struct rockchip_drm_private *priv = drm->dev_private; 358 363 359 - if (!drm) 360 - return 0; 361 - 362 - drm_modeset_lock_all(drm); 363 - list_for_each_entry(connector, &drm->mode_config.connector_list, head) { 364 - int desired_mode = connector->dpms; 365 - 366 - /* 367 - * at suspend time, we save dpms to connector->dpms, 368 - * restore the old_dpms, and at current time, the connector 369 - * dpms status must be DRM_MODE_DPMS_OFF. 370 - */ 371 - connector->dpms = DRM_MODE_DPMS_OFF; 372 - 373 - /* 374 - * If the connector has been disconnected during suspend, 375 - * disconnect it from the encoder and leave it off. We'll notify 376 - * userspace at the end. 377 - */ 378 - if (desired_mode == DRM_MODE_DPMS_ON) { 379 - status = connector->funcs->detect(connector, true); 380 - if (status == connector_status_disconnected) { 381 - connector->encoder = NULL; 382 - connector->status = status; 383 - changed = true; 384 - continue; 385 - } 386 - } 387 - if (connector->funcs->dpms) 388 - connector->funcs->dpms(connector, desired_mode); 389 - } 390 - drm_modeset_unlock_all(drm); 391 - 392 - drm_helper_resume_force_mode(drm); 393 - 394 - if (changed) 395 - drm_kms_helper_hotplug_event(drm); 364 + drm_atomic_helper_resume(drm, priv->state); 365 + rockchip_drm_fb_resume(drm); 366 + drm_kms_helper_poll_enable(drm); 396 367 397 368 return 0; 398 369 } ··· 395 438 component_match_add(dev, match, compare_of, remote); 396 439 of_node_put(remote); 397 440 } 398 - } 399 - 400 - static int rockchip_drm_bind(struct device *dev) 401 - { 402 - struct drm_device *drm; 403 - int ret; 404 - 405 - drm = drm_dev_alloc(&rockchip_drm_driver, dev); 406 - if (!drm) 407 - return -ENOMEM; 408 - 409 - ret = drm_dev_register(drm, 0); 410 - if (ret) 411 - goto err_free; 412 - 413 - dev_set_drvdata(dev, drm); 414 - 415 - return 0; 416 - 417 - err_free: 418 - drm_dev_unref(drm); 419 - return ret; 420 - } 421 - 422 - static void rockchip_drm_unbind(struct device *dev) 423 - { 424 - struct drm_device *drm = dev_get_drvdata(dev); 425 - 426 - drm_dev_unregister(drm); 427 - drm_dev_unref(drm); 428 - dev_set_drvdata(dev, NULL); 429 441 } 430 442 431 443 static const struct component_master_ops rockchip_drm_ops = {
+1 -11
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
··· 40 40 int (*enable_vblank)(struct drm_crtc *crtc); 41 41 void (*disable_vblank)(struct drm_crtc *crtc); 42 42 void (*wait_for_update)(struct drm_crtc *crtc); 43 - void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file *file_priv); 44 - }; 45 - 46 - struct rockchip_atomic_commit { 47 - struct work_struct work; 48 - struct drm_atomic_state *state; 49 - struct drm_device *dev; 50 - struct mutex lock; 51 43 }; 52 44 53 45 struct rockchip_crtc_state { ··· 60 68 struct drm_fb_helper fbdev_helper; 61 69 struct drm_gem_object *fbdev_bo; 62 70 const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC]; 63 - 64 - struct rockchip_atomic_commit commit; 71 + struct drm_atomic_state *state; 65 72 }; 66 73 67 - void rockchip_drm_atomic_work(struct work_struct *work); 68 74 int rockchip_register_crtc_funcs(struct drm_crtc *crtc, 69 75 const struct rockchip_crtc_funcs *crtc_funcs); 70 76 void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
+9 -63
drivers/gpu/drm/rockchip/rockchip_drm_fb.c
··· 228 228 } 229 229 230 230 static void 231 - rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit) 231 + rockchip_atomic_commit_tail(struct drm_atomic_state *state) 232 232 { 233 - struct drm_atomic_state *state = commit->state; 234 - struct drm_device *dev = commit->dev; 233 + struct drm_device *dev = state->dev; 235 234 236 - /* 237 - * TODO: do fence wait here. 238 - */ 239 - 240 - /* 241 - * Rockchip crtc support runtime PM, can't update display planes 242 - * when crtc is disabled. 243 - * 244 - * drm_atomic_helper_commit comments detail that: 245 - * For drivers supporting runtime PM the recommended sequence is 246 - * 247 - * drm_atomic_helper_commit_modeset_disables(dev, state); 248 - * 249 - * drm_atomic_helper_commit_modeset_enables(dev, state); 250 - * 251 - * drm_atomic_helper_commit_planes(dev, state, true); 252 - * 253 - * See the kerneldoc entries for these three functions for more details. 254 - */ 255 235 drm_atomic_helper_commit_modeset_disables(dev, state); 256 236 257 237 drm_atomic_helper_commit_modeset_enables(dev, state); 258 238 259 239 drm_atomic_helper_commit_planes(dev, state, true); 260 240 241 + drm_atomic_helper_commit_hw_done(state); 242 + 261 243 rockchip_atomic_wait_for_complete(dev, state); 262 244 263 245 drm_atomic_helper_cleanup_planes(dev, state); 264 - 265 - drm_atomic_state_free(state); 266 246 } 267 247 268 - void rockchip_drm_atomic_work(struct work_struct *work) 269 - { 270 - struct rockchip_atomic_commit *commit = container_of(work, 271 - struct rockchip_atomic_commit, work); 272 - 273 - rockchip_atomic_commit_complete(commit); 274 - } 275 - 276 - int rockchip_drm_atomic_commit(struct drm_device *dev, 277 - struct drm_atomic_state *state, 278 - bool nonblock) 279 - { 280 - struct rockchip_drm_private *private = dev->dev_private; 281 - struct rockchip_atomic_commit *commit = &private->commit; 282 - int ret; 283 - 284 - ret = drm_atomic_helper_prepare_planes(dev, state); 285 - if (ret) 286 - return ret; 287 - 288 - /* serialize outstanding nonblocking commits */ 289 - mutex_lock(&commit->lock); 290 - flush_work(&commit->work); 291 - 292 - drm_atomic_helper_swap_state(dev, state); 293 - 294 - commit->dev = dev; 295 - commit->state = state; 296 - 297 - if (nonblock) 298 - schedule_work(&commit->work); 299 - else 300 - rockchip_atomic_commit_complete(commit); 301 - 302 - mutex_unlock(&commit->lock); 303 - 304 - return 0; 305 - } 248 + struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = { 249 + .atomic_commit_tail = rockchip_atomic_commit_tail, 250 + }; 306 251 307 252 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = { 308 253 .fb_create = rockchip_user_fb_create, 309 254 .output_poll_changed = rockchip_drm_output_poll_changed, 310 255 .atomic_check = drm_atomic_helper_check, 311 - .atomic_commit = rockchip_drm_atomic_commit, 256 + .atomic_commit = drm_atomic_helper_commit, 312 257 }; 313 258 314 259 struct drm_framebuffer * ··· 284 339 dev->mode_config.max_height = 4096; 285 340 286 341 dev->mode_config.funcs = &rockchip_drm_mode_config_funcs; 342 + dev->mode_config.helper_private = &rockchip_mode_config_helpers; 287 343 }
+1 -4
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
··· 108 108 fbi->screen_size = rk_obj->base.size; 109 109 fbi->fix.smem_len = rk_obj->base.size; 110 110 111 - DRM_DEBUG_KMS("FB [%dx%d]-%d kvaddr=%p offset=%ld size=%d\n", 111 + DRM_DEBUG_KMS("FB [%dx%d]-%d kvaddr=%p offset=%ld size=%zu\n", 112 112 fb->width, fb->height, fb->depth, rk_obj->kvaddr, 113 113 offset, size); 114 114 ··· 155 155 dev_err(dev->dev, "Failed to add connectors - %d.\n", ret); 156 156 goto err_drm_fb_helper_fini; 157 157 } 158 - 159 - /* disable all the possible outputs/crtcs before entering KMS mode */ 160 - drm_helper_disable_unused_functions(dev); 161 158 162 159 ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); 163 160 if (ret < 0) {
+1 -1
drivers/gpu/drm/rockchip/rockchip_drm_gem.c
··· 38 38 &rk_obj->dma_addr, GFP_KERNEL, 39 39 &rk_obj->dma_attrs); 40 40 if (!rk_obj->kvaddr) { 41 - DRM_ERROR("failed to allocate %#x byte dma buffer", obj->size); 41 + DRM_ERROR("failed to allocate %zu byte dma buffer", obj->size); 42 42 return -ENOMEM; 43 43 } 44 44
+35 -33
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
··· 98 98 const struct vop_win_data *data; 99 99 struct vop *vop; 100 100 101 - struct vop_plane_state state; 101 + /* protected by dev->event_lock */ 102 + bool enable; 103 + dma_addr_t yrgb_mst; 102 104 }; 103 105 104 106 struct vop { ··· 114 112 bool vsync_work_pending; 115 113 struct completion dsp_hold_completion; 116 114 struct completion wait_update_complete; 115 + 116 + /* protected by dev->event_lock */ 117 117 struct drm_pending_vblank_event *event; 118 118 119 119 const struct vop_data *data; ··· 435 431 struct vop *vop = to_vop(crtc); 436 432 int ret; 437 433 438 - if (vop->is_enabled) 439 - return; 440 - 441 434 ret = pm_runtime_get_sync(vop->dev); 442 435 if (ret < 0) { 443 436 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); ··· 502 501 struct vop *vop = to_vop(crtc); 503 502 int i; 504 503 505 - if (!vop->is_enabled) 506 - return; 504 + WARN_ON(vop->event); 507 505 508 506 /* 509 507 * We need to make sure that all windows are disabled before we ··· 553 553 clk_disable(vop->aclk); 554 554 clk_disable(vop->hclk); 555 555 pm_runtime_put(vop->dev); 556 + 557 + if (crtc->state->event && !crtc->state->active) { 558 + spin_lock_irq(&crtc->dev->event_lock); 559 + drm_crtc_send_vblank_event(crtc, crtc->state->event); 560 + spin_unlock_irq(&crtc->dev->event_lock); 561 + 562 + crtc->state->event = NULL; 563 + } 556 564 } 557 565 558 566 static void vop_plane_destroy(struct drm_plane *plane) ··· 666 658 if (!old_state->crtc) 667 659 return; 668 660 661 + spin_lock_irq(&plane->dev->event_lock); 662 + vop_win->enable = false; 663 + vop_win->yrgb_mst = 0; 664 + spin_unlock_irq(&plane->dev->event_lock); 665 + 669 666 spin_lock(&vop->reg_lock); 670 667 671 668 VOP_WIN_SET(vop, win, enable, 0); ··· 705 692 /* 706 693 * can't update plane when vop is disabled. 707 694 */ 708 - if (!crtc) 695 + if (WARN_ON(!crtc)) 709 696 return; 710 697 711 698 if (WARN_ON(!vop->is_enabled)) ··· 733 720 offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0); 734 721 offset += (src->y1 >> 16) * fb->pitches[0]; 735 722 vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; 723 + 724 + spin_lock_irq(&plane->dev->event_lock); 725 + vop_win->enable = true; 726 + vop_win->yrgb_mst = vop_plane_state->yrgb_mst; 727 + spin_unlock_irq(&plane->dev->event_lock); 736 728 737 729 spin_lock(&vop->reg_lock); 738 730 ··· 894 876 WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100)); 895 877 } 896 878 897 - static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc, 898 - struct drm_file *file_priv) 899 - { 900 - struct drm_device *drm = crtc->dev; 901 - struct vop *vop = to_vop(crtc); 902 - struct drm_pending_vblank_event *e; 903 - unsigned long flags; 904 - 905 - spin_lock_irqsave(&drm->event_lock, flags); 906 - e = vop->event; 907 - if (e && e->base.file_priv == file_priv) { 908 - vop->event = NULL; 909 - 910 - kfree(&e->base); 911 - file_priv->event_space += sizeof(e->event); 912 - } 913 - spin_unlock_irqrestore(&drm->event_lock, flags); 914 - } 915 - 916 879 static const struct rockchip_crtc_funcs private_crtc_funcs = { 917 880 .enable_vblank = vop_crtc_enable_vblank, 918 881 .disable_vblank = vop_crtc_disable_vblank, 919 882 .wait_for_update = vop_crtc_wait_for_update, 920 - .cancel_pending_vblank = vop_crtc_cancel_pending_vblank, 921 883 }; 922 884 923 885 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, ··· 928 930 u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start; 929 931 u16 vact_end = vact_st + vdisplay; 930 932 uint32_t val; 933 + 934 + WARN_ON(vop->event); 931 935 932 936 vop_enable(crtc); 933 937 /* ··· 1027 1027 { 1028 1028 struct vop *vop = to_vop(crtc); 1029 1029 1030 + spin_lock_irq(&crtc->dev->event_lock); 1030 1031 if (crtc->state->event) { 1031 1032 WARN_ON(drm_crtc_vblank_get(crtc) != 0); 1033 + WARN_ON(vop->event); 1032 1034 1033 1035 vop->event = crtc->state->event; 1034 1036 crtc->state->event = NULL; 1035 1037 } 1038 + spin_unlock_irq(&crtc->dev->event_lock); 1036 1039 } 1037 1040 1038 1041 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = { ··· 1083 1080 1084 1081 static bool vop_win_pending_is_complete(struct vop_win *vop_win) 1085 1082 { 1086 - struct drm_plane *plane = &vop_win->base; 1087 - struct vop_plane_state *state = to_vop_plane_state(plane->state); 1088 1083 dma_addr_t yrgb_mst; 1089 1084 1090 - if (!state->enable) 1085 + if (!vop_win->enable) 1091 1086 return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0; 1092 1087 1093 1088 yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data); 1094 1089 1095 - return yrgb_mst == state->yrgb_mst; 1090 + return yrgb_mst == vop_win->yrgb_mst; 1096 1091 } 1097 1092 1098 1093 static void vop_handle_vblank(struct vop *vop) ··· 1105 1104 return; 1106 1105 } 1107 1106 1107 + spin_lock_irqsave(&drm->event_lock, flags); 1108 1108 if (vop->event) { 1109 - spin_lock_irqsave(&drm->event_lock, flags); 1110 1109 1111 1110 drm_crtc_send_vblank_event(crtc, vop->event); 1112 1111 drm_crtc_vblank_put(crtc); 1113 1112 vop->event = NULL; 1114 1113 1115 - spin_unlock_irqrestore(&drm->event_lock, flags); 1116 1114 } 1115 + spin_unlock_irqrestore(&drm->event_lock, flags); 1116 + 1117 1117 if (!completion_done(&vop->wait_update_complete)) 1118 1118 complete(&vop->wait_update_complete); 1119 1119 }
+1 -1
drivers/gpu/drm/sti/sti_drv.c
··· 215 215 * the software side now. 216 216 */ 217 217 218 - drm_atomic_helper_swap_state(drm, state); 218 + drm_atomic_helper_swap_state(state, true); 219 219 220 220 if (nonblock) 221 221 sti_atomic_schedule(private, state);
-10
drivers/gpu/drm/sti/sti_dvo.c
··· 377 377 return MODE_OK; 378 378 } 379 379 380 - struct drm_encoder *sti_dvo_best_encoder(struct drm_connector *connector) 381 - { 382 - struct sti_dvo_connector *dvo_connector 383 - = to_sti_dvo_connector(connector); 384 - 385 - /* Best encoder is the one associated during connector creation */ 386 - return dvo_connector->encoder; 387 - } 388 - 389 380 static const 390 381 struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = { 391 382 .get_modes = sti_dvo_connector_get_modes, 392 383 .mode_valid = sti_dvo_connector_mode_valid, 393 - .best_encoder = sti_dvo_best_encoder, 394 384 }; 395 385 396 386 static enum drm_connector_status
-10
drivers/gpu/drm/sti/sti_hda.c
··· 669 669 return MODE_OK; 670 670 } 671 671 672 - struct drm_encoder *sti_hda_best_encoder(struct drm_connector *connector) 673 - { 674 - struct sti_hda_connector *hda_connector 675 - = to_sti_hda_connector(connector); 676 - 677 - /* Best encoder is the one associated during connector creation */ 678 - return hda_connector->encoder; 679 - } 680 - 681 672 static const 682 673 struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = { 683 674 .get_modes = sti_hda_connector_get_modes, 684 675 .mode_valid = sti_hda_connector_mode_valid, 685 - .best_encoder = sti_hda_best_encoder, 686 676 }; 687 677 688 678 static enum drm_connector_status
-10
drivers/gpu/drm/sti/sti_hdmi.c
··· 890 890 return MODE_OK; 891 891 } 892 892 893 - struct drm_encoder *sti_hdmi_best_encoder(struct drm_connector *connector) 894 - { 895 - struct sti_hdmi_connector *hdmi_connector 896 - = to_sti_hdmi_connector(connector); 897 - 898 - /* Best encoder is the one associated during connector creation */ 899 - return hdmi_connector->encoder; 900 - } 901 - 902 893 static const 903 894 struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = { 904 895 .get_modes = sti_hdmi_connector_get_modes, 905 896 .mode_valid = sti_hdmi_connector_mode_valid, 906 - .best_encoder = sti_hdmi_best_encoder, 907 897 }; 908 898 909 899 /* get detection status of display device */
+12
drivers/gpu/drm/sun4i/sun4i_crtc.c
··· 51 51 { 52 52 struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); 53 53 struct sun4i_drv *drv = scrtc->drv; 54 + struct drm_pending_vblank_event *event = crtc->state->event; 54 55 55 56 DRM_DEBUG_DRIVER("Committing plane changes\n"); 56 57 57 58 sun4i_backend_commit(drv->backend); 59 + 60 + if (event) { 61 + crtc->state->event = NULL; 62 + 63 + spin_lock_irq(&crtc->dev->event_lock); 64 + if (drm_crtc_vblank_get(crtc) == 0) 65 + drm_crtc_arm_vblank_event(crtc, event); 66 + else 67 + drm_crtc_send_vblank_event(crtc, event); 68 + spin_unlock_irq(&crtc->dev->event_lock); 69 + } 58 70 } 59 71 60 72 static void sun4i_crtc_disable(struct drm_crtc *crtc)
-10
drivers/gpu/drm/sun4i/sun4i_rgb.c
··· 90 90 return MODE_OK; 91 91 } 92 92 93 - static struct drm_encoder * 94 - sun4i_rgb_best_encoder(struct drm_connector *connector) 95 - { 96 - struct sun4i_rgb *rgb = 97 - drm_connector_to_sun4i_rgb(connector); 98 - 99 - return &rgb->encoder; 100 - } 101 - 102 93 static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = { 103 94 .get_modes = sun4i_rgb_get_modes, 104 95 .mode_valid = sun4i_rgb_mode_valid, 105 - .best_encoder = sun4i_rgb_best_encoder, 106 96 }; 107 97 108 98 static enum drm_connector_status
-9
drivers/gpu/drm/sun4i/sun4i_tv.c
··· 526 526 return MODE_OK; 527 527 } 528 528 529 - static struct drm_encoder * 530 - sun4i_tv_comp_best_encoder(struct drm_connector *connector) 531 - { 532 - struct sun4i_tv *tv = drm_connector_to_sun4i_tv(connector); 533 - 534 - return &tv->encoder; 535 - } 536 - 537 529 static struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs = { 538 530 .get_modes = sun4i_tv_comp_get_modes, 539 531 .mode_valid = sun4i_tv_comp_mode_valid, 540 - .best_encoder = sun4i_tv_comp_best_encoder, 541 532 }; 542 533 543 534 static enum drm_connector_status
+1 -1
drivers/gpu/drm/tegra/drm.c
··· 93 93 * the software side now. 94 94 */ 95 95 96 - drm_atomic_helper_swap_state(drm, state); 96 + drm_atomic_helper_swap_state(state, true); 97 97 98 98 if (nonblock) 99 99 tegra_atomic_schedule(tegra, state);
-2
drivers/gpu/drm/tegra/drm.h
··· 239 239 void tegra_output_exit(struct tegra_output *output); 240 240 241 241 int tegra_output_connector_get_modes(struct drm_connector *connector); 242 - struct drm_encoder * 243 - tegra_output_connector_best_encoder(struct drm_connector *connector); 244 242 enum drm_connector_status 245 243 tegra_output_connector_detect(struct drm_connector *connector, bool force); 246 244 void tegra_output_connector_destroy(struct drm_connector *connector);
-1
drivers/gpu/drm/tegra/dsi.c
··· 794 794 static const struct drm_connector_helper_funcs tegra_dsi_connector_helper_funcs = { 795 795 .get_modes = tegra_output_connector_get_modes, 796 796 .mode_valid = tegra_dsi_connector_mode_valid, 797 - .best_encoder = tegra_output_connector_best_encoder, 798 797 }; 799 798 800 799 static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = {
-1
drivers/gpu/drm/tegra/hdmi.c
··· 806 806 tegra_hdmi_connector_helper_funcs = { 807 807 .get_modes = tegra_output_connector_get_modes, 808 808 .mode_valid = tegra_hdmi_connector_mode_valid, 809 - .best_encoder = tegra_output_connector_best_encoder, 810 809 }; 811 810 812 811 static const struct drm_encoder_funcs tegra_hdmi_encoder_funcs = {
-8
drivers/gpu/drm/tegra/output.c
··· 42 42 return err; 43 43 } 44 44 45 - struct drm_encoder * 46 - tegra_output_connector_best_encoder(struct drm_connector *connector) 47 - { 48 - struct tegra_output *output = connector_to_output(connector); 49 - 50 - return &output->encoder; 51 - } 52 - 53 45 enum drm_connector_status 54 46 tegra_output_connector_detect(struct drm_connector *connector, bool force) 55 47 {
-1
drivers/gpu/drm/tegra/rgb.c
··· 112 112 static const struct drm_connector_helper_funcs tegra_rgb_connector_helper_funcs = { 113 113 .get_modes = tegra_output_connector_get_modes, 114 114 .mode_valid = tegra_rgb_connector_mode_valid, 115 - .best_encoder = tegra_output_connector_best_encoder, 116 115 }; 117 116 118 117 static const struct drm_encoder_funcs tegra_rgb_encoder_funcs = {
-1
drivers/gpu/drm/tegra/sor.c
··· 1087 1087 static const struct drm_connector_helper_funcs tegra_sor_connector_helper_funcs = { 1088 1088 .get_modes = tegra_sor_connector_get_modes, 1089 1089 .mode_valid = tegra_sor_connector_mode_valid, 1090 - .best_encoder = tegra_output_connector_best_encoder, 1091 1090 }; 1092 1091 1093 1092 static const struct drm_encoder_funcs tegra_sor_encoder_funcs = {
-9
drivers/gpu/drm/vc4/vc4_dpi.c
··· 208 208 return 0; 209 209 } 210 210 211 - static struct drm_encoder * 212 - vc4_dpi_connector_best_encoder(struct drm_connector *connector) 213 - { 214 - struct vc4_dpi_connector *dpi_connector = 215 - to_vc4_dpi_connector(connector); 216 - return dpi_connector->encoder; 217 - } 218 - 219 211 static const struct drm_connector_funcs vc4_dpi_connector_funcs = { 220 212 .dpms = drm_atomic_helper_connector_dpms, 221 213 .detect = vc4_dpi_connector_detect, ··· 220 228 221 229 static const struct drm_connector_helper_funcs vc4_dpi_connector_helper_funcs = { 222 230 .get_modes = vc4_dpi_connector_get_modes, 223 - .best_encoder = vc4_dpi_connector_best_encoder, 224 231 }; 225 232 226 233 static struct drm_connector *vc4_dpi_connector_init(struct drm_device *dev,
-9
drivers/gpu/drm/vc4/vc4_hdmi.c
··· 208 208 return ret; 209 209 } 210 210 211 - static struct drm_encoder * 212 - vc4_hdmi_connector_best_encoder(struct drm_connector *connector) 213 - { 214 - struct vc4_hdmi_connector *hdmi_connector = 215 - to_vc4_hdmi_connector(connector); 216 - return hdmi_connector->encoder; 217 - } 218 - 219 211 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { 220 212 .dpms = drm_atomic_helper_connector_dpms, 221 213 .detect = vc4_hdmi_connector_detect, ··· 220 228 221 229 static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = { 222 230 .get_modes = vc4_hdmi_connector_get_modes, 223 - .best_encoder = vc4_hdmi_connector_best_encoder, 224 231 }; 225 232 226 233 static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
+1 -1
drivers/gpu/drm/vc4/vc4_kms.c
··· 148 148 * the software side now. 149 149 */ 150 150 151 - drm_atomic_helper_swap_state(dev, state); 151 + drm_atomic_helper_swap_state(state, true); 152 152 153 153 /* 154 154 * Everything below can be run asynchronously without the need to grab
+13 -68
drivers/gpu/drm/virtio/virtgpu_display.c
··· 38 38 #define XRES_MAX 8192 39 39 #define YRES_MAX 8192 40 40 41 - static int virtio_gpu_page_flip(struct drm_crtc *crtc, 42 - struct drm_framebuffer *fb, 43 - struct drm_pending_vblank_event *event, 44 - uint32_t flags) 45 - { 46 - struct virtio_gpu_device *vgdev = crtc->dev->dev_private; 47 - struct virtio_gpu_output *output = 48 - container_of(crtc, struct virtio_gpu_output, crtc); 49 - struct drm_plane *plane = crtc->primary; 50 - struct virtio_gpu_framebuffer *vgfb; 51 - struct virtio_gpu_object *bo; 52 - unsigned long irqflags; 53 - uint32_t handle; 54 - 55 - plane->fb = fb; 56 - vgfb = to_virtio_gpu_framebuffer(plane->fb); 57 - bo = gem_to_virtio_gpu_obj(vgfb->obj); 58 - handle = bo->hw_res_handle; 59 - 60 - DRM_DEBUG("handle 0x%x%s, crtc %dx%d\n", handle, 61 - bo->dumb ? ", dumb" : "", 62 - crtc->mode.hdisplay, crtc->mode.vdisplay); 63 - if (bo->dumb) { 64 - virtio_gpu_cmd_transfer_to_host_2d 65 - (vgdev, handle, 0, 66 - cpu_to_le32(crtc->mode.hdisplay), 67 - cpu_to_le32(crtc->mode.vdisplay), 68 - 0, 0, NULL); 69 - } 70 - virtio_gpu_cmd_set_scanout(vgdev, output->index, handle, 71 - crtc->mode.hdisplay, 72 - crtc->mode.vdisplay, 0, 0); 73 - virtio_gpu_cmd_resource_flush(vgdev, handle, 0, 0, 74 - crtc->mode.hdisplay, 75 - crtc->mode.vdisplay); 76 - 77 - if (event) { 78 - spin_lock_irqsave(&crtc->dev->event_lock, irqflags); 79 - drm_crtc_send_vblank_event(crtc, event); 80 - spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags); 81 - } 82 - 83 - return 0; 84 - } 85 - 86 41 static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { 87 42 .set_config = drm_atomic_helper_set_config, 88 43 .destroy = drm_crtc_cleanup, 89 44 90 - .page_flip = virtio_gpu_page_flip, 45 + .page_flip = drm_atomic_helper_page_flip, 91 46 .reset = drm_atomic_helper_crtc_reset, 92 47 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 93 48 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, ··· 140 185 spin_lock_irqsave(&crtc->dev->event_lock, flags); 141 186 if (crtc->state->event) 142 187 drm_crtc_send_vblank_event(crtc, crtc->state->event); 188 + crtc->state->event = NULL; 143 189 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 144 190 } 145 191 ··· 215 259 return MODE_BAD; 216 260 } 217 261 218 - static struct drm_encoder* 219 - virtio_gpu_best_encoder(struct drm_connector *connector) 220 - { 221 - struct virtio_gpu_output *virtio_gpu_output = 222 - drm_connector_to_virtio_gpu_output(connector); 223 - 224 - return &virtio_gpu_output->enc; 225 - } 226 - 227 262 static const struct drm_encoder_helper_funcs virtio_gpu_enc_helper_funcs = { 228 263 .mode_set = virtio_gpu_enc_mode_set, 229 264 .enable = virtio_gpu_enc_enable, ··· 224 277 static const struct drm_connector_helper_funcs virtio_gpu_conn_helper_funcs = { 225 278 .get_modes = virtio_gpu_conn_get_modes, 226 279 .mode_valid = virtio_gpu_conn_mode_valid, 227 - .best_encoder = virtio_gpu_best_encoder, 228 280 }; 229 281 230 282 static enum drm_connector_status virtio_gpu_conn_detect( ··· 334 388 return &virtio_gpu_fb->base; 335 389 } 336 390 337 - static int vgdev_atomic_commit(struct drm_device *dev, 338 - struct drm_atomic_state *state, 339 - bool nonblock) 391 + static void vgdev_atomic_commit_tail(struct drm_atomic_state *state) 340 392 { 341 - if (nonblock) 342 - return -EBUSY; 343 - 344 - drm_atomic_helper_swap_state(dev, state); 345 - drm_atomic_helper_wait_for_fences(dev, state); 393 + struct drm_device *dev = state->dev; 346 394 347 395 drm_atomic_helper_commit_modeset_disables(dev, state); 348 396 drm_atomic_helper_commit_modeset_enables(dev, state); 349 397 drm_atomic_helper_commit_planes(dev, state, true); 350 398 399 + drm_atomic_helper_commit_hw_done(state); 400 + 351 401 drm_atomic_helper_wait_for_vblanks(dev, state); 352 402 drm_atomic_helper_cleanup_planes(dev, state); 353 - drm_atomic_state_free(state); 354 - return 0; 355 403 } 404 + 405 + struct drm_mode_config_helper_funcs virtio_mode_config_helpers = { 406 + .atomic_commit_tail = vgdev_atomic_commit_tail, 407 + }; 356 408 357 409 static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { 358 410 .fb_create = virtio_gpu_user_framebuffer_create, 359 411 .atomic_check = drm_atomic_helper_check, 360 - .atomic_commit = vgdev_atomic_commit, 412 + .atomic_commit = drm_atomic_helper_commit, 361 413 }; 362 414 363 415 int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) ··· 363 419 int i; 364 420 365 421 drm_mode_config_init(vgdev->ddev); 366 - vgdev->ddev->mode_config.funcs = (void *)&virtio_gpu_mode_funcs; 422 + vgdev->ddev->mode_config.funcs = &virtio_gpu_mode_funcs; 423 + vgdev->ddev->mode_config.helper_private = &virtio_mode_config_helpers; 367 424 368 425 /* modes will be validated against the framebuffer size */ 369 426 vgdev->ddev->mode_config.min_width = XRES_MIN;
+2 -5
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
··· 293 293 struct vmw_cmdbuf_man *man = header->man; 294 294 u32 val; 295 295 296 - if (sizeof(header->handle) > 4) 297 - val = (header->handle >> 32); 298 - else 299 - val = 0; 296 + val = upper_32_bits(header->handle); 300 297 vmw_write(man->dev_priv, SVGA_REG_COMMAND_HIGH, val); 301 298 302 - val = (header->handle & 0xFFFFFFFFULL); 299 + val = lower_32_bits(header->handle); 303 300 val |= header->cb_context & SVGA_CB_CONTEXT_MASK; 304 301 vmw_write(man->dev_priv, SVGA_REG_COMMAND_LOW, val); 305 302
+2 -8
include/drm/drmP.h
··· 68 68 69 69 #include <drm/drm_agpsupport.h> 70 70 #include <drm/drm_crtc.h> 71 + #include <drm/drm_fourcc.h> 71 72 #include <drm/drm_global.h> 72 73 #include <drm/drm_hashtab.h> 73 74 #include <drm/drm_mem_util.h> ··· 284 283 285 284 /* Event queued up for userspace to read */ 286 285 struct drm_pending_event { 286 + struct completion *completion; 287 287 struct drm_event *event; 288 288 struct fence *fence; 289 289 struct list_head link; ··· 419 417 void (*postclose) (struct drm_device *, struct drm_file *); 420 418 void (*lastclose) (struct drm_device *); 421 419 int (*unload) (struct drm_device *); 422 - int (*suspend) (struct drm_device *, pm_message_t state); 423 - int (*resume) (struct drm_device *); 424 420 int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); 425 421 int (*dma_quiescent) (struct drm_device *); 426 422 int (*context_dtor) (struct drm_device *dev, int context); ··· 969 969 struct timeval *vblanktime); 970 970 extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, 971 971 struct timeval *vblanktime); 972 - extern void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe, 973 - struct drm_pending_vblank_event *e); 974 972 extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, 975 973 struct drm_pending_vblank_event *e); 976 - extern void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe, 977 - struct drm_pending_vblank_event *e); 978 974 extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, 979 975 struct drm_pending_vblank_event *e); 980 976 extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); 981 977 extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc); 982 - extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe); 983 - extern void drm_vblank_put(struct drm_device *dev, unsigned int pipe); 984 978 extern int drm_crtc_vblank_get(struct drm_crtc *crtc); 985 979 extern void drm_crtc_vblank_put(struct drm_crtc *crtc); 986 980 extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
+16
include/drm/drm_atomic.h
··· 30 30 31 31 #include <drm/drm_crtc.h> 32 32 33 + void drm_crtc_commit_put(struct drm_crtc_commit *commit); 34 + static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit) 35 + { 36 + kref_get(&commit->ref); 37 + } 38 + 33 39 struct drm_atomic_state * __must_check 34 40 drm_atomic_state_alloc(struct drm_device *dev); 35 41 void drm_atomic_state_clear(struct drm_atomic_state *state); ··· 204 198 (plane_state) = (__state)->planes[__i].state, 1); \ 205 199 (__i)++) \ 206 200 for_each_if (plane_state) 201 + 202 + /** 203 + * drm_atomic_crtc_needs_modeset - compute combined modeset need 204 + * @state: &drm_crtc_state for the CRTC 205 + * 206 + * To give drivers flexibility struct &drm_crtc_state has 3 booleans to track 207 + * whether the state CRTC changed enough to need a full modeset cycle: 208 + * connectors_changed, mode_changed and active_change. This helper simply 209 + * combines these three to compute the overall need for a modeset for @state. 210 + */ 207 211 static inline bool 208 212 drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) 209 213 {
+11 -3
include/drm/drm_atomic_helper.h
··· 38 38 struct drm_atomic_state *state); 39 39 int drm_atomic_helper_check(struct drm_device *dev, 40 40 struct drm_atomic_state *state); 41 + void drm_atomic_helper_commit_tail(struct drm_atomic_state *state); 41 42 int drm_atomic_helper_commit(struct drm_device *dev, 42 43 struct drm_atomic_state *state, 43 44 bool nonblock); ··· 72 71 void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc, 73 72 bool atomic); 74 73 75 - void drm_atomic_helper_swap_state(struct drm_device *dev, 76 - struct drm_atomic_state *state); 74 + void drm_atomic_helper_swap_state(struct drm_atomic_state *state, 75 + bool stall); 76 + 77 + /* nonblocking commit helpers */ 78 + int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, 79 + bool nonblock); 80 + void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state); 81 + void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state); 82 + void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state); 77 83 78 84 /* implementations for legacy interfaces */ 79 85 int drm_atomic_helper_update_plane(struct drm_plane *plane, ··· 167 159 * This iterates over the current state, useful (for example) when applying 168 160 * atomic state after it has been checked and swapped. To iterate over the 169 161 * planes which *will* be attached (for ->atomic_check()) see 170 - * drm_crtc_for_each_pending_plane(). 162 + * drm_atomic_crtc_state_for_each_plane(). 171 163 */ 172 164 #define drm_atomic_crtc_for_each_plane(plane, crtc) \ 173 165 drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask)
+146 -15
include/drm/drm_crtc.h
··· 728 728 * @gamma_store: gamma ramp values 729 729 * @helper_private: mid-layer private data 730 730 * @properties: property tracking for this CRTC 731 - * @state: current atomic state for this CRTC 732 - * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for 733 - * legacy IOCTLs 734 731 * 735 732 * Each CRTC may have one or more connectors associated with it. This structure 736 733 * allows the CRTC to be controlled. ··· 784 787 785 788 struct drm_object_properties properties; 786 789 790 + /** 791 + * @state: 792 + * 793 + * Current atomic state for this CRTC. 794 + */ 787 795 struct drm_crtc_state *state; 788 796 789 - /* 790 - * For legacy crtc IOCTLs so that atomic drivers can get at the locking 791 - * acquire context. 797 + /** 798 + * @commit_list: 799 + * 800 + * List of &drm_crtc_commit structures tracking pending commits. 801 + * Protected by @commit_lock. This list doesn't hold its own full 802 + * reference, but burrows it from the ongoing commit. Commit entries 803 + * must be removed from this list once the commit is fully completed, 804 + * but before it's correspoding &drm_atomic_state gets destroyed. 805 + */ 806 + struct list_head commit_list; 807 + 808 + /** 809 + * @commit_lock: 810 + * 811 + * Spinlock to protect @commit_list. 812 + */ 813 + spinlock_t commit_lock; 814 + 815 + /** 816 + * @acquire_ctx: 817 + * 818 + * Per-CRTC implicit acquire context used by atomic drivers for legacy 819 + * IOCTLs, so that atomic drivers can get at the locking acquire 820 + * context. 792 821 */ 793 822 struct drm_modeset_acquire_ctx *acquire_ctx; 794 823 }; ··· 1756 1733 void *driver_private; 1757 1734 }; 1758 1735 1736 + /** 1737 + * struct drm_crtc_commit - track modeset commits on a CRTC 1738 + * 1739 + * This structure is used to track pending modeset changes and atomic commit on 1740 + * a per-CRTC basis. Since updating the list should never block this structure 1741 + * is reference counted to allow waiters to safely wait on an event to complete, 1742 + * without holding any locks. 1743 + * 1744 + * It has 3 different events in total to allow a fine-grained synchronization 1745 + * between outstanding updates:: 1746 + * 1747 + * atomic commit thread hardware 1748 + * 1749 + * write new state into hardware ----> ... 1750 + * signal hw_done 1751 + * switch to new state on next 1752 + * ... v/hblank 1753 + * 1754 + * wait for buffers to show up ... 1755 + * 1756 + * ... send completion irq 1757 + * irq handler signals flip_done 1758 + * cleanup old buffers 1759 + * 1760 + * signal cleanup_done 1761 + * 1762 + * wait for flip_done <---- 1763 + * clean up atomic state 1764 + * 1765 + * The important bit to know is that cleanup_done is the terminal event, but the 1766 + * ordering between flip_done and hw_done is entirely up to the specific driver 1767 + * and modeset state change. 1768 + * 1769 + * For an implementation of how to use this look at 1770 + * drm_atomic_helper_setup_commit() from the atomic helper library. 1771 + */ 1772 + struct drm_crtc_commit { 1773 + /** 1774 + * @crtc: 1775 + * 1776 + * DRM CRTC for this commit. 1777 + */ 1778 + struct drm_crtc *crtc; 1779 + 1780 + /** 1781 + * @ref: 1782 + * 1783 + * Reference count for this structure. Needed to allow blocking on 1784 + * completions without the risk of the completion disappearing 1785 + * meanwhile. 1786 + */ 1787 + struct kref ref; 1788 + 1789 + /** 1790 + * @flip_done: 1791 + * 1792 + * Will be signaled when the hardware has flipped to the new set of 1793 + * buffers. Signals at the same time as when the drm event for this 1794 + * commit is sent to userspace, or when an out-fence is singalled. Note 1795 + * that for most hardware, in most cases this happens after @hw_done is 1796 + * signalled. 1797 + */ 1798 + struct completion flip_done; 1799 + 1800 + /** 1801 + * @hw_done: 1802 + * 1803 + * Will be signalled when all hw register changes for this commit have 1804 + * been written out. Especially when disabling a pipe this can be much 1805 + * later than than @flip_done, since that can signal already when the 1806 + * screen goes black, whereas to fully shut down a pipe more register 1807 + * I/O is required. 1808 + * 1809 + * Note that this does not need to include separately reference-counted 1810 + * resources like backing storage buffer pinning, or runtime pm 1811 + * management. 1812 + */ 1813 + struct completion hw_done; 1814 + 1815 + /** 1816 + * @cleanup_done: 1817 + * 1818 + * Will be signalled after old buffers have been cleaned up by calling 1819 + * drm_atomic_helper_cleanup_planes(). Since this can only happen after 1820 + * a vblank wait completed it might be a bit later. This completion is 1821 + * useful to throttle updates and avoid hardware updates getting ahead 1822 + * of the buffer cleanup too much. 1823 + */ 1824 + struct completion cleanup_done; 1825 + 1826 + /** 1827 + * @commit_entry: 1828 + * 1829 + * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock. 1830 + */ 1831 + struct list_head commit_entry; 1832 + 1833 + /** 1834 + * @event: 1835 + * 1836 + * &drm_pending_vblank_event pointer to clean up private events. 1837 + */ 1838 + struct drm_pending_vblank_event *event; 1839 + }; 1840 + 1759 1841 struct __drm_planes_state { 1760 1842 struct drm_plane *ptr; 1761 1843 struct drm_plane_state *state; ··· 1869 1741 struct __drm_crtcs_state { 1870 1742 struct drm_crtc *ptr; 1871 1743 struct drm_crtc_state *state; 1744 + struct drm_crtc_commit *commit; 1872 1745 }; 1873 1746 1874 1747 struct __drm_connnectors_state { ··· 1900 1771 struct __drm_connnectors_state *connectors; 1901 1772 1902 1773 struct drm_modeset_acquire_ctx *acquire_ctx; 1774 + 1775 + /** 1776 + * @commit_work: 1777 + * 1778 + * Work item which can be used by the driver or helpers to execute the 1779 + * commit without blocking. 1780 + */ 1781 + struct work_struct commit_work; 1903 1782 }; 1904 1783 1905 1784 ··· 2248 2111 * @async_page_flip: does this device support async flips on the primary plane? 2249 2112 * @cursor_width: hint to userspace for max cursor width 2250 2113 * @cursor_height: hint to userspace for max cursor height 2114 + * @helper_private: mid-layer private data 2251 2115 * 2252 2116 * Core mode resource tracking structure. All CRTC, encoders, and connectors 2253 2117 * enumerated by the driver are added here, as are global properties. Some ··· 2392 2254 2393 2255 /* cursor size */ 2394 2256 uint32_t cursor_width, cursor_height; 2257 + 2258 + struct drm_mode_config_helper_funcs *helper_private; 2395 2259 }; 2396 2260 2397 2261 /** ··· 2785 2645 extern int drm_mode_atomic_ioctl(struct drm_device *dev, 2786 2646 void *data, struct drm_file *file_priv); 2787 2647 2788 - extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, 2789 - int *bpp); 2790 - extern int drm_format_num_planes(uint32_t format); 2791 - extern int drm_format_plane_cpp(uint32_t format, int plane); 2792 - extern int drm_format_horz_chroma_subsampling(uint32_t format); 2793 - extern int drm_format_vert_chroma_subsampling(uint32_t format); 2794 - extern int drm_format_plane_width(int width, uint32_t format, int plane); 2795 - extern int drm_format_plane_height(int height, uint32_t format, int plane); 2796 - extern const char *drm_get_format_name(uint32_t format); 2797 2648 extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, 2798 2649 unsigned int supported_rotations); 2799 2650 extern unsigned int drm_rotation_simplify(unsigned int rotation,
-11
include/drm/drm_fb_helper.h
··· 212 212 * needs to be reprobe when fbdev is in control again. 213 213 */ 214 214 bool delayed_hotplug; 215 - 216 - /** 217 - * @atomic: 218 - * 219 - * Use atomic updates for restore_fbdev_mode(), etc. This defaults to 220 - * true if driver has DRIVER_ATOMIC feature flag, but drivers can 221 - * override it to true after drm_fb_helper_init() if they support atomic 222 - * modeset but do not yet advertise DRIVER_ATOMIC (note that fb-helper 223 - * does not require ASYNC commits). 224 - */ 225 - bool atomic; 226 215 }; 227 216 228 217 #ifdef CONFIG_DRM_FBDEV_EMULATION
+37
include/drm/drm_fourcc.h
··· 1 + /* 2 + * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 3 + * 4 + * Permission to use, copy, modify, distribute, and sell this software and its 5 + * documentation for any purpose is hereby granted without fee, provided that 6 + * the above copyright notice appear in all copies and that both that copyright 7 + * notice and this permission notice appear in supporting documentation, and 8 + * that the name of the copyright holders not be used in advertising or 9 + * publicity pertaining to distribution of the software without specific, 10 + * written prior permission. The copyright holders make no representations 11 + * about the suitability of this software for any purpose. It is provided "as 12 + * is" without express or implied warranty. 13 + * 14 + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 + * OF THIS SOFTWARE. 21 + */ 22 + #ifndef __DRM_FOURCC_H__ 23 + #define __DRM_FOURCC_H__ 24 + 25 + #include <linux/types.h> 26 + #include <uapi/drm/drm_fourcc.h> 27 + 28 + void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp); 29 + int drm_format_num_planes(uint32_t format); 30 + int drm_format_plane_cpp(uint32_t format, int plane); 31 + int drm_format_horz_chroma_subsampling(uint32_t format); 32 + int drm_format_vert_chroma_subsampling(uint32_t format); 33 + int drm_format_plane_width(int width, uint32_t format, int plane); 34 + int drm_format_plane_height(int height, uint32_t format, int plane); 35 + const char *drm_get_format_name(uint32_t format); 36 + 37 + #endif /* __DRM_FOURCC_H__ */
+2
include/drm/drm_mipi_dsi.h
··· 180 180 unsigned long mode_flags; 181 181 }; 182 182 183 + #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:" 184 + 183 185 static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) 184 186 { 185 187 return container_of(dev, struct mipi_dsi_device, dev);
+39
include/drm/drm_modeset_helper_vtables.h
··· 931 931 plane->helper_private = funcs; 932 932 } 933 933 934 + /** 935 + * struct drm_mode_config_helper_funcs - global modeset helper operations 936 + * 937 + * These helper functions are used by the atomic helpers. 938 + */ 939 + struct drm_mode_config_helper_funcs { 940 + /** 941 + * @atomic_commit_tail: 942 + * 943 + * This hook is used by the default atomic_commit() hook implemented in 944 + * drm_atomic_helper_commit() together with the nonblocking commit 945 + * helpers (see drm_atomic_helper_setup_commit() for a starting point) 946 + * to implement blocking and nonblocking commits easily. It is not used 947 + * by the atomic helpers 948 + * 949 + * This hook should first commit the given atomic state to the hardware. 950 + * But drivers can add more waiting calls at the start of their 951 + * implementation, e.g. to wait for driver-internal request for implicit 952 + * syncing, before starting to commit the update to the hardware. 953 + * 954 + * After the atomic update is committed to the hardware this hook needs 955 + * to call drm_atomic_helper_commit_hw_done(). Then wait for the upate 956 + * to be executed by the hardware, for example using 957 + * drm_atomic_helper_wait_for_vblanks(), and then clean up the old 958 + * framebuffers using drm_atomic_helper_cleanup_planes(). 959 + * 960 + * When disabling a CRTC this hook _must_ stall for the commit to 961 + * complete. Vblank waits don't work on disabled CRTC, hence the core 962 + * can't take care of this. And it also can't rely on the vblank event, 963 + * since that can be signalled already when the screen shows black, 964 + * which can happen much earlier than the last hardware access needed to 965 + * shut off the display pipeline completely. 966 + * 967 + * This hook is optional, the default implementation is 968 + * drm_atomic_helper_commit_tail(). 969 + */ 970 + void (*atomic_commit_tail)(struct drm_atomic_state *state); 971 + }; 972 + 934 973 #endif
+94
include/drm/drm_simple_kms_helper.h
··· 1 + /* 2 + * Copyright (C) 2016 Noralf Trønnes 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + */ 9 + 10 + #ifndef __LINUX_DRM_SIMPLE_KMS_HELPER_H 11 + #define __LINUX_DRM_SIMPLE_KMS_HELPER_H 12 + 13 + struct drm_simple_display_pipe; 14 + 15 + /** 16 + * struct drm_simple_display_pipe_funcs - helper operations for a simple 17 + * display pipeline 18 + */ 19 + struct drm_simple_display_pipe_funcs { 20 + /** 21 + * @enable: 22 + * 23 + * This function should be used to enable the pipeline. 24 + * It is called when the underlying crtc is enabled. 25 + * This hook is optional. 26 + */ 27 + void (*enable)(struct drm_simple_display_pipe *pipe, 28 + struct drm_crtc_state *crtc_state); 29 + /** 30 + * @disable: 31 + * 32 + * This function should be used to disable the pipeline. 33 + * It is called when the underlying crtc is disabled. 34 + * This hook is optional. 35 + */ 36 + void (*disable)(struct drm_simple_display_pipe *pipe); 37 + 38 + /** 39 + * @check: 40 + * 41 + * This function is called in the check phase of an atomic update, 42 + * specifically when the underlying plane is checked. 43 + * The simple display pipeline helpers already check that the plane is 44 + * not scaled, fills the entire visible area and is always enabled 45 + * when the crtc is also enabled. 46 + * This hook is optional. 47 + * 48 + * RETURNS: 49 + * 50 + * 0 on success, -EINVAL if the state or the transition can't be 51 + * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 52 + * attempt to obtain another state object ran into a &drm_modeset_lock 53 + * deadlock. 54 + */ 55 + int (*check)(struct drm_simple_display_pipe *pipe, 56 + struct drm_plane_state *plane_state, 57 + struct drm_crtc_state *crtc_state); 58 + /** 59 + * @update: 60 + * 61 + * This function is called when the underlying plane state is updated. 62 + * This hook is optional. 63 + */ 64 + void (*update)(struct drm_simple_display_pipe *pipe, 65 + struct drm_plane_state *plane_state); 66 + }; 67 + 68 + /** 69 + * struct drm_simple_display_pipe - simple display pipeline 70 + * @crtc: CRTC control structure 71 + * @plane: Plane control structure 72 + * @encoder: Encoder control structure 73 + * @connector: Connector control structure 74 + * @funcs: Pipeline control functions (optional) 75 + * 76 + * Simple display pipeline with plane, crtc and encoder collapsed into one 77 + * entity. It should be initialized by calling drm_simple_display_pipe_init(). 78 + */ 79 + struct drm_simple_display_pipe { 80 + struct drm_crtc crtc; 81 + struct drm_plane plane; 82 + struct drm_encoder encoder; 83 + struct drm_connector *connector; 84 + 85 + const struct drm_simple_display_pipe_funcs *funcs; 86 + }; 87 + 88 + int drm_simple_display_pipe_init(struct drm_device *dev, 89 + struct drm_simple_display_pipe *pipe, 90 + const struct drm_simple_display_pipe_funcs *funcs, 91 + const uint32_t *formats, unsigned int format_count, 92 + struct drm_connector *connector); 93 + 94 + #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */
+254 -139
scripts/kernel-doc
··· 59 59 -text Output plain text format. 60 60 61 61 Output selection (mutually exclusive): 62 + -export Only output documentation for symbols that have been 63 + exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() 64 + in the same FILE. 65 + -internal Only output documentation for symbols that have NOT been 66 + exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() 67 + in the same FILE. 62 68 -function NAME Only output documentation for the given function(s) 63 69 or DOC: section title(s). All other functions and DOC: 64 70 sections are ignored. May be specified multiple times. ··· 74 68 75 69 Output selection modifiers: 76 70 -no-doc-sections Do not output DOC: sections. 71 + -enable-lineno Enable output of #define LINENO lines. Only works with 72 + reStructuredText format. 77 73 78 74 Other parameters: 79 75 -v Verbose output, more warnings and other information. ··· 214 206 my $type_env = '(\$\w+)'; 215 207 my $type_enum_full = '\&(enum)\s*([_\w]+)'; 216 208 my $type_struct_full = '\&(struct)\s*([_\w]+)'; 209 + my $type_typedef_full = '\&(typedef)\s*([_\w]+)'; 210 + my $type_union_full = '\&(union)\s*([_\w]+)'; 211 + my $type_member = '\&([_\w]+)((\.|->)[_\w]+)'; 212 + my $type_member_func = $type_member . '\(\)'; 217 213 218 214 # Output conversion substitutions. 219 215 # One for each output format ··· 286 274 # rst-mode 287 275 my @highlights_rst = ( 288 276 [$type_constant, "``\$1``"], 289 - [$type_func, "\\:c\\:func\\:`\$1`"], 277 + # Note: need to escape () to avoid func matching later 278 + [$type_member_func, "\\:c\\:type\\:`\$1\$2\\\\(\\\\) <\$1>`"], 279 + [$type_member, "\\:c\\:type\\:`\$1\$2 <\$1>`"], 280 + [$type_func, "\\:c\\:func\\:`\$1()`"], 290 281 [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 291 282 [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 292 - [$type_struct, "\\:c\\:type\\:`struct \$1 <\$1>`"], 283 + [$type_typedef_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 284 + [$type_union_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 285 + # in rst this can refer to any type 286 + [$type_struct, "\\:c\\:type\\:`\$1`"], 293 287 [$type_param, "**\$1**"] 294 288 ); 295 289 my $blankline_rst = "\n"; ··· 321 303 my $output_mode = "man"; 322 304 my $output_preformatted = 0; 323 305 my $no_doc_sections = 0; 306 + my $enable_lineno = 0; 324 307 my @highlights = @highlights_man; 325 308 my $blankline = $blankline_man; 326 309 my $modulename = "Kernel API"; 327 - my $function_only = 0; 310 + 311 + use constant { 312 + OUTPUT_ALL => 0, # output all symbols and doc sections 313 + OUTPUT_INCLUDE => 1, # output only specified symbols 314 + OUTPUT_EXCLUDE => 2, # output everything except specified symbols 315 + OUTPUT_EXPORTED => 3, # output exported symbols 316 + OUTPUT_INTERNAL => 4, # output non-exported symbols 317 + }; 318 + my $output_selection = OUTPUT_ALL; 328 319 my $show_not_found = 0; 329 320 330 321 my @build_time; ··· 354 327 # CAVEAT EMPTOR! Some of the others I localised may not want to be, which 355 328 # could cause "use of undefined value" or other bugs. 356 329 my ($function, %function_table, %parametertypes, $declaration_purpose); 330 + my $declaration_start_line; 357 331 my ($type, $declaration_name, $return_type); 358 332 my ($newsection, $newcontents, $prototype, $brcount, %source_map); 359 333 ··· 372 344 373 345 my $lineprefix=""; 374 346 375 - # states 376 - # 0 - normal code 377 - # 1 - looking for function name 378 - # 2 - scanning field start. 379 - # 3 - scanning prototype. 380 - # 4 - documentation block 381 - # 5 - gathering documentation outside main block 347 + # Parser states 348 + use constant { 349 + STATE_NORMAL => 0, # normal code 350 + STATE_NAME => 1, # looking for function name 351 + STATE_FIELD => 2, # scanning field start 352 + STATE_PROTO => 3, # scanning prototype 353 + STATE_DOCBLOCK => 4, # documentation block 354 + STATE_INLINE => 5, # gathering documentation outside main block 355 + }; 382 356 my $state; 383 357 my $in_doc_sect; 384 358 385 - # Split Doc State 386 - # 0 - Invalid (Before start or after finish) 387 - # 1 - Is started (the /** was found inside a struct) 388 - # 2 - The @parameter header was found, start accepting multi paragraph text. 389 - # 3 - Finished (the */ was found) 390 - # 4 - Error - Comment without header was found. Spit a warning as it's not 391 - # proper kernel-doc and ignore the rest. 392 - my $split_doc_state; 359 + # Inline documentation state 360 + use constant { 361 + STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE) 362 + STATE_INLINE_NAME => 1, # looking for member name (@foo:) 363 + STATE_INLINE_TEXT => 2, # looking for member documentation 364 + STATE_INLINE_END => 3, # done 365 + STATE_INLINE_ERROR => 4, # error - Comment without header was found. 366 + # Spit a warning as it's not 367 + # proper kernel-doc and ignore the rest. 368 + }; 369 + my $inline_doc_state; 393 370 394 371 #declaration types: can be 395 372 # 'function', 'struct', 'union', 'enum', 'typedef' 396 373 my $decl_type; 397 - 398 - my $doc_special = "\@\%\$\&"; 399 374 400 375 my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. 401 376 my $doc_end = '\*/'; 402 377 my $doc_com = '\s*\*\s*'; 403 378 my $doc_com_body = '\s*\* ?'; 404 379 my $doc_decl = $doc_com . '(\w+)'; 405 - my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)'; 380 + # @params and a strictly limited set of supported section names 381 + my $doc_sect = $doc_com . 382 + '\s*(\@\w+|description|context|returns?|notes?|examples?)\s*:(.*)'; 406 383 my $doc_content = $doc_com_body . '(.*)'; 407 384 my $doc_block = $doc_com . 'DOC:\s*(.*)?'; 408 - my $doc_split_start = '^\s*/\*\*\s*$'; 409 - my $doc_split_sect = '\s*\*\s*(@[\w\s]+):(.*)'; 410 - my $doc_split_end = '^\s*\*/\s*$'; 385 + my $doc_inline_start = '^\s*/\*\*\s*$'; 386 + my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; 387 + my $doc_inline_end = '^\s*\*/\s*$'; 388 + my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; 411 389 412 - my %constants; 413 390 my %parameterdescs; 391 + my %parameterdesc_start_lines; 414 392 my @parameterlist; 415 393 my %sections; 416 394 my @sectionlist; 395 + my %section_start_lines; 417 396 my $sectcheck; 418 397 my $struct_actual; 419 398 420 399 my $contents = ""; 400 + my $new_start_line = 0; 401 + 402 + # the canonical section names. see also $doc_sect above. 421 403 my $section_default = "Description"; # default section 422 404 my $section_intro = "Introduction"; 423 405 my $section = $section_default; ··· 475 437 } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document 476 438 $modulename = shift @ARGV; 477 439 } elsif ($cmd eq "-function") { # to only output specific functions 478 - $function_only = 1; 440 + $output_selection = OUTPUT_INCLUDE; 479 441 $function = shift @ARGV; 480 442 $function_table{$function} = 1; 481 - } elsif ($cmd eq "-nofunction") { # to only output specific functions 482 - $function_only = 2; 443 + } elsif ($cmd eq "-nofunction") { # output all except specific functions 444 + $output_selection = OUTPUT_EXCLUDE; 483 445 $function = shift @ARGV; 484 446 $function_table{$function} = 1; 447 + } elsif ($cmd eq "-export") { # only exported symbols 448 + $output_selection = OUTPUT_EXPORTED; 449 + %function_table = () 450 + } elsif ($cmd eq "-internal") { # only non-exported symbols 451 + $output_selection = OUTPUT_INTERNAL; 452 + %function_table = () 485 453 } elsif ($cmd eq "-v") { 486 454 $verbose = 1; 487 455 } elsif (($cmd eq "-h") || ($cmd eq "--help")) { 488 456 usage(); 489 457 } elsif ($cmd eq '-no-doc-sections') { 490 458 $no_doc_sections = 1; 459 + } elsif ($cmd eq '-enable-lineno') { 460 + $enable_lineno = 1; 491 461 } elsif ($cmd eq '-show-not-found') { 492 462 $show_not_found = 1; 493 463 } ··· 513 467 return $version; 514 468 } 515 469 470 + # 471 + sub print_lineno { 472 + my $lineno = shift; 473 + if ($enable_lineno && defined($lineno)) { 474 + print "#define LINENO " . $lineno . "\n"; 475 + } 476 + } 516 477 ## 517 478 # dumps section contents to arrays/hashes intended for that purpose. 518 479 # ··· 528 475 my $name = shift; 529 476 my $contents = join "\n", @_; 530 477 531 - if ($name =~ m/$type_constant/) { 532 - $name = $1; 533 - # print STDERR "constant section '$1' = '$contents'\n"; 534 - $constants{$name} = $contents; 535 - } elsif ($name =~ m/$type_param/) { 478 + if ($name =~ m/$type_param/) { 536 479 # print STDERR "parameter def '$1' = '$contents'\n"; 537 480 $name = $1; 538 481 $parameterdescs{$name} = $contents; 539 482 $sectcheck = $sectcheck . $name . " "; 483 + $parameterdesc_start_lines{$name} = $new_start_line; 484 + $new_start_line = 0; 540 485 } elsif ($name eq "@\.\.\.") { 541 486 # print STDERR "parameter def '...' = '$contents'\n"; 542 487 $name = "..."; 543 488 $parameterdescs{$name} = $contents; 544 489 $sectcheck = $sectcheck . $name . " "; 490 + $parameterdesc_start_lines{$name} = $new_start_line; 491 + $new_start_line = 0; 545 492 } else { 546 493 # print STDERR "other section '$name' = '$contents'\n"; 547 494 if (defined($sections{$name}) && ($sections{$name} ne "")) { 548 - print STDERR "${file}:$.: error: duplicate section name '$name'\n"; 549 - ++$errors; 495 + print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; 496 + ++$warnings; 497 + $sections{$name} .= $contents; 498 + } else { 499 + $sections{$name} = $contents; 500 + push @sectionlist, $name; 501 + $section_start_lines{$name} = $new_start_line; 502 + $new_start_line = 0; 550 503 } 551 - $sections{$name} = $contents; 552 - push @sectionlist, $name; 553 504 } 554 505 } 555 506 ··· 569 512 return; 570 513 } 571 514 572 - if (($function_only == 0) || 573 - ( $function_only == 1 && defined($function_table{$name})) || 574 - ( $function_only == 2 && !defined($function_table{$name}))) 515 + if (($output_selection == OUTPUT_ALL) || 516 + ($output_selection == OUTPUT_INCLUDE && 517 + defined($function_table{$name})) || 518 + ($output_selection == OUTPUT_EXCLUDE && 519 + !defined($function_table{$name}))) 575 520 { 576 521 dump_section($file, $name, $contents); 577 522 output_blockhead({'sectionlist' => \@sectionlist, 578 523 'sections' => \%sections, 579 524 'module' => $modulename, 580 - 'content-only' => ($function_only != 0), }); 525 + 'content-only' => ($output_selection != OUTPUT_ALL), }); 581 526 } 582 527 } 583 528 ··· 1795 1736 my ($parameter, $section); 1796 1737 1797 1738 foreach $section (@{$args{'sectionlist'}}) { 1798 - print "**$section**\n\n"; 1739 + if ($output_selection != OUTPUT_INCLUDE) { 1740 + print "**$section**\n\n"; 1741 + } 1742 + print_lineno($section_start_lines{$section}); 1799 1743 output_highlight_rst($args{'sections'}{$section}); 1800 1744 print "\n"; 1801 1745 } ··· 1815 1753 die $@ if $@; 1816 1754 1817 1755 foreach $line (split "\n", $contents) { 1818 - if ($line eq "") { 1819 - print $lineprefix, $blankline; 1820 - } else { 1821 - $line =~ s/\\\\\\/\&/g; 1822 - print $lineprefix, $line; 1823 - } 1824 - print "\n"; 1756 + print $lineprefix . $line . "\n"; 1825 1757 } 1826 1758 } 1827 1759 1828 1760 sub output_function_rst(%) { 1829 1761 my %args = %{$_[0]}; 1830 1762 my ($parameter, $section); 1763 + my $oldprefix = $lineprefix; 1831 1764 my $start; 1832 1765 1833 1766 print ".. c:function:: "; ··· 1847 1790 print $type . " " . $parameter; 1848 1791 } 1849 1792 } 1850 - print ")\n\n " . $args{'purpose'} . "\n\n"; 1793 + print ")\n\n"; 1794 + print_lineno($declaration_start_line); 1795 + $lineprefix = " "; 1796 + output_highlight_rst($args{'purpose'}); 1797 + print "\n"; 1851 1798 1852 - print ":Parameters:\n\n"; 1799 + print "**Parameters**\n\n"; 1800 + $lineprefix = " "; 1853 1801 foreach $parameter (@{$args{'parameterlist'}}) { 1854 1802 my $parameter_name = $parameter; 1855 1803 #$parameter_name =~ s/\[.*//; 1856 1804 $type = $args{'parametertypes'}{$parameter}; 1857 1805 1858 1806 if ($type ne "") { 1859 - print " ``$type $parameter``\n"; 1807 + print "``$type $parameter``\n"; 1860 1808 } else { 1861 - print " ``$parameter``\n"; 1809 + print "``$parameter``\n"; 1862 1810 } 1863 - if ($args{'parameterdescs'}{$parameter_name} ne $undescribed) { 1864 - my $oldprefix = $lineprefix; 1865 - $lineprefix = " "; 1811 + 1812 + print_lineno($parameterdesc_start_lines{$parameter_name}); 1813 + 1814 + if (defined($args{'parameterdescs'}{$parameter_name}) && 1815 + $args{'parameterdescs'}{$parameter_name} ne $undescribed) { 1866 1816 output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 1867 - $lineprefix = $oldprefix; 1868 1817 } else { 1869 - print "\n _undescribed_\n"; 1818 + print " *undescribed*\n"; 1870 1819 } 1871 1820 print "\n"; 1872 1821 } 1822 + 1823 + $lineprefix = $oldprefix; 1873 1824 output_section_rst(@_); 1874 1825 } 1875 1826 ··· 1885 1820 my %args = %{$_[0]}; 1886 1821 my $section; 1887 1822 my $oldprefix = $lineprefix; 1888 - $lineprefix = " "; 1823 + $lineprefix = ""; 1889 1824 1890 1825 foreach $section (@{$args{'sectionlist'}}) { 1891 - print ":$section:\n\n"; 1826 + print "**$section**\n\n"; 1827 + print_lineno($section_start_lines{$section}); 1892 1828 output_highlight_rst($args{'sections'}{$section}); 1893 1829 print "\n"; 1894 1830 } ··· 1900 1834 sub output_enum_rst(%) { 1901 1835 my %args = %{$_[0]}; 1902 1836 my ($parameter); 1837 + my $oldprefix = $lineprefix; 1903 1838 my $count; 1904 1839 my $name = "enum " . $args{'enum'}; 1905 1840 1906 1841 print "\n\n.. c:type:: " . $name . "\n\n"; 1907 - print " " . $args{'purpose'} . "\n\n"; 1842 + print_lineno($declaration_start_line); 1843 + $lineprefix = " "; 1844 + output_highlight_rst($args{'purpose'}); 1845 + print "\n"; 1908 1846 1909 - print "..\n\n:Constants:\n\n"; 1910 - my $oldprefix = $lineprefix; 1911 - $lineprefix = " "; 1847 + print "**Constants**\n\n"; 1848 + $lineprefix = " "; 1912 1849 foreach $parameter (@{$args{'parameterlist'}}) { 1913 - print " `$parameter`\n"; 1850 + print "``$parameter``\n"; 1914 1851 if ($args{'parameterdescs'}{$parameter} ne $undescribed) { 1915 1852 output_highlight_rst($args{'parameterdescs'}{$parameter}); 1916 1853 } else { 1917 - print " undescribed\n"; 1854 + print " *undescribed*\n"; 1918 1855 } 1919 1856 print "\n"; 1920 1857 } 1858 + 1921 1859 $lineprefix = $oldprefix; 1922 1860 output_section_rst(@_); 1923 1861 } ··· 1929 1859 sub output_typedef_rst(%) { 1930 1860 my %args = %{$_[0]}; 1931 1861 my ($parameter); 1932 - my $count; 1862 + my $oldprefix = $lineprefix; 1933 1863 my $name = "typedef " . $args{'typedef'}; 1934 1864 1935 - ### FIXME: should the name below contain "typedef" or not? 1936 1865 print "\n\n.. c:type:: " . $name . "\n\n"; 1937 - print " " . $args{'purpose'} . "\n\n"; 1866 + print_lineno($declaration_start_line); 1867 + $lineprefix = " "; 1868 + output_highlight_rst($args{'purpose'}); 1869 + print "\n"; 1938 1870 1871 + $lineprefix = $oldprefix; 1939 1872 output_section_rst(@_); 1940 1873 } 1941 1874 1942 1875 sub output_struct_rst(%) { 1943 1876 my %args = %{$_[0]}; 1944 1877 my ($parameter); 1878 + my $oldprefix = $lineprefix; 1945 1879 my $name = $args{'type'} . " " . $args{'struct'}; 1946 1880 1947 1881 print "\n\n.. c:type:: " . $name . "\n\n"; 1948 - print " " . $args{'purpose'} . "\n\n"; 1882 + print_lineno($declaration_start_line); 1883 + $lineprefix = " "; 1884 + output_highlight_rst($args{'purpose'}); 1885 + print "\n"; 1949 1886 1950 - print ":Definition:\n\n"; 1951 - print " ::\n\n"; 1887 + print "**Definition**\n\n"; 1888 + print "::\n\n"; 1952 1889 print " " . $args{'type'} . " " . $args{'struct'} . " {\n"; 1953 1890 foreach $parameter (@{$args{'parameterlist'}}) { 1954 1891 if ($parameter =~ /^#/) { 1955 - print " " . "$parameter\n"; 1892 + print " " . "$parameter\n"; 1956 1893 next; 1957 1894 } 1958 1895 ··· 1980 1903 } 1981 1904 print " };\n\n"; 1982 1905 1983 - print ":Members:\n\n"; 1906 + print "**Members**\n\n"; 1907 + $lineprefix = " "; 1984 1908 foreach $parameter (@{$args{'parameterlist'}}) { 1985 1909 ($parameter =~ /^#/) && next; 1986 1910 ··· 1990 1912 1991 1913 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 1992 1914 $type = $args{'parametertypes'}{$parameter}; 1993 - print " `$type $parameter`" . "\n"; 1994 - my $oldprefix = $lineprefix; 1995 - $lineprefix = " "; 1915 + print_lineno($parameterdesc_start_lines{$parameter_name}); 1916 + print "``$type $parameter``\n"; 1996 1917 output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 1997 - $lineprefix = $oldprefix; 1998 1918 print "\n"; 1999 1919 } 2000 1920 print "\n"; 1921 + 1922 + $lineprefix = $oldprefix; 2001 1923 output_section_rst(@_); 2002 1924 } 2003 1925 ··· 2047 1969 my $name = shift; 2048 1970 my $functype = shift; 2049 1971 my $func = "output_${functype}_$output_mode"; 2050 - if (($function_only==0) || 2051 - ( $function_only == 1 && defined($function_table{$name})) || 2052 - ( $function_only == 2 && !($functype eq "function" && defined($function_table{$name})))) 1972 + if (($output_selection == OUTPUT_ALL) || 1973 + (($output_selection == OUTPUT_INCLUDE || 1974 + $output_selection == OUTPUT_EXPORTED) && 1975 + defined($function_table{$name})) || 1976 + (($output_selection == OUTPUT_EXCLUDE || 1977 + $output_selection == OUTPUT_INTERNAL) && 1978 + !($functype eq "function" && defined($function_table{$name})))) 2053 1979 { 2054 1980 &$func(@_); 2055 1981 $section_counter++; ··· 2553 2471 2554 2472 sub reset_state { 2555 2473 $function = ""; 2556 - %constants = (); 2557 2474 %parameterdescs = (); 2558 2475 %parametertypes = (); 2559 2476 @parameterlist = (); ··· 2562 2481 $struct_actual = ""; 2563 2482 $prototype = ""; 2564 2483 2565 - $state = 0; 2566 - $split_doc_state = 0; 2484 + $state = STATE_NORMAL; 2485 + $inline_doc_state = STATE_INLINE_NA; 2567 2486 } 2568 2487 2569 2488 sub tracepoint_munge($) { ··· 2626 2545 } 2627 2546 } 2628 2547 2629 - sub process_state3_function($$) { 2548 + sub process_proto_function($$) { 2630 2549 my $x = shift; 2631 2550 my $file = shift; 2632 2551 ··· 2656 2575 } 2657 2576 } 2658 2577 2659 - sub process_state3_type($$) { 2578 + sub process_proto_type($$) { 2660 2579 my $x = shift; 2661 2580 my $file = shift; 2662 2581 ··· 2738 2657 my $in_purpose = 0; 2739 2658 my $initial_section_counter = $section_counter; 2740 2659 my ($orig_file) = @_; 2660 + my $leading_space; 2741 2661 2742 2662 if (defined($ENV{'SRCTREE'})) { 2743 2663 $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; ··· 2756 2674 return; 2757 2675 } 2758 2676 2677 + # two passes for -export and -internal 2678 + if ($output_selection == OUTPUT_EXPORTED || 2679 + $output_selection == OUTPUT_INTERNAL) { 2680 + while (<IN>) { 2681 + if (/$export_symbol/o) { 2682 + $function_table{$2} = 1; 2683 + } 2684 + } 2685 + seek(IN, 0, 0); 2686 + } 2687 + 2759 2688 $. = 1; 2760 2689 2761 2690 $section_counter = 0; ··· 2774 2681 while (s/\\\s*$//) { 2775 2682 $_ .= <IN>; 2776 2683 } 2777 - if ($state == 0) { 2684 + if ($state == STATE_NORMAL) { 2778 2685 if (/$doc_start/o) { 2779 - $state = 1; # next line is always the function name 2686 + $state = STATE_NAME; # next line is always the function name 2780 2687 $in_doc_sect = 0; 2688 + $declaration_start_line = $. + 1; 2781 2689 } 2782 - } elsif ($state == 1) { # this line is the function name (always) 2690 + } elsif ($state == STATE_NAME) {# this line is the function name (always) 2783 2691 if (/$doc_block/o) { 2784 - $state = 4; 2692 + $state = STATE_DOCBLOCK; 2785 2693 $contents = ""; 2694 + $new_start_line = $. + 1; 2695 + 2786 2696 if ( $1 eq "" ) { 2787 2697 $section = $section_intro; 2788 2698 } else { ··· 2798 2702 $identifier = $1; 2799 2703 } 2800 2704 2801 - $state = 2; 2705 + $state = STATE_FIELD; 2706 + # if there's no @param blocks need to set up default section 2707 + # here 2708 + $contents = ""; 2709 + $section = $section_default; 2710 + $new_start_line = $. + 1; 2802 2711 if (/-(.*)/) { 2803 2712 # strip leading/trailing/multiple spaces 2804 2713 $descr= $1; ··· 2841 2740 print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", 2842 2741 " - I thought it was a doc line\n"; 2843 2742 ++$warnings; 2844 - $state = 0; 2743 + $state = STATE_NORMAL; 2845 2744 } 2846 - } elsif ($state == 2) { # look for head: lines, and include content 2847 - if (/$doc_sect/o) { 2745 + } elsif ($state == STATE_FIELD) { # look for head: lines, and include content 2746 + if (/$doc_sect/i) { # case insensitive for supported section names 2848 2747 $newsection = $1; 2849 2748 $newcontents = $2; 2749 + 2750 + # map the supported section names to the canonical names 2751 + if ($newsection =~ m/^description$/i) { 2752 + $newsection = $section_default; 2753 + } elsif ($newsection =~ m/^context$/i) { 2754 + $newsection = $section_context; 2755 + } elsif ($newsection =~ m/^returns?$/i) { 2756 + $newsection = $section_return; 2757 + } elsif ($newsection =~ m/^\@return$/) { 2758 + # special: @return is a section, not a param description 2759 + $newsection = $section_return; 2760 + } 2850 2761 2851 2762 if (($contents ne "") && ($contents ne "\n")) { 2852 2763 if (!$in_doc_sect && $verbose) { ··· 2872 2759 $in_doc_sect = 1; 2873 2760 $in_purpose = 0; 2874 2761 $contents = $newcontents; 2762 + $new_start_line = $.; 2763 + while ((substr($contents, 0, 1) eq " ") || 2764 + substr($contents, 0, 1) eq "\t") { 2765 + $contents = substr($contents, 1); 2766 + } 2875 2767 if ($contents ne "") { 2876 - while ((substr($contents, 0, 1) eq " ") || 2877 - substr($contents, 0, 1) eq "\t") { 2878 - $contents = substr($contents, 1); 2879 - } 2880 2768 $contents .= "\n"; 2881 2769 } 2882 2770 $section = $newsection; 2771 + $leading_space = undef; 2883 2772 } elsif (/$doc_end/) { 2884 2773 if (($contents ne "") && ($contents ne "\n")) { 2885 2774 dump_section($file, $section, xml_escape($contents)); ··· 2895 2780 } 2896 2781 2897 2782 $prototype = ""; 2898 - $state = 3; 2783 + $state = STATE_PROTO; 2899 2784 $brcount = 0; 2900 2785 # print STDERR "end of doc comment, looking for prototype\n"; 2901 2786 } elsif (/$doc_content/) { ··· 2906 2791 dump_section($file, $section, xml_escape($contents)); 2907 2792 $section = $section_default; 2908 2793 $contents = ""; 2794 + $new_start_line = $.; 2909 2795 } else { 2910 2796 $contents .= "\n"; 2911 2797 } ··· 2917 2801 $declaration_purpose .= " " . xml_escape($1); 2918 2802 $declaration_purpose =~ s/\s+/ /g; 2919 2803 } else { 2920 - $contents .= $1 . "\n"; 2804 + my $cont = $1; 2805 + if ($section =~ m/^@/ || $section eq $section_context) { 2806 + if (!defined $leading_space) { 2807 + if ($cont =~ m/^(\s+)/) { 2808 + $leading_space = $1; 2809 + } else { 2810 + $leading_space = ""; 2811 + } 2812 + } 2813 + 2814 + $cont =~ s/^$leading_space//; 2815 + } 2816 + $contents .= $cont . "\n"; 2921 2817 } 2922 2818 } else { 2923 2819 # i dont know - bad line? ignore. 2924 2820 print STDERR "${file}:$.: warning: bad line: $_"; 2925 2821 ++$warnings; 2926 2822 } 2927 - } elsif ($state == 5) { # scanning for split parameters 2823 + } elsif ($state == STATE_INLINE) { # scanning for inline parameters 2928 2824 # First line (state 1) needs to be a @parameter 2929 - if ($split_doc_state == 1 && /$doc_split_sect/o) { 2825 + if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { 2930 2826 $section = $1; 2931 2827 $contents = $2; 2828 + $new_start_line = $.; 2932 2829 if ($contents ne "") { 2933 2830 while ((substr($contents, 0, 1) eq " ") || 2934 2831 substr($contents, 0, 1) eq "\t") { 2935 2832 $contents = substr($contents, 1); 2936 2833 } 2937 - $contents .= "\n"; 2834 + $contents .= "\n"; 2938 2835 } 2939 - $split_doc_state = 2; 2836 + $inline_doc_state = STATE_INLINE_TEXT; 2940 2837 # Documentation block end */ 2941 - } elsif (/$doc_split_end/) { 2838 + } elsif (/$doc_inline_end/) { 2942 2839 if (($contents ne "") && ($contents ne "\n")) { 2943 2840 dump_section($file, $section, xml_escape($contents)); 2944 2841 $section = $section_default; 2945 2842 $contents = ""; 2946 2843 } 2947 - $state = 3; 2948 - $split_doc_state = 0; 2844 + $state = STATE_PROTO; 2845 + $inline_doc_state = STATE_INLINE_NA; 2949 2846 # Regular text 2950 2847 } elsif (/$doc_content/) { 2951 - if ($split_doc_state == 2) { 2848 + if ($inline_doc_state == STATE_INLINE_TEXT) { 2952 2849 $contents .= $1 . "\n"; 2953 - } elsif ($split_doc_state == 1) { 2954 - $split_doc_state = 4; 2850 + # nuke leading blank lines 2851 + if ($contents =~ /^\s*$/) { 2852 + $contents = ""; 2853 + } 2854 + } elsif ($inline_doc_state == STATE_INLINE_NAME) { 2855 + $inline_doc_state = STATE_INLINE_ERROR; 2955 2856 print STDERR "Warning(${file}:$.): "; 2956 2857 print STDERR "Incorrect use of kernel-doc format: $_"; 2957 2858 ++$warnings; 2958 2859 } 2959 2860 } 2960 - } elsif ($state == 3) { # scanning for function '{' (end of prototype) 2961 - if (/$doc_split_start/) { 2962 - $state = 5; 2963 - $split_doc_state = 1; 2861 + } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) 2862 + if (/$doc_inline_start/) { 2863 + $state = STATE_INLINE; 2864 + $inline_doc_state = STATE_INLINE_NAME; 2964 2865 } elsif ($decl_type eq 'function') { 2965 - process_state3_function($_, $file); 2866 + process_proto_function($_, $file); 2966 2867 } else { 2967 - process_state3_type($_, $file); 2868 + process_proto_type($_, $file); 2968 2869 } 2969 - } elsif ($state == 4) { 2970 - # Documentation block 2971 - if (/$doc_block/) { 2972 - dump_doc_section($file, $section, xml_escape($contents)); 2973 - $contents = ""; 2974 - $function = ""; 2975 - %constants = (); 2976 - %parameterdescs = (); 2977 - %parametertypes = (); 2978 - @parameterlist = (); 2979 - %sections = (); 2980 - @sectionlist = (); 2981 - $prototype = ""; 2982 - if ( $1 eq "" ) { 2983 - $section = $section_intro; 2984 - } else { 2985 - $section = $1; 2986 - } 2987 - } 2988 - elsif (/$doc_end/) 2870 + } elsif ($state == STATE_DOCBLOCK) { 2871 + if (/$doc_end/) 2989 2872 { 2990 2873 dump_doc_section($file, $section, xml_escape($contents)); 2874 + $section = $section_default; 2991 2875 $contents = ""; 2992 2876 $function = ""; 2993 - %constants = (); 2994 2877 %parameterdescs = (); 2995 2878 %parametertypes = (); 2996 2879 @parameterlist = (); 2997 2880 %sections = (); 2998 2881 @sectionlist = (); 2999 2882 $prototype = ""; 3000 - $state = 0; 2883 + $state = STATE_NORMAL; 3001 2884 } 3002 2885 elsif (/$doc_content/) 3003 2886 { ··· 3013 2898 } 3014 2899 if ($initial_section_counter == $section_counter) { 3015 2900 print STDERR "${file}:1: warning: no structured comments found\n"; 3016 - if (($function_only == 1) && ($show_not_found == 1)) { 2901 + if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) { 3017 2902 print STDERR " Was looking for '$_'.\n" for keys %function_table; 3018 2903 } 3019 2904 if ($output_mode eq "xml") {