Staging: add CSR Wifi "os helper" module
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 May 2012 16:47:38 +0000 (09:47 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Jun 2012 23:36:15 +0000 (16:36 -0700)
This module is used by the CSR wifi driver to "abstract" away the
OS-specific parts of core functions.  It will be eventually deleted, but
for now is needed as the CSR driver relies on it.

Cc: Mikko Virkkilä <mikko.virkkila@bluegiga.com>
Cc: Lauri Hintsala <Lauri.Hintsala@bluegiga.com>
Cc: Riku Mettälä <riku.mettala@bluegiga.com>
Cc: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30 files changed:
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/csr/Kconfig [new file with mode: 0644]
drivers/staging/csr/Makefile [new file with mode: 0644]
drivers/staging/csr/oska/Makefile [new file with mode: 0644]
drivers/staging/csr/oska/all.h [new file with mode: 0644]
drivers/staging/csr/oska/alloc.h [new file with mode: 0644]
drivers/staging/csr/oska/compat.c [new file with mode: 0644]
drivers/staging/csr/oska/event.c [new file with mode: 0644]
drivers/staging/csr/oska/event.h [new file with mode: 0644]
drivers/staging/csr/oska/io.h [new file with mode: 0644]
drivers/staging/csr/oska/kernel-compat.h [new file with mode: 0644]
drivers/staging/csr/oska/list.c [new file with mode: 0644]
drivers/staging/csr/oska/list.h [new file with mode: 0644]
drivers/staging/csr/oska/mutex.h [new file with mode: 0644]
drivers/staging/csr/oska/oska_module.c [new file with mode: 0644]
drivers/staging/csr/oska/print.c [new file with mode: 0644]
drivers/staging/csr/oska/print.h [new file with mode: 0644]
drivers/staging/csr/oska/refcount.c [new file with mode: 0644]
drivers/staging/csr/oska/refcount.h [new file with mode: 0644]
drivers/staging/csr/oska/semaphore.h [new file with mode: 0644]
drivers/staging/csr/oska/spinlock.h [new file with mode: 0644]
drivers/staging/csr/oska/thread.c [new file with mode: 0644]
drivers/staging/csr/oska/thread.h [new file with mode: 0644]
drivers/staging/csr/oska/time.h [new file with mode: 0644]
drivers/staging/csr/oska/timer.c [new file with mode: 0644]
drivers/staging/csr/oska/timer.h [new file with mode: 0644]
drivers/staging/csr/oska/trace.h [new file with mode: 0644]
drivers/staging/csr/oska/types.h [new file with mode: 0644]
drivers/staging/csr/oska/util.h [new file with mode: 0644]

index 38f1fb08eaef4f81cf0a8effa8726ae1f572ab7e..d3934d79524a15216548751e63c0fb713ad1cdbb 100644 (file)
@@ -132,4 +132,6 @@ source "drivers/staging/ipack/Kconfig"
 
 source "drivers/staging/gdm72xx/Kconfig"
 
+source "drivers/staging/csr/Kconfig"
+
 endif # STAGING
index e0c4c2444fedb72e935b3dcf2b562d0a6816c7b2..5b2219ac52072526ceadab7a5e6beb3cd835a2d8 100644 (file)
@@ -58,3 +58,4 @@ obj-$(CONFIG_RAMSTER)         += ramster/
 obj-$(CONFIG_USB_WPAN_HCD)     += ozwpan/
 obj-$(CONFIG_USB_G_CCG)                += ccg/
 obj-$(CONFIG_WIMAX_GDM72XX)    += gdm72xx/
+obj-$(CONFIG_CSR_WIFI)         += csr/
diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig
new file mode 100644 (file)
index 0000000..5d7b800
--- /dev/null
@@ -0,0 +1,7 @@
+config CSR_WIFI
+       tristate "CSR wireless driver"
+       depends on PCI
+       help
+         Driver for the CSR wireless SDIO device.
+
+         If unsure, select N.
diff --git a/drivers/staging/csr/Makefile b/drivers/staging/csr/Makefile
new file mode 100644 (file)
index 0000000..b9ba3b3
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_CSR_WIFI) += oska/
diff --git a/drivers/staging/csr/oska/Makefile b/drivers/staging/csr/oska/Makefile
new file mode 100644 (file)
index 0000000..3a0b648
--- /dev/null
@@ -0,0 +1,12 @@
+obj-$(CONFIG_CSR_WIFI) := csr_oska.o
+
+csr_oska-y := \
+       list.o \
+       refcount.o \
+       compat.o \
+       event.o \
+       oska_module.o \
+       print.o  \
+       thread.o \
+       timer.o
+
diff --git a/drivers/staging/csr/oska/all.h b/drivers/staging/csr/oska/all.h
new file mode 100644 (file)
index 0000000..5fe8583
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Operating system kernel abstraction -- all functions
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_ALL_H
+#define __OSKA_ALL_H
+
+/**
+ * @mainpage Operating System Kernel Abstraction
+ *
+ * @section intro Introduction
+ *
+ * The Operating System Kernel Abstraction (oska) is a software
+ * package providing an abstraction for various operating system
+ * kernel facilities for use by device drivers and other OS kernel
+ * software (e.g., SDIO stacks).  Oska is modularized and intended to
+ * be a lightweight wrapper around an OSes interfaces.
+ *
+ * @section modules Modules
+ *
+ * Oska is organized into the modules, each of which has it's own
+ * header file providing the interface.
+ *
+ *   - \ref alloc "Memory allocation" <oska/alloc.h>
+ *   - \ref event "Events" <oska/event.h>
+ *   - \ref mutex "Mutexes" <oska/mutex.h>
+ *   - \ref print "Console output" <oska/print.h>
+ *   - \ref spinlock "Spinlocks" <oska/spinlock.h>
+ *   - \ref thread "Threading" <oska/thread.h>
+ *   - \ref time "Timing and delays" <oska/time.h>
+ *   - \ref timer "Timers" <oska/timer.h>
+ *   - \ref types "Standard Types" <oska/types.h>
+ *   - \ref util "Miscellaneous utilities" <oska/util.h>
+ *
+ * An <oska/all.h> header is provided which includes all the above
+ * modules.
+ *
+ * There are additional modules that are not included in <oska/all.h>.
+ *
+ *   - \ref io "Memory mapped I/O" <oska/io.h>
+ *   - \ref refcount "Reference Counting" <oska/refcount.h>
+ *   - \ref list "Linked lists" <oska/list.h>
+ *   - \ref trace "Tracing messages" <oska/trace.h>
+ */
+
+#include "alloc.h"
+#include "event.h"
+#include "mutex.h"
+#include "print.h"
+#include "spinlock.h"
+#include "thread.h"
+#include "time.h"
+#include "timer.h"
+#include "types.h"
+#include "util.h"
+
+#endif /* __OSKA_ALL_H */
diff --git a/drivers/staging/csr/oska/alloc.h b/drivers/staging/csr/oska/alloc.h
new file mode 100644 (file)
index 0000000..0f10601
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * OSKA Linux implementation -- memory allocation
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_ALLOC_H
+#define __OSKA_LINUX_ALLOC_H
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+static inline void *os_alloc(size_t size)
+{
+    return kzalloc(size, GFP_ATOMIC);
+}
+
+static inline void *os_alloc_nonzeroed(size_t size)
+{
+    return kmalloc(size, GFP_KERNEL);
+}
+
+static inline void os_free(void *ptr)
+{
+    kfree(ptr);
+}
+
+static inline void *os_alloc_big(size_t size)
+{
+    return vmalloc(size);
+}
+
+static inline void os_free_big(void *ptr)
+{
+    vfree(ptr);
+}
+
+#endif /* #ifndef __OSKA_LINUX_ALLOC_H */
diff --git a/drivers/staging/csr/oska/compat.c b/drivers/staging/csr/oska/compat.c
new file mode 100644 (file)
index 0000000..790b97a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Linux version compatibility functions.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "kernel-compat.h"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+
+int dev_set_name(struct device *dev, const char *fmt, ...)
+{
+    va_list vargs;
+
+    va_start(vargs, fmt);
+    vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
+    va_end(vargs);
+    return 0;
+}
+EXPORT_SYMBOL_GPL(dev_set_name);
+
+#endif /* Linux kernel < 2.6.26 */
+
+#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 *))
+{
+    struct device *dev;
+
+    list_for_each_entry(dev, &class->devices, node) {
+        if (match(dev, data)) {
+            get_device(dev);
+            return dev;
+        }
+    }
+    return NULL;
+}
+EXPORT_SYMBOL_GPL(class_find_device);
+
+#endif /* Linux kernel < 2.6.25 */
diff --git a/drivers/staging/csr/oska/event.c b/drivers/staging/csr/oska/event.c
new file mode 100644 (file)
index 0000000..4aedaaa
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Linux event functions.
+ *
+ * Copyright (C) 2009 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include "event.h"
+
+void os_event_init(os_event_t *evt)
+{
+    init_waitqueue_head(&evt->wq);
+    spin_lock_init(&evt->lock);
+    evt->events = 0;
+}
+EXPORT_SYMBOL(os_event_init);
+
+uint16_t os_event_wait(os_event_t *evt)
+{
+    uint16_t e;
+    unsigned long flags;
+
+    wait_event(evt->wq, evt->events != 0);
+
+    spin_lock_irqsave(&evt->lock, flags);
+    e = evt->events;
+    evt->events &= ~e;
+    spin_unlock_irqrestore(&evt->lock, flags);
+
+    return e;
+}
+EXPORT_SYMBOL(os_event_wait);
+
+uint16_t os_event_wait_interruptible(os_event_t *evt)
+{
+    uint16_t e;
+    unsigned long flags;
+
+    wait_event_interruptible(evt->wq, evt->events != 0);
+
+    spin_lock_irqsave(&evt->lock, flags);
+    e = evt->events;
+    evt->events &= ~e;
+    spin_unlock_irqrestore(&evt->lock, flags);
+
+    return e;
+}
+EXPORT_SYMBOL(os_event_wait_interruptible);
+
+uint16_t os_event_wait_timed(os_event_t *evt, unsigned timeout_ms)
+{
+    uint16_t e;
+    unsigned long flags;
+
+    wait_event_interruptible_timeout(evt->wq,
+                                     evt->events != 0,
+                                     msecs_to_jiffies(timeout_ms));
+
+    spin_lock_irqsave(&evt->lock, flags);
+    e = evt->events;
+    evt->events &= ~e;
+    spin_unlock_irqrestore(&evt->lock, flags);
+
+    return e;
+}
+EXPORT_SYMBOL(os_event_wait_timed);
+
+void os_event_raise(os_event_t *evt, uint16_t events)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&evt->lock, flags);
+    evt->events |= events;
+    spin_unlock_irqrestore(&evt->lock, flags);
+
+    wake_up(&evt->wq);
+}
+EXPORT_SYMBOL(os_event_raise);
diff --git a/drivers/staging/csr/oska/event.h b/drivers/staging/csr/oska/event.h
new file mode 100644 (file)
index 0000000..be52e42
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * OSKA Linux implementation -- events
+ *
+ * Copyright (C) 2009 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_EVENT_H
+#define __OSKA_LINUX_EVENT_H
+
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+
+typedef struct {
+    wait_queue_head_t wq;
+    spinlock_t lock;
+    uint16_t events;
+} os_event_t;
+
+void os_event_init(os_event_t *evt);
+
+static inline void os_event_destroy(os_event_t *evt)
+{
+}
+
+uint16_t os_event_wait(os_event_t *evt);
+uint16_t os_event_wait_interruptible(os_event_t *evt);
+uint16_t os_event_wait_timed(os_event_t *evt, unsigned timeout_ms);
+void os_event_raise(os_event_t *evt, uint16_t events);
+
+#endif /* #ifndef __OSKA_LINUX_EVENT_H */
diff --git a/drivers/staging/csr/oska/io.h b/drivers/staging/csr/oska/io.h
new file mode 100644 (file)
index 0000000..c6c406c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * OSKA Linux implementation -- memory mapped I/O.
+ *
+ * Copyright (C) 2009 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_IO_H
+#define __OSKA_LINUX_IO_H
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/kernel-compat.h>
+
+typedef void __iomem *os_io_mem_t;
+
+static inline uint8_t os_io_read8(os_io_mem_t base, unsigned offset)
+{
+    return readb(base + offset);
+}
+
+static inline uint16_t os_io_read16(os_io_mem_t base, unsigned offset)
+{
+    return readw(base + offset);
+}
+
+static inline uint32_t os_io_read32(os_io_mem_t base, unsigned offset)
+{
+    return readl(base + offset);
+}
+
+static inline uint64_t os_io_read64(os_io_mem_t base, unsigned offset)
+{
+    return readq(base + offset);
+}
+
+static inline void os_io_write8(os_io_mem_t base, unsigned offset, uint8_t val)
+{
+    writeb(val, base + offset);
+}
+
+static inline void os_io_write16(os_io_mem_t base, unsigned offset, uint16_t val)
+{
+    writew(val, base + offset);
+}
+
+static inline void os_io_write32(os_io_mem_t base, unsigned offset, uint32_t val)
+{
+    writel(val, base + offset);
+}
+
+static inline void os_io_write64(os_io_mem_t base, unsigned offset, uint64_t val)
+{
+    writeq(val, base + offset);
+}
+
+static inline void os_io_memory_barrier(void)
+{
+    mb();
+}
+
+#endif /* #ifndef __OSKA_LINUX_IO_H */
diff --git a/drivers/staging/csr/oska/kernel-compat.h b/drivers/staging/csr/oska/kernel-compat.h
new file mode 100644 (file)
index 0000000..b6d27d3
--- /dev/null
@@ -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 */
diff --git a/drivers/staging/csr/oska/list.c b/drivers/staging/csr/oska/list.c
new file mode 100644 (file)
index 0000000..b5e884e
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Operating system kernel abstraction -- linked lists.
+ *
+ * Copyright (C) 2009-2010 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+
+#include <stddef.h>
+
+#include "list.h"
+#include "util.h"
+
+/**
+ * Initialize an empty list.
+ *
+ * @ingroup list
+ */
+void os_list_init(struct os_list *list)
+{
+    list->head.next = list->head.prev = &list->head;
+}
+
+/**
+ * Is the list empty?
+ *
+ * @return true iff the list contains no nodes.
+ *
+ * @ingroup list
+ */
+int os_list_empty(struct os_list *list)
+{
+    return list->head.next == &list->head;
+}
+
+static void os_list_add(struct os_list_node *prev, struct os_list_node *new,
+                        struct os_list_node *next)
+{
+    OS_ASSERT(new->next == NULL && new->prev == NULL);
+
+    next->prev = new;
+    new->next  = next;
+    new->prev  = prev;
+    prev->next = new;
+}
+
+/**
+ * Add a node to the tail of the list.
+ *
+ * @param list the list.
+ * @param node the list node to add.
+ *
+ * @ingroup list
+ */
+void os_list_add_tail(struct os_list *list, struct os_list_node *node)
+{
+    os_list_add(list->head.prev, node, &list->head);
+}
+
+/**
+ * Remove a node from a list.
+ *
+ * @param node the node to remove.
+ *
+ * @ingroup list
+ */
+void os_list_del(struct os_list_node *node)
+{
+    node->prev->next = node->next;
+    node->next->prev = node->prev;
+
+    node->prev = node->next = NULL;
+}
+
+/**
+ * The node at the head of the list.
+ *
+ * @param list the list.
+ *
+ * @return the node at the head of the list; or os_list_end() if the
+ * list is empty.
+ *
+ * @ingroup list
+ */
+struct os_list_node *os_list_head(struct os_list *list)
+{
+    return list->head.next;
+}
+
+/**
+ * The node marking the end of a list.
+ *
+ * @param list the list.
+ *
+ * @return the node that marks the end of the list.
+ *
+ * @ingroup list
+ */
+struct os_list_node *os_list_end(struct os_list *list)
+{
+    return &list->head;
+}
diff --git a/drivers/staging/csr/oska/list.h b/drivers/staging/csr/oska/list.h
new file mode 100644 (file)
index 0000000..a69b3b7
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Operating system kernel abstraction -- linked lists.
+ *
+ * Copyright (C) 2009-2010 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LIST_H
+#define __OSKA_LIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup list Linked Lists
+ *
+ * Generic linked list implementations suitable for all platforms.
+ *
+ *   - Circular, doubly-linked list (struct os_list).
+ */
+
+/**
+ * A list node.
+ *
+ * This list node structure should be the first field within any
+ * structure that is to be stored in a list.
+ *
+ * @see struct os_list
+ * @ingroup list
+ */
+struct os_list_node {
+    /**
+     * The pointer to the previous node in the list, or os_list_end()
+     * if the end of the list has been reached.
+     */
+    struct os_list_node *prev;
+    /**
+     * The pointer to the next node in the list, or os_list_end() if
+     * the end of the list has been reached.
+     */
+    struct os_list_node *next;
+};
+
+/**
+ * A circular, doubly-linked list of nodes.
+ *
+ * Structures to be stored in a list should contains a struct
+ * os_list_node as the \e first field.
+ * \code
+ *   struct foo {
+ *      struct os_list_node node;
+ *      int bar;
+ *      ...
+ *   };
+ * \endcode
+ * Going to/from a struct foo to a list node is then simple.
+ * \code
+ *   struct os_list_node *node;
+ *   struct foo *foo;
+ *   [...]
+ *   node = &foo->node;
+ *   foo = (struct foo *)node
+ * \endcode
+ * Lists must be initialized with os_list_init() before adding nodes
+ * with os_list_add_tail().  The node at the head of the list is
+ * obtained with os_list_head().  Nodes are removed from the list with
+ * os_list_del().
+ *
+ * A list can be interated from the head to the tail using:
+ * \code
+ *   struct os_list_node *node;
+ *   for (node = os_list_head(list); node != os_list_end(list); node = node->next) {
+ *      struct foo *foo = (struct foo *)node;
+ *      ...
+ *   }
+ * \endcode
+ *
+ * In the above loop, the current list node cannot be removed (with
+ * os_list_del()).  If this is required use this form of loop:
+ * \code
+ *   struct os_list_node *node, *next;
+ *   for (node = os_list_head(list), next = node->next;
+ *        node != os_list_end(list);
+ *        node = next, next = node->next) {
+ *      struct foo *foo = (struct foo *)node;
+ *      ...
+ *      os_list_del(node);
+ *      ...
+ *   }
+ * \endcode
+ *
+ * @ingroup list
+ */
+struct os_list {
+    /**
+     * @internal
+     * The dummy node marking the end of the list.
+     */
+    struct os_list_node head;
+};
+
+void os_list_init(struct os_list *list);
+int os_list_empty(struct os_list *list);
+void os_list_add_tail(struct os_list *list, struct os_list_node *node);
+void os_list_del(struct os_list_node *node);
+struct os_list_node *os_list_head(struct os_list *list);
+struct os_list_node *os_list_end(struct os_list *list);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* #ifndef __OSKA_LIST_H */
diff --git a/drivers/staging/csr/oska/mutex.h b/drivers/staging/csr/oska/mutex.h
new file mode 100644 (file)
index 0000000..9138b28
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * OSKA Linux implementation -- mutexes
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_MUTEX_H
+#define __OSKA_LINUX_MUTEX_H
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+
+#include "kernel-compat.h"
+
+/* Real mutexes were only added to 2.6.16 so use semaphores
+   instead. */
+typedef struct semaphore os_mutex_t;
+
+static inline void os_mutex_init(os_mutex_t *mutex)
+{
+    //init_MUTEX(mutex);
+    sema_init(mutex, 1);
+}
+
+static inline void os_mutex_destroy(os_mutex_t *mutex)
+{
+    /* no op */
+}
+
+static inline void os_mutex_lock(os_mutex_t *mutex)
+{
+    down(mutex);
+}
+
+static inline void os_mutex_unlock(os_mutex_t *mutex)
+{
+    up(mutex);
+}
+
+#endif /* __OSKA_LINUX_MUTEX_H */
diff --git a/drivers/staging/csr/oska/oska_module.c b/drivers/staging/csr/oska/oska_module.c
new file mode 100644 (file)
index 0000000..da12564
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Linux kernel module support.
+ *
+ * Copyright (C) 2010 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+
+#include "all.h"
+#include "refcount.h"
+
+EXPORT_SYMBOL(os_refcount_init);
+EXPORT_SYMBOL(os_refcount_destroy);
+EXPORT_SYMBOL(os_refcount_get);
+EXPORT_SYMBOL(os_refcount_put);
+
+MODULE_DESCRIPTION("Operating System Kernel Abstraction");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/staging/csr/oska/print.c b/drivers/staging/csr/oska/print.c
new file mode 100644 (file)
index 0000000..5f5b263
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Linux console printing functions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+
+#include "print.h"
+
+void os_print(enum os_print_level level, const char *prefix, const char *name,
+              const char *format, ...)
+{
+    va_list va_args;
+
+    va_start(va_args, format);
+    os_vprint(level, prefix, name, format, va_args);
+    va_end(va_args);
+}
+EXPORT_SYMBOL(os_print);
+
+void os_vprint(enum os_print_level level, const char *prefix, const char *name,
+               const char *format, va_list args)
+{
+    const char *level_str[] = {
+        [OS_PRINT_ERROR]   = KERN_ERR,
+        [OS_PRINT_WARNING] = KERN_WARNING,
+        [OS_PRINT_INFO]    = KERN_INFO,
+        [OS_PRINT_DEBUG]   = KERN_DEBUG,
+    };
+    char buf[80];
+    int w = 0;
+
+    if (name) {
+        w += snprintf(buf + w, sizeof(buf) - w, "%s%s%s: ", level_str[level], prefix, name);
+    } else {
+        w += snprintf(buf + w, sizeof(buf) - w, "%s%s", level_str[level], prefix);
+    }
+    w += vsnprintf(buf + w, sizeof(buf) - w, format, args);
+    printk("%s\n", buf);
+}
+EXPORT_SYMBOL(os_vprint);
diff --git a/drivers/staging/csr/oska/print.h b/drivers/staging/csr/oska/print.h
new file mode 100644 (file)
index 0000000..f48bb83
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * OSKA Linux implementation -- console printing
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_PRINT_H
+#define __OSKA_LINUX_PRINT_H
+
+#include <linux/kernel.h>
+
+/**
+ * Severity of a console or log message.
+ *
+ * @ingroup print
+ */
+enum os_print_level {
+    OS_PRINT_ERROR,
+    OS_PRINT_WARNING,
+    OS_PRINT_INFO,
+    OS_PRINT_DEBUG,
+};
+
+void os_print(enum os_print_level level, const char *prefix, const char *name,
+              const char *format, ...);
+void os_vprint(enum os_print_level level, const char *prefix, const char *name,
+               const char *format, va_list args);
+
+
+#endif /* #ifndef __OSKA_LINUX_PRINT_H */
diff --git a/drivers/staging/csr/oska/refcount.c b/drivers/staging/csr/oska/refcount.c
new file mode 100644 (file)
index 0000000..28abb64
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * OSKA generic implementation -- reference counting.
+ *
+ * Copyright (C) 2010 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "refcount.h"
+#include "types.h"
+
+void os_refcount_init(os_refcount_t *refcount, os_refcount_callback_f func, void *arg)
+{
+    os_spinlock_init(&refcount->lock);
+    refcount->count = 1;
+    refcount->func  = func;
+    refcount->arg   = arg;
+}
+
+void os_refcount_destroy(os_refcount_t *refcount)
+{
+    os_spinlock_destroy(&refcount->lock);
+}
+
+void os_refcount_get(os_refcount_t *refcount)
+{
+    os_int_status_t istate;
+
+    os_spinlock_lock_intsave(&refcount->lock, &istate);
+    refcount->count++;
+    os_spinlock_unlock_intrestore(&refcount->lock, &istate);
+}
+
+void os_refcount_put(os_refcount_t *refcount)
+{
+    bool is_zero;
+    os_int_status_t istate;
+
+    os_spinlock_lock_intsave(&refcount->lock, &istate);
+    refcount->count--;
+    is_zero = refcount->count == 0;
+    os_spinlock_unlock_intrestore(&refcount->lock, &istate);
+
+    if (is_zero) {
+        refcount->func(refcount->arg);
+    }
+}
diff --git a/drivers/staging/csr/oska/refcount.h b/drivers/staging/csr/oska/refcount.h
new file mode 100644 (file)
index 0000000..741b00a
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Operating system kernel abstraction -- reference counting.
+ *
+ * Copyright (C) 2010 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_REFCOUNT_H
+#define __OSKA_REFCOUNT_H
+
+#include "spinlock.h"
+
+/**
+ * @defgroup refcount Reference Counting
+ *
+ * A reference count is an atomic counter.  A callback function is
+ * called whenever the count reaches zero.
+ *
+ * A generic implementation is provided that is suitable for all
+ * platforms that support the spinlock API in <oska/spinlock.h> (see
+ * \ref spinlock).
+ */
+
+typedef void (*os_refcount_callback_f)(void *arg);
+
+struct __os_refcount_impl {
+    unsigned count;
+    os_spinlock_t lock;
+    os_refcount_callback_f func;
+    void *arg;
+};
+
+/**
+ * A reference count object.
+ *
+ * @ingroup refcount
+ */
+typedef struct __os_refcount_impl os_refcount_t;
+
+/**
+ * Initialize a reference count to 1.
+ *
+ * Initialized reference counts must be destroyed by calling
+ * os_refcount_destroy().
+ *
+ * @param refcount the reference count.
+ * @param func     the function which will be called when the
+ *                 reference count reaches 0.
+ * @param arg      an argument to pass to func.
+ *
+ * @ingroup refcount
+ */
+void os_refcount_init(os_refcount_t *refcount, os_refcount_callback_f func, void *arg);
+
+/**
+ * Destroy a reference count object.
+ *
+ * @param refcount the reference count.
+ *
+ * @ingroup refcount
+ */
+void os_refcount_destroy(os_refcount_t *refcount);
+
+/**
+ * Atomically increase the reference count by 1.
+ *
+ * @param refcount the reference count.
+ *
+ * @ingroup refcount
+ */
+void os_refcount_get(os_refcount_t *refcount);
+
+/**
+ * Atomically decrease the reference count by 1.
+ *
+ * The callback function passed to the call to os_refcount_init() is
+ * called if the count was decreased to zero.
+ *
+ * @param refcount the reference count.
+ *
+ * @ingroup refcount
+ */
+void os_refcount_put(os_refcount_t *refcount);
+
+#endif /* #ifndef __OSKA_REFCOUNT_H */
diff --git a/drivers/staging/csr/oska/semaphore.h b/drivers/staging/csr/oska/semaphore.h
new file mode 100644 (file)
index 0000000..965bfe8
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * OSKA Linux implementation -- semaphores
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_SEMAPHORE_H
+#define __OSKA_LINUX_SEMAPHORE_H
+
+#include <linux/kernel.h>
+
+#include <linux/kernel-compat.h>
+
+typedef struct semaphore os_semaphore_t;
+
+static inline void os_semaphore_init(os_semaphore_t *sem)
+{
+    sema_init(sem, 0);
+}
+
+static inline void os_semaphore_destroy(os_semaphore_t *sem)
+{
+}
+
+static inline void os_semaphore_wait(os_semaphore_t *sem)
+{
+    down(sem);
+}
+
+/*
+ * down_timeout() was added in 2.6.26 with the generic semaphore
+ * implementation.  For now, only support it on recent kernels as
+ * semaphores may be replaced by an event API that would be
+ * implemented with wait_event(), and wait_event_timeout().
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+
+static inline int os_semaphore_wait_timed(os_semaphore_t *sem,
+                                           int time_ms)
+{
+    if (down_timeout(sem, msecs_to_jiffies(time_ms)) < 0) {
+        return -ETIMEDOUT;
+    }
+    return 0;
+}
+
+#else
+
+static inline int os_semaphore_wait_timed(os_semaphore_t *sem, int time_ms)
+{
+       unsigned long now = jiffies;
+       do{
+               if(!down_trylock(sem))
+                       return 0;
+               msleep(1);
+       } while(time_before(jiffies, now + msecs_to_jiffies(time_ms)));
+
+       return -ETIMEDOUT;
+}
+
+#endif
+
+static inline void os_semaphore_post(os_semaphore_t *sem)
+{
+    up(sem);
+}
+
+#endif /* __OSKA_LINUX_SEMAPHORE_H */
diff --git a/drivers/staging/csr/oska/spinlock.h b/drivers/staging/csr/oska/spinlock.h
new file mode 100644 (file)
index 0000000..157b350
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * OSKA Linux implementation -- spinlocks
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_SPINLOCK_H
+#define __OSKA_LINUX_SPINLOCK_H
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+typedef spinlock_t os_spinlock_t;
+typedef unsigned long os_int_status_t;
+
+static inline void os_spinlock_init(os_spinlock_t *lock)
+{
+    spinlock_t *l = (spinlock_t *)lock;
+    spin_lock_init(l);
+}
+
+static inline void os_spinlock_destroy(os_spinlock_t *lock)
+{
+    /* no op */
+}
+
+static inline void os_spinlock_lock_intsave(os_spinlock_t *lock,
+                                           os_int_status_t *int_state)
+{
+    spinlock_t *l = (spinlock_t *)lock;
+    spin_lock_irqsave(l, *int_state);
+}
+
+static inline void os_spinlock_unlock_intrestore(os_spinlock_t *lock,
+                                                os_int_status_t *int_state)
+{
+    spinlock_t *l = (spinlock_t *)lock;
+    spin_unlock_irqrestore(l, *int_state);
+}
+
+#endif /* #ifndef __OSKA_LINUX_SPINLOCK_H */
diff --git a/drivers/staging/csr/oska/thread.c b/drivers/staging/csr/oska/thread.c
new file mode 100644 (file)
index 0000000..f680cef
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Linux thread functions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+
+#include "thread.h"
+
+static int thread_func(void *data)
+{
+    os_thread_t *thread = data;
+
+    thread->func(thread->arg);
+
+    /*
+     * kthread_stop() cannot handle the thread exiting while
+     * kthread_should_stop() is false, so sleep until kthread_stop()
+     * wakes us up.
+     */
+    set_current_state(TASK_INTERRUPTIBLE);
+    if (!kthread_should_stop())
+        schedule();
+
+    return 0;
+}
+
+int os_thread_create(os_thread_t *thread, const char *name, void (*func)(void *), void *arg)
+{
+    thread->func = func;
+    thread->arg = arg;
+
+    thread->stop = 0;
+
+    thread->task = kthread_run(thread_func, thread, name);
+    if (IS_ERR(thread->task)) {
+        return PTR_ERR(thread->task);
+    }
+    return 0;
+}
+EXPORT_SYMBOL(os_thread_create);
+
+void os_thread_stop(os_thread_t *thread, os_event_t *evt)
+{
+    /*
+     * Stop flag must be set before the event is raised so
+     * kthread_should_stop() cannot be used.
+     */
+    thread->stop = 1;
+
+    if (evt) {
+        os_event_raise(evt, ~0);
+    }
+
+    kthread_stop(thread->task);
+}
+EXPORT_SYMBOL(os_thread_stop);
+
+int os_thread_should_stop(os_thread_t *thread)
+{
+    return thread->stop;
+}
+EXPORT_SYMBOL(os_thread_should_stop);
diff --git a/drivers/staging/csr/oska/thread.h b/drivers/staging/csr/oska/thread.h
new file mode 100644 (file)
index 0000000..8816dc8
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * OSKA Linux implementation -- threading
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_THREAD_H
+#define __OSKA_LINUX_THREAD_H
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
+#include <linux/freezer.h>
+#endif
+#include "event.h"
+
+struct os_thread_lx {
+    void (*func)(void *);
+    void *arg;
+    struct task_struct *task;
+    int stop;
+};
+
+typedef struct os_thread_lx os_thread_t;
+
+int os_thread_create(os_thread_t *thread, const char *name,
+                     void (*func)(void *), void *arg);
+void os_thread_stop(os_thread_t *thread, os_event_t *evt);
+int os_thread_should_stop(os_thread_t *thread);
+
+static inline void os_try_suspend_thread(os_thread_t *thread)
+{
+    try_to_freeze();
+}
+
+#endif /* __OSKA_LINUX_THREAD_H */
diff --git a/drivers/staging/csr/oska/time.h b/drivers/staging/csr/oska/time.h
new file mode 100644 (file)
index 0000000..d246ce9
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * OSKA Linux implementation -- timing
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_TIME_H
+#define __OSKA_LINUX_TIME_H
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+
+static inline unsigned long os_current_time_ms(void)
+{
+    return jiffies_to_msecs(jiffies);
+}
+
+static inline void os_sleep_ms(unsigned ms)
+{
+    msleep_interruptible(ms);
+}
+
+static inline void os_delay_us(unsigned us)
+{
+    udelay(us);
+}
+
+#define os_time_after(a, b) time_after((a), (b))
+
+#endif /* __OSKA_LINUX_TIME_H */
diff --git a/drivers/staging/csr/oska/timer.c b/drivers/staging/csr/oska/timer.c
new file mode 100644 (file)
index 0000000..67d3423
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * OSKA Linux implementation -- timers.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+
+#include "timer.h"
+
+static void timer_func(unsigned long data)
+{
+    os_timer_t *timer = (os_timer_t *)data;
+
+    timer->func(timer->arg);
+}
+
+void os_timer_init(os_timer_t *timer, os_timer_func_t func, void *arg)
+{
+    timer->func = func;
+    timer->arg = arg;
+    timer->timer.function = timer_func;
+    timer->timer.data = (unsigned long)timer;
+    init_timer(&timer->timer);
+}
+EXPORT_SYMBOL(os_timer_init);
diff --git a/drivers/staging/csr/oska/timer.h b/drivers/staging/csr/oska/timer.h
new file mode 100644 (file)
index 0000000..3045fc3
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * OSKA Linux implementation -- timers.
+ *
+ * Copyright (C) 2009 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_TIMER_H
+#define __OSKA_LINUX_TIMER_H
+
+#include <linux/kernel.h>
+#include <linux/timer.h>
+
+typedef void (*os_timer_func_t)(void *arg);
+
+typedef struct {
+    os_timer_func_t func;
+    void *arg;
+    struct timer_list timer;
+} os_timer_t;
+
+void os_timer_init(os_timer_t *timer, os_timer_func_t func, void *arg);
+
+static inline void os_timer_destroy(os_timer_t *timer)
+{
+    del_timer_sync(&timer->timer);
+}
+
+static inline void os_timer_set(os_timer_t *timer, unsigned long expires_ms)
+{
+    mod_timer(&timer->timer, jiffies + msecs_to_jiffies(expires_ms));
+}
+
+static inline void os_timer_cancel(os_timer_t *timer)
+{
+    del_timer(&timer->timer);
+}
+
+#endif /* #ifndef __OSKA_LINUX_TIMER_H */
diff --git a/drivers/staging/csr/oska/trace.h b/drivers/staging/csr/oska/trace.h
new file mode 100644 (file)
index 0000000..b28f37d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * OSKA Linux implementation -- tracing messages.
+ *
+ * Copyright (C) 2009 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_TRACE_H
+#define __OSKA_LINUX_TRACE_H
+
+#include <linux/kernel.h>
+
+#ifndef OS_TRACE_PREFIX
+#  define OS_TRACE_PREFIX ""
+#endif
+
+#define os_trace_err(format, ...)  printk(KERN_ERR OS_TRACE_PREFIX format "\n", ## __VA_ARGS__)
+#define os_trace_warn(format, ...) printk(KERN_WARNING OS_TRACE_PREFIX format "\n", ##  __VA_ARGS__)
+#define os_trace_info(format, ...) printk(KERN_INFO OS_TRACE_PREFIX format "\n", ## __VA_ARGS__)
+#define os_trace_dbg(format, ...)  printk(KERN_DEBUG OS_TRACE_PREFIX format "\n", ## __VA_ARGS__)
+
+#endif /* #ifndef __OSKA_LINUX_TRACE_H */
diff --git a/drivers/staging/csr/oska/types.h b/drivers/staging/csr/oska/types.h
new file mode 100644 (file)
index 0000000..18d7c11
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * OSKA Linux implementation -- types
+ *
+ * Copyright (C) 2009 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_TYPES_H
+#define __OSKA_LINUX_TYPES_H
+
+#include <linux/types.h>
+
+#endif /* #ifndef __OSKA_LINUX_TYPES_H */
diff --git a/drivers/staging/csr/oska/util.h b/drivers/staging/csr/oska/util.h
new file mode 100644 (file)
index 0000000..bf29e2d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * OSKA Linux implementation -- misc. utility functions
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_UTILS_H
+#define __OSKA_LINUX_UTILS_H
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <asm/byteorder.h>
+
+#define OS_ASSERT(expr) BUG_ON(!(expr))
+
+static inline uint16_t os_le16_to_cpu(uint16_t x)
+{
+    return le16_to_cpu(x);
+}
+
+static inline uint16_t os_cpu_to_le16(uint16_t x)
+{
+    return cpu_to_le16(x);
+}
+
+static inline uint32_t os_le32_to_cpu(uint32_t x)
+{
+    return le32_to_cpu(x);
+}
+
+static inline uint32_t os_cpu_to_le32(uint32_t x)
+{
+    return cpu_to_le32(x);
+}
+
+static inline uint64_t os_le64_to_cpu(uint64_t x)
+{
+    return le64_to_cpu(x);
+}
+
+static inline uint64_t os_cpu_to_le64(uint64_t x)
+{
+    return cpu_to_le64(x);
+}
+
+#endif /* __OSKA_LINUX_UTILS_H */