mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-25 13:29:56 +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_init_wakeup(struct device *dev, bool val) { TRACE; return 0; }
|
||||||
int device_wakeup_enable(struct device *dev) { 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; }
|
int device_set_wakeup_enable(struct device *dev, bool enable) { TRACE; return 0; }
|
||||||
bool device_can_wakeup(struct device *dev) { TRACE; return 0; }
|
bool device_can_wakeup(struct device *dev) { TRACE; return 0; }
|
||||||
|
|
||||||
|
@ -957,8 +957,6 @@ void breakpoint();
|
|||||||
/* our wait event implementation */
|
/* our wait event implementation */
|
||||||
void __wait_event(void);
|
void __wait_event(void);
|
||||||
|
|
||||||
#define wait_event(wq, condition) \
|
|
||||||
({ dde_kit_printf("wait_event, not yet implemented\n"); 0; })
|
|
||||||
|
|
||||||
#define _wait_event(condition) \
|
#define _wait_event(condition) \
|
||||||
while(!(condition)) { \
|
while(!(condition)) { \
|
||||||
@ -967,6 +965,10 @@ void __wait_event(void);
|
|||||||
msleep(1); \
|
msleep(1); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
#define wait_event(wq, condition) \
|
||||||
|
({ _wait_event(condition); })
|
||||||
|
|
||||||
|
|
||||||
#define _wait_event_timeout(condition, timeout) \
|
#define _wait_event_timeout(condition, timeout) \
|
||||||
({ \
|
({ \
|
||||||
unsigned long _j = jiffies + (timeout / HZ); \
|
unsigned long _j = jiffies + (timeout / HZ); \
|
||||||
|
@ -71,6 +71,13 @@ class Irq_context : public Driver_context,
|
|||||||
/* called by the DDE kit upon IRQ */
|
/* called by the DDE kit upon IRQ */
|
||||||
static void _dde_handler(void *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 */
|
/* unlock if main thread is waiting */
|
||||||
_irq_wait.unlock();
|
_irq_wait.unlock();
|
||||||
|
|
||||||
@ -99,9 +106,6 @@ class Irq_context : public Driver_context,
|
|||||||
if (h->handler(_irq, h->dev) != IRQ_HANDLED)
|
if (h->handler(_irq, h->dev) != IRQ_HANDLED)
|
||||||
return handled;
|
return handled;
|
||||||
|
|
||||||
if (!handled)
|
|
||||||
Routine::schedule_all();
|
|
||||||
|
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
||||||
} while (true);
|
} while (true);
|
||||||
@ -117,13 +121,16 @@ class Irq_context : public Driver_context,
|
|||||||
/* report IRQ to all clients */
|
/* report IRQ to all clients */
|
||||||
for (Irq_handler *h = _handler_list.first(); h; h = h->next()) {
|
for (Irq_handler *h = _handler_list.first(); h; h = h->next()) {
|
||||||
|
|
||||||
handled = _handle_one(h);
|
handled |= _handle_one(h);
|
||||||
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u %p", _irq, handled, h->handler);
|
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u h: %p dev: %p", _irq, handled, h->handler, h->dev);
|
||||||
if (handled)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* interrupt should be acked at device now */
|
/* interrupt should be acked at device now */
|
||||||
_irq_sync.unlock();
|
_irq_sync.unlock();
|
||||||
|
|
||||||
|
if (handled)
|
||||||
|
Routine::schedule_all();
|
||||||
|
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user