mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-23 09:56:00 +00:00
Staging: add CSR Wifi "os helper" module
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>
This commit is contained in:
parent
55232eca66
commit
15a4bc17b7
@ -132,4 +132,6 @@ source "drivers/staging/ipack/Kconfig"
|
||||
|
||||
source "drivers/staging/gdm72xx/Kconfig"
|
||||
|
||||
source "drivers/staging/csr/Kconfig"
|
||||
|
||||
endif # STAGING
|
||||
|
@ -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/
|
||||
|
7
drivers/staging/csr/Kconfig
Normal file
7
drivers/staging/csr/Kconfig
Normal file
@ -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.
|
1
drivers/staging/csr/Makefile
Normal file
1
drivers/staging/csr/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-$(CONFIG_CSR_WIFI) += oska/
|
12
drivers/staging/csr/oska/Makefile
Normal file
12
drivers/staging/csr/oska/Makefile
Normal file
@ -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
|
||||
|
61
drivers/staging/csr/oska/all.h
Normal file
61
drivers/staging/csr/oska/all.h
Normal file
@ -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 */
|
41
drivers/staging/csr/oska/alloc.h
Normal file
41
drivers/staging/csr/oska/alloc.h
Normal file
@ -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 */
|
54
drivers/staging/csr/oska/compat.c
Normal file
54
drivers/staging/csr/oska/compat.c
Normal file
@ -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 */
|
82
drivers/staging/csr/oska/event.c
Normal file
82
drivers/staging/csr/oska/event.c
Normal file
@ -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);
|
33
drivers/staging/csr/oska/event.h
Normal file
33
drivers/staging/csr/oska/event.h
Normal file
@ -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 */
|
63
drivers/staging/csr/oska/io.h
Normal file
63
drivers/staging/csr/oska/io.h
Normal file
@ -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 */
|
199
drivers/staging/csr/oska/kernel-compat.h
Normal file
199
drivers/staging/csr/oska/kernel-compat.h
Normal file
@ -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 */
|
103
drivers/staging/csr/oska/list.c
Normal file
103
drivers/staging/csr/oska/list.c
Normal file
@ -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;
|
||||
}
|
115
drivers/staging/csr/oska/list.h
Normal file
115
drivers/staging/csr/oska/list.h
Normal file
@ -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 */
|
42
drivers/staging/csr/oska/mutex.h
Normal file
42
drivers/staging/csr/oska/mutex.h
Normal file
@ -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 */
|
21
drivers/staging/csr/oska/oska_module.c
Normal file
21
drivers/staging/csr/oska/oska_module.c
Normal file
@ -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");
|
44
drivers/staging/csr/oska/print.c
Normal file
44
drivers/staging/csr/oska/print.c
Normal file
@ -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);
|
32
drivers/staging/csr/oska/print.h
Normal file
32
drivers/staging/csr/oska/print.h
Normal file
@ -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 */
|
47
drivers/staging/csr/oska/refcount.c
Normal file
47
drivers/staging/csr/oska/refcount.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
86
drivers/staging/csr/oska/refcount.h
Normal file
86
drivers/staging/csr/oska/refcount.h
Normal file
@ -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 */
|
70
drivers/staging/csr/oska/semaphore.h
Normal file
70
drivers/staging/csr/oska/semaphore.h
Normal file
@ -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 */
|
43
drivers/staging/csr/oska/spinlock.h
Normal file
43
drivers/staging/csr/oska/spinlock.h
Normal file
@ -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 */
|
66
drivers/staging/csr/oska/thread.c
Normal file
66
drivers/staging/csr/oska/thread.c
Normal file
@ -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);
|
39
drivers/staging/csr/oska/thread.h
Normal file
39
drivers/staging/csr/oska/thread.h
Normal file
@ -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 */
|
34
drivers/staging/csr/oska/time.h
Normal file
34
drivers/staging/csr/oska/time.h
Normal file
@ -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 */
|
28
drivers/staging/csr/oska/timer.c
Normal file
28
drivers/staging/csr/oska/timer.c
Normal file
@ -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);
|
40
drivers/staging/csr/oska/timer.h
Normal file
40
drivers/staging/csr/oska/timer.h
Normal file
@ -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 */
|
23
drivers/staging/csr/oska/trace.h
Normal file
23
drivers/staging/csr/oska/trace.h
Normal file
@ -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 */
|
14
drivers/staging/csr/oska/types.h
Normal file
14
drivers/staging/csr/oska/types.h
Normal file
@ -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 */
|
48
drivers/staging/csr/oska/util.h
Normal file
48
drivers/staging/csr/oska/util.h
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user