xref: /openbmc/linux/drivers/tty/hvc/hvc_irq.c (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
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