diff options
Diffstat (limited to 'drivers/parisc/iosapic.c')
| -rw-r--r-- | drivers/parisc/iosapic.c | 38 | 
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index e79e006eb9ab..9ee04b4b68bf 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -811,18 +811,28 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)  	return pcidev->irq;  } -static struct iosapic_info *first_isi = NULL; +static struct iosapic_info *iosapic_list;  #ifdef CONFIG_64BIT -int iosapic_serial_irq(int num) +int iosapic_serial_irq(struct parisc_device *dev)  { -	struct iosapic_info *isi = first_isi; -	struct irt_entry *irte = NULL;  /* only used if PAT PDC */ +	struct iosapic_info *isi; +	struct irt_entry *irte;  	struct vector_info *vi; -	int isi_line;	/* line used by device */ +	int cnt; +	int intin; + +	intin = (dev->mod_info >> 24) & 15;  	/* lookup IRT entry for isi/slot/pin set */ -	irte = &irt_cell[num]; +	for (cnt = 0; cnt < irt_num_entry; cnt++) { +		irte = &irt_cell[cnt]; +		if (COMPARE_IRTE_ADDR(irte, dev->mod0) && +		    irte->dest_iosapic_intin == intin) +			break; +	} +	if (cnt >= irt_num_entry) +		return 0; /* no irq found, force polling */  	DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",  		irte, @@ -834,11 +844,17 @@ int iosapic_serial_irq(int num)  		irte->src_seg_id,  		irte->dest_iosapic_intin,  		(u32) irte->dest_iosapic_addr); -	isi_line = irte->dest_iosapic_intin; + +	/* search for iosapic */ +	for (isi = iosapic_list; isi; isi = isi->isi_next) +		if (isi->isi_hpa == dev->mod0) +			break; +	if (!isi) +		return 0; /* no iosapic found, force polling */  	/* get vector info for this input line */ -	vi = isi->isi_vector + isi_line; -	DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", isi_line, vi); +	vi = isi->isi_vector + intin; +	DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", iosapic_intin, vi);  	/* If this IRQ line has already been setup, skip it */  	if (vi->irte) @@ -941,8 +957,8 @@ void *iosapic_register(unsigned long hpa)  		vip->irqline = (unsigned char) cnt;  		vip->iosapic = isi;  	} -	if (!first_isi) -		first_isi = isi; +	isi->isi_next = iosapic_list; +	iosapic_list = isi;  	return isi;  }  | 
