Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 735e60f4 authored by Mark Maule's avatar Mark Maule Committed by Tony Luck
Browse files

[IA64-SGI] abstract force_interrupt() mechanism



Altix patch to abstract the force_interrupt() mechanism away from the
pcibr provider.

Signed-off-by: default avatarMark Maule <maule@sgi.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 89963d16
Loading
Loading
Loading
Loading
+28 −22
Original line number Diff line number Diff line
@@ -317,6 +317,16 @@ void sn_irq_unfixup(struct pci_dev *pci_dev)
	pci_dev_put(pci_dev);
}

static inline void
sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info)
{
	struct sn_pcibus_provider *pci_provider;

	pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type];
	if (pci_provider && pci_provider->force_interrupt)
		(*pci_provider->force_interrupt)(sn_irq_info);
}

static void force_interrupt(int irq)
{
	struct sn_irq_info *sn_irq_info;
@@ -325,11 +335,9 @@ static void force_interrupt(int irq)
		return;

	rcu_read_lock();
	list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) {
		if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
		    (sn_irq_info->irq_bridge != NULL))
			pcibr_force_interrupt(sn_irq_info);
	}
	list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list)
		sn_call_force_intr_provider(sn_irq_info);

	rcu_read_unlock();
}

@@ -351,6 +359,14 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
	struct pcidev_info *pcidev_info;
	struct pcibus_info *pcibus_info;

	/*
	 * Bridge types attached to TIO (anything but PIC) do not need this WAR
	 * since they do not target Shub II interrupt registers.  If that
	 * ever changes, this check needs to accomodate.
	 */
	if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_PIC)
		return;

	pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
	if (!pcidev_info)
		return;
@@ -377,16 +393,12 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
		break;
	}
	if (!test_bit(irr_bit, &irr_reg)) {
		if (!test_bit(irq, pda->sn_soft_irr)) {
		if (!test_bit(irq, pda->sn_in_service_ivecs)) {
			regval &= 0xff;
			if (sn_irq_info->irq_int_bit & regval &
			    sn_irq_info->irq_last_intr) {
					regval &=
					    ~(sn_irq_info->
					      irq_int_bit & regval);
					pcibr_force_interrupt(sn_irq_info);
				}
				regval &= ~(sn_irq_info->irq_int_bit & regval);
				sn_call_force_intr_provider(sn_irq_info);
			}
		}
	}
@@ -404,12 +416,6 @@ void sn_lb_int_war_check(void)
	rcu_read_lock();
	for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) {
		list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) {
			/*
			 * Only call for PCI bridges that are fully
			 * initialized.
			 */
			if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
			    (sn_irq_info->irq_bridge != NULL))
			sn_check_intr(i, sn_irq_info);
		}
	}
+4 −0
Original line number Diff line number Diff line
@@ -178,6 +178,9 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info)
	struct pcibus_info *pcibus_info;
	int bit = sn_irq_info->irq_int_bit;

	if (! sn_irq_info->irq_bridge)
		return;

	pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
	if (pcidev_info) {
		pcibus_info =
@@ -222,6 +225,7 @@ struct sn_pcibus_provider pcibr_provider = {
	.dma_map_consistent = pcibr_dma_map_consistent,
	.dma_unmap = pcibr_dma_unmap,
	.bus_fixup = pcibr_bus_fixup,
	.force_interrupt = pcibr_force_interrupt
};

int
+1 −0
Original line number Diff line number Diff line
@@ -657,6 +657,7 @@ static struct sn_pcibus_provider tioca_pci_interfaces = {
	.dma_map_consistent = tioca_dma_map,
	.dma_unmap = tioca_dma_unmap,
	.bus_fixup = tioca_bus_fixup,
	.force_interrupt = NULL
};

/**
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct sn_pcibus_provider {
	dma_addr_t	(*dma_map_consistent)(struct pci_dev *, unsigned long, size_t);
	void		(*dma_unmap)(struct pci_dev *, dma_addr_t, int);
	void *		(*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *);
 	void		(*force_interrupt)(struct sn_irq_info *);
};

extern struct sn_pcibus_provider *sn_pci_provider[];
+0 −1
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ typedef struct pda_s {
	unsigned long pio_write_status_val;
	volatile unsigned long *pio_shub_war_cam_addr;

	unsigned long	sn_soft_irr[4];
	unsigned long	sn_in_service_ivecs[4];
	int		sn_lb_int_war_ticks;
	int		sn_last_irq;