intel_extreme: read and loop for new interrupts. Fix #9718.
* MSI seems to trigger the need to loop: interrupts are not generated for bits set while we process.
This commit is contained in:
@@ -78,36 +78,41 @@ static int32
|
|||||||
intel_interrupt_handler(void* data)
|
intel_interrupt_handler(void* data)
|
||||||
{
|
{
|
||||||
intel_info &info = *(intel_info*)data;
|
intel_info &info = *(intel_info*)data;
|
||||||
|
uint32 reg = find_reg(info, INTEL_INTERRUPT_IDENTITY);
|
||||||
uint16 identity = read16(info, find_reg(info, INTEL_INTERRUPT_IDENTITY));
|
uint16 identity = read16(info, reg);
|
||||||
if (identity == 0)
|
if (identity == 0)
|
||||||
return B_UNHANDLED_INTERRUPT;
|
return B_UNHANDLED_INTERRUPT;
|
||||||
|
|
||||||
int32 handled = B_HANDLED_INTERRUPT;
|
int32 handled = B_HANDLED_INTERRUPT;
|
||||||
|
|
||||||
// TODO: verify that these aren't actually the same
|
while (identity != 0) {
|
||||||
bool hasPCH = info.device_type.HasPlatformControlHub();
|
|
||||||
uint16 mask = hasPCH ? PCH_INTERRUPT_VBLANK_PIPEA : INTERRUPT_VBLANK_PIPEA;
|
|
||||||
if ((identity & mask) != 0) {
|
|
||||||
handled = release_vblank_sem(info);
|
|
||||||
|
|
||||||
// make sure we'll get another one of those
|
// TODO: verify that these aren't actually the same
|
||||||
write32(info, INTEL_DISPLAY_A_PIPE_STATUS,
|
bool hasPCH = info.device_type.HasPlatformControlHub();
|
||||||
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
uint16 mask = hasPCH ? PCH_INTERRUPT_VBLANK_PIPEA
|
||||||
|
: INTERRUPT_VBLANK_PIPEA;
|
||||||
|
if ((identity & mask) != 0) {
|
||||||
|
handled = release_vblank_sem(info);
|
||||||
|
|
||||||
|
// make sure we'll get another one of those
|
||||||
|
write32(info, INTEL_DISPLAY_A_PIPE_STATUS,
|
||||||
|
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = hasPCH ? PCH_INTERRUPT_VBLANK_PIPEB : INTERRUPT_VBLANK_PIPEB;
|
||||||
|
if ((identity & mask) != 0) {
|
||||||
|
handled = release_vblank_sem(info);
|
||||||
|
|
||||||
|
// make sure we'll get another one of those
|
||||||
|
write32(info, INTEL_DISPLAY_B_PIPE_STATUS,
|
||||||
|
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// setting the bit clears it!
|
||||||
|
write16(info, reg, identity);
|
||||||
|
identity = read16(info, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = hasPCH ? PCH_INTERRUPT_VBLANK_PIPEB : INTERRUPT_VBLANK_PIPEB;
|
|
||||||
if ((identity & mask) != 0) {
|
|
||||||
handled = release_vblank_sem(info);
|
|
||||||
|
|
||||||
// make sure we'll get another one of those
|
|
||||||
write32(info, INTEL_DISPLAY_B_PIPE_STATUS,
|
|
||||||
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setting the bit clears it!
|
|
||||||
write16(info, find_reg(info, INTEL_INTERRUPT_IDENTITY), identity);
|
|
||||||
|
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user