Пример #1
0
static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
	struct vt8500_irq_data *priv = d->domain->host_data;
	void __iomem *base = priv->base;
	u8 dctr;

	dctr = readb(base + VT8500_ICDC + d->hwirq);
	dctr &= ~VT8500_EDGE;

	switch (flow_type) {
	case IRQF_TRIGGER_LOW:
		return -EINVAL;
	case IRQF_TRIGGER_HIGH:
		dctr |= VT8500_TRIGGER_HIGH;
		irq_set_handler_locked(d, handle_level_irq);
		break;
	case IRQF_TRIGGER_FALLING:
		dctr |= VT8500_TRIGGER_FALLING;
		irq_set_handler_locked(d, handle_edge_irq);
		break;
	case IRQF_TRIGGER_RISING:
		dctr |= VT8500_TRIGGER_RISING;
		irq_set_handler_locked(d, handle_edge_irq);
		break;
	}
	writeb(dctr, base + VT8500_ICDC + d->hwirq);

	return 0;
}
Пример #2
0
static int mpc52xx_extirq_set_type(struct irq_data *d, unsigned int flow_type)
{
	u32 ctrl_reg, type;
	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
	void *handler = handle_level_irq;

	pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__,
		(int) irqd_to_hwirq(d), l2irq, flow_type);

	switch (flow_type) {
	case IRQF_TRIGGER_HIGH: type = 0; break;
	case IRQF_TRIGGER_RISING: type = 1; handler = handle_edge_irq; break;
	case IRQF_TRIGGER_FALLING: type = 2; handler = handle_edge_irq; break;
	case IRQF_TRIGGER_LOW: type = 3; break;
	default:
		type = 0;
	}

	ctrl_reg = in_be32(&intr->ctrl);
	ctrl_reg &= ~(0x3 << (22 - (l2irq * 2)));
	ctrl_reg |= (type << (22 - (l2irq * 2)));
	out_be32(&intr->ctrl, ctrl_reg);

	irq_set_handler_locked(d, handler);

	return 0;
}
Пример #3
0
static int oxnas_gpio_irq_set_type(struct irq_data *data, unsigned int type)
{
	if ((type & (IRQ_TYPE_EDGE_RISING|IRQ_TYPE_EDGE_FALLING)) == 0)
		return -EINVAL;

	irq_set_handler_locked(data, handle_edge_irq);

	return 0;
}
Пример #4
0
/*
 * gpio_int_type1 controls whether the interrupt is level (0) or
 * edge (1) triggered, while gpio_int_type2 controls whether it
 * triggers on low/falling (0) or high/rising (1).
 */
static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
{
	const int gpio = irq_to_gpio(d->irq);
	const int port = gpio >> 3;
	const int port_mask = 1 << (gpio & 7);
	irq_flow_handler_t handler;

	gpio_direction_input(gpio);

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		gpio_int_type1[port] |= port_mask;
		gpio_int_type2[port] |= port_mask;
		handler = handle_edge_irq;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		gpio_int_type1[port] |= port_mask;
		gpio_int_type2[port] &= ~port_mask;
		handler = handle_edge_irq;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		gpio_int_type1[port] &= ~port_mask;
		gpio_int_type2[port] |= port_mask;
		handler = handle_level_irq;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		gpio_int_type1[port] &= ~port_mask;
		gpio_int_type2[port] &= ~port_mask;
		handler = handle_level_irq;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		gpio_int_type1[port] |= port_mask;
		/* set initial polarity based on current input level */
		if (gpio_get_value(gpio))
			gpio_int_type2[port] &= ~port_mask; /* falling */
		else
			gpio_int_type2[port] |= port_mask; /* rising */
		handler = handle_edge_irq;
		break;
	default:
		return -EINVAL;
	}

	irq_set_handler_locked(d, handler);

	gpio_int_enabled[port] |= port_mask;

	ep93xx_gpio_update_int_params(port);

	return 0;
}
Пример #5
0
static int ft010_irq_set_type(struct irq_data *d, unsigned int trigger)
{
	struct ft010_irq_data *f = irq_data_get_irq_chip_data(d);
	int offset = irqd_to_hwirq(d);
	u32 mode, polarity;

	mode = readl(FT010_IRQ_MODE(f->base));
	polarity = readl(FT010_IRQ_POLARITY(f->base));

	if (trigger & (IRQ_TYPE_LEVEL_LOW)) {
		irq_set_handler_locked(d, handle_level_irq);
		mode &= ~BIT(offset);
		polarity |= BIT(offset);
	} else if (trigger & (IRQ_TYPE_LEVEL_HIGH)) {
		irq_set_handler_locked(d, handle_level_irq);
		mode &= ~BIT(offset);
		polarity &= ~BIT(offset);
	} else if (trigger & IRQ_TYPE_EDGE_FALLING) {
		irq_set_handler_locked(d, handle_edge_irq);
		mode |= BIT(offset);
		polarity |= BIT(offset);
	} else if (trigger & IRQ_TYPE_EDGE_RISING) {
		irq_set_handler_locked(d, handle_edge_irq);
		mode |= BIT(offset);
		polarity &= ~BIT(offset);
	} else {
		irq_set_handler_locked(d, handle_bad_irq);
		pr_warn("Faraday IRQ: no supported trigger selected for line %d\n",
			offset);
	}

	writel(mode, FT010_IRQ_MODE(f->base));
	writel(polarity, FT010_IRQ_POLARITY(f->base));

	return 0;
}
Пример #6
0
static int ftgpio_gpio_set_irq_type(struct irq_data *d, unsigned int type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct ftgpio_gpio *g = gpiochip_get_data(gc);
	u32 mask = BIT(irqd_to_hwirq(d));
	u32 reg_both, reg_level, reg_type;

	reg_type = readl(g->base + GPIO_INT_TYPE);
	reg_level = readl(g->base + GPIO_INT_LEVEL);
	reg_both = readl(g->base + GPIO_INT_BOTH_EDGE);

	switch (type) {
	case IRQ_TYPE_EDGE_BOTH:
		irq_set_handler_locked(d, handle_edge_irq);
		reg_type &= ~mask;
		reg_both |= mask;
		break;
	case IRQ_TYPE_EDGE_RISING:
		irq_set_handler_locked(d, handle_edge_irq);
		reg_type &= ~mask;
		reg_both &= ~mask;
		reg_level &= ~mask;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		irq_set_handler_locked(d, handle_edge_irq);
		reg_type &= ~mask;
		reg_both &= ~mask;
		reg_level |= mask;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		irq_set_handler_locked(d, handle_level_irq);
		reg_type |= mask;
		reg_level &= ~mask;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		irq_set_handler_locked(d, handle_level_irq);
		reg_type |= mask;
		reg_level |= mask;
		break;
	default:
		irq_set_handler_locked(d, handle_bad_irq);
		return -EINVAL;
	}

	writel(reg_type, g->base + GPIO_INT_TYPE);
	writel(reg_level, g->base + GPIO_INT_LEVEL);
	writel(reg_both, g->base + GPIO_INT_BOTH_EDGE);

	ftgpio_gpio_ack_irq(d);

	return 0;
}
Пример #7
0
static int bcm63xx_external_irq_set_type(struct irq_data *d,
					 unsigned int flow_type)
{
	unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
	u32 reg, regaddr;
	int levelsense, sense, bothedge;
	unsigned long flags;

	flow_type &= IRQ_TYPE_SENSE_MASK;

	if (flow_type == IRQ_TYPE_NONE)
		flow_type = IRQ_TYPE_LEVEL_LOW;

	levelsense = sense = bothedge = 0;
	switch (flow_type) {
	case IRQ_TYPE_EDGE_BOTH:
		bothedge = 1;
		break;

	case IRQ_TYPE_EDGE_RISING:
		sense = 1;
		break;

	case IRQ_TYPE_EDGE_FALLING:
		break;

	case IRQ_TYPE_LEVEL_HIGH:
		levelsense = 1;
		sense = 1;
		break;

	case IRQ_TYPE_LEVEL_LOW:
		levelsense = 1;
		break;

	default:
		pr_err("bogus flow type combination given !\n");
		return -EINVAL;
	}

	regaddr = get_ext_irq_perf_reg(irq);
	spin_lock_irqsave(&epic_lock, flags);
	reg = bcm_perf_readl(regaddr);
	irq %= 4;

	switch (bcm63xx_get_cpu_id()) {
	case BCM6348_CPU_ID:
		if (levelsense)
			reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq);
		else
			reg &= ~EXTIRQ_CFG_LEVELSENSE_6348(irq);
		if (sense)
			reg |= EXTIRQ_CFG_SENSE_6348(irq);
		else
			reg &= ~EXTIRQ_CFG_SENSE_6348(irq);
		if (bothedge)
			reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq);
		else
			reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
		break;

	case BCM3368_CPU_ID:
	case BCM6328_CPU_ID:
	case BCM6338_CPU_ID:
	case BCM6345_CPU_ID:
	case BCM6358_CPU_ID:
	case BCM6362_CPU_ID:
	case BCM6368_CPU_ID:
		if (levelsense)
			reg |= EXTIRQ_CFG_LEVELSENSE(irq);
		else
			reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
		if (sense)
			reg |= EXTIRQ_CFG_SENSE(irq);
		else
			reg &= ~EXTIRQ_CFG_SENSE(irq);
		if (bothedge)
			reg |= EXTIRQ_CFG_BOTHEDGE(irq);
		else
			reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
		break;
	default:
		BUG();
	}

	bcm_perf_writel(reg, regaddr);
	spin_unlock_irqrestore(&epic_lock, flags);

	irqd_set_trigger_type(d, flow_type);
	if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
		irq_set_handler_locked(d, handle_level_irq);
	else
		irq_set_handler_locked(d, handle_edge_irq);

	return IRQ_SET_MASK_OK_NOCOPY;
}