Re: [PATCH v3 7/9] pci: keystone SoC driver adapted to new irq API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Gustavo,

On Thursday 28 December 2017 05:26 PM, Gustavo Pimentel wrote:
> This patch adapts Keystone SoC specific driver to use the new interrupt api
> available in pcie-designware. A new callback was added to dw_pcie_host_ops
> to handle a specific Keystone function and msi_host_init callback is
> changed to simplify the access to pci data structure for keystone all SoC
> drivers that use the structure.
> 
> Signed-off-by: Gustavo Pimentel <gustavo.pimentel@xxxxxxxxxxxx>
> ---
> Change v1->v2:
> - Removed hardcoded num_vectors configuration (now it is done in the core driver by default)
> Change v2->v3:
> - 
> 
> 
> 
> 
> 
>  drivers/pci/dwc/pci-keystone-dw.c      | 88 ++--------------------------------
>  drivers/pci/dwc/pci-keystone.c         |  1 +
>  drivers/pci/dwc/pci-keystone.h         |  4 +-
>  drivers/pci/dwc/pci-layerscape.c       |  3 +-
>  drivers/pci/dwc/pcie-designware-host.c | 19 ++++++--
>  drivers/pci/dwc/pcie-designware.h      |  3 +-
>  6 files changed, 26 insertions(+), 92 deletions(-)
> 
> diff --git a/drivers/pci/dwc/pci-keystone-dw.c b/drivers/pci/dwc/pci-keystone-dw.c
> index 2fb20b8..4fe4ab3 100644
> --- a/drivers/pci/dwc/pci-keystone-dw.c
> +++ b/drivers/pci/dwc/pci-keystone-dw.c
> @@ -124,19 +124,15 @@ void ks_dw_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie, int offset)
>  	}
>  }
>  
> -static void ks_dw_pcie_msi_irq_ack(struct irq_data *d)
> +void ks_dw_pcie_msi_irq_ack(int irq, struct pcie_port *pp)
>  {
>  	u32 offset, reg_offset, bit_pos;
>  	struct keystone_pcie *ks_pcie;
> -	struct msi_desc *msi;
> -	struct pcie_port *pp;
>  	struct dw_pcie *pci;
>  
> -	msi = irq_data_get_msi_desc(d);
> -	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
>  	pci = to_dw_pcie_from_pp(pp);
>  	ks_pcie = to_keystone_pcie(pci);
> -	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
> +	offset = irq - irq_linear_revmap(pp->irq_domain, 0);
>  	update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
>  
>  	ks_dw_app_writel(ks_pcie, MSI0_IRQ_STATUS + (reg_offset << 4),
> @@ -166,85 +162,9 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)
>  			 BIT(bit_pos));
>  }
>  
> -static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)
> +int ks_dw_pcie_msi_host_init(struct dw_pcie *pci, struct msi_controller *chip)
>  {
> -	struct msi_desc *msi;
> -	struct pcie_port *pp;
> -	u32 offset;
> -
> -	msi = irq_data_get_msi_desc(d);
> -	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
> -	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
> -
> -	/* Mask the end point if PVM implemented */
> -	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> -		if (msi->msi_attrib.maskbit)
> -			pci_msi_mask_irq(d);
> -	}
> -
> -	ks_dw_pcie_msi_clear_irq(pp, offset);
> -}
> -
> -static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)
> -{
> -	struct msi_desc *msi;
> -	struct pcie_port *pp;
> -	u32 offset;
> -
> -	msi = irq_data_get_msi_desc(d);
> -	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
> -	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
> -
> -	/* Mask the end point if PVM implemented */
> -	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> -		if (msi->msi_attrib.maskbit)
> -			pci_msi_unmask_irq(d);
> -	}
> -
> -	ks_dw_pcie_msi_set_irq(pp, offset);
> -}
> -
> -static struct irq_chip ks_dw_pcie_msi_irq_chip = {
> -	.name = "Keystone-PCIe-MSI-IRQ",
> -	.irq_ack = ks_dw_pcie_msi_irq_ack,
> -	.irq_mask = ks_dw_pcie_msi_irq_mask,
> -	.irq_unmask = ks_dw_pcie_msi_irq_unmask,
> -};
> -
> -static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
> -			      irq_hw_number_t hwirq)
> -{
> -	irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip,
> -				 handle_level_irq);
> -	irq_set_chip_data(irq, domain->host_data);
> -
> -	return 0;
> -}
> -
> -static const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = {
> -	.map = ks_dw_pcie_msi_map,
> -};
> -
> -int ks_dw_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
> -{
> -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> -	struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
> -	struct device *dev = pci->dev;
> -	int i;
> -
> -	pp->irq_domain = irq_domain_add_linear(ks_pcie->msi_intc_np,
> -					MAX_MSI_IRQS,
> -					&ks_dw_pcie_msi_domain_ops,
> -					chip);
> -	if (!pp->irq_domain) {
> -		dev_err(dev, "irq domain init failed\n");
> -		return -ENXIO;
> -	}
> -
> -	for (i = 0; i < MAX_MSI_IRQS; i++)
> -		irq_create_mapping(pp->irq_domain, i);
> -
> -	return 0;
> +	return dw_pcie_allocate_domains(pci);
>  }
>  
>  void ks_dw_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie)
> diff --git a/drivers/pci/dwc/pci-keystone.c b/drivers/pci/dwc/pci-keystone.c
> index 5bee3af..76901fa 100644
> --- a/drivers/pci/dwc/pci-keystone.c
> +++ b/drivers/pci/dwc/pci-keystone.c
> @@ -297,6 +297,7 @@ static const struct dw_pcie_host_ops keystone_pcie_host_ops = {
>  	.msi_clear_irq = ks_dw_pcie_msi_clear_irq,
>  	.get_msi_addr = ks_dw_pcie_get_msi_addr,
>  	.msi_host_init = ks_dw_pcie_msi_host_init,
> +	.msi_irq_ack = ks_dw_pcie_msi_irq_ack,
>  	.scan_bus = ks_dw_pcie_v3_65_scan_bus,
>  };
>  
> diff --git a/drivers/pci/dwc/pci-keystone.h b/drivers/pci/dwc/pci-keystone.h
> index 30b7bc2..04e1366 100644
> --- a/drivers/pci/dwc/pci-keystone.h
> +++ b/drivers/pci/dwc/pci-keystone.h
> @@ -53,9 +53,9 @@ int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  		unsigned int devfn, int where, int size, u32 *val);
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie);
>  void ks_dw_pcie_initiate_link_train(struct keystone_pcie *ks_pcie);
> +void ks_dw_pcie_msi_irq_ack(int i, struct pcie_port *pp);
>  void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq);
>  void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq);
>  void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp);
> -int ks_dw_pcie_msi_host_init(struct pcie_port *pp,
> -		struct msi_controller *chip);
> +int ks_dw_pcie_msi_host_init(struct dw_pcie *pci, struct msi_controller *chip);
>  int ks_dw_pcie_link_up(struct dw_pcie *pci);
> diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c
> index 8f34c2f..cb9af93e3 100644
> --- a/drivers/pci/dwc/pci-layerscape.c
> +++ b/drivers/pci/dwc/pci-layerscape.c
> @@ -185,10 +185,9 @@ static int ls1021_pcie_host_init(struct pcie_port *pp)
>  	return ls_pcie_host_init(pp);
>  }
>  
> -static int ls_pcie_msi_host_init(struct pcie_port *pp,
> +static int ls_pcie_msi_host_init(struct dw_pcie *pci,
>  				 struct msi_controller *chip)
>  {
> -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  	struct device *dev = pci->dev;
>  	struct device_node *np = dev->of_node;
>  	struct device_node *msi_node;
> diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
> index 289d476..ee1c105 100644
> --- a/drivers/pci/dwc/pcie-designware-host.c
> +++ b/drivers/pci/dwc/pcie-designware-host.c
> @@ -66,8 +66,20 @@ static void dw_msi_unmask_irq(struct irq_data *d)
>  	irq_chip_unmask_parent(d);
>  }
>  
> +static void dw_pci_ack_irq(struct irq_data *d)
> +{
> +	struct msi_desc *msi = irq_data_get_msi_desc(d);
> +	struct pcie_port *pp;
> +
> +	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
> +
> +	if (pp->ops->msi_irq_ack)
> +		pp->ops->msi_irq_ack(d->irq, pp);
> +}
> +
>  static struct irq_chip dw_pcie_msi_irq_chip = {
>  	.name = "PCI-MSI",
> +	.irq_ack = dw_pci_ack_irq,
>  	.irq_mask = dw_msi_mask_irq,
>  	.irq_unmask = dw_msi_unmask_irq,
>  };
> @@ -234,7 +246,7 @@ static int dw_pcie_irq_domain_alloc(struct irq_domain *domain,
>  	for (i = 0; i < nr_irqs; i++)
>  		irq_domain_set_info(domain, virq + i, bit + i,
>  				    &dw_pci_msi_bottom_irq_chip,
> -				    domain->host_data, handle_simple_irq,
> +				    domain->host_data, handle_level_irq,
>  				    NULL, NULL);
>  
>  	return 0;
> @@ -619,11 +631,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  			if (ret)
>  				goto error;
>  
> -			irq_set_chained_handler_and_data(pci->pp.msi_irq,
> +			if (pp->msi_irq)
> +				irq_set_chained_handler_and_data(pp->msi_irq,
>  							 dw_chained_msi_isr,
>  							 pci);
>  		} else {
> -			ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip);
> +			ret = pp->ops->msi_host_init(pci, &dw_pcie_msi_chip);
>  			if (ret < 0)
>  				goto error;
>  		}
> diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
> index 6178251..5294352 100644
> --- a/drivers/pci/dwc/pcie-designware.h
> +++ b/drivers/pci/dwc/pcie-designware.h
> @@ -145,7 +145,8 @@ struct dw_pcie_host_ops {
>  	u32 (*get_msi_data)(struct pcie_port *pp, int pos);
>  	void (*scan_bus)(struct pcie_port *pp);
>  	void (*set_num_vectors)(struct pcie_port *pp);
> -	int (*msi_host_init)(struct pcie_port *pp, struct msi_controller *chip);
> +	int (*msi_host_init)(struct dw_pcie *pci, struct msi_controller *chip);

I'd prefer the signature is maintained since msi_host_init being a host
specific callback, it makes sense to have "struct pcie_port *pp".

Thanks
Kishon



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux