diff options
| -rw-r--r-- | series | 1 | ||||
| -rw-r--r-- | staging-add-csr-wifi-os-helper-module.patch | 1651 |
2 files changed, 1652 insertions, 0 deletions
@@ -1,4 +1,5 @@ # My specific stuff, at the top to make it easier to work stuff below. +staging-add-csr-wifi-os-helper-module.patch time-don-t-inline-export_symbol-functions.patch perf-turn-off-compiler-warnings-for-flex-and-bison-generated-files.patch hfsplus-bugfixes.patch diff --git a/staging-add-csr-wifi-os-helper-module.patch b/staging-add-csr-wifi-os-helper-module.patch new file mode 100644 index 00000000000000..fe6cb7b2176008 --- /dev/null +++ b/staging-add-csr-wifi-os-helper-module.patch @@ -0,0 +1,1651 @@ +From 7d8f03379459cef5dd852503cecfff935d005abd Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Date: Thu, 24 May 2012 09:47:38 -0700 +Subject: [PATCH] Staging: add CSR Wifi "os helper" module +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig +index 97d412d..3cf7223 100644 +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -132,4 +132,6 @@ source "drivers/staging/ramster/Kconfig" + + source "drivers/staging/ozwpan/Kconfig" + ++source "drivers/staging/csr/Kconfig" ++ + endif # STAGING +diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile +index ffe7d44..845ee64 100644 +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -57,3 +57,4 @@ obj-$(CONFIG_ANDROID) += android/ + obj-$(CONFIG_PHONE) += telephony/ + obj-$(CONFIG_RAMSTER) += ramster/ + obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ ++obj-$(CONFIG_CSR_WIFI) += csr/ +diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig +new file mode 100644 +index 0000000..5d7b800 +--- /dev/null ++++ b/drivers/staging/csr/Kconfig +@@ -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 +index 0000000..b9ba3b3 +--- /dev/null ++++ b/drivers/staging/csr/Makefile +@@ -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 +index 0000000..3a0b648 +--- /dev/null ++++ b/drivers/staging/csr/oska/Makefile +@@ -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 +index 0000000..5fe8583 +--- /dev/null ++++ b/drivers/staging/csr/oska/all.h +@@ -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 +index 0000000..0f10601 +--- /dev/null ++++ b/drivers/staging/csr/oska/alloc.h +@@ -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 +index 0000000..790b97a +--- /dev/null ++++ b/drivers/staging/csr/oska/compat.c +@@ -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 +index 0000000..36bfcd9 +--- /dev/null ++++ b/drivers/staging/csr/oska/event.c +@@ -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 +index 0000000..be52e42 +--- /dev/null ++++ b/drivers/staging/csr/oska/event.h +@@ -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 +index 0000000..c6c406c +--- /dev/null ++++ b/drivers/staging/csr/oska/io.h +@@ -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 +index 0000000..b6d27d3 +--- /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 */ +diff --git a/drivers/staging/csr/oska/list.c b/drivers/staging/csr/oska/list.c +new file mode 100644 +index 0000000..b5e884e +--- /dev/null ++++ b/drivers/staging/csr/oska/list.c +@@ -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 +index 0000000..a69b3b7 +--- /dev/null ++++ b/drivers/staging/csr/oska/list.h +@@ -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 +index 0000000..9138b28 +--- /dev/null ++++ b/drivers/staging/csr/oska/mutex.h +@@ -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 +index 0000000..da12564 +--- /dev/null ++++ b/drivers/staging/csr/oska/oska_module.c +@@ -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 +index 0000000..5f5b263 +--- /dev/null ++++ b/drivers/staging/csr/oska/print.c +@@ -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 +index 0000000..f48bb83 +--- /dev/null ++++ b/drivers/staging/csr/oska/print.h +@@ -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 +index 0000000..28abb64 +--- /dev/null ++++ b/drivers/staging/csr/oska/refcount.c +@@ -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 +index 0000000..741b00a +--- /dev/null ++++ b/drivers/staging/csr/oska/refcount.h +@@ -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 +index 0000000..965bfe8 +--- /dev/null ++++ b/drivers/staging/csr/oska/semaphore.h +@@ -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 +index 0000000..157b350 +--- /dev/null ++++ b/drivers/staging/csr/oska/spinlock.h +@@ -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 +index 0000000..f680cef +--- /dev/null ++++ b/drivers/staging/csr/oska/thread.c +@@ -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 +index 0000000..8816dc8 +--- /dev/null ++++ b/drivers/staging/csr/oska/thread.h +@@ -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 +index 0000000..d246ce9 +--- /dev/null ++++ b/drivers/staging/csr/oska/time.h +@@ -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 +index 0000000..67d3423 +--- /dev/null ++++ b/drivers/staging/csr/oska/timer.c +@@ -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 +index 0000000..3045fc3 +--- /dev/null ++++ b/drivers/staging/csr/oska/timer.h +@@ -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 +index 0000000..b28f37d +--- /dev/null ++++ b/drivers/staging/csr/oska/trace.h +@@ -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 +index 0000000..18d7c11 +--- /dev/null ++++ b/drivers/staging/csr/oska/types.h +@@ -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 +index 0000000..bf29e2d +--- /dev/null ++++ b/drivers/staging/csr/oska/util.h +@@ -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 */ |
