diff options
Diffstat (limited to 'drivers/staging/csr/oska/kernel-compat.h')
-rw-r--r-- | drivers/staging/csr/oska/kernel-compat.h | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/drivers/staging/csr/oska/kernel-compat.h b/drivers/staging/csr/oska/kernel-compat.h new file mode 100644 index 00000000000..b6d27d39c33 --- /dev/null +++ b/drivers/staging/csr/oska/kernel-compat.h @@ -0,0 +1,199 @@ +/* + * Kernel version compatibility. + * + * Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * Wherever possible compatible implementations of newer APIs are + * provided for older kernel versions. + */ +#ifndef __LINUX_KERNEL_COMPAT_H +#define __LINUX_KERNEL_COMPAT_H + +#include <linux/version.h> +#include <linux/device.h> +#include <linux/workqueue.h> + +#include <asm/io.h> + +/* + * linux/semaphore.h replaces asm/semaphore.h in 2.6.27. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +# include <asm/semaphore.h> +#else +# include <linux/semaphore.h> +#endif + +/* + * Workqueue API changes in 2.6.20 + * + * See http://lwn.net/Articles/211279/ for details. + * + * We deliberately don't provide the non-automatic release (NAR) + * variants as a simple compatible implementation is not possible. + * This shouldn't be a problem as all usage so far is to embed the + * struct work_struct into another struct and the NAR variants aren't + * useful in this case (see http://lwn.net/Articles/213149/). + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + +#include <linux/workqueue.h> + +#undef INIT_WORK +#define INIT_WORK(_work, _func) \ + do { \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->pending = 0; \ + PREPARE_WORK((_work), (_func), (_work)); \ + init_timer(&(_work)->timer); \ + } while(0) + +#undef DECLARE_WORK +#define DECLARE_WORK(n, f) \ + struct work_struct n = __WORK_INITIALIZER((n), (f), &(n)) + +struct delayed_work { + struct work_struct work; +}; + +#define INIT_DELAYED_WORK(dw, fn) \ + INIT_WORK(&(dw)->work, (fn)) + +#define queue_delayed_work(wq, dw, delay) \ + queue_delayed_work((wq), &(dw)->work, (delay)) + +#define schedule_delayed_work(dw, delay) \ + schedule_delayed_work(&(dw)->work, (delay)) + +#define cancel_delayed_work(dw) \ + cancel_delayed_work(&(dw)->work) + +#endif /* Linux kernel < 2.6.20 */ + +/* + * device_create()/class_device_create() + * + * device_create() gains a drvdata parameter in 2.6.27. Since all + * users of device_create() in CSR code don't use drvdata just ignore + * it. + * + * device_create() replaces class_device_create() in 2.6.21. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) + +#define device_create(class, parent, devt, drvdata, fmt, args...) \ + class_device_create((class), (parent), (devt), NULL, (fmt), ## args) +#define device_destroy(class, devt) \ + class_device_destroy(class, devt) + +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + +#define device_create(class, parent, devt, drvdata, fmt, args...) \ + device_create((class), (parent), (devt), (fmt), ## args) + +#endif /* Linux kernel < 2.6.26 */ + +/* + * dev_name() and dev_set_name() added in 2.6.26. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + +static inline char *dev_name(struct device *dev) +{ + return dev->bus_id; +} + +int dev_set_name(struct device *dev, const char *fmt, ...); + +#endif /* Linux kernel < 2.6.26 */ + +/* + * class_find_device() in 2.6.25 + */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) + +struct device *class_find_device(struct class *class, struct device *start, + void *data, int (*match)(struct device *, void *)); + +#endif /* Linux kernel < 2.6.25 */ + +/* + * list_first_entry in 2.6.22. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +#endif /* Linux kernel < 2.6.22 */ + +/* + * 2.6.19 adds a bool type. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + +typedef _Bool bool; +enum { + false = 0, + true = 1 +}; + +#endif /* Linux kernel < 2.6.19 */ + +/* + * Provide readq() and writeq() if unavailable. + */ +#ifndef readq +static inline __u64 readq(const volatile void __iomem *addr) +{ + const volatile u32 __iomem *p = addr; + u32 low, high; + + low = readl(p); + high = readl(p + 1); + + return low + ((u64)high << 32); +} +#endif + +#ifndef writeq +static inline void writeq(__u64 val, volatile void __iomem *addr) +{ + writel(val, addr); + writel(val >> 32, addr+4); +} +#endif + +/* + * get_unaligned_le16() and friends added in 2.6.26. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#include <asm/unaligned.h> + +static inline __u16 get_unaligned_le16(const void *p) +{ + return le16_to_cpu(get_unaligned((__le16 *)p)); +} + +static inline void put_unaligned_le16(__u16 val, const void *p) +{ + put_unaligned(cpu_to_le16(val), (__le16 *)p); +} +#endif /* Linux kernel < 2.6.26 */ + +/* + * Various device or vendor IDs may not exist. + */ +#ifndef PCI_VENDOR_ID_CSR +# define PCI_VENDOR_ID_CSR 0x18e5 +#endif + +#ifndef PCI_DEVICE_ID_JMICRON_JMB38X_SD +# define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 +#endif + +#endif /* #ifndef __LINUX_KERNEL_COMPAT_H */ |