lkml.org 
[lkml]   [2018]   [Jun]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectRe: [PATCH 2/6] PCI: iproc: Add INTx support with better modeling
    From
    Date


    On 6/12/2018 1:52 AM, poza@codeaurora.org wrote:
    > On 2018-05-30 03:28, Ray Jui wrote:
    >> Add PCIe legacy interrupt INTx support to the iProc PCIe driver by
    >> modeling it with its own IRQ domain. All 4 interrupts INTA, INTB, INTC,
    >> INTD share the same interrupt line connected to the GIC in the system,
    >> while the status of each INTx can be obtained through the INTX CSR
    >> register
    >>
    >> Signed-off-by: Ray Jui <ray.jui@broadcom.com>
    >> ---
    >>  drivers/pci/host/pcie-iproc-platform.c |  2 +
    >>  drivers/pci/host/pcie-iproc.c          | 95
    >> +++++++++++++++++++++++++++++++++-
    >>  drivers/pci/host/pcie-iproc.h          |  6 +++
    >>  3 files changed, 101 insertions(+), 2 deletions(-)
    >>
    >> diff --git a/drivers/pci/host/pcie-iproc-platform.c
    >> b/drivers/pci/host/pcie-iproc-platform.c
    >> index e764a2a..7a51e6c 100644
    >> --- a/drivers/pci/host/pcie-iproc-platform.c
    >> +++ b/drivers/pci/host/pcie-iproc-platform.c
    >> @@ -70,6 +70,8 @@ static int iproc_pcie_pltfm_probe(struct
    >> platform_device *pdev)
    >>      }
    >>      pcie->base_addr = reg.start;
    >>
    >> +    pcie->irq = platform_get_irq(pdev, 0);
    >> +
    >>      if (of_property_read_bool(np, "brcm,pcie-ob")) {
    >>          u32 val;
    >>
    >> diff --git a/drivers/pci/host/pcie-iproc.c
    >> b/drivers/pci/host/pcie-iproc.c
    >> index 14f374d..0bd2c14 100644
    >> --- a/drivers/pci/host/pcie-iproc.c
    >> +++ b/drivers/pci/host/pcie-iproc.c
    >> @@ -14,6 +14,7 @@
    >>  #include <linux/delay.h>
    >>  #include <linux/interrupt.h>
    >>  #include <linux/irqchip/arm-gic-v3.h>
    >> +#include <linux/irqchip/chained_irq.h>
    >>  #include <linux/platform_device.h>
    >>  #include <linux/of_address.h>
    >>  #include <linux/of_pci.h>
    >> @@ -264,6 +265,7 @@ enum iproc_pcie_reg {
    >>
    >>      /* enable INTx */
    >>      IPROC_PCIE_INTX_EN,
    >> +    IPROC_PCIE_INTX_CSR,
    >>
    >>      /* outbound address mapping */
    >>      IPROC_PCIE_OARR0,
    >> @@ -305,6 +307,7 @@ static const u16 iproc_pcie_reg_paxb_bcma[] = {
    >>      [IPROC_PCIE_CFG_ADDR]        = 0x1f8,
    >>      [IPROC_PCIE_CFG_DATA]        = 0x1fc,
    >>      [IPROC_PCIE_INTX_EN]        = 0x330,
    >> +    [IPROC_PCIE_INTX_CSR]        = 0x334,
    >>      [IPROC_PCIE_LINK_STATUS]    = 0xf0c,
    >>  };
    >>
    >> @@ -316,6 +319,7 @@ static const u16 iproc_pcie_reg_paxb[] = {
    >>      [IPROC_PCIE_CFG_ADDR]        = 0x1f8,
    >>      [IPROC_PCIE_CFG_DATA]        = 0x1fc,
    >>      [IPROC_PCIE_INTX_EN]        = 0x330,
    >> +    [IPROC_PCIE_INTX_CSR]        = 0x334,
    >>      [IPROC_PCIE_OARR0]        = 0xd20,
    >>      [IPROC_PCIE_OMAP0]        = 0xd40,
    >>      [IPROC_PCIE_OARR1]        = 0xd28,
    >> @@ -332,6 +336,7 @@ static const u16 iproc_pcie_reg_paxb_v2[] = {
    >>      [IPROC_PCIE_CFG_ADDR]        = 0x1f8,
    >>      [IPROC_PCIE_CFG_DATA]        = 0x1fc,
    >>      [IPROC_PCIE_INTX_EN]        = 0x330,
    >> +    [IPROC_PCIE_INTX_CSR]        = 0x334,
    >>      [IPROC_PCIE_OARR0]        = 0xd20,
    >>      [IPROC_PCIE_OMAP0]        = 0xd40,
    >>      [IPROC_PCIE_OARR1]        = 0xd28,
    >> @@ -782,9 +787,90 @@ static int iproc_pcie_check_link(struct
    >> iproc_pcie *pcie)
    >>      return link_is_active ? 0 : -ENODEV;
    >>  }
    >>
    >> -static void iproc_pcie_enable(struct iproc_pcie *pcie)
    >> +static int iproc_pcie_intx_map(struct irq_domain *domain, unsigned
    >> int irq,
    >> +                   irq_hw_number_t hwirq)
    >>  {
    >> +    irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
    >> +    irq_set_chip_data(irq, domain->host_data);
    >> +
    >> +    return 0;
    >> +}
    >> +
    >> +static const struct irq_domain_ops intx_domain_ops = {
    >> +    .map = iproc_pcie_intx_map,
    >> +};
    >> +
    >> +static void iproc_pcie_isr(struct irq_desc *desc)
    >> +{
    >> +    struct irq_chip *chip = irq_desc_get_chip(desc);
    >> +    struct iproc_pcie *pcie;
    >> +    struct device *dev;
    >> +    unsigned long status;
    >> +    u32 bit, virq;
    >> +
    >> +    chained_irq_enter(chip, desc);
    >> +    pcie = irq_desc_get_handler_data(desc);
    >> +    dev = pcie->dev;
    >> +
    >> +    /* go through INTx A, B, C, D until all interrupts are handled */
    >> +    while ((status = iproc_pcie_read_reg(pcie, IPROC_PCIE_INTX_CSR) &
    >> +        SYS_RC_INTX_MASK) != 0) {
    >> +        for_each_set_bit(bit, &status, PCI_NUM_INTX) {
    >> +            virq = irq_find_mapping(pcie->irq_domain, bit + 1);
    >> +            if (virq)
    >> +                generic_handle_irq(virq);
    >> +            else
    >> +                dev_err(dev, "unexpected INTx%u\n", bit);
    >> +        }
    >> +    }
    >> +
    >
    > Are these level or edge interrupts ? although I see DT says: IRQ_TYPE_NONE

    DT entries should be fixed to trigger on level HIGH like Florian and I
    discussed on the mailing list yesterday. It looks like you are missing a
    lot of discussions on the mailing list. Could you please help to make
    sure you read all the existing discussions when commenting on a patch?

    > do you not need to clear interrupt status bits in IPROC_PCIE_INTX_CSR ?
    >

    RO

    \
     
     \ /
      Last update: 2018-06-12 19:07    [W:2.581 / U:0.192 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site