On 08/05/17 15:40, Joao Pinto wrote: > Às 11:59 AM de 5/8/2017, Marc Zyngier escreveu: >> On 08/05/17 11:24, Joao Pinto wrote: >>> Às 11:22 AM de 5/8/2017, Marc Zyngier escreveu: >>>> On 08/05/17 10:59, Joao Pinto wrote: >>>>> Às 3:57 PM de 5/5/2017, Marc Zyngier escreveu: >>>>>> Joao, >>>>>> >>>>>> On 05/05/17 15:11, Joao Pinto wrote: >>>>>>> Hello, >>>>>>> I am currently adding the support for both MSI and MSI-x in pcie-designware and >>>>>>> I am now facing a dificulty. >>>>>>> >>>>>>> My test endpoint is a USB 3.1 MSI / MSI-X capable and I tested that with >>>>>>> the changes introduced by this patch we are able to enable MSI and MSI-X >>>>>>> in this endpoint (depends on the usage of the MSI_FLAG_PCI_MSIX flag). >>>>>>> >>>>>>> The problem I am facing now is that Intc for the USB 3.1 Endpoint is completely >>>>>>> bogus (524288) when it should be 1, and so I am not receiving any interrupts >>>>>>> from the endpoint. >>>>>> >>>>>> It is not bogus at all. It is computed from the PCI requester ID in >>>>>> pci_msi_domain_calc_hwirq. What you're seeing is the PCI/MDI domain >>>>>> view of that interrupt, which is completely virtual. >>>>>> >>>>>> The real thing happens in your own irqdomain, where the hwirq for IRQ46 >>>>>> is probably 1 (only you can know that). As for why it doesn't work, see >>>>>> below: >>>>>> >>>>>>> >>>>>>> I would apreciate that more experienced people in this interrupt subject could >>>>>>> give me an hint. >>>> >>>> [...] >>>> >>>>> Yep makes perfectly sense and thanks for clearing the Domains :), I understood >>>>> them now. >>>> >>>> I guess that you have your MSI controller working with MSI-X now? >>> >>> I started working one hour ago and still putting some subjects in order, I am >>> going to return to PCI in a bit. I will keep you updated. I thought you were in >>> US Pacific timezone. >> >> I'm firmly rooted in BST! ;-) >> >> M. >> > > You were right, it was missing the bottom part related to the PCie DW IP: > > static void dw_pci_bottom_mask(struct irq_data *data) > { > struct dw_pcie *pci = irq_data_get_irq_chip_data(data); > struct pcie_port *pp = &pci->pp; > unsigned int res, bit, val; > > res = (data->hwirq / 32) * 12; > bit = data->hwirq % 32; > > dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); > val &= ~(1 << bit); > dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); be careful: you have a horrible race here, where another CPU try to mask another MSI at the same time. Any form of RMW should be guarded by a spinlock. > } > > static void dw_pci_bottom_unmask(struct irq_data *data) > { > struct dw_pcie *pci = irq_data_get_irq_chip_data(data); > struct pcie_port *pp = &pci->pp; > unsigned int res, bit, val; > > res = (data->hwirq / 32) * 12; > bit = data->hwirq % 32; > > dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); > val |= 1 << bit; > dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); Same here. Also, you could perfectly replace the read with a variable that caches the most recent value (as there should be no other code changing this register). > } > > static struct irq_chip dw_pci_msi_bottom_irq_chip = { > .name = "DW MSI", > .irq_compose_msi_msg = dw_pci_compose_msi_msg, > .irq_set_affinity = dw_pci_msi_set_affinity, > .irq_mask = dw_pci_bottom_mask, > .irq_unmask = dw_pci_bottom_unmask, > }; > > > With these 2 functions I was able to perform test with MSI and with MSI-X > Endpoints. I am goingo to clean this up and check the compatibility with other > SoC drivers and send a patch soon. > > Thanks for the help Marc! No worries. Cheers, M. -- Jazz is not dead. It just smells funny...