drm/bridge: cdns-mhdp8546: Fix the interrupt enable/disable
authorNikhil Devshatwar <nikhil.nd@ti.com>
Tue, 6 Jun 2023 08:21:42 +0000 (13:51 +0530)
committerJavier Martinez Canillas <javierm@redhat.com>
Mon, 10 Jul 2023 12:21:35 +0000 (14:21 +0200)
When removing the tidss driver, there is a warning reported by
kernel about an unhandled interrupt for mhdp driver.

[   43.238895] irq 31: nobody cared (try booting with the "irqpoll" option)
... [snipped backtrace]
[   43.330735] handlers:
[   43.333020] [<000000005367c4f9>] irq_default_primary_handler threaded [<000000007e02b601>]
cdns_mhdp_irq_handler [cdns_mhdp8546]
[   43.344607] Disabling IRQ #31

This happens because as part of cdns_mhdp_bridge_hpd_disable, driver tries
to disable the interrupts. While disabling the SW_EVENT interrupts,
it accidentally enables the MBOX interrupts, which are not handled by
the driver.

Fix this with a read-modify-write to update only required bits.
Use the enable / disable function as required in other places.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Reviewed-by: Swapnil Jakhade <sjakhade@cadence.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Aradhya Bhatia <a-bhatia1@ti.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230606082142.23760-9-a-bhatia1@ti.com
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c

index f12fb62..ecb935e 100644 (file)
 #include "cdns-mhdp8546-hdcp.h"
 #include "cdns-mhdp8546-j721e.h"
 
+static void cdns_mhdp_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+       struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
+
+       /* Enable SW event interrupts */
+       if (mhdp->bridge_attached)
+               writel(readl(mhdp->regs + CDNS_APB_INT_MASK) &
+                      ~CDNS_APB_INT_MASK_SW_EVENT_INT,
+                      mhdp->regs + CDNS_APB_INT_MASK);
+}
+
+static void cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+       struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
+
+       writel(readl(mhdp->regs + CDNS_APB_INT_MASK) |
+              CDNS_APB_INT_MASK_SW_EVENT_INT,
+              mhdp->regs + CDNS_APB_INT_MASK);
+}
+
 static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
 {
        int ret, empty;
@@ -749,9 +769,7 @@ static int cdns_mhdp_fw_activate(const struct firmware *fw,
         * MHDP_HW_STOPPED happens only due to driver removal when
         * bridge should already be detached.
         */
-       if (mhdp->bridge_attached)
-               writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT,
-                      mhdp->regs + CDNS_APB_INT_MASK);
+       cdns_mhdp_bridge_hpd_enable(&mhdp->bridge);
 
        spin_unlock(&mhdp->start_lock);
 
@@ -1740,8 +1758,7 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge,
 
        /* Enable SW event interrupts */
        if (hw_ready)
-               writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT,
-                      mhdp->regs + CDNS_APB_INT_MASK);
+               cdns_mhdp_bridge_hpd_enable(bridge);
 
        return 0;
 aux_unregister:
@@ -2212,23 +2229,6 @@ static struct edid *cdns_mhdp_bridge_get_edid(struct drm_bridge *bridge,
        return cdns_mhdp_get_edid(mhdp, connector);
 }
 
-static void cdns_mhdp_bridge_hpd_enable(struct drm_bridge *bridge)
-{
-       struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
-
-       /* Enable SW event interrupts */
-       if (mhdp->bridge_attached)
-               writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT,
-                      mhdp->regs + CDNS_APB_INT_MASK);
-}
-
-static void cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge)
-{
-       struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
-
-       writel(CDNS_APB_INT_MASK_SW_EVENT_INT, mhdp->regs + CDNS_APB_INT_MASK);
-}
-
 static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
        .atomic_enable = cdns_mhdp_atomic_enable,
        .atomic_disable = cdns_mhdp_atomic_disable,