18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Dummy IRQ handler driver.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * This module only registers itself as a handler that is specified to it
68c2ecf20Sopenharmony_ci * by the 'irq' parameter.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * The sole purpose of this module is to help with debugging of systems on
98c2ecf20Sopenharmony_ci * which spurious IRQs would happen on disabled IRQ vector.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * Copyright (C) 2013 Jiri Kosina
128c2ecf20Sopenharmony_ci */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/module.h>
158c2ecf20Sopenharmony_ci#include <linux/irq.h>
168c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic int irq = -1;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic irqreturn_t dummy_interrupt(int irq, void *dev_id)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	static int count = 0;
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	if (count == 0) {
258c2ecf20Sopenharmony_ci		printk(KERN_INFO "dummy-irq: interrupt occurred on IRQ %d\n",
268c2ecf20Sopenharmony_ci				irq);
278c2ecf20Sopenharmony_ci		count++;
288c2ecf20Sopenharmony_ci	}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	return IRQ_NONE;
318c2ecf20Sopenharmony_ci}
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic int __init dummy_irq_init(void)
348c2ecf20Sopenharmony_ci{
358c2ecf20Sopenharmony_ci	if (irq < 0) {
368c2ecf20Sopenharmony_ci		printk(KERN_ERR "dummy-irq: no IRQ given.  Use irq=N\n");
378c2ecf20Sopenharmony_ci		return -EIO;
388c2ecf20Sopenharmony_ci	}
398c2ecf20Sopenharmony_ci	if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) {
408c2ecf20Sopenharmony_ci		printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq);
418c2ecf20Sopenharmony_ci		return -EIO;
428c2ecf20Sopenharmony_ci	}
438c2ecf20Sopenharmony_ci	printk(KERN_INFO "dummy-irq: registered for IRQ %d\n", irq);
448c2ecf20Sopenharmony_ci	return 0;
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistatic void __exit dummy_irq_exit(void)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	printk(KERN_INFO "dummy-irq unloaded\n");
508c2ecf20Sopenharmony_ci	free_irq(irq, &irq);
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cimodule_init(dummy_irq_init);
548c2ecf20Sopenharmony_cimodule_exit(dummy_irq_exit);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
578c2ecf20Sopenharmony_ciMODULE_AUTHOR("Jiri Kosina");
588c2ecf20Sopenharmony_cimodule_param_hw(irq, uint, irq, 0444);
598c2ecf20Sopenharmony_ciMODULE_PARM_DESC(irq, "The IRQ to register for");
608c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Dummy IRQ handler driver");
61