예제 #1
0
파일: irq.c 프로젝트: 08opt/linux
static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type)
{
	/* There's nothing to do in the PIC configuration when changing
	 * flow type.  Level and edge-triggered interrupts are both
	 * supported, but it's PIC-implementation specific which type
	 * is handled. */

	return irq_setup_alt_chip(data, flow_type);
}
예제 #2
0
파일: irq-tb10x.c 프로젝트: 03199618/linux
static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
	uint32_t im, mod, pol;

	im = data->mask;

	irq_gc_lock(gc);

	mod = ab_irqctl_readreg(gc, AB_IRQCTL_SRC_MODE) | im;
	pol = ab_irqctl_readreg(gc, AB_IRQCTL_SRC_POLARITY) | im;

	switch (flow_type & IRQF_TRIGGER_MASK) {
	case IRQ_TYPE_EDGE_FALLING:
		pol ^= im;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		mod ^= im;
		break;
	case IRQ_TYPE_NONE:
		flow_type = IRQ_TYPE_LEVEL_LOW;
	case IRQ_TYPE_LEVEL_LOW:
		mod ^= im;
		pol ^= im;
		break;
	case IRQ_TYPE_EDGE_RISING:
		break;
	default:
		irq_gc_unlock(gc);
		pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n",
			__func__, data->irq);
		return -EBADR;
	}

	irqd_set_trigger_type(data, flow_type);
	irq_setup_alt_chip(data, flow_type);

	ab_irqctl_writereg(gc, AB_IRQCTL_SRC_MODE, mod);
	ab_irqctl_writereg(gc, AB_IRQCTL_SRC_POLARITY, pol);
	ab_irqctl_writereg(gc, AB_IRQCTL_INT_STATUS, im);

	irq_gc_unlock(gc);

	return IRQ_SET_MASK_OK;
}
예제 #3
0
static int syswake_irq_set_type(struct irq_data *data, unsigned int flow_type)
{
	struct pdc_intc_priv *priv = irqd_to_priv(data);
	unsigned int syswake = hwirq_to_syswake(data->hwirq);
	unsigned int irq_mode;
	unsigned int soc_sys_wake_regoff, soc_sys_wake;

	/* translate to syswake IRQ mode */
	switch (flow_type) {
	case IRQ_TYPE_EDGE_BOTH:
		irq_mode = PDC_SYS_WAKE_INT_CHANGE;
		break;
	case IRQ_TYPE_EDGE_RISING:
		irq_mode = PDC_SYS_WAKE_INT_UP;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		irq_mode = PDC_SYS_WAKE_INT_DOWN;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		irq_mode = PDC_SYS_WAKE_INT_HIGH;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		irq_mode = PDC_SYS_WAKE_INT_LOW;
		break;
	default:
		return -EINVAL;
	}

	raw_spin_lock(&priv->lock);

	/* set the IRQ mode */
	soc_sys_wake_regoff = PDC_SYS_WAKE_BASE + syswake*PDC_SYS_WAKE_STRIDE;
	soc_sys_wake = pdc_read(priv, soc_sys_wake_regoff);
	soc_sys_wake &= ~PDC_SYS_WAKE_INT_MODE;
	soc_sys_wake |= irq_mode << PDC_SYS_WAKE_INT_MODE_SHIFT;
	pdc_write(priv, soc_sys_wake_regoff, soc_sys_wake);

	/* and update the handler */
	irq_setup_alt_chip(data, flow_type);

	raw_spin_unlock(&priv->lock);

	return 0;
}
예제 #4
0
static int gpio_set_irq_type(struct irq_data *data, unsigned int flow_type)
{
	struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
	unsigned int type;
	unsigned int polarity;

	switch (flow_type) {
	case IRQ_TYPE_EDGE_BOTH:
		type = REG_GPIO_IRQ_TYPE_EDGE;
		polarity = REG_GPIO_IRQ_PLRT_LOW;
		break;
	case IRQ_TYPE_EDGE_RISING:
		type = REG_GPIO_IRQ_TYPE_EDGE;
		polarity = REG_GPIO_IRQ_PLRT_HIGH;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		type = REG_GPIO_IRQ_TYPE_EDGE;
		polarity = REG_GPIO_IRQ_PLRT_LOW;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		type = REG_GPIO_IRQ_TYPE_LEVEL;
		polarity = REG_GPIO_IRQ_PLRT_HIGH;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		type = REG_GPIO_IRQ_TYPE_LEVEL;
		polarity = REG_GPIO_IRQ_PLRT_LOW;
		break;
	default:
		return -EINVAL;
	}

	tz1090_gpio_irq_type(bank, data->hwirq, type);
	irq_setup_alt_chip(data, flow_type);

	if (flow_type == IRQ_TYPE_EDGE_BOTH)
		tz1090_gpio_irq_next_edge(bank, data->hwirq);
	else
		tz1090_gpio_irq_polarity(bank, data->hwirq, polarity);

	return 0;
}