summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2015-07-03 03:39:12 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-07-06 06:24:36 -0400
commita8956a7b7232da5f4ce4a305c72a54cc5e4a8307 (patch)
treefd460edb28a11ac7eb63170a3571163701e88d9d /arch/powerpc
parentaaf6fd5c75eb4aa734ec2062deab371633c3655f (diff)
powerpc/powernv: Fix opal-elog interrupt handler
The conversion of opal events to a proper irqchip means that handlers are called until the relevant opal event has been cleared by processing it. Events that queue work should therefore use a threaded handler to mask the event until processing is complete. Signed-off-by: Alistair Popple <alistair@popple.id.au> Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/powernv/opal-elog.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index 4949ef0d9400..37f959bf392e 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -237,7 +237,7 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
237 return elog; 237 return elog;
238} 238}
239 239
240static void elog_work_fn(struct work_struct *work) 240static irqreturn_t elog_event(int irq, void *data)
241{ 241{
242 __be64 size; 242 __be64 size;
243 __be64 id; 243 __be64 id;
@@ -251,7 +251,7 @@ static void elog_work_fn(struct work_struct *work)
251 rc = opal_get_elog_size(&id, &size, &type); 251 rc = opal_get_elog_size(&id, &size, &type);
252 if (rc != OPAL_SUCCESS) { 252 if (rc != OPAL_SUCCESS) {
253 pr_err("ELOG: OPAL log info read failed\n"); 253 pr_err("ELOG: OPAL log info read failed\n");
254 return; 254 return IRQ_HANDLED;
255 } 255 }
256 256
257 elog_size = be64_to_cpu(size); 257 elog_size = be64_to_cpu(size);
@@ -270,16 +270,10 @@ static void elog_work_fn(struct work_struct *work)
270 * entries. 270 * entries.
271 */ 271 */
272 if (kset_find_obj(elog_kset, name)) 272 if (kset_find_obj(elog_kset, name))
273 return; 273 return IRQ_HANDLED;
274 274
275 create_elog_obj(log_id, elog_size, elog_type); 275 create_elog_obj(log_id, elog_size, elog_type);
276}
277
278static DECLARE_WORK(elog_work, elog_work_fn);
279 276
280static irqreturn_t elog_event(int irq, void *data)
281{
282 schedule_work(&elog_work);
283 return IRQ_HANDLED; 277 return IRQ_HANDLED;
284} 278}
285 279
@@ -304,8 +298,8 @@ int __init opal_elog_init(void)
304 return irq; 298 return irq;
305 } 299 }
306 300
307 rc = request_irq(irq, elog_event, 301 rc = request_threaded_irq(irq, NULL, elog_event,
308 IRQ_TYPE_LEVEL_HIGH, "opal-elog", NULL); 302 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "opal-elog", NULL);
309 if (rc) { 303 if (rc) {
310 pr_err("%s: Can't request OPAL event irq (%d)\n", 304 pr_err("%s: Can't request OPAL event irq (%d)\n",
311 __func__, rc); 305 __func__, rc);