11e59d133SFrançois Tigeot /* 2*183e2373SFrançois Tigeot * Copyright (c) 2017-2018 François Tigeot <ftigeot@wolfpond.org> 31e59d133SFrançois Tigeot * All rights reserved. 41e59d133SFrançois Tigeot * 51e59d133SFrançois Tigeot * Redistribution and use in source and binary forms, with or without 61e59d133SFrançois Tigeot * modification, are permitted provided that the following conditions 71e59d133SFrançois Tigeot * are met: 81e59d133SFrançois Tigeot * 1. Redistributions of source code must retain the above copyright 91e59d133SFrançois Tigeot * notice unmodified, this list of conditions, and the following 101e59d133SFrançois Tigeot * disclaimer. 111e59d133SFrançois Tigeot * 2. Redistributions in binary form must reproduce the above copyright 121e59d133SFrançois Tigeot * notice, this list of conditions and the following disclaimer in the 131e59d133SFrançois Tigeot * documentation and/or other materials provided with the distribution. 141e59d133SFrançois Tigeot * 151e59d133SFrançois Tigeot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161e59d133SFrançois Tigeot * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171e59d133SFrançois Tigeot * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181e59d133SFrançois Tigeot * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191e59d133SFrançois Tigeot * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201e59d133SFrançois Tigeot * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211e59d133SFrançois Tigeot * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221e59d133SFrançois Tigeot * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231e59d133SFrançois Tigeot * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241e59d133SFrançois Tigeot * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251e59d133SFrançois Tigeot */ 261e59d133SFrançois Tigeot 271e59d133SFrançois Tigeot #ifndef _LINUX_INTERRUPT_H_ 281e59d133SFrançois Tigeot #define _LINUX_INTERRUPT_H_ 291e59d133SFrançois Tigeot 301e59d133SFrançois Tigeot #include <linux/kernel.h> 311e59d133SFrançois Tigeot #include <linux/bitops.h> 32de2d8016SFrançois Tigeot #include <linux/irqreturn.h> 331334141fSFrançois Tigeot #include <linux/hardirq.h> 34de2d8016SFrançois Tigeot #include <linux/irqflags.h> 355915b712SFrançois Tigeot #include <linux/hrtimer.h> 361e59d133SFrançois Tigeot #include <linux/kref.h> 371e59d133SFrançois Tigeot 381e59d133SFrançois Tigeot #include <linux/atomic.h> 391e59d133SFrançois Tigeot 40*183e2373SFrançois Tigeot #define IRQF_SHARED 0x00000080 41*183e2373SFrançois Tigeot 421e59d133SFrançois Tigeot struct tasklet_struct { 431e59d133SFrançois Tigeot unsigned long state; 441e59d133SFrançois Tigeot void (*func)(unsigned long); 451e59d133SFrançois Tigeot unsigned long data; 461e59d133SFrançois Tigeot struct lock lock; 471e59d133SFrançois Tigeot }; 481e59d133SFrançois Tigeot 491e59d133SFrançois Tigeot enum { 501e59d133SFrançois Tigeot TASKLET_STATE_SCHED, 511e59d133SFrançois Tigeot TASKLET_STATE_RUN 521e59d133SFrançois Tigeot }; 531e59d133SFrançois Tigeot 541e59d133SFrançois Tigeot /* 551e59d133SFrançois Tigeot * TODO: verify these points: 561e59d133SFrançois Tigeot * - tasklets that have the same type cannot be run on multiple processors at the same time 571e59d133SFrançois Tigeot * - tasklets always run on the processor from which they were originally 581e59d133SFrançois Tigeot * submitted 591e59d133SFrançois Tigeot * - when a tasklet is scheduled, its state is set to TASKLET_STATE_SCHED, and the tasklet 601e59d133SFrançois Tigeot * added to a queue 611e59d133SFrançois Tigeot * - during the execution of its function, the tasklet state is set to TASKLET_STATE_RUN 621e59d133SFrançois Tigeot * and the TASKLET_STATE_SCHED state is removed 631e59d133SFrançois Tigeot */ 641e59d133SFrançois Tigeot 651e59d133SFrançois Tigeot /* XXX scheduling and execution should be handled separately */ 661e59d133SFrançois Tigeot static inline void 671e59d133SFrançois Tigeot tasklet_schedule(struct tasklet_struct *t) 681e59d133SFrançois Tigeot { 69f06706ddSFrançois Tigeot set_bit(TASKLET_STATE_SCHED, &t->state); 701e59d133SFrançois Tigeot 711e59d133SFrançois Tigeot lockmgr(&t->lock, LK_EXCLUSIVE); 72f06706ddSFrançois Tigeot clear_bit(TASKLET_STATE_SCHED, &t->state); 731e59d133SFrançois Tigeot 74f06706ddSFrançois Tigeot set_bit(TASKLET_STATE_RUN, &t->state); 75f06706ddSFrançois Tigeot if (t->func) 761e59d133SFrançois Tigeot t->func(t->data); 77f06706ddSFrançois Tigeot clear_bit(TASKLET_STATE_RUN, &t->state); 781e59d133SFrançois Tigeot 791e59d133SFrançois Tigeot lockmgr(&t->lock, LK_RELEASE); 801e59d133SFrançois Tigeot } 811e59d133SFrançois Tigeot 821e59d133SFrançois Tigeot /* This function ensures that the tasklet is not scheduled to run again */ 831e59d133SFrançois Tigeot /* XXX this doesn't kill anything */ 841e59d133SFrançois Tigeot static inline void 851e59d133SFrançois Tigeot tasklet_kill(struct tasklet_struct *t) 861e59d133SFrançois Tigeot { 871e59d133SFrançois Tigeot lockmgr(&t->lock, LK_EXCLUSIVE); 88f06706ddSFrançois Tigeot clear_bit(TASKLET_STATE_SCHED, &t->state); 891e59d133SFrançois Tigeot lockmgr(&t->lock, LK_RELEASE); 901e59d133SFrançois Tigeot } 911e59d133SFrançois Tigeot 921e59d133SFrançois Tigeot static inline void 931e59d133SFrançois Tigeot tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data) 941e59d133SFrançois Tigeot { 951e59d133SFrançois Tigeot lockinit(&t->lock, "ltasklet", 0, LK_CANRECURSE); 961e59d133SFrançois Tigeot t->state = 0; 971e59d133SFrançois Tigeot t->func = func; 981e59d133SFrançois Tigeot t->data = data; 991e59d133SFrançois Tigeot } 1001e59d133SFrançois Tigeot 101*183e2373SFrançois Tigeot typedef irqreturn_t (*irq_handler_t)(int, void *); 102*183e2373SFrançois Tigeot 103*183e2373SFrançois Tigeot int request_irq(unsigned int irq, irq_handler_t handler, 104*183e2373SFrançois Tigeot unsigned long flags, const char *name, void *dev); 105*183e2373SFrançois Tigeot 106*183e2373SFrançois Tigeot void free_irq(unsigned int irq, void *dev_id); 107*183e2373SFrançois Tigeot 1081e59d133SFrançois Tigeot #endif /* _LINUX_INTERRUPT_H_ */ 109