mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 08:25:38 +00:00
USB: Sync interrupts
On systems that use multiple UHCI/EHCI controllers, synchronize access to low level interrupt handler. Let 'device_may_wakeup' return 1, so suspended controllers will send interrupts upon device connection. Make sure URBs are shutdown upon disconnect. Fixes #332
This commit is contained in:
parent
71b2b42936
commit
c98a80251c
@ -310,7 +310,7 @@ void pm_runtime_no_callbacks(struct device *dev) { TRACE; }
|
||||
|
||||
int device_init_wakeup(struct device *dev, bool val) { TRACE; return 0; }
|
||||
int device_wakeup_enable(struct device *dev) { TRACE; return 0; }
|
||||
bool device_may_wakeup(struct device *dev) { TRACE; return 0; }
|
||||
bool device_may_wakeup(struct device *dev) { TRACE; return 1; }
|
||||
int device_set_wakeup_enable(struct device *dev, bool enable) { TRACE; return 0; }
|
||||
bool device_can_wakeup(struct device *dev) { TRACE; return 0; }
|
||||
|
||||
|
@ -957,8 +957,6 @@ void breakpoint();
|
||||
/* our wait event implementation */
|
||||
void __wait_event(void);
|
||||
|
||||
#define wait_event(wq, condition) \
|
||||
({ dde_kit_printf("wait_event, not yet implemented\n"); 0; })
|
||||
|
||||
#define _wait_event(condition) \
|
||||
while(!(condition)) { \
|
||||
@ -967,6 +965,10 @@ void __wait_event(void);
|
||||
msleep(1); \
|
||||
} \
|
||||
|
||||
#define wait_event(wq, condition) \
|
||||
({ _wait_event(condition); })
|
||||
|
||||
|
||||
#define _wait_event_timeout(condition, timeout) \
|
||||
({ \
|
||||
unsigned long _j = jiffies + (timeout / HZ); \
|
||||
|
@ -71,6 +71,13 @@ class Irq_context : public Driver_context,
|
||||
/* called by the DDE kit upon IRQ */
|
||||
static void _dde_handler(void *irq)
|
||||
{
|
||||
/*
|
||||
* Make sure there is only one interrupt handled at a time, since dde_kit
|
||||
* will use one thread per IRQ
|
||||
*/
|
||||
static Genode::Lock handler_lock;
|
||||
Genode::Lock::Guard guard(handler_lock);
|
||||
|
||||
/* unlock if main thread is waiting */
|
||||
_irq_wait.unlock();
|
||||
|
||||
@ -99,9 +106,6 @@ class Irq_context : public Driver_context,
|
||||
if (h->handler(_irq, h->dev) != IRQ_HANDLED)
|
||||
return handled;
|
||||
|
||||
if (!handled)
|
||||
Routine::schedule_all();
|
||||
|
||||
handled = true;
|
||||
|
||||
} while (true);
|
||||
@ -117,13 +121,16 @@ class Irq_context : public Driver_context,
|
||||
/* report IRQ to all clients */
|
||||
for (Irq_handler *h = _handler_list.first(); h; h = h->next()) {
|
||||
|
||||
handled = _handle_one(h);
|
||||
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u %p", _irq, handled, h->handler);
|
||||
if (handled)
|
||||
break;
|
||||
handled |= _handle_one(h);
|
||||
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u h: %p dev: %p", _irq, handled, h->handler, h->dev);
|
||||
}
|
||||
|
||||
/* interrupt should be acked at device now */
|
||||
_irq_sync.unlock();
|
||||
|
||||
if (handled)
|
||||
Routine::schedule_all();
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user