static int uv_domain_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *arg) { struct uv_irq_2_mmr_pnode *chip_data; struct irq_alloc_info *info = arg; struct irq_data *irq_data = irq_domain_get_irq_data(domain, virq); int ret; if (nr_irqs > 1 || !info || info->type != X86_IRQ_ALLOC_TYPE_UV) return -EINVAL; chip_data = kmalloc_node(sizeof(*chip_data), GFP_KERNEL, irq_data_get_node(irq_data)); if (!chip_data) return -ENOMEM; ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg); if (ret >= 0) { if (info->uv_limit == UV_AFFINITY_CPU) irq_set_status_flags(virq, IRQ_NO_BALANCING); else irq_set_status_flags(virq, IRQ_MOVE_PCNTXT); chip_data->pnode = uv_blade_to_pnode(info->uv_blade); chip_data->offset = info->uv_offset; irq_domain_set_info(domain, virq, virq, &uv_irq_chip, chip_data, handle_percpu_irq, NULL, info->uv_name); } else { kfree(chip_data); } return ret; }
static int __init db1300_device_init(void) { int swapped, cpldirq; /* setup CPLD IRQ muxer */ cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1); irq_set_irq_type(cpldirq, IRQ_TYPE_LEVEL_HIGH); bcsr_init_irq(DB1300_FIRST_INT, DB1300_LAST_INT, cpldirq); /* insert/eject IRQs: one always triggers so don't enable them * when doing request_irq() on them. DB1200 has this bug too. */ irq_set_status_flags(DB1300_SD1_INSERT_INT, IRQ_NOAUTOEN); irq_set_status_flags(DB1300_SD1_EJECT_INT, IRQ_NOAUTOEN); irq_set_status_flags(DB1300_CF_INSERT_INT, IRQ_NOAUTOEN); irq_set_status_flags(DB1300_CF_EJECT_INT, IRQ_NOAUTOEN); /* * setup board */ prom_get_ethernet_addr(&db1300_eth_config.mac[0]); i2c_register_board_info(0, db1300_i2c_devs, ARRAY_SIZE(db1300_i2c_devs)); /* Audio PSC clock is supplied by codecs (PSC1, 2) */ __raw_writel(PSC_SEL_CLK_SERCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); wmb(); __raw_writel(PSC_SEL_CLK_SERCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); wmb(); /* I2C uses internal 48MHz EXTCLK1 */ __raw_writel(PSC_SEL_CLK_INTCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); wmb(); /* enable power to USB ports */ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_USBHPWR | BCSR_RESETS_OTGPWR); /* although it is socket #0, it uses the CPLD bits which previous boards * have used for socket #1. */ db1x_register_pcmcia_socket( AU1000_PCMCIA_ATTR_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x00400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x00400000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_IO_PHYS_ADDR + 0x00010000 - 1, DB1300_CF_INT, DB1300_CF_INSERT_INT, 0, DB1300_CF_EJECT_INT, 1); swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; db1x_register_norflash(64 << 20, 2, swapped); return platform_add_devices(db1300_dev, ARRAY_SIZE(db1300_dev)); }
/** * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt * @dev: Device entry * @irq: Device wake-up interrupt * * Unless your hardware has separate wake-up interrupts in addition * to the device IO interrupts, you don't need this. * * Sets up a threaded interrupt handler for a device that has * a dedicated wake-up interrupt in addition to the device IO * interrupt. * * The interrupt starts disabled, and needs to be managed for * the device by the bus code or the device driver using * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq() * functions. */ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) { struct wake_irq *wirq; int err; if (irq < 0) return -EINVAL; wirq = kzalloc(sizeof(*wirq), GFP_KERNEL); if (!wirq) return -ENOMEM; wirq->name = kasprintf(GFP_KERNEL, "%s:wakeup", dev_name(dev)); if (!wirq->name) { err = -ENOMEM; goto err_free; } wirq->dev = dev; wirq->irq = irq; irq_set_status_flags(irq, IRQ_NOAUTOEN); /* Prevent deferred spurious wakeirqs with disable_irq_nosync() */ irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); /* * Consumer device may need to power up and restore state * so we use a threaded irq. */ err = request_threaded_irq(irq, NULL, handle_threaded_wake_irq, IRQF_ONESHOT, wirq->name, wirq); if (err) goto err_free_name; err = dev_pm_attach_wake_irq(dev, irq, wirq); if (err) goto err_free_irq; wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; return err; err_free_irq: free_irq(irq, wirq); err_free_name: kfree(wirq->name); err_free: kfree(wirq); return err; }
static int __init db1300_device_init(void) { int swapped, cpldirq; cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1); irq_set_irq_type(cpldirq, IRQ_TYPE_LEVEL_HIGH); bcsr_init_irq(DB1300_FIRST_INT, DB1300_LAST_INT, cpldirq); irq_set_status_flags(DB1300_SD1_INSERT_INT, IRQ_NOAUTOEN); irq_set_status_flags(DB1300_SD1_EJECT_INT, IRQ_NOAUTOEN); irq_set_status_flags(DB1300_CF_INSERT_INT, IRQ_NOAUTOEN); irq_set_status_flags(DB1300_CF_EJECT_INT, IRQ_NOAUTOEN); prom_get_ethernet_addr(&db1300_eth_config.mac[0]); i2c_register_board_info(0, db1300_i2c_devs, ARRAY_SIZE(db1300_i2c_devs)); __raw_writel(PSC_SEL_CLK_SERCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); wmb(); __raw_writel(PSC_SEL_CLK_SERCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); wmb(); __raw_writel(PSC_SEL_CLK_INTCLK, (void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); wmb(); bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_USBHPWR | BCSR_RESETS_OTGPWR); db1x_register_pcmcia_socket( AU1000_PCMCIA_ATTR_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x00400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x00400000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_IO_PHYS_ADDR + 0x00010000 - 1, DB1300_CF_INT, DB1300_CF_INSERT_INT, 0, DB1300_CF_EJECT_INT, 1); swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; db1x_register_norflash(64 << 20, 2, swapped); return platform_add_devices(db1300_dev, ARRAY_SIZE(db1300_dev)); }
static int i8259_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw); /* We block the internal cascade */ if (hw == 2) irq_set_status_flags(virq, IRQ_NOREQUEST); /* We use the level handler only for now, we might want to * be more cautious here but that works for now */ irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_and_handler(virq, &i8259_pic, handle_level_irq); return 0; }
static int xics_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct ics *ics; pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw); irq_radix_revmap_insert(xics_host, virq, hw); irq_set_status_flags(virq, IRQ_LEVEL); if (hw == XICS_IPI) { irq_set_chip_and_handler(virq, &xics_ipi_chip, handle_percpu_irq); return 0; } list_for_each_entry(ics, &ics_list, link) if (ics->map(ics, virq) == 0) return 0; return -EINVAL; }
static struct clk * __init at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq, const char *name, const char *parent_name) { int ret; struct clk_utmi *utmi; struct clk *clk = NULL; struct clk_init_data init; utmi = kzalloc(sizeof(*utmi), GFP_KERNEL); if (!utmi) return ERR_PTR(-ENOMEM); init.name = name; init.ops = &utmi_ops; init.parent_names = parent_name ? &parent_name : NULL; init.num_parents = parent_name ? 1 : 0; init.flags = CLK_SET_RATE_GATE; utmi->hw.init = &init; utmi->pmc = pmc; utmi->irq = irq; init_waitqueue_head(&utmi->wait); irq_set_status_flags(utmi->irq, IRQ_NOAUTOEN); ret = request_irq(utmi->irq, clk_utmi_irq_handler, IRQF_TRIGGER_HIGH, "clk-utmi", utmi); if (ret) return ERR_PTR(ret); clk = clk_register(NULL, &utmi->hw); if (IS_ERR(clk)) kfree(utmi); return clk; }
void __init dove_init_irq(void) { int i; orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); /* * Initialize gpiolib for GPIOs 0-71. */ orion_gpio_init(NULL, 0, 32, DOVE_GPIO_LO_VIRT_BASE, 0, IRQ_DOVE_GPIO_START, gpio0_irqs); orion_gpio_init(NULL, 32, 32, DOVE_GPIO_HI_VIRT_BASE, 0, IRQ_DOVE_GPIO_START + 32, gpio1_irqs); orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0, IRQ_DOVE_GPIO_START + 64, gpio2_irqs); /* * Mask and clear PMU interrupts */ writel(0, PMU_INTERRUPT_MASK); writel(0, PMU_INTERRUPT_CAUSE); for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) { irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); set_irq_flags(i, IRQF_VALID); } irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); }
static int xics_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct ics *ics; pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw); /* Insert the interrupt mapping into the radix tree for fast lookup */ irq_radix_revmap_insert(xics_host, virq, hw); /* They aren't all level sensitive but we just don't really know */ irq_set_status_flags(virq, IRQ_LEVEL); /* Don't call into ICS for IPIs */ if (hw == XICS_IPI) { irq_set_chip_and_handler(virq, &xics_ipi_chip, handle_percpu_irq); return 0; } /* Let the ICS setup the chip data */ list_for_each_entry(ics, &ics_list, link) if (ics->map(ics, virq) == 0) return 0; return -EINVAL; }
static void __init alcor_init_irq(void) { long i; if (alpha_using_srm) alpha_mv.device_interrupt = srm_device_interrupt; *(vuip)GRU_INT_MASK = 0; mb(); /* */ *(vuip)GRU_INT_EDGE = 0; mb(); /* */ *(vuip)GRU_INT_HILO = 0x80000000U; mb(); /* */ *(vuip)GRU_INT_CLEAR = 0; mb(); /* */ for (i = 16; i < 48; ++i) { /* */ if (i >= 16+20 && i <= 16+30) continue; irq_set_chip_and_handler(i, &alcor_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } i8259a_irq_type.irq_ack = alcor_isa_mask_and_ack_irq; init_i8259a_irqs(); common_init_isa_dma(); setup_irq(16+31, &isa_cascade_irqaction); }
static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) { irq_set_chip_and_handler(virq, &idu_irq_chip, handle_level_irq); irq_set_status_flags(virq, IRQ_MOVE_PCNTXT); return 0; }
static void __init rawhide_init_irq(void) { struct pci_controller *hose; long i; mcpcia_init_hoses(); /* Clear them all; only hoses that exist will be non-zero. */ for (i = 0; i < MCPCIA_MAX_HOSES; i++) cached_irq_masks[i] = 0; for (hose = hose_head; hose; hose = hose->next) { unsigned int h = hose->index; unsigned int mask = hose_irq_masks[h]; cached_irq_masks[h] = mask; *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask; *(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0; } for (i = 16; i < 128; ++i) { irq_set_chip_and_handler(i, &rawhide_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } init_i8259a_irqs(); common_init_isa_dma(); }
static void __init common_init_irq(void (*srm_dev_int)(unsigned long v)) { init_i8259a_irqs(); if (alpha_using_srm) { alpha_mv.device_interrupt = srm_dev_int; init_srm_irqs(35, 0); } else { long i; outb(0xff, 0x804); outb(0xff, 0x805); outb(0xff, 0x806); for (i = 16; i < 35; ++i) { irq_set_chip_and_handler(i, &cabriolet_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } } common_init_isa_dma(); setup_irq(16+4, &isa_cascade_irqaction); }
static void __init alcor_init_irq(void) { long i; if (alpha_using_srm) alpha_mv.device_interrupt = srm_device_interrupt; *(vuip)GRU_INT_MASK = 0; mb(); /* all disabled */ *(vuip)GRU_INT_EDGE = 0; mb(); /* all are level */ *(vuip)GRU_INT_HILO = 0x80000000U; mb(); /* ISA only HI */ *(vuip)GRU_INT_CLEAR = 0; mb(); /* all clear */ for (i = 16; i < 48; ++i) { /* On Alcor, at least, lines 20..30 are not connected and can generate spurious interrupts if we turn them on while IRQ probing. */ if (i >= 16+20 && i <= 16+30) continue; irq_set_chip_and_handler(i, &alcor_irq_type, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } i8259a_irq_type.irq_ack = alcor_isa_mask_and_ack_irq; init_i8259a_irqs(); common_init_isa_dma(); setup_irq(16+31, &isa_cascade_irqaction); }
void __init dove_init_irq(void) { int i; orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0, IRQ_DOVE_GPIO_START); irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0, IRQ_DOVE_GPIO_START + 32); irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0, IRQ_DOVE_GPIO_START + 64); writel(0, PMU_INTERRUPT_MASK); writel(0, PMU_INTERRUPT_CAUSE); for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) { irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); set_irq_flags(i, IRQF_VALID); } irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); }
static int flipper_pic_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { irq_set_chip_data(virq, h->host_data); irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_and_handler(virq, &flipper_pic, handle_level_irq); return 0; }
static void bcm2836_arm_irqchip_register_irq(int hwirq, struct irq_chip *chip) { int irq = irq_create_mapping(intc.domain, hwirq); irq_set_percpu_devid(irq); irq_set_chip_and_handler(irq, chip, handle_percpu_devid_irq); irq_set_status_flags(irq, IRQ_NOAUTOEN); }
static int cpld_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_and_handler(virq, &cpld_pic, handle_level_irq); return 0; }
static int pci_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_data(virq, h->host_data); irq_set_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq); return 0; }
/* When an interrupt is being configured, this call allows some flexibilty * in deciding which irq_chip structure is used */ static int gef_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { /* All interrupts are LEVEL sensitive */ irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_and_handler(virq, &gef_pic_chip, handle_level_irq); return 0; }
static void mpcore_wdt_irq_disable(unsigned int irq) { unsigned long flags; local_irq_save(flags); irq_set_status_flags(irq, IRQ_NOPROBE); mt_irq_mask(irq_get_irq_data(irq)); local_irq_restore(flags); }
static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw); irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq); return 0; }
static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { struct or1k_pic_dev *pic = d->host_data; irq_set_chip_and_handler(irq, &pic->chip, pic->handle); irq_set_status_flags(irq, pic->flags); return 0; }
static int media5200_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw); irq_set_chip_data(virq, &media5200_irq); irq_set_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq); irq_set_status_flags(virq, IRQ_LEVEL); return 0; }
static void __init init_titan_irqs(struct irq_chip * ops, int imin, int imax) { long i; for (i = imin; i <= imax; ++i) { irq_set_chip_and_handler(i, ops, handle_level_irq); irq_set_status_flags(i, IRQ_LEVEL); } }
static int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, unsigned long mmr_offset, int limit) { const struct cpumask *eligible_cpu = cpumask_of(cpu); struct irq_cfg *cfg = irq_get_chip_data(irq); unsigned long mmr_value; struct uv_IO_APIC_route_entry *entry; int mmr_pnode, err; BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); err = assign_irq_vector(irq, cfg, eligible_cpu); if (err != 0) return err; if (limit == UV_AFFINITY_CPU) irq_set_status_flags(irq, IRQ_NO_BALANCING); else irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); irq_set_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq, irq_name); mmr_value = 0; entry = (struct uv_IO_APIC_route_entry *)&mmr_value; entry->vector = cfg->vector; entry->delivery_mode = apic->irq_delivery_mode; entry->dest_mode = apic->irq_dest_mode; entry->polarity = 0; entry->trigger = 0; entry->mask = 0; entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); mmr_pnode = uv_blade_to_pnode(mmr_blade); uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); if (cfg->move_in_progress) send_cleanup_vector(cfg); return irq; }
static int hpet_msi_init(struct irq_domain *domain, struct msi_domain_info *info, unsigned int virq, irq_hw_number_t hwirq, msi_alloc_info_t *arg) { irq_set_status_flags(virq, IRQ_MOVE_PCNTXT); irq_domain_set_info(domain, virq, arg->hpet_index, info->chip, NULL, handle_edge_irq, arg->hpet_data, "edge"); return 0; }
/** * irq_free_hwirqs - Free irq descriptor and cleanup the hardware * @from: Free from irq number * @cnt: number of interrupts to free * */ void irq_free_hwirqs(unsigned int from, int cnt) { int i, j; for (i = from, j = cnt; j > 0; i++, j--) { irq_set_status_flags(i, _IRQ_NOREQUEST | _IRQ_NOPROBE); arch_teardown_hwirq(i); } irq_free_descs(from, cnt); }
static int pci_irq_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { unsigned int irq; DBG("%s(%d, 0x%lx)\n", __func__, virq, hw); if ((virq >= 1) && (virq <= 4)){ irq = virq + IRQ_PCI_INTAD_BASE - 1; irq_set_status_flags(irq, IRQ_LEVEL); irq_set_chip(irq, &tsi108_pci_irq); } return 0; }
static int xtensa_mx_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { if (hw < HW_IRQ_IPI_COUNT) { struct irq_chip *irq_chip = d->host_data; irq_set_chip_and_handler_name(irq, irq_chip, handle_percpu_irq, "ipi"); irq_set_status_flags(irq, IRQ_LEVEL); return 0; } return xtensa_irq_map(d, irq, hw); }