예제 #1
0
static irqreturn_t
snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy)
{
    nm256_t *chip = dev_id;
    u16 status;
    u8 cbyte;

    status = snd_nm256_readw(chip, NM_INT_REG);

    /* Not ours. */
    if (status == 0) {
        snd_nm256_intr_check(chip);
        return IRQ_NONE;
    }

    chip->badintrcount = 0;

    /* Rather boring; check for individual interrupts and process them. */

    spin_lock(&chip->reg_lock);
    if (status & NM_PLAYBACK_INT) {
        status &= ~NM_PLAYBACK_INT;
        NM_ACK_INT(chip, NM_PLAYBACK_INT);
        snd_nm256_playback_update(chip);
    }

    if (status & NM_RECORD_INT) {
        status &= ~NM_RECORD_INT;
        NM_ACK_INT(chip, NM_RECORD_INT);
        snd_nm256_capture_update(chip);
    }

    if (status & NM_MISC_INT_1) {
        status &= ~NM_MISC_INT_1;
        NM_ACK_INT(chip, NM_MISC_INT_1);
        snd_printd("NM256: Got misc interrupt #1\n");
        snd_nm256_writew(chip, NM_INT_REG, 0x8000);
        cbyte = snd_nm256_readb(chip, 0x400);
        snd_nm256_writeb(chip, 0x400, cbyte | 2);
    }

    if (status & NM_MISC_INT_2) {
        status &= ~NM_MISC_INT_2;
        NM_ACK_INT(chip, NM_MISC_INT_2);
        snd_printd("NM256: Got misc interrupt #2\n");
        cbyte = snd_nm256_readb(chip, 0x400);
        snd_nm256_writeb(chip, 0x400, cbyte & ~2);
    }

    /* Unknown interrupt. */
    if (status) {
        snd_printd("NM256: Fire in the hole! Unknown status 0x%x\n",
                   status);
        /* Pray. */
        NM_ACK_INT(chip, status);
    }

    spin_unlock(&chip->reg_lock);
    return IRQ_HANDLED;
}
예제 #2
0
static irqreturn_t
snd_nm256_interrupt(int irq, void *dev_id)
{
	struct nm256 *chip = dev_id;
	u16 status;
	u8 cbyte;

	status = snd_nm256_readw(chip, NM_INT_REG);

	
	if (status == 0)
		return snd_nm256_intr_check(chip);

	chip->badintrcount = 0;

	

	spin_lock(&chip->reg_lock);
	if (status & NM_PLAYBACK_INT) {
		status &= ~NM_PLAYBACK_INT;
		NM_ACK_INT(chip, NM_PLAYBACK_INT);
		snd_nm256_playback_update(chip);
	}

	if (status & NM_RECORD_INT) {
		status &= ~NM_RECORD_INT;
		NM_ACK_INT(chip, NM_RECORD_INT);
		snd_nm256_capture_update(chip);
	}

	if (status & NM_MISC_INT_1) {
		status &= ~NM_MISC_INT_1;
		NM_ACK_INT(chip, NM_MISC_INT_1);
		snd_printd("NM256: Got misc interrupt #1\n");
		snd_nm256_writew(chip, NM_INT_REG, 0x8000);
		cbyte = snd_nm256_readb(chip, 0x400);
		snd_nm256_writeb(chip, 0x400, cbyte | 2);
	}

	if (status & NM_MISC_INT_2) {
		status &= ~NM_MISC_INT_2;
		NM_ACK_INT(chip, NM_MISC_INT_2);
		snd_printd("NM256: Got misc interrupt #2\n");
		cbyte = snd_nm256_readb(chip, 0x400);
		snd_nm256_writeb(chip, 0x400, cbyte & ~2);
	}

	
	if (status) {
		snd_printd("NM256: Fire in the hole! Unknown status 0x%x\n",
			   status);
		
		NM_ACK_INT(chip, status);
	}

	spin_unlock(&chip->reg_lock);
	return IRQ_HANDLED;
}
예제 #3
0
static void
nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
{
    struct nm256_info *card = (struct nm256_info *)dev_id;
    u16 status;
    static int badintrcount = 0;

    if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) {
	printk (KERN_ERR "NM256: Bad card pointer\n");
	return;
    }

    status = nm256_readPort16 (card, 2, NM_INT_REG);

    /* Not ours. */
    if (status == 0) {
	if (badintrcount++ > 1000) {
	    /*
	     * I'm not sure if the best thing is to stop the card from
	     * playing or just release the interrupt (after all, we're in
	     * a bad situation, so doing fancy stuff may not be such a good
	     * idea).
	     *
	     * I worry about the card engine continuing to play noise
	     * over and over, however--that could become a very
	     * obnoxious problem.  And we know that when this usually
	     * happens things are fairly safe, it just means the user's
	     * inserted a PCMCIA card and someone's spamming us with IRQ 9s.
	     */

	    if (card->playing)
		stopPlay (card);
	    if (card->recording)
		stopRecord (card);
	    badintrcount = 0;
	}
	return;
    }

    badintrcount = 0;

    /* Rather boring; check for individual interrupts and process them. */

    if (status & NM_PLAYBACK_INT) {
	status &= ~NM_PLAYBACK_INT;
	NM_ACK_INT (card, NM_PLAYBACK_INT);

	if (card->playing)
	    nm256_get_new_block (card);
    }

    if (status & NM_RECORD_INT) {
	status &= ~NM_RECORD_INT;
	NM_ACK_INT (card, NM_RECORD_INT);

	if (card->recording)
	    nm256_read_block (card);
    }

    if (status & NM_MISC_INT_1) {
	u8 cbyte;

	status &= ~NM_MISC_INT_1;
	printk (KERN_ERR "NM256: Got misc interrupt #1\n");
	NM_ACK_INT (card, NM_MISC_INT_1);
	nm256_writePort16 (card, 2, NM_INT_REG, 0x8000);
	cbyte = nm256_readPort8 (card, 2, 0x400);
	nm256_writePort8 (card, 2, 0x400, cbyte | 2);
    }

    if (status & NM_MISC_INT_2) {
	u8 cbyte;

	status &= ~NM_MISC_INT_2;
	printk (KERN_ERR "NM256: Got misc interrupt #2\n");
	NM_ACK_INT (card, NM_MISC_INT_2);
	cbyte = nm256_readPort8 (card, 2, 0x400);
	nm256_writePort8 (card, 2, 0x400, cbyte & ~2);
    }

    /* Unknown interrupt. */
    if (status) {
	printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n",
		status);
	/* Pray. */
	NM_ACK_INT (card, status);
    }
}