Esempio n. 1
0
static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
{
	struct irq_cfg *cfg = irqd_cfg(data);

	msg->address_hi = MSI_ADDR_BASE_HI;

	if (x2apic_enabled())
		msg->address_hi |= MSI_ADDR_EXT_DEST_ID(cfg->dest_apicid);

	msg->address_lo =
		MSI_ADDR_BASE_LO |
		((apic->irq_dest_mode == 0) ?
			MSI_ADDR_DEST_MODE_PHYSICAL :
			MSI_ADDR_DEST_MODE_LOGICAL) |
		((apic->irq_delivery_mode != dest_LowestPrio) ?
			MSI_ADDR_REDIRECTION_CPU :
			MSI_ADDR_REDIRECTION_LOWPRI) |
		MSI_ADDR_DEST_ID(cfg->dest_apicid);

	msg->data =
		MSI_DATA_TRIGGER_EDGE |
		MSI_DATA_LEVEL_ASSERT |
		((apic->irq_delivery_mode != dest_LowestPrio) ?
			MSI_DATA_DELIVERY_FIXED :
			MSI_DATA_DELIVERY_LOWPRI) |
		MSI_DATA_VECTOR(cfg->vector);
}
Esempio n. 2
0
static int hyperv_irq_remapping_activate(struct irq_domain *domain,
			  struct irq_data *irq_data, bool reserve)
{
	struct irq_cfg *cfg = irqd_cfg(irq_data);
	struct IO_APIC_route_entry *entry = irq_data->chip_data;

	entry->dest = cfg->dest_apicid;
	entry->vector = cfg->vector;

	return 0;
}
Esempio n. 3
0
/*
 * Disable the specified MMR located on the specified blade so that MSIs are
 * longer allowed to be sent.
 */
static void uv_domain_deactivate(struct irq_domain *domain,
				 struct irq_data *irq_data)
{
	unsigned long mmr_value;
	struct uv_IO_APIC_route_entry *entry;

	mmr_value = 0;
	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
	entry->mask = 1;
	uv_program_mmr(irqd_cfg(irq_data), irq_data->chip_data);
}
Esempio n. 4
0
static int
ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
{
	struct irq_cfg *cfg = irqd_cfg(data);
	unsigned int dest;
	int ret;

	ret = apic_set_affinity(data, mask, &dest);
	if (ret)
		return ret;

	target_ht_irq(data->irq, dest, cfg->vector);
	return IRQ_SET_MASK_OK_NOCOPY;
}
Esempio n. 5
0
static int
uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask,
		    bool force)
{
	struct irq_data *parent = data->parent_data;
	struct irq_cfg *cfg = irqd_cfg(data);
	int ret;

	ret = parent->chip->irq_set_affinity(parent, mask, force);
	if (ret >= 0) {
		uv_program_mmr(cfg, data->chip_data);
		send_cleanup_vector(cfg);
	}

	return ret;
}
Esempio n. 6
0
static void htirq_domain_activate(struct irq_domain *domain,
				  struct irq_data *irq_data)
{
	struct ht_irq_msg msg;
	struct irq_cfg *cfg = irqd_cfg(irq_data);

	msg.address_hi = HT_IRQ_HIGH_DEST_ID(cfg->dest_apicid);
	msg.address_lo =
		HT_IRQ_LOW_BASE |
		HT_IRQ_LOW_DEST_ID(cfg->dest_apicid) |
		HT_IRQ_LOW_VECTOR(cfg->vector) |
		((apic->irq_dest_mode == 0) ?
			HT_IRQ_LOW_DM_PHYSICAL :
			HT_IRQ_LOW_DM_LOGICAL) |
		HT_IRQ_LOW_RQEOI_EDGE |
		((apic->irq_delivery_mode != dest_LowestPrio) ?
			HT_IRQ_LOW_MT_FIXED :
			HT_IRQ_LOW_MT_ARBITRATED) |
		HT_IRQ_LOW_IRQ_MASKED;
	write_ht_irq_msg(irq_data->irq, &msg);
}
Esempio n. 7
0
/*
 * Hypertransport interrupt support
 */
static int
ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
{
	struct irq_data *parent = data->parent_data;
	int ret;

	ret = parent->chip->irq_set_affinity(parent, mask, force);
	if (ret >= 0) {
		struct ht_irq_msg msg;
		struct irq_cfg *cfg = irqd_cfg(data);

		fetch_ht_irq_msg(data->irq, &msg);
		msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK |
				    HT_IRQ_LOW_DEST_ID_MASK);
		msg.address_lo |= HT_IRQ_LOW_VECTOR(cfg->vector) |
				  HT_IRQ_LOW_DEST_ID(cfg->dest_apicid);
		msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
		msg.address_hi |= HT_IRQ_HIGH_DEST_ID(cfg->dest_apicid);
		write_ht_irq_msg(data->irq, &msg);
	}

	return ret;
}
Esempio n. 8
0
static int hyperv_ir_set_affinity(struct irq_data *data,
		const struct cpumask *mask, bool force)
{
	struct irq_data *parent = data->parent_data;
	struct irq_cfg *cfg = irqd_cfg(data);
	struct IO_APIC_route_entry *entry;
	int ret;

	/* Return error If new irq affinity is out of ioapic_max_cpumask. */
	if (!cpumask_subset(mask, &ioapic_max_cpumask))
		return -EINVAL;

	ret = parent->chip->irq_set_affinity(parent, mask, force);
	if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE)
		return ret;

	entry = data->chip_data;
	entry->dest = cfg->dest_apicid;
	entry->vector = cfg->vector;
	send_cleanup_vector(cfg);

	return 0;
}
Esempio n. 9
0
/*
 * Re-target the irq to the specified CPU and enable the specified MMR located
 * on the specified blade to allow the sending of MSIs to the specified CPU.
 */
static void uv_domain_activate(struct irq_domain *domain,
			       struct irq_data *irq_data)
{
	uv_program_mmr(irqd_cfg(irq_data), irq_data->chip_data);
}