示例#1
0
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;
}
示例#2
0
static int dmar_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_domain_set_info(domain, virq, arg->dmar_id, info->chip, NULL,
			    handle_edge_irq, arg->dmar_data, "edge");

	return 0;
}
示例#3
0
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;
}
示例#4
0
static int htirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
			      unsigned int nr_irqs, void *arg)
{
	struct ht_irq_cfg *ht_cfg;
	struct irq_alloc_info *info = arg;
	struct pci_dev *dev;
	irq_hw_number_t hwirq;
	int ret;

	if (nr_irqs > 1 || !info)
		return -EINVAL;

	dev = info->ht_dev;
	hwirq = (info->ht_idx & 0xFF) |
		PCI_DEVID(dev->bus->number, dev->devfn) << 8 |
		(pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 24;
	if (irq_find_mapping(domain, hwirq) > 0)
		return -EEXIST;

	ht_cfg = kmalloc(sizeof(*ht_cfg), GFP_KERNEL);
	if (!ht_cfg)
		return -ENOMEM;

	ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info);
	if (ret < 0) {
		kfree(ht_cfg);
		return ret;
	}

	/* Initialize msg to a value that will never match the first write. */
	ht_cfg->msg.address_lo = 0xffffffff;
	ht_cfg->msg.address_hi = 0xffffffff;
	ht_cfg->dev = info->ht_dev;
	ht_cfg->update = info->ht_update;
	ht_cfg->pos = info->ht_pos;
	ht_cfg->idx = 0x10 + (info->ht_idx * 2);
	irq_domain_set_info(domain, virq, hwirq, &ht_irq_chip, ht_cfg,
			    handle_edge_irq, ht_cfg, "edge");

	return 0;
}