RE: [PATCH] Add IPIC MSI interrupt support
From: Li Tony <hidden>
Date: 2007-12-04 10:35:05
=20
-----Original Message----- From: Michael Ellerman [mailto:michael@ellerman.id.au]=20 Sent: 2007=C4=EA12=D4=C24=C8=D5 13:38 To: Li Tony Cc: Li Tony; Gala Kumar; linuxppc-dev Subject: Re: [PATCH] Add IPIC MSI interrupt support =20 On Mon, 2007-12-03 at 17:07 +0800, Li Li wrote:quoted
Hi Michael, =20 I emulate mpic to write this IPIC MSI routines. :) =20 =20quoted
quoted
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c=20b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 6048f1b..dbea34b 100644--- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c=20quoted
quoted
quoted
+ +#define ipic_msi_irq_to_hw(virq)=09((unsigned int)irq_map[virq].hwirq)quoted
quoted
=20 What's wrong with virq_to_hw() ? =20=20 viqr_to_hw is not __inline__.=20 Hmm, ok. The three places you use it you also take a spin=20 lock, so I'm not sure the function call's really going to=20 kill you performance wise. =20
I am not very sure about spin_lock influence. But maybe somebody will change the virq_to_hw implementation. I will take virq_to_hw instead.=20 I see that the virq_to_hw is do inline in 2.6.22. Why remove it?
quoted
quoted
quoted
+ +static void ipic_msi_compose_msg(struct ipic_msi *msi,=20int hwirq,quoted
quoted
quoted
+ struct=20msi_msg *msg)quoted
quoted
quoted
+{ + unsigned int srs; + unsigned int ibs; + + srs =3D hwirq / msi->int_per_msir; + ibs =3D hwirq - srs * msi->int_per_msir; + + msg->address_lo =3D msi->msi_addr_lo; + msg->address_hi =3D msi->msi_addr_hi; + msg->data =3D (srs << 5) | (ibs & 0x1F); + + pr_debug("%s: allocated srs: %d, ibs: %d\n", + __FUNCTION__, srs, ibs); + +} + +static int ipic_msi_setup_irqs(struct pci_dev *pdev, int nvec,=20 +int type) { + struct ipic_msi *msi =3D ipic_msi; + irq_hw_number_t hwirq; + unsigned int virq; + struct msi_desc *entry; + struct msi_msg msg; + + list_for_each_entry(entry, &pdev->msi_list, list) { + hwirq =3D ipic_msi_alloc_hwirqs(msi, 1); + if (hwirq < 0) { + pr_debug("%s: fail allocating=20msi interrupt\n",quoted
quoted
quoted
+ __FUNCTION__); + return hwirq; + } + + /* This hwirq belongs to the irq_host=20other than irq_host of IPICquoted
quoted
quoted
+ * So, it is independent to hwirq of IPIC */ + virq =3D irq_create_mapping(msi->irqhost, hwirq); + if (virq =3D=3D NO_IRQ) { + pr_debug("%s: fail mapping=20hwirq 0x%lx\n",quoted
quoted
quoted
+ __FUNCTION__, hwirq); + ipic_msi_free_hwirqs(msi, hwirq, 1); + return -ENOSPC; + } + set_irq_msi(virq, entry); + ipic_msi_compose_msg(msi, hwirq, &msg); + write_msi_msg(virq, &msg); + + hwirq++;=20 ^^^^ this looks like my bug=20 I have a question here. Do we support more MSI interrupts=20on ONE pci=20quoted
device?=20 I'm not sure what you mean? For MSI there is only one MSI per=20 device, but this code is used also for MSI-X which supports >=20 1 MSI per device. =20 Either way we shouldn't be incrementing hwirq by hand, it's=20 reassigned at the top of the loop. I think that's left over=20 from old code that allocated nvec hwirqs in a block and then=20 created virq mappings for each one, whereas the new code=20 allocates each hwirq separately. =20 cheers =20 -- Michael Ellerman OzLabs, IBM Australia Development Lab =20 wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) =20 We do not inherit the earth from our ancestors, we borrow it=20 from our children. - S.M.A.R.T Person =20