From patchwork Wed May 24 14:51:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 9746131 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2AE1560209 for ; Wed, 24 May 2017 14:53:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2040928453 for ; Wed, 24 May 2017 14:53:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 150E12899A; Wed, 24 May 2017 14:53:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RCVD_IN_SORBS_SPAM,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 68C5B28453 for ; Wed, 24 May 2017 14:53:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DF4BF6E778; Wed, 24 May 2017 14:52:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x242.google.com (mail-wm0-x242.google.com [IPv6:2a00:1450:400c:c09::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7E25C6E770 for ; Wed, 24 May 2017 14:52:31 +0000 (UTC) Received: by mail-wm0-x242.google.com with SMTP id k15so46612468wmh.3 for ; Wed, 24 May 2017 07:52:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tZtalkRaXJouAkgiS82lyGAgR9CgNlHDTSAx1w06EL4=; b=K/ZaXEPWirk+VouxQs9bW96ZMbUUbycvfs0gu5G6Sf19RkI0QVlZdgvDJMUS+9qtg7 +hAyOMI+Q1gfuCDaOK+dedGdA4RY3rbjKU1OEccEhVHVlVvhCLEcylQK0MbLgv9DkmY3 BjznJAQwAXzX/Uw621wuqYP4jWch+WhP4j4gw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=tZtalkRaXJouAkgiS82lyGAgR9CgNlHDTSAx1w06EL4=; b=R3HTQ5jQWIxDUijvsVs+171xM8SyKdmfTLcMtbdp7u5HGPKNJ2sbkjxQAeUrzE/NI+ u5htP+xW1b7hNWXjDOb/ZQdf0m4Wh4Jsahs+zrz78lcTo/Sobjw2hS7Rs5+ww+rUFfAx O8lMXnUCIaE8srzQurtRSJilkwRttLqAJVYek6I9ohfYiWoxZ4L2G5+t/5ET3Q5YcovL yza+QvkOOV3JWRG6tlu7halL2nvxb4jppZ5cnIxfMU6ECFPWQ3D7hrQsXYgrvv7DGXRy sGhoI2BLzYGXHAjZoYTGPSmBL7TLjl+aD2UqU+QihransEAv94WW1afhbSTgQJUzou+z 1J6A== X-Gm-Message-State: AODbwcCwOARnX4puCeX25vZXen+ypQEJVCbzNRXRIOSIzuoM5cjj9xW5 Wtk+9oG5sFejN6rV X-Received: by 10.80.146.154 with SMTP id k26mr25905132eda.23.1495637549946; Wed, 24 May 2017 07:52:29 -0700 (PDT) Received: from phenom.ffwll.local ([2a02:168:5640:0:960b:2678:e223:c1c6]) by smtp.gmail.com with ESMTPSA id m9sm1778858edm.62.2017.05.24.07.52.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 May 2017 07:52:29 -0700 (PDT) From: Daniel Vetter To: DRI Development Subject: [PATCH 08/37] drm/doc: Polish irq helper documentation Date: Wed, 24 May 2017 16:51:43 +0200 Message-Id: <20170524145212.27837-9-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170524145212.27837-1-daniel.vetter@ffwll.ch> References: <20170524145212.27837-1-daniel.vetter@ffwll.ch> Cc: Daniel Vetter , Intel Graphics Development , Daniel Vetter X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Pull a (much shorter) overview into drm_irq.c, and instead put the callback documentation into in-line comments in drm_drv.h. Signed-off-by: Daniel Vetter Reviewed-by: Stefan Agner --- Documentation/gpu/drm-internals.rst | 62 +++++-------------------------------- drivers/gpu/drm/drm_irq.c | 30 +++++++++++++++--- drivers/gpu/drm/drm_vblank.c | 3 ++ include/drm/drmP.h | 9 ++++-- include/drm/drm_drv.h | 33 ++++++++++++++++++-- 5 files changed, 74 insertions(+), 63 deletions(-) diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index d218dd29221a..82b406d3d377 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -149,60 +149,14 @@ 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 ` irq_enabled field to 1 upon -registration of the IRQs, and clear it to 0 after unregistering the -IRQs. +IRQ Helper Library +~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_irq.c + :doc: irq helpers + +.. kernel-doc:: drivers/gpu/drm/drm_irq.c + :export: Memory Manager Initialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 @@ #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. 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) * @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) { 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 { 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; diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index ebb41688581b..f495eee01302 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -325,11 +325,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); /**