]> git.sur5r.net Git - groeck-nct6775/blob - compat.h
Add driver removal notice
[groeck-nct6775] / compat.h
1 #ifndef __COMPAT_H
2 #define __COMPAT_H
3
4 #include <linux/version.h>
5
6 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
7 #error This driver is for kernel versions 2.6.32 and later
8 #endif
9
10 #if !defined (CONFIG_HWMON_VID) && !defined(CONFIG_HWMON_VID_MODULE)
11 int vid_from_reg(int val, u8 vrm)
12 {
13         return 0;
14 }
15
16 u8 vid_which_vrm(void)
17 {
18         return 0;
19 }
20 #endif
21
22 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
23 #if !(defined RHEL_MAJOR && RHEL_MAJOR == 7)
24 #if !(defined RHEL_MAJOR && RHEL_MAJOR == 6 && RHEL_MINOR >= 7)
25 static int sysfs_create_groups(struct kobject *kobj,
26                                const struct attribute_group **groups)
27 {
28         int error = 0;
29         int i;
30
31         if (!groups)
32                 return 0;
33
34         for (i = 0; groups[i]; i++) {
35                 error = sysfs_create_group(kobj, groups[i]);
36                 if (error) {
37                         while (--i >= 0)
38                                 sysfs_remove_group(kobj, groups[i]);
39                         break;
40                 }
41         }
42         return error;
43 }
44 #endif
45
46 static void sysfs_remove_groups(struct kobject *kobj,
47                                 const struct attribute_group **groups)
48 {
49         int i;
50
51         if (!groups)
52                 return;
53         for (i = 0; groups[i]; i++)
54                 sysfs_remove_group(kobj, groups[i]);
55 }
56 #endif
57
58 #if !(defined RHEL_MAJOR && RHEL_MAJOR == 7)
59 #if !(defined RHEL_MAJOR && RHEL_MAJOR == 6 && RHEL_MINOR >= 7)
60 static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr)
61 {
62         if (IS_ERR(ptr))
63                 return PTR_ERR(ptr);
64         else
65                 return 0;
66 }
67 #endif
68 #endif
69 #endif
70
71 #ifdef __NEED_I2C__
72
73 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
74 #if !(defined RHEL_MAJOR && RHEL_MAJOR == 5 && RHEL_MINOR >= 6)
75 /* Simplified version for compatibility */
76 struct i2c_board_info {
77         char            type[I2C_NAME_SIZE];
78         unsigned short  flags;
79         unsigned short  addr;
80 };
81 #endif
82 #endif
83
84 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 25)
85 /* Some older kernels have a different, useless struct i2c_device_id */
86 #define i2c_device_id i2c_device_id_compat
87 struct i2c_device_id {
88         char name[I2C_NAME_SIZE];
89         kernel_ulong_t driver_data      /* Data private to the driver */
90                         __attribute__((aligned(sizeof(kernel_ulong_t))));
91 };
92 #endif
93
94 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
95 static unsigned short empty_i2c[] =  { I2C_CLIENT_END };
96 static struct i2c_client_address_data addr_data = {
97         .normal_i2c     = normal_i2c,
98         .probe          = empty_i2c,
99         .ignore         = empty_i2c,
100 };
101 #endif
102
103 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
104 static inline s32
105 i2c_smbus_read_word_swapped(const struct i2c_client *client, u8 command)
106 {
107         s32 value = i2c_smbus_read_word_data(client, command);
108
109         return (value < 0) ? value : swab16(value);
110 }
111
112 static inline s32
113 i2c_smbus_write_word_swapped(const struct i2c_client *client,
114                              u8 command, u16 value)
115 {
116         return i2c_smbus_write_word_data(client, command, swab16(value));
117 }
118 #endif
119
120 /* Red Hat EL5 includes backports of these functions, so we can't redefine
121  * our own. */
122 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
123 #if !(defined RHEL_MAJOR && RHEL_MAJOR == 5 && RHEL_MINOR >= 5)
124 static inline int strict_strtoul(const char *cp, unsigned int base,
125                                  unsigned long *res)
126 {
127         *res = simple_strtoul(cp, NULL, base);
128         return 0;
129 }
130
131 static inline int strict_strtol(const char *cp, unsigned int base, long *res)
132 {
133         *res = simple_strtol(cp, NULL, base);
134         return 0;
135 }
136 #endif
137 #endif
138
139 #endif  /* __NEED_I2C__ */
140
141 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28)
142 /*
143  * Divide positive or negative dividend by positive divisor and round
144  * to closest integer. Result is undefined for negative divisors and
145  * for negative dividends if the divisor variable type is unsigned.
146  */
147 #define DIV_ROUND_CLOSEST(x, divisor)(                  \
148 {                                                       \
149         typeof(x) __x = x;                              \
150         typeof(divisor) __d = divisor;                  \
151         (((typeof(x))-1) > 0 ||                         \
152          ((typeof(divisor))-1) > 0 || (__x) > 0) ?      \
153                 (((__x) + ((__d) / 2)) / (__d)) :       \
154                 (((__x) - ((__d) / 2)) / (__d));        \
155 }                                                       \
156 )
157 #endif
158
159 #ifndef module_driver
160 /**
161  * module_driver() - Helper macro for drivers that don't do anything
162  * special in module init/exit. This eliminates a lot of boilerplate.
163  * Each module may only use this macro once, and calling it replaces
164  * module_init() and module_exit().
165  *
166  * @__driver: driver name
167  * @__register: register function for this driver type
168  * @__unregister: unregister function for this driver type
169  * @...: Additional arguments to be passed to __register and __unregister.
170  *
171  * Use this macro to construct bus specific macros for registering
172  * drivers, and do not use it on its own.
173  */
174 #define module_driver(__driver, __register, __unregister, ...) \
175 static int __init __driver##_init(void) \
176 { \
177         return __register(&(__driver) , ##__VA_ARGS__); \
178 } \
179 module_init(__driver##_init); \
180 static void __exit __driver##_exit(void) \
181 { \
182         __unregister(&(__driver) , ##__VA_ARGS__); \
183 } \
184 module_exit(__driver##_exit);
185 #endif
186
187 #ifdef __NEED_I2C__
188
189 #ifndef module_i2c_driver
190 /**
191  * module_i2c_driver() - Helper macro for registering a I2C driver
192  * @__i2c_driver: i2c_driver struct
193  *
194  * Helper macro for I2C drivers which do not do anything special in module
195  * init/exit. This eliminates a lot of boilerplate. Each module may only
196  * use this macro once, and calling it replaces module_init() and module_exit()
197  */
198 #define module_i2c_driver(__i2c_driver) \
199         module_driver(__i2c_driver, i2c_add_driver, \
200                         i2c_del_driver)
201 #endif
202
203 #endif /* __NEED_I2C__ */
204
205 #ifndef clamp_val
206 #define clamp_val SENSORS_LIMIT
207 #endif
208
209 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
210 #ifndef kstrtol
211 #define kstrtol strict_strtol
212 #endif
213 #ifndef kstrtoul
214 #define kstrtoul strict_strtoul
215 #endif
216 #endif
217
218 #ifndef request_muxed_region
219 #define request_muxed_region(a, b, c) (true)
220 #endif
221 #ifndef release_region
222 #define release_region(a, b)
223 #endif
224
225 #ifndef pr_warn
226 /* pr_warn macro not introduced until 2.6.35 */
227 #define pr_warn pr_warning
228 #endif
229 #ifndef pr_warn_ratelimited
230 #define pr_warn_ratelimited pr_warning_ratelimited
231 #endif
232
233 #ifndef sysfs_attr_init
234 #define sysfs_attr_init(attr) do {} while (0)
235 #endif
236
237 #ifndef __ATTR_RO
238 #define __ATTR_RO(_name) {                                              \
239         .attr   = { .name = __stringify(_name), .mode = 0444 },         \
240         .show   = _name##_show,                                         \
241 }
242 #endif
243
244 #ifndef DEVICE_ATTR_RO
245 #define DEVICE_ATTR_RO(_name) \
246         struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
247 #endif
248
249 #endif /* __COMPAT_H */