i915: enable hotplug && power savings
git-svn-id: svn://kolibrios.org@3482 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
105
drivers/ddk/linux/workqueue.c
Normal file
105
drivers/ddk/linux/workqueue.c
Normal file
@@ -0,0 +1,105 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <ddk.h>
|
||||
|
||||
struct workqueue_struct *alloc_workqueue(const char *fmt,
|
||||
unsigned int flags,
|
||||
int max_active)
|
||||
{
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
wq = kzalloc(sizeof(*wq),0);
|
||||
if (!wq)
|
||||
goto err;
|
||||
|
||||
INIT_LIST_HEAD(&wq->worklist);
|
||||
INIT_LIST_HEAD(&wq->delayed_worklist);
|
||||
|
||||
return wq;
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void run_workqueue(struct workqueue_struct *cwq)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
|
||||
// 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))
|
||||
{
|
||||
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);
|
||||
|
||||
spin_unlock_irqrestore(&cwq->lock, irqflags);
|
||||
f(work);
|
||||
spin_lock_irqsave(&cwq->lock, irqflags);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&cwq->lock, irqflags);
|
||||
|
||||
delay(1);
|
||||
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
|
||||
bool queue_work(struct workqueue_struct *wq, struct work_struct *work)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if(!list_empty(&work->entry))
|
||||
return 0;
|
||||
|
||||
// dbgprintf("%s %p queue: %p\n", __FUNCTION__, work, wq);
|
||||
|
||||
spin_lock_irqsave(&wq->lock, flags);
|
||||
|
||||
list_add_tail(&work->entry, &wq->worklist);
|
||||
|
||||
spin_unlock_irqrestore(&wq->lock, flags);
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
void __stdcall delayed_work_timer_fn(unsigned long __data)
|
||||
{
|
||||
struct delayed_work *dwork = (struct delayed_work *)__data;
|
||||
struct workqueue_struct *wq = dwork->work.data;
|
||||
|
||||
queue_work(wq, &dwork->work);
|
||||
}
|
||||
|
||||
int queue_delayed_work(struct workqueue_struct *wq,
|
||||
struct delayed_work *dwork, unsigned long delay)
|
||||
{
|
||||
struct work_struct *work = &dwork->work;
|
||||
|
||||
if (delay == 0)
|
||||
return queue_work(wq, &dwork->work);
|
||||
|
||||
// dbgprintf("%s %p queue: %p\n", __FUNCTION__, &dwork->work, wq);
|
||||
|
||||
work->data = wq;
|
||||
TimerHs(delay,0, delayed_work_timer_fn, dwork);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay)
|
||||
{
|
||||
return queue_delayed_work(system_wq, dwork, delay);
|
||||
}
|
||||
|
Reference in New Issue
Block a user