Esempio n. 1
0
/*
 * Register the handler for a given RETU interrupt source.
 */
int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
{
	struct retu_irq_handler_desc *hnd;

	if (irq_handler == NULL || id >= MAX_RETU_IRQ_HANDLERS ||
	    name == NULL) {
		printk(KERN_ERR PFX "Invalid arguments to %s\n",
		       __FUNCTION__);
		return -EINVAL;
	}
	hnd = &retu_irq_handlers[id];
	if (hnd->func != NULL) {
		printk(KERN_ERR PFX "IRQ %d already reserved\n", id);
		return -EBUSY;
	}
	printk(KERN_INFO PFX "Registering interrupt %d for device %s\n",
	       id, name);
	hnd->func = irq_handler;
	hnd->arg = arg;
	strlcpy(hnd->name, name, sizeof(hnd->name));

	retu_ack_irq(id);
	retu_enable_irq(id);

	return 0;
}
Esempio n. 2
0
/*
 * Tasklet handler
 */
static void retu_tasklet_handler(unsigned long data)
{
	struct retu_irq_handler_desc *hnd;
	u16 id;
	u16 im;
	int i;

	for (;;) {
		id = retu_read_reg(RETU_REG_IDR);
		im = ~retu_read_reg(RETU_REG_IMR);
		id &= im;

		if (!id)
			break;

		for (i = 0; id != 0; i++, id >>= 1) {
			if (!(id & 1))
				continue;
			hnd = &retu_irq_handlers[i];
			if (hnd->func == NULL) {
                               /* Spurious retu interrupt - disable and ack it */
				printk(KERN_INFO "Spurious Retu interrupt "
						 "(id %d)\n", i);
				retu_disable_irq(i);
				retu_ack_irq(i);
				continue;
			}
			hnd->func(hnd->arg);
			/*
			 * Don't acknowledge the interrupt here
			 * It must be done explicitly
			 */
		}
	}
}
Esempio n. 3
0
static void retu_headset_hook_interrupt(unsigned long arg)
{
	struct retu_headset *hs = (struct retu_headset *) arg;
	unsigned long flags;

	retu_ack_irq(RETU_INT_HOOK);
	spin_lock_irqsave(&hs->lock, flags);
	if (!hs->pressed) {
		/* Headset button was just pressed down. */
		hs->pressed = 1;
		input_report_key(hs->idev, RETU_HEADSET_KEY, 1);
	}
	spin_unlock_irqrestore(&hs->lock, flags);
	retu_set_clear_reg_bits(RETU_REG_CC1, 0, (1 << 10) | (1 << 8));
	mod_timer(&hs->enable_timer, jiffies + msecs_to_jiffies(50));
}
Esempio n. 4
0
/**
 * Interrupt function is called whenever power button key is pressed
 * or released.
 */
static void retubutton_irq(unsigned long arg)
{
	retu_ack_irq(RETU_INT_PWR);
	mod_timer(&pwrbtn_timer, jiffies + msecs_to_jiffies(PWRBTN_DELAY));
}