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; }
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; }
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; }
/* * 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; }
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; }
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; }
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; }