summaryrefslogtreecommitdiff
path: root/drivers/staging/csr/oska/kernel-compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/csr/oska/kernel-compat.h')
-rw-r--r--drivers/staging/csr/oska/kernel-compat.h199
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 */