1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2728674a7SGreg Kroah-Hartman /*
3728674a7SGreg Kroah-Hartman * Copyright IBM Corp. 2001,2008
4728674a7SGreg Kroah-Hartman *
5728674a7SGreg Kroah-Hartman * This file contains the IRQ specific code for hvc_console
6728674a7SGreg Kroah-Hartman *
7728674a7SGreg Kroah-Hartman */
8728674a7SGreg Kroah-Hartman
9728674a7SGreg Kroah-Hartman #include <linux/interrupt.h>
10728674a7SGreg Kroah-Hartman
11728674a7SGreg Kroah-Hartman #include "hvc_console.h"
12728674a7SGreg Kroah-Hartman
hvc_handle_interrupt(int irq,void * dev_instance)13728674a7SGreg Kroah-Hartman static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
14728674a7SGreg Kroah-Hartman {
15728674a7SGreg Kroah-Hartman /* if hvc_poll request a repoll, then kick the hvcd thread */
16728674a7SGreg Kroah-Hartman if (hvc_poll(dev_instance))
17728674a7SGreg Kroah-Hartman hvc_kick();
18bbc3dfe8SSam Mendoza-Jonas
19bbc3dfe8SSam Mendoza-Jonas /*
20bbc3dfe8SSam Mendoza-Jonas * We're safe to always return IRQ_HANDLED as the hvcd thread will
21bbc3dfe8SSam Mendoza-Jonas * iterate through each hvc_struct.
22bbc3dfe8SSam Mendoza-Jonas */
23728674a7SGreg Kroah-Hartman return IRQ_HANDLED;
24728674a7SGreg Kroah-Hartman }
25728674a7SGreg Kroah-Hartman
26728674a7SGreg Kroah-Hartman /*
27728674a7SGreg Kroah-Hartman * For IRQ based systems these callbacks can be used
28728674a7SGreg Kroah-Hartman */
notifier_add_irq(struct hvc_struct * hp,int irq)29728674a7SGreg Kroah-Hartman int notifier_add_irq(struct hvc_struct *hp, int irq)
30728674a7SGreg Kroah-Hartman {
31728674a7SGreg Kroah-Hartman int rc;
32728674a7SGreg Kroah-Hartman
33728674a7SGreg Kroah-Hartman if (!irq) {
34728674a7SGreg Kroah-Hartman hp->irq_requested = 0;
35728674a7SGreg Kroah-Hartman return 0;
36728674a7SGreg Kroah-Hartman }
37bbc3dfe8SSam Mendoza-Jonas rc = request_irq(irq, hvc_handle_interrupt, hp->flags,
38728674a7SGreg Kroah-Hartman "hvc_console", hp);
39728674a7SGreg Kroah-Hartman if (!rc)
40728674a7SGreg Kroah-Hartman hp->irq_requested = 1;
41728674a7SGreg Kroah-Hartman return rc;
42728674a7SGreg Kroah-Hartman }
43728674a7SGreg Kroah-Hartman
notifier_del_irq(struct hvc_struct * hp,int irq)44728674a7SGreg Kroah-Hartman void notifier_del_irq(struct hvc_struct *hp, int irq)
45728674a7SGreg Kroah-Hartman {
46728674a7SGreg Kroah-Hartman if (!hp->irq_requested)
47728674a7SGreg Kroah-Hartman return;
48728674a7SGreg Kroah-Hartman free_irq(irq, hp);
49728674a7SGreg Kroah-Hartman hp->irq_requested = 0;
50728674a7SGreg Kroah-Hartman }
51728674a7SGreg Kroah-Hartman
notifier_hangup_irq(struct hvc_struct * hp,int irq)52728674a7SGreg Kroah-Hartman void notifier_hangup_irq(struct hvc_struct *hp, int irq)
53728674a7SGreg Kroah-Hartman {
54728674a7SGreg Kroah-Hartman notifier_del_irq(hp, irq);
55728674a7SGreg Kroah-Hartman }
56