diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/ec.c | 11 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 36 |
2 files changed, 27 insertions, 20 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e7e197e3a4f..7222a18a031 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -129,7 +129,6 @@ static struct acpi_ec { struct mutex lock; wait_queue_head_t wait; struct list_head list; - atomic_t irq_count; u8 handlers_installed; } *boot_ec, *first_ec; @@ -182,8 +181,6 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) { int ret = 0; - atomic_set(&ec->irq_count, 0); - if (unlikely(event == ACPI_EC_EVENT_OBF_1 && test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) force_poll = 1; @@ -230,7 +227,6 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) while (time_before(jiffies, delay)) { if (acpi_ec_check_status(ec, event)) goto end; - msleep(5); } } pr_err(PREFIX "acpi_ec_wait timeout," @@ -533,13 +529,6 @@ static u32 acpi_ec_gpe_handler(void *data) struct acpi_ec *ec = data; pr_debug(PREFIX "~~~> interrupt\n"); - atomic_inc(&ec->irq_count); - if (atomic_read(&ec->irq_count) > 5) { - pr_err(PREFIX "GPE storm detected, disabling EC GPE\n"); - acpi_disable_gpe(NULL, ec->gpe, ACPI_ISR); - clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); - return ACPI_INTERRUPT_HANDLED; - } clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) wake_up(&ec->wait); diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 0518a2e948c..4c86a8d84b4 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -423,6 +423,25 @@ void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) } /* + * We got an interrupt on a task_in case, but no errors and no DRQ. + * + * It might be a spurious irq (shared irq), but it might be a + * command that had no output. + */ +static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat) +{ + /* Command all done? */ + if (OK_STAT(stat, READY_STAT, BUSY_STAT)) { + task_end_request(drive, rq, stat); + return ide_stopped; + } + + /* Assume it was a spurious irq */ + ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); + return ide_started; +} + +/* * Handler for command with PIO data-in phase (Read/Read Multiple). */ static ide_startstop_t task_in_intr(ide_drive_t *drive) @@ -431,18 +450,17 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) struct request *rq = HWGROUP(drive)->rq; u8 stat = ide_read_status(drive); - /* new way for dealing with premature shared PCI interrupts */ - if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { - if (stat & (ERR_STAT | DRQ_STAT)) - return task_error(drive, rq, __FUNCTION__, stat); - /* No data yet, so wait for another IRQ. */ - ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); - return ide_started; - } + /* Error? */ + if (stat & ERR_STAT) + return task_error(drive, rq, __FUNCTION__, stat); + + /* Didn't want any data? Odd. */ + if (!(stat & DRQ_STAT)) + return task_in_unexpected(drive, rq, stat); ide_pio_datablock(drive, rq, 0); - /* If it was the last datablock check status and finish transfer. */ + /* Are we done? Check status and finish transfer. */ if (!hwif->nleft) { stat = wait_drive_not_busy(drive); if (!OK_STAT(stat, 0, BAD_STAT)) |