From a3e5776171b8557b609f0a241f1bed816e267e2a Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Fri, 5 Jul 2013 07:41:18 +0000 Subject: [PATCH] ddk: v3.10 git-svn-id: svn://kolibrios.org@3763 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/ddk/linux/workqueue.c | 37 ++--- drivers/include/drm/drmP.h | 4 +- drivers/include/drm/drm_mem_util.h | 67 +++++++++ drivers/include/drm/ttm/ttm_memory.h | 6 +- drivers/include/linux/bug.h | 1 - drivers/include/linux/firmware.h | 4 - drivers/include/linux/kobject.h | 216 +++++++++++++++++++++++++++ 7 files changed, 308 insertions(+), 27 deletions(-) create mode 100644 drivers/include/drm/drm_mem_util.h create mode 100644 drivers/include/linux/kobject.h diff --git a/drivers/ddk/linux/workqueue.c b/drivers/ddk/linux/workqueue.c index 72e69a7cfc..c2e46bd4fd 100644 --- a/drivers/ddk/linux/workqueue.c +++ b/drivers/ddk/linux/workqueue.c @@ -2,6 +2,8 @@ #include #include +extern int driver_wq_state; + struct workqueue_struct *alloc_workqueue(const char *fmt, unsigned int flags, int max_active) @@ -29,29 +31,28 @@ void run_workqueue(struct workqueue_struct *cwq) // dbgprintf("wq: %x head %x, next %x\n", // cwq, &cwq->worklist, cwq->worklist.next); -repeat: - - spin_lock_irqsave(&cwq->lock, irqflags); - - while (!list_empty(&cwq->worklist)) + while(driver_wq_state != 0) { - struct work_struct *work = list_entry(cwq->worklist.next, + spin_lock_irqsave(&cwq->lock, irqflags); + + while (!list_empty(&cwq->worklist)) + { + struct work_struct *work = list_entry(cwq->worklist.next, struct work_struct, entry); - work_func_t f = work->func; - list_del_init(cwq->worklist.next); -// dbgprintf("head %x, next %x\n", -// &cwq->worklist, cwq->worklist.next); + work_func_t f = work->func; + list_del_init(cwq->worklist.next); +// printf("work %p, func %p\n", +// work, f); + + spin_unlock_irqrestore(&cwq->lock, irqflags); + f(work); + spin_lock_irqsave(&cwq->lock, irqflags); + } spin_unlock_irqrestore(&cwq->lock, irqflags); - f(work); - spin_lock_irqsave(&cwq->lock, irqflags); - } - spin_unlock_irqrestore(&cwq->lock, irqflags); - - delay(1); - - goto repeat; + delay(1); + }; } diff --git a/drivers/include/drm/drmP.h b/drivers/include/drm/drmP.h index 4d72c8d055..d4c9a8dc2e 100644 --- a/drivers/include/drm/drmP.h +++ b/drivers/include/drm/drmP.h @@ -56,7 +56,9 @@ #include #include -//#include +#include +#include + //#include //#include //#include diff --git a/drivers/include/drm/drm_mem_util.h b/drivers/include/drm/drm_mem_util.h new file mode 100644 index 0000000000..26f501a387 --- /dev/null +++ b/drivers/include/drm/drm_mem_util.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Jesse Barnes + * + */ +#ifndef _DRM_MEM_UTIL_H_ +#define _DRM_MEM_UTIL_H_ + +static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) +{ + void *p; + + if (size != 0 && nmemb > SIZE_MAX / size) + return NULL; + + if (size * nmemb <= PAGE_SIZE) + return calloc(nmemb, size); + + p = (void*)KernelAlloc(size * nmemb); + if ( p != NULL ) + memset(p, 0,size * nmemb); + + return p; +} + +/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ +static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) +{ + if (size != 0 && nmemb > SIZE_MAX / size) + return NULL; + + if (size * nmemb <= PAGE_SIZE) + return kmalloc(nmemb * size, GFP_KERNEL); + + return (void*)KernelAlloc(size * nmemb); +} + +static __inline void drm_free_large(void *ptr) +{ + if( ((addr_t)ptr & 0xFFF) == 0 ) // !!! + KernelFree(ptr); + else + kfree(ptr); +} + +#endif diff --git a/drivers/include/drm/ttm/ttm_memory.h b/drivers/include/drm/ttm/ttm_memory.h index 1de3ad3542..8c1bd961a9 100644 --- a/drivers/include/drm/ttm/ttm_memory.h +++ b/drivers/include/drm/ttm/ttm_memory.h @@ -28,12 +28,12 @@ #ifndef TTM_MEMORY_H #define TTM_MEMORY_H -//#include +#include #include #include #include #include -//#include +#include #include /** @@ -75,7 +75,7 @@ struct ttm_mem_shrink { #define TTM_MEM_MAX_ZONES 2 struct ttm_mem_zone; struct ttm_mem_global { -// struct kobject kobj; + struct kobject kobj; struct ttm_mem_shrink *shrink; struct workqueue_struct *swap_queue; struct work_struct work; diff --git a/drivers/include/linux/bug.h b/drivers/include/linux/bug.h index 13dbd350f8..87893eaec1 100644 --- a/drivers/include/linux/bug.h +++ b/drivers/include/linux/bug.h @@ -53,7 +53,6 @@ #define BUG() do { \ printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ - while(1){ delay(10); }; \ } while (0) #define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while(0) diff --git a/drivers/include/linux/firmware.h b/drivers/include/linux/firmware.h index c19dc5586b..ed11ad9562 100644 --- a/drivers/include/linux/firmware.h +++ b/drivers/include/linux/firmware.h @@ -59,9 +59,5 @@ struct platform_device #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) -static inline long IS_ERR(const void *ptr) -{ - return IS_ERR_VALUE((unsigned long)ptr); -} #endif diff --git a/drivers/include/linux/kobject.h b/drivers/include/linux/kobject.h new file mode 100644 index 0000000000..6c053df694 --- /dev/null +++ b/drivers/include/linux/kobject.h @@ -0,0 +1,216 @@ +/* + * kobject.h - generic kernel object infrastructure. + * + * Copyright (c) 2002-2003 Patrick Mochel + * Copyright (c) 2002-2003 Open Source Development Labs + * Copyright (c) 2006-2008 Greg Kroah-Hartman + * Copyright (c) 2006-2008 Novell Inc. + * + * This file is released under the GPLv2. + * + * Please read Documentation/kobject.txt before using the kobject + * interface, ESPECIALLY the parts about reference counts and object + * destructors. + */ + +#ifndef _KOBJECT_H_ +#define _KOBJECT_H_ + +#include +#include +//#include +#include +#include +#include +//#include +#include +#include +//#include + +#define UEVENT_HELPER_PATH_LEN 256 +#define UEVENT_NUM_ENVP 32 /* number of env pointers */ +#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ + +/* path to the userspace helper executed on an event */ +extern char uevent_helper[]; + +/* counter to tag the uevent, read only except for the kobject core */ +extern u64 uevent_seqnum; + +/* + * The actions here must match the index to the string array + * in lib/kobject_uevent.c + * + * Do not add new actions here without checking with the driver-core + * maintainers. Action strings are not meant to express subsystem + * or device specific properties. In most cases you want to send a + * kobject_uevent_env(kobj, KOBJ_CHANGE, env) with additional event + * specific variables added to the event environment. + */ +enum kobject_action { + KOBJ_ADD, + KOBJ_REMOVE, + KOBJ_CHANGE, + KOBJ_MOVE, + KOBJ_ONLINE, + KOBJ_OFFLINE, + KOBJ_MAX +}; + +struct kobject { + const char *name; + struct list_head entry; + struct kobject *parent; +// struct kset *kset; + struct kobj_type *ktype; +// struct sysfs_dirent *sd; + struct kref kref; + unsigned int state_initialized:1; + unsigned int state_in_sysfs:1; + unsigned int state_add_uevent_sent:1; + unsigned int state_remove_uevent_sent:1; + unsigned int uevent_suppress:1; +}; + +extern __printf(2, 3) +int kobject_set_name(struct kobject *kobj, const char *name, ...); +extern int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, + va_list vargs); + +static inline const char *kobject_name(const struct kobject *kobj) +{ + return kobj->name; +} + +extern void kobject_init(struct kobject *kobj, struct kobj_type *ktype); +extern __printf(3, 4) __must_check +int kobject_add(struct kobject *kobj, struct kobject *parent, + const char *fmt, ...); +extern __printf(4, 5) __must_check +int kobject_init_and_add(struct kobject *kobj, + struct kobj_type *ktype, struct kobject *parent, + const char *fmt, ...); + +extern void kobject_del(struct kobject *kobj); + +extern struct kobject * __must_check kobject_create(void); +extern struct kobject * __must_check kobject_create_and_add(const char *name, + struct kobject *parent); + +extern int __must_check kobject_rename(struct kobject *, const char *new_name); +extern int __must_check kobject_move(struct kobject *, struct kobject *); + +extern struct kobject *kobject_get(struct kobject *kobj); +extern void kobject_put(struct kobject *kobj); + +extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); + +struct kobj_type { + void (*release)(struct kobject *kobj); +// const struct sysfs_ops *sysfs_ops; +// struct attribute **default_attrs; +// const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj); +// const void *(*namespace)(struct kobject *kobj); +}; + +struct kobj_uevent_env { + char *envp[UEVENT_NUM_ENVP]; + int envp_idx; + char buf[UEVENT_BUFFER_SIZE]; + int buflen; +}; + +//struct kset_uevent_ops { +// int (* const filter)(struct kset *kset, struct kobject *kobj); +// const char *(* const name)(struct kset *kset, struct kobject *kobj); +// int (* const uevent)(struct kset *kset, struct kobject *kobj, +// struct kobj_uevent_env *env); +//}; + +struct kobj_attribute { +// struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +}; + +extern const struct sysfs_ops kobj_sysfs_ops; + +struct sock; + +/** + * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. + * + * A kset defines a group of kobjects. They can be individually + * different "types" but overall these kobjects all want to be grouped + * together and operated on in the same manner. ksets are used to + * define the attribute callbacks and other common events that happen to + * a kobject. + * + * @list: the list of all kobjects for this kset + * @list_lock: a lock for iterating over the kobjects + * @kobj: the embedded kobject for this kset (recursion, isn't it fun...) + * @uevent_ops: the set of uevent operations for this kset. These are + * called whenever a kobject has something happen to it so that the kset + * can add new environment variables, or filter out the uevents if so + * desired. + */ +struct kset { + struct list_head list; + spinlock_t list_lock; + struct kobject kobj; +// const struct kset_uevent_ops *uevent_ops; +}; + +//extern void kset_init(struct kset *kset); +//extern int __must_check kset_register(struct kset *kset); +//extern void kset_unregister(struct kset *kset); +//extern struct kset * __must_check kset_create_and_add(const char *name, +// const struct kset_uevent_ops *u, +// struct kobject *parent_kobj); + +//static inline struct kset *to_kset(struct kobject *kobj) +//{ +// return kobj ? container_of(kobj, struct kset, kobj) : NULL; +//} + +//static inline struct kset *kset_get(struct kset *k) +//{ +// return k ? to_kset(kobject_get(&k->kobj)) : NULL; +//} + +//static inline void kset_put(struct kset *k) +//{ +// kobject_put(&k->kobj); +//} + +static inline struct kobj_type *get_ktype(struct kobject *kobj) +{ + return kobj->ktype; +} + +//extern struct kobject *kset_find_obj(struct kset *, const char *); + +/* The global /sys/kernel/ kobject for people to chain off of */ +extern struct kobject *kernel_kobj; +/* The global /sys/kernel/mm/ kobject for people to chain off of */ +extern struct kobject *mm_kobj; +/* The global /sys/hypervisor/ kobject for people to chain off of */ +extern struct kobject *hypervisor_kobj; +/* The global /sys/power/ kobject for people to chain off of */ +extern struct kobject *power_kobj; +/* The global /sys/firmware/ kobject for people to chain off of */ +extern struct kobject *firmware_kobj; + +int kobject_uevent(struct kobject *kobj, enum kobject_action action); +int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, + char *envp[]); + +__printf(2, 3) +int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); + +int kobject_action_type(const char *buf, size_t count, + enum kobject_action *type); + +#endif /* _KOBJECT_H_ */