drm/doc: Polish irq helper documentation
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 31 May 2017 09:22:53 +0000 (11:22 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 1 Jun 2017 06:02:14 +0000 (08:02 +0200)
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
Documentation/gpu/drm-internals.rst
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_vblank.c
include/drm/drmP.h
include/drm/drm_drv.h

index 9067cd9..f6882ad 100644 (file)
@@ -149,60 +149,6 @@ Device Instance and Driver Handling
 Driver Load
 -----------
 
-IRQ Registration
-~~~~~~~~~~~~~~~~
-
-The DRM core tries to facilitate IRQ handler registration and
-unregistration by providing :c:func:`drm_irq_install()` and
-:c:func:`drm_irq_uninstall()` functions. Those functions only
-support a single interrupt per device, devices that use more than one
-IRQs need to be handled manually.
-
-Managed IRQ Registration
-''''''''''''''''''''''''
-
-:c:func:`drm_irq_install()` starts by calling the irq_preinstall
-driver operation. The operation is optional and must make sure that the
-interrupt will not get fired by clearing all pending interrupt flags or
-disabling the interrupt.
-
-The passed-in IRQ will then be requested by a call to
-:c:func:`request_irq()`. If the DRIVER_IRQ_SHARED driver feature
-flag is set, a shared (IRQF_SHARED) IRQ handler will be requested.
-
-The IRQ handler function must be provided as the mandatory irq_handler
-driver operation. It will get passed directly to
-:c:func:`request_irq()` and thus has the same prototype as all IRQ
-handlers. It will get called with a pointer to the DRM device as the
-second argument.
-
-Finally the function calls the optional irq_postinstall driver
-operation. The operation usually enables interrupts (excluding the
-vblank interrupt, which is enabled separately), but drivers may choose
-to enable/disable interrupts at a different time.
-
-:c:func:`drm_irq_uninstall()` is similarly used to uninstall an
-IRQ handler. It starts by waking up all processes waiting on a vblank
-interrupt to make sure they don't hang, and then calls the optional
-irq_uninstall driver operation. The operation must disable all hardware
-interrupts. Finally the function frees the IRQ by calling
-:c:func:`free_irq()`.
-
-Manual IRQ Registration
-'''''''''''''''''''''''
-
-Drivers that require multiple interrupt handlers can't use the managed
-IRQ registration functions. In that case IRQs must be registered and
-unregistered manually (usually with the :c:func:`request_irq()` and
-:c:func:`free_irq()` functions, or their :c:func:`devm_request_irq()` and
-:c:func:`devm_free_irq()` equivalents).
-
-When manually registering IRQs, drivers must not set the
-DRIVER_HAVE_IRQ driver feature flag, and must not provide the
-irq_handler driver operation. They must set the :c:type:`struct
-drm_device <drm_device>` irq_enabled field to 1 upon
-registration of the IRQs, and clear it to 0 after unregistering the
-IRQs.
 
 IRQ Helper Library
 ~~~~~~~~~~~~~~~~~~
index 28d736c..3b04c25 100644 (file)
 #include "drm_internal.h"
 
 /**
+ * DOC: irq helpers
+ *
+ * The DRM core provides very simple support helpers to enable IRQ handling on a
+ * device through the drm_irq_install() and drm_irq_uninstall() functions. This
+ * only supports devices with a single interrupt on the main device stored in
+ * &drm_device.dev and set as the device paramter in drm_dev_alloc().
+ *
+ * These IRQ helpers are strictly optional. Drivers which roll their own only
+ * need to set &drm_device.irq_enabled to signal the DRM core that vblank
+ * interrupts are working. Since these helpers don't automatically clean up the
+ * requested interrupt like e.g. devm_request_irq() they're not really
+ * recommended.
+ */
+
+/**
  * drm_irq_install - install IRQ handler
  * @dev: DRM device
  * @irq: IRQ number to install the handler for
  *
  * Initializes the IRQ related data. Installs the handler, calling the driver
- * irq_preinstall() and irq_postinstall() functions before and after the
- * installation.
+ * &drm_driver.irq_preinstall and &drm_driver.irq_postinstall functions before
+ * and after the installation.
  *
  * This is the simplified helper interface provided for drivers with no special
  * needs. Drivers which need to install interrupt handlers for multiple
  * interrupts must instead set &drm_device.irq_enabled to signal the DRM core
  * that vblank interrupts are available.
  *
+ * @irq must match the interrupt number that would be passed to request_irq(),
+ * if called directly instead of using this helper function.
+ *
+ * &drm_driver.irq_handler is called to handle the registered interrupt.
+ *
  * Returns:
  * Zero on success or a negative error code on failure.
  */
@@ -136,9 +156,9 @@ EXPORT_SYMBOL(drm_irq_install);
  * drm_irq_uninstall - uninstall the IRQ handler
  * @dev: DRM device
  *
- * Calls the driver's irq_uninstall() function and unregisters the IRQ handler.
- * This should only be called by drivers which used drm_irq_install() to set up
- * their interrupt handler. Other drivers must only reset
+ * Calls the driver's &drm_driver.irq_uninstall function and unregisters the IRQ
+ * handler.  This should only be called by drivers which used drm_irq_install()
+ * to set up their interrupt handler. Other drivers must only reset
  * &drm_device.irq_enabled to false.
  *
  * Note that for kernel modesetting drivers it is a bug if this function fails.
index 630dc26..463e4d8 100644 (file)
@@ -363,6 +363,9 @@ static void vblank_disable_fn(unsigned long arg)
  * @dev: DRM device
  *
  * This function cleans up any resources allocated in drm_vblank_init.
+ *
+ * Drivers which don't use drm_irq_install() need to set &drm_device.irq_enabled
+ * themselves, to signal to the DRM core that vblank interrupts are enabled.
  */
 void drm_vblank_cleanup(struct drm_device *dev)
 {
index 2e0b76c..39df16a 100644 (file)
@@ -377,8 +377,13 @@ struct drm_device {
        int last_context;               /**< Last current context */
        /*@} */
 
-       /** \name VBLANK IRQ support */
-       /*@{ */
+       /**
+        * @irq_enabled:
+        *
+        * Indicates that interrupt handling is enabled, specifically vblank
+        * handling. Drivers which don't use drm_irq_install() need to set this
+        * to true manually.
+        */
        bool irq_enabled;
        int irq;
 
index e64e33b..18f3181 100644 (file)
@@ -327,11 +327,40 @@ struct drm_driver {
                                     struct timeval *vblank_time,
                                     bool in_vblank_irq);
 
-       /* these have to be filled in */
-
+       /**
+        * @irq_handler:
+        *
+        * Interrupt handler called when using drm_irq_install(). Not used by
+        * drivers which implement their own interrupt handling.
+        */
        irqreturn_t(*irq_handler) (int irq, void *arg);
+
+       /**
+        * @irq_preinstall:
+        *
+        * Optional callback used by drm_irq_install() which is called before
+        * the interrupt handler is registered. This should be used to clear out
+        * any pending interrupts (from e.g. firmware based drives) and reset
+        * the interrupt handling registers.
+        */
        void (*irq_preinstall) (struct drm_device *dev);
+
+       /**
+        * @irq_postinstall:
+        *
+        * Optional callback used by drm_irq_install() which is called after
+        * the interrupt handler is registered. This should be used to enable
+        * interrupt generation in the hardware.
+        */
        int (*irq_postinstall) (struct drm_device *dev);
+
+       /**
+        * @irq_uninstall:
+        *
+        * Optional callback used by drm_irq_uninstall() which is called before
+        * the interrupt handler is unregistered. This should be used to disable
+        * interrupt generation in the hardware.
+        */
        void (*irq_uninstall) (struct drm_device *dev);
 
        /**