aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalcolm Priestley <tvboxspy@gmail.com>2019-03-24 14:53:49 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-03-25 16:54:17 -0400
commit3b9c2f2e0e99bb67c96abcb659b3465efe3bee1f (patch)
treeb3d1913403e6e78b74a616113846fb0f520b67d9
parent6a8ca24590a2136921439b376c926c11a6effc0e (diff)
staging: vt6655: Fix interrupt race condition on device start up.
It appears on some slower systems that the driver can find its way out of the workqueue while the interrupt is disabled by continuous polling by it. Move MACvIntEnable to vnt_interrupt_work so that it is always enabled on all routes out of vnt_interrupt_process. Move MACvIntDisable so that the device doesn't keep polling the system while the workqueue is being processed. Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> CC: stable@vger.kernel.org # v4.2+ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/vt6655/device_main.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index b370985b58a1..83f1a1cf9182 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -1033,8 +1033,6 @@ static void vnt_interrupt_process(struct vnt_private *priv)
1033 return; 1033 return;
1034 } 1034 }
1035 1035
1036 MACvIntDisable(priv->PortOffset);
1037
1038 spin_lock_irqsave(&priv->lock, flags); 1036 spin_lock_irqsave(&priv->lock, flags);
1039 1037
1040 /* Read low level stats */ 1038 /* Read low level stats */
@@ -1122,8 +1120,6 @@ static void vnt_interrupt_process(struct vnt_private *priv)
1122 } 1120 }
1123 1121
1124 spin_unlock_irqrestore(&priv->lock, flags); 1122 spin_unlock_irqrestore(&priv->lock, flags);
1125
1126 MACvIntEnable(priv->PortOffset, IMR_MASK_VALUE);
1127} 1123}
1128 1124
1129static void vnt_interrupt_work(struct work_struct *work) 1125static void vnt_interrupt_work(struct work_struct *work)
@@ -1133,6 +1129,8 @@ static void vnt_interrupt_work(struct work_struct *work)
1133 1129
1134 if (priv->vif) 1130 if (priv->vif)
1135 vnt_interrupt_process(priv); 1131 vnt_interrupt_process(priv);
1132
1133 MACvIntEnable(priv->PortOffset, IMR_MASK_VALUE);
1136} 1134}
1137 1135
1138static irqreturn_t vnt_interrupt(int irq, void *arg) 1136static irqreturn_t vnt_interrupt(int irq, void *arg)
@@ -1142,6 +1140,8 @@ static irqreturn_t vnt_interrupt(int irq, void *arg)
1142 if (priv->vif) 1140 if (priv->vif)
1143 schedule_work(&priv->interrupt_work); 1141 schedule_work(&priv->interrupt_work);
1144 1142
1143 MACvIntDisable(priv->PortOffset);
1144
1145 return IRQ_HANDLED; 1145 return IRQ_HANDLED;
1146} 1146}
1147 1147