1c369667eSFrançois Tigeot /*
277343d59SFrançois Tigeot * Copyright (c) 2010 Isilon Systems, Inc.
377343d59SFrançois Tigeot * Copyright (c) 2010 iX Systems, Inc.
477343d59SFrançois Tigeot * Copyright (c) 2010 Panasas, Inc.
523b649bfSFrançois Tigeot * Copyright (c) 2014-2020 François Tigeot <ftigeot@wolfpond.org>
677343d59SFrançois Tigeot * All rights reserved.
777343d59SFrançois Tigeot *
877343d59SFrançois Tigeot * Redistribution and use in source and binary forms, with or without
977343d59SFrançois Tigeot * modification, are permitted provided that the following conditions
1077343d59SFrançois Tigeot * are met:
1177343d59SFrançois Tigeot * 1. Redistributions of source code must retain the above copyright
1277343d59SFrançois Tigeot * notice unmodified, this list of conditions, and the following
1377343d59SFrançois Tigeot * disclaimer.
1477343d59SFrançois Tigeot * 2. Redistributions in binary form must reproduce the above copyright
1577343d59SFrançois Tigeot * notice, this list of conditions and the following disclaimer in the
1677343d59SFrançois Tigeot * documentation and/or other materials provided with the distribution.
1777343d59SFrançois Tigeot *
1877343d59SFrançois Tigeot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1977343d59SFrançois Tigeot * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2077343d59SFrançois Tigeot * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2177343d59SFrançois Tigeot * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2277343d59SFrançois Tigeot * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2377343d59SFrançois Tigeot * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2477343d59SFrançois Tigeot * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2577343d59SFrançois Tigeot * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2677343d59SFrançois Tigeot * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2777343d59SFrançois Tigeot * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2877343d59SFrançois Tigeot */
2977343d59SFrançois Tigeot #ifndef _LINUX_TIMER_H_
3077343d59SFrançois Tigeot #define _LINUX_TIMER_H_
3177343d59SFrançois Tigeot
32c369667eSFrançois Tigeot #include <linux/list.h>
3301c621f3SFrançois Tigeot #include <linux/ktime.h>
34c369667eSFrançois Tigeot #include <linux/stddef.h>
35c369667eSFrançois Tigeot #include <linux/stringify.h>
36c369667eSFrançois Tigeot
37c369667eSFrançois Tigeot #include <sys/callout.h>
3801c621f3SFrançois Tigeot
3977343d59SFrançois Tigeot struct timer_list {
4077343d59SFrançois Tigeot struct callout timer_callout;
4177343d59SFrançois Tigeot void (*function)(unsigned long);
4277343d59SFrançois Tigeot unsigned long data;
4377343d59SFrançois Tigeot unsigned long expires;
4477343d59SFrançois Tigeot };
4577343d59SFrançois Tigeot
4677343d59SFrançois Tigeot static inline void
_timer_fn(void * context)4777343d59SFrançois Tigeot _timer_fn(void *context)
4877343d59SFrançois Tigeot {
4977343d59SFrançois Tigeot struct timer_list *timer;
5077343d59SFrançois Tigeot
5177343d59SFrançois Tigeot timer = context;
5277343d59SFrançois Tigeot timer->function(timer->data);
5377343d59SFrançois Tigeot }
5477343d59SFrançois Tigeot
5577343d59SFrançois Tigeot #define setup_timer(timer, func, dat) \
5677343d59SFrançois Tigeot do { \
5777343d59SFrançois Tigeot (timer)->function = (func); \
5877343d59SFrançois Tigeot (timer)->data = (dat); \
59fe87864cSFrançois Tigeot callout_init_mp(&(timer)->timer_callout); \
6077343d59SFrançois Tigeot } while (0)
6177343d59SFrançois Tigeot
62d9b1635cSFrançois Tigeot #define setup_timer_on_stack(t, f,d) setup_timer(t, f, d)
63d9b1635cSFrançois Tigeot
6423b649bfSFrançois Tigeot #define __setup_timer(timer, func, data, flags) \
6523b649bfSFrançois Tigeot do { \
6623b649bfSFrançois Tigeot setup_timer(timer, func, data); \
6723b649bfSFrançois Tigeot } while (0)
6823b649bfSFrançois Tigeot
6977343d59SFrançois Tigeot #define init_timer(timer) \
7077343d59SFrançois Tigeot do { \
7177343d59SFrançois Tigeot (timer)->function = NULL; \
7277343d59SFrançois Tigeot (timer)->data = 0; \
73fe87864cSFrançois Tigeot callout_init_mp(&(timer)->timer_callout); \
7477343d59SFrançois Tigeot } while (0)
7577343d59SFrançois Tigeot
7677343d59SFrançois Tigeot #define mod_timer(timer, exp) \
7777343d59SFrançois Tigeot do { \
7877343d59SFrançois Tigeot (timer)->expires = (exp); \
7977343d59SFrançois Tigeot callout_reset(&(timer)->timer_callout, (exp) - jiffies, \
8077343d59SFrançois Tigeot _timer_fn, (timer)); \
8177343d59SFrançois Tigeot } while (0)
8277343d59SFrançois Tigeot
83203d5d51SFrançois Tigeot #define mod_timer_pinned(timer, exp) mod_timer(timer, exp)
84203d5d51SFrançois Tigeot
8577343d59SFrançois Tigeot #define add_timer(timer) \
8677343d59SFrançois Tigeot callout_reset(&(timer)->timer_callout, \
87fe87864cSFrançois Tigeot (timer)->expires - jiffies, _timer_fn, (timer)); \
8877343d59SFrançois Tigeot
89fe87864cSFrançois Tigeot static inline void
del_timer(struct timer_list * timer)90fe87864cSFrançois Tigeot del_timer(struct timer_list *timer)
91fe87864cSFrançois Tigeot {
92fe87864cSFrançois Tigeot callout_stop(&(timer)->timer_callout);
93fe87864cSFrançois Tigeot }
94fe87864cSFrançois Tigeot
955abb6f61SImre Vadász static inline int
del_timer_sync(struct timer_list * timer)965abb6f61SImre Vadász del_timer_sync(struct timer_list *timer)
975abb6f61SImre Vadász {
985abb6f61SImre Vadász return callout_drain(&(timer)->timer_callout) == 0;
995abb6f61SImre Vadász }
1005abb6f61SImre Vadász
101d9b1635cSFrançois Tigeot #define del_singleshot_timer_sync(timer) del_timer_sync(timer)
10277343d59SFrançois Tigeot
10377343d59SFrançois Tigeot #define timer_pending(timer) callout_pending(&(timer)->timer_callout)
10477343d59SFrançois Tigeot
10577343d59SFrançois Tigeot static inline unsigned long
round_jiffies(unsigned long j)10677343d59SFrançois Tigeot round_jiffies(unsigned long j)
10777343d59SFrançois Tigeot {
10877343d59SFrançois Tigeot return roundup(j, hz);
10977343d59SFrançois Tigeot }
11077343d59SFrançois Tigeot
111fe87864cSFrançois Tigeot static inline unsigned long
round_jiffies_up(unsigned long j)112fe87864cSFrançois Tigeot round_jiffies_up(unsigned long j)
113fe87864cSFrançois Tigeot {
114fe87864cSFrançois Tigeot return roundup(j, hz);
115fe87864cSFrançois Tigeot }
116fe87864cSFrançois Tigeot
1177f070b26SFrançois Tigeot static inline unsigned long
round_jiffies_up_relative(unsigned long j)1187f070b26SFrançois Tigeot round_jiffies_up_relative(unsigned long j)
1197f070b26SFrançois Tigeot {
1207f070b26SFrançois Tigeot return roundup(j, hz);
1217f070b26SFrançois Tigeot }
1227f070b26SFrançois Tigeot
1234c816622SFrançois Tigeot #define destroy_timer_on_stack(timer)
1244c816622SFrançois Tigeot
12523b649bfSFrançois Tigeot #define TIMER_IRQSAFE 0x00200000
12623b649bfSFrançois Tigeot
127*3f2dd94aSFrançois Tigeot #define from_timer(var, arg, field) \
128*3f2dd94aSFrançois Tigeot container_of(arg, typeof(*(var)), field)
129*3f2dd94aSFrançois Tigeot
130*3f2dd94aSFrançois Tigeot static inline void
timer_setup(struct timer_list * timer,void (* callback)(struct timer_list *),unsigned int flags)131*3f2dd94aSFrançois Tigeot timer_setup(struct timer_list *timer,
132*3f2dd94aSFrançois Tigeot void (*callback)(struct timer_list *),
133*3f2dd94aSFrançois Tigeot unsigned int flags)
134*3f2dd94aSFrançois Tigeot {
135*3f2dd94aSFrançois Tigeot setup_timer(timer,
136*3f2dd94aSFrançois Tigeot (void (*)(unsigned long))callback,
137*3f2dd94aSFrançois Tigeot (unsigned long)timer);
138*3f2dd94aSFrançois Tigeot }
139*3f2dd94aSFrançois Tigeot
14077343d59SFrançois Tigeot #endif /* _LINUX_TIMER_H_ */
141