Exemplo n.º 1
0
/*
 * Hypertransport interrupt support
 */
static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
{
	struct ht_irq_msg msg;

	fetch_ht_irq_msg(irq, &msg);

	msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
	msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);

	msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
	msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);

	write_ht_irq_msg(irq, &msg);
}
Exemplo n.º 2
0
int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
{
	struct irq_cfg *cfg;
	struct ht_irq_msg msg;
	unsigned dest;
	int err;

	if (disable_apic)
		return -ENXIO;

	cfg = irq_cfg(irq);
	err = assign_irq_vector(irq, cfg, apic->target_cpus());
	if (err)
		return err;

	err = apic->cpu_mask_to_apicid_and(cfg->domain,
					   apic->target_cpus(), &dest);
	if (err)
		return err;

	msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);

	msg.address_lo =
		HT_IRQ_LOW_BASE |
		HT_IRQ_LOW_DEST_ID(dest) |
		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, &msg);

	irq_set_chip_and_handler_name(irq, &ht_irq_chip,
				      handle_edge_irq, "edge");

	dev_dbg(&dev->dev, "irq %d for HT\n", irq);

	return 0;
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
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;
}