Greg Kroah-Hartman | f91121b | 2014-09-11 08:22:06 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Greybus kernel "version" glue logic. |
| 3 | * |
| 4 | * Copyright 2014 Google Inc. |
Alex Elder | a46e967 | 2014-12-12 12:08:42 -0600 | [diff] [blame] | 5 | * Copyright 2014 Linaro Ltd. |
Greg Kroah-Hartman | f91121b | 2014-09-11 08:22:06 -0700 | [diff] [blame] | 6 | * |
| 7 | * Released under the GPLv2 only. |
| 8 | * |
| 9 | * Backports of newer kernel apis to allow the code to build properly on older |
| 10 | * kernel versions. Remove this file when merging to upstream, it should not be |
| 11 | * needed at all |
| 12 | */ |
| 13 | |
| 14 | #ifndef __GREYBUS_KERNEL_VER_H |
| 15 | #define __GREYBUS_KERNEL_VER_H |
| 16 | |
Viresh Kumar | e2cb6ca | 2015-03-27 16:32:56 +0530 | [diff] [blame] | 17 | #include <linux/kernel.h> |
| 18 | |
Greg Kroah-Hartman | 4efe606 | 2014-11-17 16:55:54 -0800 | [diff] [blame] | 19 | #ifndef __ATTR_WO |
| 20 | #define __ATTR_WO(_name) { \ |
Greg Kroah-Hartman | 99a4bd5 | 2015-05-01 21:04:47 +0200 | [diff] [blame^] | 21 | .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \ |
| 22 | .store = _name##_store, \ |
Greg Kroah-Hartman | 4efe606 | 2014-11-17 16:55:54 -0800 | [diff] [blame] | 23 | } |
| 24 | #endif |
| 25 | |
Greg Kroah-Hartman | df67155 | 2014-12-21 14:10:26 -0800 | [diff] [blame] | 26 | #ifndef __ATTR_RW |
| 27 | #define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ |
Greg Kroah-Hartman | 99a4bd5 | 2015-05-01 21:04:47 +0200 | [diff] [blame^] | 28 | _name##_show, _name##_store) |
Greg Kroah-Hartman | df67155 | 2014-12-21 14:10:26 -0800 | [diff] [blame] | 29 | #endif |
| 30 | |
Greg Kroah-Hartman | f91121b | 2014-09-11 08:22:06 -0700 | [diff] [blame] | 31 | #ifndef DEVICE_ATTR_RO |
| 32 | #define DEVICE_ATTR_RO(_name) \ |
| 33 | struct device_attribute dev_attr_##_name = __ATTR_RO(_name) |
| 34 | #endif |
| 35 | |
Greg Kroah-Hartman | ac4029f | 2014-11-17 16:03:34 -0800 | [diff] [blame] | 36 | #ifndef DEVICE_ATTR_WO |
| 37 | #define DEVICE_ATTR_WO(_name) \ |
| 38 | struct device_attribute dev_attr_##_name = __ATTR_WO(_name) |
| 39 | #endif |
| 40 | |
Greg Kroah-Hartman | df67155 | 2014-12-21 14:10:26 -0800 | [diff] [blame] | 41 | #ifndef DEVICE_ATTR_RW |
| 42 | #define DEVICE_ATTR_RW(_name) \ |
| 43 | struct device_attribute dev_attr_##_name = __ATTR_RW(_name) |
| 44 | #endif |
| 45 | |
Alex Elder | 1cfc667 | 2014-09-30 19:25:21 -0500 | [diff] [blame] | 46 | #ifndef U8_MAX |
| 47 | #define U8_MAX ((u8)~0U) |
| 48 | #endif /* ! U8_MAX */ |
Greg Kroah-Hartman | f91121b | 2014-09-11 08:22:06 -0700 | [diff] [blame] | 49 | |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 50 | #ifndef U16_MAX |
| 51 | #define U16_MAX ((u16)(~0U)) |
| 52 | #endif /* !U16_MAX */ |
| 53 | |
Greg Kroah-Hartman | 213aefe | 2014-10-20 13:40:02 +0800 | [diff] [blame] | 54 | /* |
| 55 | * The GPIO api sucks rocks in places, like removal, so work around their |
| 56 | * explicit requirements of catching the return value for kernels older than |
| 57 | * 3.17, which they explicitly changed in the 3.17 kernel. Consistency is |
| 58 | * overrated. |
| 59 | */ |
| 60 | #include <linux/version.h> |
| 61 | #include <linux/gpio.h> |
| 62 | |
| 63 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| 64 | static inline void gb_gpiochip_remove(struct gpio_chip *chip) |
| 65 | { |
| 66 | gpiochip_remove(chip); |
| 67 | } |
| 68 | #else |
| 69 | static inline void gb_gpiochip_remove(struct gpio_chip *chip) |
| 70 | { |
| 71 | int ret; |
| 72 | ret = gpiochip_remove(chip); |
| 73 | } |
| 74 | #endif |
| 75 | |
Greg Kroah-Hartman | f348964 | 2014-10-28 09:27:50 +0800 | [diff] [blame] | 76 | /* |
| 77 | * ATTRIBUTE_GROUPS showed up in 3.11-rc2, but we need to build on 3.10, so add |
| 78 | * it here. |
| 79 | */ |
| 80 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) |
Greg Kroah-Hartman | 66c9898 | 2015-04-01 01:36:23 +0200 | [diff] [blame] | 81 | #include <linux/sysfs.h> |
| 82 | |
Greg Kroah-Hartman | f348964 | 2014-10-28 09:27:50 +0800 | [diff] [blame] | 83 | #define ATTRIBUTE_GROUPS(name) \ |
| 84 | static const struct attribute_group name##_group = { \ |
| 85 | .attrs = name##_attrs, \ |
| 86 | }; \ |
| 87 | static const struct attribute_group *name##_groups[] = { \ |
| 88 | &name##_group, \ |
| 89 | NULL, \ |
| 90 | } |
Greg Kroah-Hartman | 66c9898 | 2015-04-01 01:36:23 +0200 | [diff] [blame] | 91 | |
| 92 | static inline int sysfs_create_groups(struct kobject *kobj, |
| 93 | const struct attribute_group **groups) |
| 94 | { |
| 95 | int error = 0; |
| 96 | int i; |
| 97 | |
| 98 | if (!groups) |
| 99 | return 0; |
| 100 | |
| 101 | for (i = 0; groups[i]; i++) { |
| 102 | error = sysfs_create_group(kobj, groups[i]); |
| 103 | if (error) { |
| 104 | while (--i >= 0) |
| 105 | sysfs_remove_group(kobj, groups[i]); |
| 106 | break; |
| 107 | } |
| 108 | } |
| 109 | return error; |
| 110 | } |
| 111 | |
| 112 | static inline void sysfs_remove_groups(struct kobject *kobj, |
| 113 | const struct attribute_group **groups) |
| 114 | { |
| 115 | int i; |
| 116 | |
| 117 | if (!groups) |
| 118 | return; |
| 119 | for (i = 0; groups[i]; i++) |
| 120 | sysfs_remove_group(kobj, groups[i]); |
| 121 | } |
Greg Kroah-Hartman | f348964 | 2014-10-28 09:27:50 +0800 | [diff] [blame] | 122 | #endif |
| 123 | |
Greg Kroah-Hartman | f91121b | 2014-09-11 08:22:06 -0700 | [diff] [blame] | 124 | #endif /* __GREYBUS_KERNEL_VER_H */ |