aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2017-05-31 05:22:53 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2017-06-01 02:02:14 -0400
commit16584b204573ece64de80f20eb6202495aeb35c2 (patch)
tree655ffd124df38ea5883e146ece397bb270bcffdc
parent3ed4351a83ca05d3cd886ade6900be1067aa7903 (diff)
drm/doc: Polish irq helper documentation
Pull a (much shorter) overview into drm_irq.c, and instead put the callback documentation into in-line comments in drm_drv.h. v2: Move the include stanzas back to the split-up patch (Stefan). Cc: Stefan Agner <stefan@agner.ch> Reviewed-by: Stefan Agner <stefan@agner.ch> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170531092253.12833-1-daniel.vetter@ffwll.ch
-rw-r--r--Documentation/gpu/drm-internals.rst54
-rw-r--r--drivers/gpu/drm/drm_irq.c30
-rw-r--r--drivers/gpu/drm/drm_vblank.c3
-rw-r--r--include/drm/drmP.h9
-rw-r--r--include/drm/drm_drv.h33
5 files changed, 66 insertions, 63 deletions
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index 9067cd9586bd..f6882ad0b3c3 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -149,60 +149,6 @@ Device Instance and Driver Handling
149Driver Load 149Driver Load
150----------- 150-----------
151 151
152IRQ Registration
153~~~~~~~~~~~~~~~~
154
155The DRM core tries to facilitate IRQ handler registration and
156unregistration by providing :c:func:`drm_irq_install()` and
157:c:func:`drm_irq_uninstall()` functions. Those functions only
158support a single interrupt per device, devices that use more than one
159IRQs need to be handled manually.
160
161Managed IRQ Registration
162''''''''''''''''''''''''
163
164:c:func:`drm_irq_install()` starts by calling the irq_preinstall
165driver operation. The operation is optional and must make sure that the
166interrupt will not get fired by clearing all pending interrupt flags or
167disabling the interrupt.
168
169The passed-in IRQ will then be requested by a call to
170:c:func:`request_irq()`. If the DRIVER_IRQ_SHARED driver feature
171flag is set, a shared (IRQF_SHARED) IRQ handler will be requested.
172
173The IRQ handler function must be provided as the mandatory irq_handler
174driver operation. It will get passed directly to
175:c:func:`request_irq()` and thus has the same prototype as all IRQ
176handlers. It will get called with a pointer to the DRM device as the
177second argument.
178
179Finally the function calls the optional irq_postinstall driver
180operation. The operation usually enables interrupts (excluding the
181vblank interrupt, which is enabled separately), but drivers may choose
182to enable/disable interrupts at a different time.
183
184:c:func:`drm_irq_uninstall()` is similarly used to uninstall an
185IRQ handler. It starts by waking up all processes waiting on a vblank
186interrupt to make sure they don't hang, and then calls the optional
187irq_uninstall driver operation. The operation must disable all hardware
188interrupts. Finally the function frees the IRQ by calling
189:c:func:`free_irq()`.
190
191Manual IRQ Registration
192'''''''''''''''''''''''
193
194Drivers that require multiple interrupt handlers can't use the managed
195IRQ registration functions. In that case IRQs must be registered and
196unregistered manually (usually with the :c:func:`request_irq()` and
197:c:func:`free_irq()` functions, or their :c:func:`devm_request_irq()` and
198:c:func:`devm_free_irq()` equivalents).
199
200When manually registering IRQs, drivers must not set the
201DRIVER_HAVE_IRQ driver feature flag, and must not provide the
202irq_handler driver operation. They must set the :c:type:`struct
203drm_device <drm_device>` irq_enabled field to 1 upon
204registration of the IRQs, and clear it to 0 after unregistering the
205IRQs.
206 152
207IRQ Helper Library 153IRQ Helper Library
208~~~~~~~~~~~~~~~~~~ 154~~~~~~~~~~~~~~~~~~
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 28d736c3fcb4..3b04c25100ae 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -62,19 +62,39 @@
62#include "drm_internal.h" 62#include "drm_internal.h"
63 63
64/** 64/**
65 * DOC: irq helpers
66 *
67 * The DRM core provides very simple support helpers to enable IRQ handling on a
68 * device through the drm_irq_install() and drm_irq_uninstall() functions. This
69 * only supports devices with a single interrupt on the main device stored in
70 * &drm_device.dev and set as the device paramter in drm_dev_alloc().
71 *
72 * These IRQ helpers are strictly optional. Drivers which roll their own only
73 * need to set &drm_device.irq_enabled to signal the DRM core that vblank
74 * interrupts are working. Since these helpers don't automatically clean up the
75 * requested interrupt like e.g. devm_request_irq() they're not really
76 * recommended.
77 */
78
79/**
65 * drm_irq_install - install IRQ handler 80 * drm_irq_install - install IRQ handler
66 * @dev: DRM device 81 * @dev: DRM device
67 * @irq: IRQ number to install the handler for 82 * @irq: IRQ number to install the handler for
68 * 83 *
69 * Initializes the IRQ related data. Installs the handler, calling the driver 84 * Initializes the IRQ related data. Installs the handler, calling the driver
70 * irq_preinstall() and irq_postinstall() functions before and after the 85 * &drm_driver.irq_preinstall and &drm_driver.irq_postinstall functions before
71 * installation. 86 * and after the installation.
72 * 87 *
73 * This is the simplified helper interface provided for drivers with no special 88 * This is the simplified helper interface provided for drivers with no special
74 * needs. Drivers which need to install interrupt handlers for multiple 89 * needs. Drivers which need to install interrupt handlers for multiple
75 * interrupts must instead set &drm_device.irq_enabled to signal the DRM core 90 * interrupts must instead set &drm_device.irq_enabled to signal the DRM core
76 * that vblank interrupts are available. 91 * that vblank interrupts are available.
77 * 92 *
93 * @irq must match the interrupt number that would be passed to request_irq(),
94 * if called directly instead of using this helper function.
95 *
96 * &drm_driver.irq_handler is called to handle the registered interrupt.
97 *
78 * Returns: 98 * Returns:
79 * Zero on success or a negative error code on failure. 99 * Zero on success or a negative error code on failure.
80 */ 100 */
@@ -136,9 +156,9 @@ EXPORT_SYMBOL(drm_irq_install);
136 * drm_irq_uninstall - uninstall the IRQ handler 156 * drm_irq_uninstall - uninstall the IRQ handler
137 * @dev: DRM device 157 * @dev: DRM device
138 * 158 *
139 * Calls the driver's irq_uninstall() function and unregisters the IRQ handler. 159 * Calls the driver's &drm_driver.irq_uninstall function and unregisters the IRQ
140 * This should only be called by drivers which used drm_irq_install() to set up 160 * handler. This should only be called by drivers which used drm_irq_install()
141 * their interrupt handler. Other drivers must only reset 161 * to set up their interrupt handler. Other drivers must only reset
142 * &drm_device.irq_enabled to false. 162 * &drm_device.irq_enabled to false.
143 * 163 *
144 * Note that for kernel modesetting drivers it is a bug if this function fails. 164 * Note that for kernel modesetting drivers it is a bug if this function fails.
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 630dc26379b7..463e4d81fb0d 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -363,6 +363,9 @@ static void vblank_disable_fn(unsigned long arg)
363 * @dev: DRM device 363 * @dev: DRM device
364 * 364 *
365 * This function cleans up any resources allocated in drm_vblank_init. 365 * This function cleans up any resources allocated in drm_vblank_init.
366 *
367 * Drivers which don't use drm_irq_install() need to set &drm_device.irq_enabled
368 * themselves, to signal to the DRM core that vblank interrupts are enabled.
366 */ 369 */
367void drm_vblank_cleanup(struct drm_device *dev) 370void drm_vblank_cleanup(struct drm_device *dev)
368{ 371{
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 2e0b76cceb97..39df16af7a4a 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -377,8 +377,13 @@ struct drm_device {
377 int last_context; /**< Last current context */ 377 int last_context; /**< Last current context */
378 /*@} */ 378 /*@} */
379 379
380 /** \name VBLANK IRQ support */ 380 /**
381 /*@{ */ 381 * @irq_enabled:
382 *
383 * Indicates that interrupt handling is enabled, specifically vblank
384 * handling. Drivers which don't use drm_irq_install() need to set this
385 * to true manually.
386 */
382 bool irq_enabled; 387 bool irq_enabled;
383 int irq; 388 int irq;
384 389
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index e64e33b9dd26..18f3181674e8 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -327,11 +327,40 @@ struct drm_driver {
327 struct timeval *vblank_time, 327 struct timeval *vblank_time,
328 bool in_vblank_irq); 328 bool in_vblank_irq);
329 329
330 /* these have to be filled in */ 330 /**
331 331 * @irq_handler:
332 *
333 * Interrupt handler called when using drm_irq_install(). Not used by
334 * drivers which implement their own interrupt handling.
335 */
332 irqreturn_t(*irq_handler) (int irq, void *arg); 336 irqreturn_t(*irq_handler) (int irq, void *arg);
337
338 /**
339 * @irq_preinstall:
340 *
341 * Optional callback used by drm_irq_install() which is called before
342 * the interrupt handler is registered. This should be used to clear out
343 * any pending interrupts (from e.g. firmware based drives) and reset
344 * the interrupt handling registers.
345 */
333 void (*irq_preinstall) (struct drm_device *dev); 346 void (*irq_preinstall) (struct drm_device *dev);
347
348 /**
349 * @irq_postinstall:
350 *
351 * Optional callback used by drm_irq_install() which is called after
352 * the interrupt handler is registered. This should be used to enable
353 * interrupt generation in the hardware.
354 */
334 int (*irq_postinstall) (struct drm_device *dev); 355 int (*irq_postinstall) (struct drm_device *dev);
356
357 /**
358 * @irq_uninstall:
359 *
360 * Optional callback used by drm_irq_uninstall() which is called before
361 * the interrupt handler is unregistered. This should be used to disable
362 * interrupt generation in the hardware.
363 */
335 void (*irq_uninstall) (struct drm_device *dev); 364 void (*irq_uninstall) (struct drm_device *dev);
336 365
337 /** 366 /**