Re: [PATCH v3] PCI: hv: Detect and fix Hyper-V PCI domain number collision

2019-08-13 Thread Lorenzo Pieralisi
On Mon, Aug 12, 2019 at 06:20:53PM +, Haiyang Zhang wrote:
> Currently in Azure cloud, for passthrough devices including GPU, the host
> sets the device instance ID's bytes 8 - 15 to a value derived from the host
> HWID, which is the same on all devices in a VM. So, the device instance
> ID's bytes 8 and 9 provided by the host are no longer unique. This can
> cause device passthrough to VMs to fail because the bytes 8 and 9 are used
> as PCI domain number. Collision of domain numbers will cause the second
> device with the same domain number fail to load.
> 
> As recommended by Azure host team, the bytes 4, 5 have more uniqueness
> (info entropy) than bytes 8, 9. So now we use bytes 4, 5 as the PCI domain
> numbers. On older hosts, bytes 4, 5 can also be used -- no backward
> compatibility issues here. The chance of collision is greatly reduced. In
> the rare cases of collision, we will detect and find another number that is
> not in use.

I have not explained what I meant correctly. This patch fixes an
issue and the "find another number" fallback can be also applied
to the current kernel without changing the bytes you use for
domain numbers.

This patch would leave old kernels susceptible to breakage.

Again, I have no Azure knowledge but it seems better to me to
add a fallback "find another number" allocation on top of mainline
and send it to stable kernels. Then we can add another patch to
change the bytes you use to reduce the number of collision.

Please let me know what you think, thanks.

Lorenzo

> Suggested-by: Michael Kelley 
> Signed-off-by: Haiyang Zhang 
> Acked-by: Sasha Levin 
> ---
>  drivers/pci/controller/pci-hyperv.c | 92 
> +++--
>  1 file changed, 79 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-hyperv.c 
> b/drivers/pci/controller/pci-hyperv.c
> index 40b6254..4f3d97e 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -2510,6 +2510,48 @@ static void put_hvpcibus(struct hv_pcibus_device *hbus)
>   complete(>remove_event);
>  }
>  
> +#define HVPCI_DOM_MAP_SIZE (64 * 1024)
> +static DECLARE_BITMAP(hvpci_dom_map, HVPCI_DOM_MAP_SIZE);
> +
> +/*
> + * PCI domain number 0 is used by emulated devices on Gen1 VMs, so define 0
> + * as invalid for passthrough PCI devices of this driver.
> + */
> +#define HVPCI_DOM_INVALID 0
> +
> +/**
> + * hv_get_dom_num() - Get a valid PCI domain number
> + * Check if the PCI domain number is in use, and return another number if
> + * it is in use.
> + *
> + * @dom: Requested domain number
> + *
> + * return: domain number on success, HVPCI_DOM_INVALID on failure
> + */
> +static u16 hv_get_dom_num(u16 dom)
> +{
> + unsigned int i;
> +
> + if (test_and_set_bit(dom, hvpci_dom_map) == 0)
> + return dom;
> +
> + for_each_clear_bit(i, hvpci_dom_map, HVPCI_DOM_MAP_SIZE) {
> + if (test_and_set_bit(i, hvpci_dom_map) == 0)
> + return i;
> + }
> +
> + return HVPCI_DOM_INVALID;
> +}
> +
> +/**
> + * hv_put_dom_num() - Mark the PCI domain number as free
> + * @dom: Domain number to be freed
> + */
> +static void hv_put_dom_num(u16 dom)
> +{
> + clear_bit(dom, hvpci_dom_map);
> +}
> +
>  /**
>   * hv_pci_probe() - New VMBus channel probe, for a root PCI bus
>   * @hdev:VMBus's tracking struct for this root PCI bus
> @@ -2521,6 +2563,7 @@ static int hv_pci_probe(struct hv_device *hdev,
>   const struct hv_vmbus_device_id *dev_id)
>  {
>   struct hv_pcibus_device *hbus;
> + u16 dom_req, dom;
>   int ret;
>  
>   /*
> @@ -2535,19 +2578,34 @@ static int hv_pci_probe(struct hv_device *hdev,
>   hbus->state = hv_pcibus_init;
>  
>   /*
> -  * The PCI bus "domain" is what is called "segment" in ACPI and
> -  * other specs.  Pull it from the instance ID, to get something
> -  * unique.  Bytes 8 and 9 are what is used in Windows guests, so
> -  * do the same thing for consistency.  Note that, since this code
> -  * only runs in a Hyper-V VM, Hyper-V can (and does) guarantee
> -  * that (1) the only domain in use for something that looks like
> -  * a physical PCI bus (which is actually emulated by the
> -  * hypervisor) is domain 0 and (2) there will be no overlap
> -  * between domains derived from these instance IDs in the same
> -  * VM.
> +  * The PCI bus "domain" is what is called "segment" in ACPI and other
> +  * specs. Pull it from the instance ID, to get something usually
> +  * unique. In rare cases of collision, we will find out another number
> +  * not in use.
> +  *
> +  * Note that, since this code only runs in a Hyper-V VM, Hyper-V
> +  * together with this guest driver can guarantee that (1) The only
> +  * domain used by Gen1 VMs for something that looks like a physical
> +  * PCI bus (which is actually emulated by the hypervisor) is domain 0.
> + 

Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.

2019-08-13 Thread Lorenzo Pieralisi
git log --oneline --follow drivers/pci/controller/dwc/pci-layerscape.c

Do you see any commit with a $SUBJECT ending with a period ?

There is not. So remove it from yours too.

On Tue, Aug 13, 2019 at 02:28:39PM +0800, Xiaowei Bao wrote:
> The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1
> is 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware,
> so set the bar_fixed_64bit with 0x14.
> 
> Signed-off-by: Xiaowei Bao 
> ---
> v2:
>  - Replace value 0x14 with a macro.
> v3:
>  - No change.
> v4:
>  - send the patch again with '--to'.
> v5:
>  - fix the commit message.
> 
>  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
>  1 file changed, 1 insertion(+)

scripts/get_maintainer.pl -f drivers/pci/controller/dwc/pci-layerscape-ep.c
Now, with the output you get justify all the people you send this email
to.

So, again, trim the CC list and it is the last time I tell you.

Before sending patches on mailing lists use git --dry-run to check
the emails you are sending.

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
> b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index be61d96..ca9aa45 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -44,6 +44,7 @@ static const struct pci_epc_features ls_pcie_epc_features = 
> {
>   .linkup_notifier = false,
>   .msi_capable = true,
>   .msix_capable = false,
> + .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
>  };
>  
>  static const struct pci_epc_features*
> -- 
> 2.9.5
> 


Re: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.

2019-08-13 Thread Lorenzo Pieralisi
You should fix your email client set-up to avoid sticking an [EXT]
tag to your emails $SUBJECT.

On Tue, Aug 13, 2019 at 07:39:48AM +, Xiaowei Bao wrote:
> 
> 
> > -Original Message-
> > From: Kishon Vijay Abraham I 
> > Sent: 2019年8月13日 15:30
> > To: Xiaowei Bao ; lorenzo.pieral...@arm.com;
> > bhelg...@google.com; M.h. Lian ; Mingkai Hu
> > ; Roy Zang ;
> > l.st...@pengutronix.de; tpie...@impinj.com; Leonard Crestez
> > ; andrew.smir...@gmail.com;
> > yue.w...@amlogic.com; hayashi.kunih...@socionext.com;
> > d...@amazon.co.uk; jon...@amazon.com; linux-...@vger.kernel.org;
> > linux-kernel@vger.kernel.org; linuxppc-...@lists.ozlabs.org;
> > linux-arm-ker...@lists.infradead.org
> > Subject: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit
> > property in EP driver.
> > 
> > Caution: EXT Email

See above, this "Caution" stuff should disappear.

Also, quoting the email header is useless, please configure your email
client to remove it.

Thanks,
Lorenzo

> > On 13/08/19 11:58 AM, Xiaowei Bao wrote:
> > > The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1 is
> > > 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware, so set
> > > the bar_fixed_64bit with 0x14.
> > >
> > > Signed-off-by: Xiaowei Bao 
> > 
> > Acked-by: Kishon Vijay Abraham I 
> > > ---
> > > v2:
> > >  - Replace value 0x14 with a macro.
> > > v3:
> > >  - No change.
> > > v4:
> > >  - send the patch again with '--to'.
> > > v5:
> > >  - fix the commit message.
> > >
> > >  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > index be61d96..ca9aa45 100644
> > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > @@ -44,6 +44,7 @@ static const struct pci_epc_features
> > ls_pcie_epc_features = {
> > >   .linkup_notifier = false,
> > >   .msi_capable = true,
> > >   .msix_capable = false,
> > > + .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> > >  };
> > >
> > >  static const struct pci_epc_features*
> I check other platforms, it is 'static const struct pci_epc_features', I can 
> get the correct 
> Value use this define way in pci-epf-test.c file.
> > >


Re: [PATCH v3 6/8] PCI: al: Add support for DW based driver type

2019-08-12 Thread Lorenzo Pieralisi
"PCI: dwc: al: Add support for DW based driver type"

Make $SUBJECT compliant with other host controllers patches.

On Tue, Jul 23, 2019 at 12:27:09PM +0300, Jonathan Chocron wrote:
> This driver is DT based and utilizes the DesignWare APIs.
> It allows using a smaller ECAM range for a larger bus range -
> usually an entire bus uses 1MB of address space, but the driver
> can use it for a larger number of buses.

I would appreciate if you can add a simple explanation of
the mechanism for completeness.

AFAIU, with ACPI you don't support all these variants.

> All link initializations are handled by the boot FW.
> 
> Signed-off-by: Jonathan Chocron 
> ---
>  drivers/pci/controller/dwc/Kconfig   |  12 +
>  drivers/pci/controller/dwc/pcie-al.c | 367 +++
>  2 files changed, 379 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/Kconfig 
> b/drivers/pci/controller/dwc/Kconfig
> index 6ea778ae4877..3c6094cbcc3b 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -230,4 +230,16 @@ config PCIE_UNIPHIER
> Say Y here if you want PCIe controller support on UniPhier SoCs.
> This driver supports LD20 and PXs3 SoCs.
>  
> +config PCIE_AL
> + bool "Amazon Annapurna Labs PCIe controller"
> + depends on OF && (ARM64 || COMPILE_TEST)
> + depends on PCI_MSI_IRQ_DOMAIN
> + select PCIE_DW_HOST
> + help
> +   Say Y here to enable support of the Amazon's Annapurna Labs PCIe
> +   controller IP on Amazon SoCs. The PCIe controller uses the DesignWare
> +   core plus Annapurna Labs proprietary hardware wrappers. This is
> +   required only for DT-based platforms. ACPI platforms with the
> +   Annapurna Labs PCIe controller don't need to enable this.
> +
>  endmenu
> diff --git a/drivers/pci/controller/dwc/pcie-al.c 
> b/drivers/pci/controller/dwc/pcie-al.c
> index 3ab58f0584a8..3ffdd3c97617 100644
> --- a/drivers/pci/controller/dwc/pcie-al.c
> +++ b/drivers/pci/controller/dwc/pcie-al.c
> @@ -91,3 +91,370 @@ struct pci_ecam_ops al_pcie_ops = {
>  };
>  
>  #endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */
> +
> +#ifdef CONFIG_PCIE_AL
> +
> +#include 
> +#include "pcie-designware.h"
> +
> +#define AL_PCIE_REV_ID_2 2
> +#define AL_PCIE_REV_ID_3 3
> +#define AL_PCIE_REV_ID_4 4
> +
> +#define AXI_BASE_OFFSET  0x0
> +
> +#define DEVICE_ID_OFFSET 0x16c
> +
> +#define DEVICE_REV_ID0x0
> +#define DEVICE_REV_ID_DEV_ID_MASKGENMASK(31, 16)
> +
> +#define DEVICE_REV_ID_DEV_ID_X4  0
> +#define DEVICE_REV_ID_DEV_ID_X8  2
> +#define DEVICE_REV_ID_DEV_ID_X16 4
> +
> +#define OB_CTRL_REV1_2_OFFSET0x0040
> +#define OB_CTRL_REV3_5_OFFSET0x0030
> +
> +#define CFG_TARGET_BUS   0x0
> +#define CFG_TARGET_BUS_MASK_MASK GENMASK(7, 0)
> +#define CFG_TARGET_BUS_BUSNUM_MASK   GENMASK(15, 8)
> +
> +#define CFG_CONTROL  0x4
> +#define CFG_CONTROL_SUBBUS_MASK  GENMASK(15, 8)
> +#define CFG_CONTROL_SEC_BUS_MASK GENMASK(23, 16)
> +
> +struct al_pcie_reg_offsets {
> + unsigned int ob_ctrl;
> +};
> +
> +struct al_pcie_target_bus_cfg {
> + u8 reg_val;
> + u8 reg_mask;
> + u8 ecam_mask;
> +};
> +
> +struct al_pcie {
> + struct dw_pcie *pci;
> + void __iomem *controller_base; /* base of PCIe unit (not DW core) */
> + struct device *dev;
> + resource_size_t ecam_size;
> + unsigned int controller_rev_id;
> + struct al_pcie_reg_offsets reg_offsets;
> + struct al_pcie_target_bus_cfg target_bus_cfg;
> +};
> +
> +#define PCIE_ECAM_DEVFN(x)   (((x) & 0xff) << 12)
> +
> +#define to_al_pcie(x)dev_get_drvdata((x)->dev)
> +
> +static inline u32 al_pcie_controller_readl(struct al_pcie *pcie, u32 offset)
> +{
> + return readl(pcie->controller_base + offset);
> +}
> +
> +static inline void al_pcie_controller_writel(struct al_pcie *pcie, u32 
> offset,
> +  u32 val)
> +{
> + writel(val, pcie->controller_base + offset);
> +}

You should be able to use the read/write{_relaxed} API.

> +
> +static int al_pcie_rev_id_get(struct al_pcie *pcie, unsigned int *rev_id)
> +{
> + u32 dev_rev_id_val;
> + u32 dev_id_val;
> +
> + dev_rev_id_val = al_pcie_controller_readl(pcie, AXI_BASE_OFFSET +
> +   DEVICE_ID_OFFSET +
> +   DEVICE_REV_ID);
> + dev_id_val = FIELD_GET(DEVICE_REV_ID_DEV_ID_MASK, dev_rev_id_val);
> +
> + switch (dev_id_val) {
> + case DEVICE_REV_ID_DEV_ID_X4:
> + *rev_id = AL_PCIE_REV_ID_2;
> + break;
> + case DEVICE_REV_ID_DEV_ID_X8:
> + *rev_id = AL_PCIE_REV_ID_3;
> + break;
> + case DEVICE_REV_ID_DEV_ID_X16:
> + *rev_id = AL_PCIE_REV_ID_4;
> + break;
> + default:
> +

Re: [PATCH v2] PCI: hv: Detect and fix Hyper-V PCI domain number collision

2019-08-12 Thread Lorenzo Pieralisi
On Tue, Aug 06, 2019 at 11:52:11PM +, Haiyang Zhang wrote:
> Currently in Azure cloud, for passthrough devices including GPU, the
> host sets the device instance ID's bytes 8 - 15 to a value derived from
> the host HWID, which is the same on all devices in a VM. So, the device
> instance ID's bytes 8 and 9 provided by the host are no longer unique.
> 
> This can cause device passthrough to VMs to fail because the bytes 8 and
> 9 is used as PCI domain number. So, as recommended by Azure host team,
> we now use the bytes 4 and 5 which usually contain unique numbers as PCI
> domain. The chance of collision is greatly reduced. In the rare cases of
> collision, we will detect and find another number that is not in use.

This is not clear at all. Why "finding another number" is fine with
this patch while it is not with current kernel code ? Also does this
have backward compatibility issues ?

I do not understand if a collision is a problem or not from the
log above.

> Thanks to Michael Kelley  for proposing this idea.

Add it as Suggested-by: tag.

Thanks,
Lorenzo

> Signed-off-by: Haiyang Zhang 
> Acked-by: Sasha Levin 
> ---
>  drivers/pci/controller/pci-hyperv.c | 92 
> +++--
>  1 file changed, 79 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-hyperv.c 
> b/drivers/pci/controller/pci-hyperv.c
> index 40b6254..4f3d97e 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -2510,6 +2510,48 @@ static void put_hvpcibus(struct hv_pcibus_device *hbus)
>   complete(>remove_event);
>  }
>  
> +#define HVPCI_DOM_MAP_SIZE (64 * 1024)
> +static DECLARE_BITMAP(hvpci_dom_map, HVPCI_DOM_MAP_SIZE);
> +
> +/*
> + * PCI domain number 0 is used by emulated devices on Gen1 VMs, so define 0
> + * as invalid for passthrough PCI devices of this driver.
> + */
> +#define HVPCI_DOM_INVALID 0
> +
> +/**
> + * hv_get_dom_num() - Get a valid PCI domain number
> + * Check if the PCI domain number is in use, and return another number if
> + * it is in use.
> + *
> + * @dom: Requested domain number
> + *
> + * return: domain number on success, HVPCI_DOM_INVALID on failure
> + */
> +static u16 hv_get_dom_num(u16 dom)
> +{
> + unsigned int i;
> +
> + if (test_and_set_bit(dom, hvpci_dom_map) == 0)
> + return dom;
> +
> + for_each_clear_bit(i, hvpci_dom_map, HVPCI_DOM_MAP_SIZE) {
> + if (test_and_set_bit(i, hvpci_dom_map) == 0)
> + return i;
> + }
> +
> + return HVPCI_DOM_INVALID;
> +}
> +
> +/**
> + * hv_put_dom_num() - Mark the PCI domain number as free
> + * @dom: Domain number to be freed
> + */
> +static void hv_put_dom_num(u16 dom)
> +{
> + clear_bit(dom, hvpci_dom_map);
> +}
> +
>  /**
>   * hv_pci_probe() - New VMBus channel probe, for a root PCI bus
>   * @hdev:VMBus's tracking struct for this root PCI bus
> @@ -2521,6 +2563,7 @@ static int hv_pci_probe(struct hv_device *hdev,
>   const struct hv_vmbus_device_id *dev_id)
>  {
>   struct hv_pcibus_device *hbus;
> + u16 dom_req, dom;
>   int ret;
>  
>   /*
> @@ -2535,19 +2578,34 @@ static int hv_pci_probe(struct hv_device *hdev,
>   hbus->state = hv_pcibus_init;
>  
>   /*
> -  * The PCI bus "domain" is what is called "segment" in ACPI and
> -  * other specs.  Pull it from the instance ID, to get something
> -  * unique.  Bytes 8 and 9 are what is used in Windows guests, so
> -  * do the same thing for consistency.  Note that, since this code
> -  * only runs in a Hyper-V VM, Hyper-V can (and does) guarantee
> -  * that (1) the only domain in use for something that looks like
> -  * a physical PCI bus (which is actually emulated by the
> -  * hypervisor) is domain 0 and (2) there will be no overlap
> -  * between domains derived from these instance IDs in the same
> -  * VM.
> +  * The PCI bus "domain" is what is called "segment" in ACPI and other
> +  * specs. Pull it from the instance ID, to get something usually
> +  * unique. In rare cases of collision, we will find out another number
> +  * not in use.
> +  *
> +  * Note that, since this code only runs in a Hyper-V VM, Hyper-V
> +  * together with this guest driver can guarantee that (1) The only
> +  * domain used by Gen1 VMs for something that looks like a physical
> +  * PCI bus (which is actually emulated by the hypervisor) is domain 0.
> +  * (2) There will be no overlap between domains (after fixing possible
> +  * collisions) in the same VM.
>*/
> - hbus->sysdata.domain = hdev->dev_instance.b[9] |
> -hdev->dev_instance.b[8] << 8;
> + dom_req = hdev->dev_instance.b[5] << 8 | hdev->dev_instance.b[4];
> + dom = hv_get_dom_num(dom_req);
> +
> + if (dom == HVPCI_DOM_INVALID) {
> + dev_err(>device,
> + "Unable to use dom# 0x%hx 

Re: [EXT] Re: [PATCHv3 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.

2019-08-12 Thread Lorenzo Pieralisi
On Mon, Aug 12, 2019 at 10:39:00AM +, Xiaowei Bao wrote:
> 
> 
> > -Original Message-
> > From: Lorenzo Pieralisi 
> > Sent: 2019年8月12日 18:12
> > To: Xiaowei Bao ; kis...@ti.com
> > Cc: bhelg...@google.com; robh...@kernel.org; mark.rutl...@arm.com;
> > shawn...@kernel.org; Leo Li ; a...@arndb.de;
> > gre...@linuxfoundation.org; M.h. Lian ; Mingkai
> > Hu ; Roy Zang ;
> > kstew...@linuxfoundation.org; pombreda...@nexb.com;
> > shawn@rock-chips.com; linux-...@vger.kernel.org;
> > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > linux-arm-ker...@lists.infradead.org; linuxppc-...@lists.ozlabs.org
> > Subject: [EXT] Re: [PATCHv3 1/2] PCI: layerscape: Add the bar_fixed_64bit
> > property in EP driver.
> > 
> > Caution: EXT Email
> > 
> > First off:
> > 
> > Trim the CC list, you CC'ed maintainers (and mailing lists) for no reasons
> > whatsover.
> [Xiaowei Bao]Hi Lorenzo, I am not clear why the mail list is the CC, I use 
> the command "git send-email --to", I will try to send the patch again, do I 
> need to modify the version is v4 when I send this patch again?

Yes you do.

Wrap lines to max 80 characters. There is no need to add [Xiaowei Bao].

1) Read, email etiquette

https://kernelnewbies.org/PatchCulture

2) get_maintainer.pl -f drivers/pci/controller/dwc/pci-layerscape.c

Compare the output to the people in CC, trim it accordingly.

3) The NXP maintainers in the MAINTAINERS file have not given a single
   comment for this patchset. Either they show up or I will remove them
   from the MAINTAINERS list.

4) Before submitting patches, talk to someone at NXP who can help you
   format them in preparation for posting, I do not have time to write
   guidelines for everyone posting on linux-pci, sorry, the information
   is out there if you care to read it.

Thanks,
Lorenzo

> > 
> > Then, read this:
> > 
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.ke
> > rnel.org%2Flinux-pci%2F20171026223701.GA25649%40bhelgaas-glaptop.roa
> > m.corp.google.com%2Fdata=02%7C01%7Cxiaowei.bao%40nxp.com%7
> > C1c586178e23c423a0e8808d71f0d8f6f%7C686ea1d3bc2b4c6fa92cd99c5c30
> > 1635%7C0%7C0%7C637012015426788575sdata=3bx1bDFIzik8FnD0wl
> > duAUv7wtLdD1J3hQ3xNH2xmFY%3Dreserved=0
> > 
> > and make your patches compliant please.
> > 
> > On Fri, Jun 28, 2019 at 09:38:25AM +0800, Xiaowei Bao wrote:
> > > The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1 is
> > > 32bit, BAR3 and BAR4 is 64bit, this is determined by hardware, so set
> > > the bar_fixed_64bit with 0x14.
> > >
> > > Signed-off-by: Xiaowei Bao 
> > > ---
> > > v2:
> > >  - Replace value 0x14 with a macro.
> > > v3:
> > >  - No change.
> > >
> > >  drivers/pci/controller/dwc/pci-layerscape-ep.c |1 +
> > >  1 files changed, 1 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > index be61d96..227c33b 100644
> > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > @@ -44,6 +44,7 @@ static int ls_pcie_establish_link(struct dw_pcie *pci)
> > >   .linkup_notifier = false,
> > >   .msi_capable = true,
> > >   .msix_capable = false,
> > > + .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> > 
> > I would appreciate Kishon's ACK on this.
> > 
> > Lorenzo
> > 
> > >  };
> > >
> > >  static const struct pci_epc_features*
> > > --
> > > 1.7.1
> > >


Re: [PATCHv3 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.

2019-08-12 Thread Lorenzo Pieralisi
First off:

Trim the CC list, you CC'ed maintainers (and mailing lists) for no
reasons whatsover.

Then, read this:

https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com/

and make your patches compliant please.

On Fri, Jun 28, 2019 at 09:38:25AM +0800, Xiaowei Bao wrote:
> The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1
> is 32bit, BAR3 and BAR4 is 64bit, this is determined by hardware,
> so set the bar_fixed_64bit with 0x14.
> 
> Signed-off-by: Xiaowei Bao 
> ---
> v2:
>  - Replace value 0x14 with a macro.
> v3:
>  - No change.
> 
>  drivers/pci/controller/dwc/pci-layerscape-ep.c |1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
> b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index be61d96..227c33b 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -44,6 +44,7 @@ static int ls_pcie_establish_link(struct dw_pcie *pci)
>   .linkup_notifier = false,
>   .msi_capable = true,
>   .msix_capable = false,
> + .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),

I would appreciate Kishon's ACK on this.

Lorenzo

>  };
>  
>  static const struct pci_epc_features*
> -- 
> 1.7.1
> 


Re: [PATCHv3 2/2] PCI: layerscape: Add CONFIG_PCI_LAYERSCAPE_EP to build EP/RC separately

2019-08-12 Thread Lorenzo Pieralisi
On Fri, Jun 28, 2019 at 09:38:26AM +0800, Xiaowei Bao wrote:
> Add CONFIG_PCI_LAYERSCAPE_EP to build EP/RC separately.
> 
> Signed-off-by: Xiaowei Bao 
> ---
> v2:
>  - No change.
> v3:
>  - modify the commit message.
> 
>  drivers/pci/controller/dwc/Kconfig  |   20 ++--
>  drivers/pci/controller/dwc/Makefile |3 ++-
>  2 files changed, 20 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/Kconfig 
> b/drivers/pci/controller/dwc/Kconfig
> index a6ce1ee..a41ccf5 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -131,13 +131,29 @@ config PCI_KEYSTONE_EP
> DesignWare core functions to implement the driver.
>  
>  config PCI_LAYERSCAPE
> - bool "Freescale Layerscape PCIe controller"
> + bool "Freescale Layerscape PCIe controller - Host mode"
>   depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
>   depends on PCI_MSI_IRQ_DOMAIN
>   select MFD_SYSCON
>   select PCIE_DW_HOST
>   help
> -   Say Y here if you want PCIe controller support on Layerscape SoCs.
> +   Say Y here if you want to enable PCIe controller support on Layerscape
> +   SoCs to work in Host mode.
> +   This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]

What's "The RCW" ? This entry should explain why a kernel configuration
should enable it.

Lorenzo

> +   determines which PCIe controller works in EP mode and which PCIe
> +   controller works in RC mode.
> +
> +config PCI_LAYERSCAPE_EP
> + bool "Freescale Layerscape PCIe controller - Endpoint mode"
> + depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
> + depends on PCI_ENDPOINT
> + select PCIE_DW_EP
> + help
> +   Say Y here if you want to enable PCIe controller support on Layerscape
> +   SoCs to work in Endpoint mode.
> +   This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]
> +   determines which PCIe controller works in EP mode and which PCIe
> +   controller works in RC mode.
>  
>  config PCI_HISI
>   depends on OF && (ARM64 || COMPILE_TEST)
> diff --git a/drivers/pci/controller/dwc/Makefile 
> b/drivers/pci/controller/dwc/Makefile
> index b085dfd..824fde7 100644
> --- a/drivers/pci/controller/dwc/Makefile
> +++ b/drivers/pci/controller/dwc/Makefile
> @@ -8,7 +8,8 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
>  obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
>  obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
>  obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
> -obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o pci-layerscape-ep.o
> +obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
> +obj-$(CONFIG_PCI_LAYERSCAPE_EP) += pci-layerscape-ep.o
>  obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
>  obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
>  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
> -- 
> 1.7.1
> 


[PATCH v2 1/8] ARM: cpuidle: Remove useless header include

2019-08-09 Thread Lorenzo Pieralisi
The generic ARM CPUidle driver includes  by mistake.

Remove the topology header include.

Signed-off-by: Lorenzo Pieralisi 
Acked-by: Daniel Lezcano 
Reviewed-by: Ulf Hansson 
Reviewed-by: Sudeep Holla 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: "Rafael J. Wysocki" 
---
 drivers/cpuidle/cpuidle-arm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 5bcd82c35dcf..dc33b3d2954f 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 
-- 
2.21.0



[PATCH v2 5/8] ARM: psci: cpuidle: Enable PSCI CPUidle driver

2019-08-09 Thread Lorenzo Pieralisi
Allow selection of the PSCI CPUidle in the kernel by updating
the respective Kconfig entry.

Remove PSCI callbacks from ARM/ARM64 generic CPU ops
to prevent the PSCI idle driver from clashing with the generic
ARM CPUidle driver initialization, that relies on CPU ops
to initialize and enter idle states.

Signed-off-by: Lorenzo Pieralisi 
Reviewed-by: Ulf Hansson 
Cc: Will Deacon 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Catalin Marinas 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 
---
 arch/arm64/kernel/cpuidle.c  |  7 ---
 arch/arm64/kernel/psci.c |  4 
 drivers/cpuidle/Kconfig.arm  |  2 +-
 drivers/firmware/psci/psci.c | 10 --
 4 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index d1048173fd8a..619e0ebb8399 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -48,15 +49,15 @@ int arm_cpuidle_suspend(int index)
 
 int acpi_processor_ffh_lpi_probe(unsigned int cpu)
 {
-   return arm_cpuidle_init(cpu);
+   return psci_cpu_init_idle(cpu);
 }
 
 int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
 {
if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
-   return CPU_PM_CPU_IDLE_ENTER_RETENTION(arm_cpuidle_suspend,
+   return CPU_PM_CPU_IDLE_ENTER_RETENTION(psci_cpu_suspend_enter,
lpi->index);
else
-   return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, lpi->index);
+   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, 
lpi->index);
 }
 #endif
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 85ee7d07889e..a543ab7e007c 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -105,10 +105,6 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 
 const struct cpu_operations cpu_psci_ops = {
.name   = "psci",
-#ifdef CONFIG_CPU_IDLE
-   .cpu_init_idle  = psci_cpu_init_idle,
-   .cpu_suspend= psci_cpu_suspend_enter,
-#endif
.cpu_init   = cpu_psci_cpu_init,
.cpu_prepare= cpu_psci_cpu_prepare,
.cpu_boot   = cpu_psci_cpu_boot,
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index eb014aa5ce6b..d8530475493c 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -14,7 +14,7 @@ config ARM_CPUIDLE
   provided by architecture code.
 
 config ARM_PSCI_CPUIDLE
-   bool
+   bool "PSCI CPU idle Driver"
depends on ARM_PSCI_FW
select DT_IDLE_STATES
select CPU_IDLE_MULTIPLE_DRIVERS
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index f82ccd39a913..b343f8a34c6a 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -436,16 +436,6 @@ int psci_cpu_suspend_enter(unsigned long index)
 
return ret;
 }
-
-/* ARM specific CPU idle operations */
-#ifdef CONFIG_ARM
-static const struct cpuidle_ops psci_cpuidle_ops __initconst = {
-   .suspend = psci_cpu_suspend_enter,
-   .init = psci_dt_cpu_init_idle,
-};
-
-CPUIDLE_METHOD_OF_DECLARE(psci, "psci", _cpuidle_ops);
-#endif
 #endif
 
 static int psci_system_suspend(unsigned long unused)
-- 
2.21.0



[PATCH v2 4/8] ARM: psci: cpuidle: Introduce PSCI CPUidle driver

2019-08-09 Thread Lorenzo Pieralisi
PSCI firmware is the standard power management control for
all ARM64 based platforms and it is also deployed on some
ARM 32 bit platforms to date.

Idle state entry in PSCI is currently achieved by calling
arm_cpuidle_init() and arm_cpuidle_suspend() in a generic
idle driver, which in turn relies on ARM/ARM64 CPUidle back-end
to relay the call into PSCI firmware if PSCI is the boot method.

Given that PSCI is the standard idle entry method on ARM64 systems
(which means that no other CPUidle driver are expected on ARM64
platforms - so PSCI is already a generic idle driver), in order to
simplify idle entry and code maintenance, it makes sense to have a PSCI
specific idle driver so that idle code that it is currently living in
drivers/firmware directory can be hoisted out of it and moved
where it belongs, into a full-fledged PSCI driver, leaving PSCI code
in drivers/firmware as a pure firmware interface, as it should be.

Implement a PSCI CPUidle driver. By default it is a silent Kconfig entry
which is left unselected, since it selection would clash with the
generic ARM CPUidle driver that provides a PSCI based idle driver
through the arm/arm64 arches back-ends CPU operations.

Signed-off-by: Lorenzo Pieralisi 
Acked-by: Daniel Lezcano 
Reviewed-by: Ulf Hansson 
Reviewed-by: Sudeep Holla 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 
---
 MAINTAINERS|   8 ++
 drivers/cpuidle/Kconfig.arm|  10 +++
 drivers/cpuidle/Makefile   |   1 +
 drivers/cpuidle/cpuidle-psci.c | 151 +
 4 files changed, 170 insertions(+)
 create mode 100644 drivers/cpuidle/cpuidle-psci.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 783569e3c4b4..c2bf8ce65e83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4286,6 +4286,14 @@ S:   Supported
 F: drivers/cpuidle/cpuidle-exynos.c
 F: arch/arm/mach-exynos/pm.c
 
+CPUIDLE DRIVER - ARM PSCI
+M:     Lorenzo Pieralisi 
+M: Sudeep Holla 
+L: linux...@vger.kernel.org
+L: linux-arm-ker...@lists.infradead.org
+S: Supported
+F: drivers/cpuidle/cpuidle-psci.c
+
 CPU IDLE TIME MANAGEMENT FRAMEWORK
 M: "Rafael J. Wysocki" 
 M: Daniel Lezcano 
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 48cb3d4bb7d1..eb014aa5ce6b 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -13,6 +13,16 @@ config ARM_CPUIDLE
   initialized by calling the CPU operations init idle hook
   provided by architecture code.
 
+config ARM_PSCI_CPUIDLE
+   bool
+   depends on ARM_PSCI_FW
+   select DT_IDLE_STATES
+   select CPU_IDLE_MULTIPLE_DRIVERS
+   help
+ Select this to enable PSCI firmware based CPUidle driver for ARM.
+ It provides an idle driver that is capable of detecting and
+ managing idle states through the PSCI firmware interface.
+
 config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors"
depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 9d7176cee3d3..40d016339b29 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)  += cpuidle-at91.o
 obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)+= cpuidle-exynos.o
 obj-$(CONFIG_ARM_CPUIDLE)  += cpuidle-arm.o
+obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
 
 ###
 # MIPS drivers
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
new file mode 100644
index ..ab1dea918ea3
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PSCI CPU idle driver.
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ * Author: Lorenzo Pieralisi 
+ */
+
+#define pr_fmt(fmt) "CPUidle PSCI: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dt_idle_states.h"
+
+static int psci_enter_idle_state(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv, int idx)
+{
+   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, idx);
+}
+
+static struct cpuidle_driver psci_idle_driver __initdata = {
+   .name = "psci_idle",
+   .owner = THIS_MODULE,
+   /*
+* PSCI idle states relies on architectural WFI to
+* be represented as state index 0.
+*/
+   .states[0] = {
+   .enter  = psci_enter_idle_state,
+   .exit_latency   = 1,
+   .target_residency   = 1,
+   .power_usage= UINT_MAX,
+   .name   = "WFI",
+   

[PATCH v2 0/8] ARM: psci: cpuidle: PSCI CPUidle rework

2019-08-09 Thread Lorenzo Pieralisi
v2 of a previous posting:

v1: 
https://lore.kernel.org/linux-pm/20190722153745.32446-1-lorenzo.pieral...@arm.com/

v1->v2:

- Split config files updates into separate patches
- Fixed minor memory leaks/bisectability issues

Original cover letter
---

Current PSCI CPUidle driver is built on top of the generic ARM
CPUidle infrastructure that relies on the architectural back-end
idle operations to initialize and enter idle states.

On ARM64 systems, PSCI is the only interface the kernel ever uses
to enter idle states, so, having to rely on a generic ARM CPUidle
driver when there is and there will always be only one method
for entering idle states proved to be overkill, more so given
that on ARM 32-bit systems (that can also enable the generic
ARM CPUidle driver) only one additional idle back-end was
ever added:

drivers/soc/qcom/spm.c

and it can be easily converted to a full-fledged CPUidle driver
without requiring the generic ARM CPUidle framework.

Furthermore, the generic ARM CPUidle infrastructure forces the
PSCI firmware layer to keep CPUidle specific information in it,
which does not really fit its purpose that should be kernel
control/data structure agnostic.

Lastly, the interface between the generic ARM CPUidle driver and
the arch back-end requires an idle state index to be passed to
suspend operations, with idle states back-end internals (such
as idle state parameters) hidden in architectural back-ends and
not available to the generic ARM CPUidle driver.

To improve the above mentioned shortcomings, implement a stand
alone PSCI CPUidle driver; this improves the current kernel
code from several perspective:

- Move CPUidle internal knowledge into CPUidle driver out of
  the PSCI firmware interface
- Give the PSCI CPUidle driver control over power state parameters,
  in particular in preparation for PSCI OSI support
- Remove generic CPUidle operations infrastructure from the kernel

This patchset does not go as far as removing the generic ARM CPUidle
infrastructure in order to collect feedback on the new approach
before completing the removal from the kernel, the generic and PSCI
CPUidle driver are left to co-exist.

Tested on Juno platform with both DT and ACPI boot firmwares.

Cc: Will Deacon 
Cc: Shawn Guo 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Catalin Marinas 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 

Lorenzo Pieralisi (8):
  ARM: cpuidle: Remove useless header include
  ARM: cpuidle: Remove overzealous error logging
  drivers: firmware: psci: Decouple checker from generic ARM CPUidle
  ARM: psci: cpuidle: Introduce PSCI CPUidle driver
  ARM: psci: cpuidle: Enable PSCI CPUidle driver
  PSCI: cpuidle: Refactor CPU suspend power_state parameter handling
  arm64: defconfig: Enable the PSCI CPUidle driver
  ARM: imx_v6_v7_defconfig: Enable the PSCI CPUidle driver

 MAINTAINERS  |   8 +
 arch/arm/configs/imx_v6_v7_defconfig |   1 +
 arch/arm64/configs/defconfig |   1 +
 arch/arm64/kernel/cpuidle.c  |  50 +-
 arch/arm64/kernel/psci.c |   4 -
 drivers/cpuidle/Kconfig.arm  |  10 ++
 drivers/cpuidle/Makefile |   1 +
 drivers/cpuidle/cpuidle-arm.c|  13 +-
 drivers/cpuidle/cpuidle-psci.c   | 236 +++
 drivers/firmware/psci/psci.c | 167 +--
 drivers/firmware/psci/psci_checker.c |  16 +-
 include/linux/cpuidle.h  |  17 +-
 include/linux/psci.h |   4 +-
 13 files changed, 342 insertions(+), 186 deletions(-)
 create mode 100644 drivers/cpuidle/cpuidle-psci.c

-- 
2.21.0



[PATCH v2 3/8] drivers: firmware: psci: Decouple checker from generic ARM CPUidle

2019-08-09 Thread Lorenzo Pieralisi
The PSCI checker currently relies on the generic ARM CPUidle
infrastructure to enter an idle state, which in turn creates
a dependency that is not really needed.

The PSCI checker code to test PSCI CPU suspend is built on
top of the CPUidle framework and can easily reuse the
struct cpuidle_state.enter() function (previously initialized
by an idle driver, with a PSCI back-end) to trigger an entry
into an idle state, decoupling the PSCI checker from the
generic ARM CPUidle infrastructure and simplyfing the code
in the process.

Convert the PSCI checker suspend entry function to use
the struct cpuidle_state.enter() function callback.

Signed-off-by: Lorenzo Pieralisi 
Acked-by: Daniel Lezcano 
Reviewed-by: Ulf Hansson 
Reviewed-by: Sudeep Holla 
Cc: Sudeep Holla 
Cc: Mark Rutland 
---
 drivers/firmware/psci/psci_checker.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/psci/psci_checker.c 
b/drivers/firmware/psci/psci_checker.c
index f3659443f8c2..6a445397771c 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -228,8 +228,11 @@ static int hotplug_tests(void)
 
 static void dummy_callback(struct timer_list *unused) {}
 
-static int suspend_cpu(int index, bool broadcast)
+static int suspend_cpu(struct cpuidle_device *dev,
+  struct cpuidle_driver *drv, int index)
 {
+   struct cpuidle_state *state = >states[index];
+   bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
int ret;
 
arch_cpu_idle_enter();
@@ -254,11 +257,7 @@ static int suspend_cpu(int index, bool broadcast)
}
}
 
-   /*
-* Replicate the common ARM cpuidle enter function
-* (arm_enter_idle_state).
-*/
-   ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
+   ret = state->enter(dev, drv, index);
 
if (broadcast)
tick_broadcast_exit();
@@ -301,9 +300,8 @@ static int suspend_test_thread(void *arg)
 * doesn't use PSCI).
 */
for (index = 1; index < drv->state_count; ++index) {
-   struct cpuidle_state *state = >states[index];
-   bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
int ret;
+   struct cpuidle_state *state = >states[index];
 
/*
 * Set the timer to wake this CPU up in some time (which
@@ -318,7 +316,7 @@ static int suspend_test_thread(void *arg)
/* IRQs must be disabled during suspend operations. */
local_irq_disable();
 
-   ret = suspend_cpu(index, broadcast);
+   ret = suspend_cpu(dev, drv, index);
 
/*
 * We have woken up. Re-enable IRQs to handle any
-- 
2.21.0



[PATCH v2 6/8] PSCI: cpuidle: Refactor CPU suspend power_state parameter handling

2019-08-09 Thread Lorenzo Pieralisi
Current PSCI code handles idle state entry through the
psci_cpu_suspend_enter() API, that takes an idle state index as a
parameter and convert the index into a previously initialized
power_state parameter before calling the PSCI.CPU_SUSPEND() with it.

This is unwieldly, since it forces the PSCI firmware layer to keep track
of power_state parameter for every idle state so that the
index->power_state conversion can be made in the PSCI firmware layer
instead of the CPUidle driver implementations.

Move the power_state handling out of drivers/firmware/psci
into the respective ACPI/DT PSCI CPUidle backends and convert
the psci_cpu_suspend_enter() API to get the power_state
parameter as input, which makes it closer to its firmware
interface PSCI.CPU_SUSPEND() API.

A notable side effect is that the PSCI ACPI/DT CPUidle backends
now can directly handle (and if needed update) power_state
parameters before handing them over to the PSCI firmware
interface to trigger PSCI.CPU_SUSPEND() calls.

Signed-off-by: Lorenzo Pieralisi 
Acked-by: Daniel Lezcano 
Reviewed-by: Ulf Hansson 
Reviewed-by: Sudeep Holla 
Cc: Will Deacon 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Catalin Marinas 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 
---
 arch/arm64/kernel/cpuidle.c|  49 +-
 drivers/cpuidle/cpuidle-psci.c |  87 +-
 drivers/firmware/psci/psci.c   | 157 ++---
 include/linux/cpuidle.h|  17 +++-
 include/linux/psci.h   |   4 +-
 5 files changed, 154 insertions(+), 160 deletions(-)

diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index 619e0ebb8399..e4d6af2fdec7 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -47,17 +47,58 @@ int arm_cpuidle_suspend(int index)
 
 #define ARM64_LPI_IS_RETENTION_STATE(arch_flags) (!(arch_flags))
 
+static int psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+   int i, count;
+   struct acpi_lpi_state *lpi;
+   struct acpi_processor *pr = per_cpu(processors, cpu);
+
+   /*
+* If the PSCI cpu_suspend function hook has not been initialized
+* idle states must not be enabled, so bail out
+*/
+   if (!psci_ops.cpu_suspend)
+   return -EOPNOTSUPP;
+
+   if (unlikely(!pr || !pr->flags.has_lpi))
+   return -EINVAL;
+
+   count = pr->power.count - 1;
+   if (count <= 0)
+   return -ENODEV;
+
+   for (i = 0; i < count; i++) {
+   u32 state;
+
+   lpi = >power.lpi_states[i + 1];
+   /*
+* Only bits[31:0] represent a PSCI power_state while
+* bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
+*/
+   state = lpi->address;
+   if (!psci_power_state_is_valid(state)) {
+   pr_warn("Invalid PSCI power state %#x\n", state);
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+
 int acpi_processor_ffh_lpi_probe(unsigned int cpu)
 {
-   return psci_cpu_init_idle(cpu);
+   return psci_acpi_cpu_init_idle(cpu);
 }
 
 int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
 {
+   u32 state = lpi->address;
+
if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
-   return CPU_PM_CPU_IDLE_ENTER_RETENTION(psci_cpu_suspend_enter,
-   lpi->index);
+   return 
CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(psci_cpu_suspend_enter,
+   lpi->index, state);
else
-   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, 
lpi->index);
+   return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+lpi->index, state);
 }
 #endif
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
index ab1dea918ea3..f3c1a2396f98 100644
--- a/drivers/cpuidle/cpuidle-psci.c
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -22,10 +22,15 @@
 
 #include "dt_idle_states.h"
 
+static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+
 static int psci_enter_idle_state(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int idx)
 {
-   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, idx);
+   u32 *state = __this_cpu_read(psci_power_state);
+
+   return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+  idx, state[idx - 1]);
 }
 
 static struct cpuidle_driver psci_idle_driver __initdata = {
@@ -51,6 +56,86 @@ static const struct of_device_id psci_idle_state_match[] 
__initconst = {
{ },
 };
 
+static int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
+{
+   int err = of_property_read_u32(np, "arm,psci-suspend-param", state);
+
+   if 

[PATCH v2 7/8] arm64: defconfig: Enable the PSCI CPUidle driver

2019-08-09 Thread Lorenzo Pieralisi
Enable the PSCI CPUidle driver to replace the functionality
previously provided by the generic ARM CPUidle driver through
CPU operations.

Signed-off-by: Lorenzo Pieralisi 
Cc: Will Deacon 
Cc: Sudeep Holla 
Cc: Catalin Marinas 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0e58ef02880c..c0a7cfe3aebd 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -72,6 +72,7 @@ CONFIG_RANDOMIZE_BASE=y
 CONFIG_HIBERNATION=y
 CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
 CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_STAT=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=m
-- 
2.21.0



[PATCH v2 8/8] ARM: imx_v6_v7_defconfig: Enable the PSCI CPUidle driver

2019-08-09 Thread Lorenzo Pieralisi
Enable the PSCI CPUidle driver to replace the functionality
previously provided by the generic ARM CPUidle driver.

Signed-off-by: Lorenzo Pieralisi 
Cc: Shawn Guo 
---
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig 
b/arch/arm/configs/imx_v6_v7_defconfig
index a53b29251ed4..4174fd1b79e7 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -60,6 +60,7 @@ CONFIG_ARM_IMX6Q_CPUFREQ=y
 CONFIG_ARM_IMX_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_PM_DEBUG=y
-- 
2.21.0



[PATCH v2 2/8] ARM: cpuidle: Remove overzealous error logging

2019-08-09 Thread Lorenzo Pieralisi
CPUidle back-end operations are not implemented in some platforms
but this should not be considered an error serious enough to be
logged. Check the arm_cpuidle_init() return value to detect whether
the failure must be reported or not in the kernel log and do
not log it if the platform does not support CPUidle operations.

Signed-off-by: Lorenzo Pieralisi 
Acked-by: Daniel Lezcano 
Reviewed-by: Ulf Hansson 
Reviewed-by: Sudeep Holla 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: "Rafael J. Wysocki" 
---
 drivers/cpuidle/cpuidle-arm.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index dc33b3d2954f..9e5156d39627 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -105,11 +105,17 @@ static int __init arm_idle_init_cpu(int cpu)
ret = arm_cpuidle_init(cpu);
 
/*
-* Allow the initialization to continue for other CPUs, if the reported
-* failure is a HW misconfiguration/breakage (-ENXIO).
+* Allow the initialization to continue for other CPUs, if the
+* reported failure is a HW misconfiguration/breakage (-ENXIO).
+*
+* Some platforms do not support idle operations
+* (arm_cpuidle_init() returning -EOPNOTSUPP), we should
+* not flag this case as an error, it is a valid
+* configuration.
 */
if (ret) {
-   pr_err("CPU %d failed to init idle CPU ops\n", cpu);
+   if (ret != -EOPNOTSUPP)
+   pr_err("CPU %d failed to init idle CPU ops\n", cpu);
ret = ret == -ENXIO ? 0 : ret;
goto out_kfree_drv;
}
-- 
2.21.0



Re: [PATCH v3 8/8] PCI: dw: Add support for PCI_PROBE_ONLY/PCI_REASSIGN_ALL_BUS flags

2019-08-08 Thread Lorenzo Pieralisi
Side note, run:

git log --oneline on drivers/pci/controller/dwc existing files and
make sure commit subjects are in line with those.

Eg PCI: dw: should be PCI: dwc:

On Thu, Aug 08, 2019 at 09:30:05AM +, Chocron, Jonathan wrote:
> On Wed, 2019-08-07 at 17:36 +0100, Lorenzo Pieralisi wrote:
> > On Tue, Jul 23, 2019 at 12:27:11PM +0300, Jonathan Chocron wrote:
> > > This basically aligns the usage of PCI_PROBE_ONLY and
> > > PCI_REASSIGN_ALL_BUS in dw_pcie_host_init() with the logic in
> > > pci_host_common_probe().
> > > 
> > > Now it will be possible to control via the devicetree whether to
> > > just
> > > probe the PCI bus (in cases where FW already configured it) or to
> > > fully
> > > configure it.
> > > 
> > > Signed-off-by: Jonathan Chocron 
> > > ---
> > >  .../pci/controller/dwc/pcie-designware-host.c | 23
> > > +++
> > >  1 file changed, 19 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index d2ca748e4c85..0a294d8aa21a 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -342,6 +342,8 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >   if (!bridge)
> > >   return -ENOMEM;
> > >  
> > > + of_pci_check_probe_only();
> > > +
> > >   ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
> > >   >windows, 
> > > >io_base);
> > >   if (ret)
> > > @@ -474,6 +476,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >  
> > >   pp->root_bus_nr = pp->busn->start;
> > >  
> > > + /* Do not reassign bus nums if probe only */
> > > + if (!pci_has_flag(PCI_PROBE_ONLY))
> > > + pci_add_flags(PCI_REASSIGN_ALL_BUS);
> > 
> > This changes the default for bus reassignment on all DWC host (that
> > are
> > !PCI_PROBE_ONLY), we should drop this line, it can trigger
> > regressions.
> > 
> Will be dropped as part of v4. There might also be a behavioral
> difference below where I added the if (pci_has_flag(PCI_PROBE_ONLY)).
> Is that still ok?

That's true but I doubt any DWC host has a DT firmware with
"linux,pci-probe-only" in it.

It is trial and error I am afraid, please make sure all DWC
maintainers are copied in.

> As I pointed out in the cover letter, since PCI_PROBE_ONLY is a system
> wide flag, does it make sense to call of_pci_check_probe_only() here,
> in the context of a specific driver (including the existing invocation
> in pci_host_common_probe()), as opposed to a platform/arch context?

It is an ongoing discussion to define how we should handle
PCI_PROBE_ONLY. Adding this code into DWC I do not think it
would hurt but if we can postpone it for the next (v5.5) merge
window after we debate this at LPC within the PCI microconference
it would be great.

Please sync with Benjamin as a first step, I trust he would ask
you to do the right thing.

> > If we still want to merge it as a separate change we must test it on
> > all
> > DWC host bridges to make sure it does not trigger any issues with
> > current set-ups, that's not going to be easy though.
> > 
> Just out of curiosity, how are such exhaustive tests achieved when a
> patch requires them?

CC DWC host bridge maintainers and ask them to test it. I do not have
the HW (and FW) required, I am sorry, that's the only option I can give
you. -next coverage would help too but to a minor extent.

Thanks,
Lorenzo

> 
> > Lorenzo
> > 
> > > +
> > >   bridge->dev.parent = dev;
> > >   bridge->sysdata = pp;
> > >   bridge->busnr = pp->root_bus_nr;
> > > @@ -490,11 +496,20 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >   if (pp->ops->scan_bus)
> > >   pp->ops->scan_bus(pp);
> > >  
> > > - pci_bus_size_bridges(pp->root_bus);
> > > - pci_bus_assign_resources(pp->root_bus);
> > > + /*
> > > +  * We insert PCI resources into the iomem_resource and
> > > +  * ioport_resource trees in either pci_bus_claim_resources()
> > > +  * or pci_bus_assign_resources().
> > > +  */
> > > + if (pci_has_flag(PCI_PROBE_ONLY)) {
> > > + pci_bus_claim_resources(pp->root_bus);
> > > + } else {
> > > + pci_bus_size_bridges(pp->root_bus);
> > > + pci_bus_assign_resources(pp->root_bus);
> > >  
> > > - list_for_each_entry(child, >root_bus->children, node)
> > > - pcie_bus_configure_settings(child);
> > > + list_for_each_entry(child, >root_bus->children,
> > > node)
> > > + pcie_bus_configure_settings(child);
> > > + }
> > >  
> > >   pci_bus_add_devices(pp->root_bus);
> > >   return 0;
> > > -- 
> > > 2.17.1
> > > 


Re: [PATCH] PCI: pci-hyperv: fix build errors on non-SYSFS config

2019-08-08 Thread Lorenzo Pieralisi
On Wed, Aug 07, 2019 at 09:27:45PM -0400, Sasha Levin wrote:
> On Wed, Aug 07, 2019 at 04:06:54PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Jul 23, 2019 at 04:21:07PM -0500, Bjorn Helgaas wrote:
> > > On Sat, Jul 13, 2019 at 11:03:53AM -0400, Sasha Levin wrote:
> > > > Queued up for hyperv-fixes, thank you!
> > > 
> > > What merge strategy do you envision for this?  Previous
> > > drivers/pci/controller/pci-hyperv.c changes have generally been merged
> > > by Lorenzo and incorporated into my PCI tree.
> > > 
> > > This particular patch doesn't actually touch pci-hyperv.c; it touches
> > > drivers/pci/Kconfig, so should somehow be coordinated with me.
> > > 
> > > Does this need to be tagged for stable?  a15f2c08c708 appeared in
> > > v4.19, so my first guess is that it's not stable material.
> > 
> > AFAIC Bjorn's question still stands. Who will pick this patch up ?
> 
> Would it be easier if I just ignored Hyper-V PCI patches?

I think it probably would, yes. Actually this patch does not even
fall within "Hyper-V CORE AND DRIVERS" maintainers entry.

As for drivers/pci/controller/pci-hyperv.c, for urgent fixes
I understand it is easier for you to pull them I would still ask
you please to sync with me before pulling them.

Thanks,
Lorenzo


Re: [PATCH v3 8/8] PCI: dw: Add support for PCI_PROBE_ONLY/PCI_REASSIGN_ALL_BUS flags

2019-08-07 Thread Lorenzo Pieralisi
On Tue, Jul 23, 2019 at 12:27:11PM +0300, Jonathan Chocron wrote:
> This basically aligns the usage of PCI_PROBE_ONLY and
> PCI_REASSIGN_ALL_BUS in dw_pcie_host_init() with the logic in
> pci_host_common_probe().
> 
> Now it will be possible to control via the devicetree whether to just
> probe the PCI bus (in cases where FW already configured it) or to fully
> configure it.
> 
> Signed-off-by: Jonathan Chocron 
> ---
>  .../pci/controller/dwc/pcie-designware-host.c | 23 +++
>  1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c 
> b/drivers/pci/controller/dwc/pcie-designware-host.c
> index d2ca748e4c85..0a294d8aa21a 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -342,6 +342,8 @@ int dw_pcie_host_init(struct pcie_port *pp)
>   if (!bridge)
>   return -ENOMEM;
>  
> + of_pci_check_probe_only();
> +
>   ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
>   >windows, >io_base);
>   if (ret)
> @@ -474,6 +476,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>   pp->root_bus_nr = pp->busn->start;
>  
> + /* Do not reassign bus nums if probe only */
> + if (!pci_has_flag(PCI_PROBE_ONLY))
> + pci_add_flags(PCI_REASSIGN_ALL_BUS);

This changes the default for bus reassignment on all DWC host (that are
!PCI_PROBE_ONLY), we should drop this line, it can trigger regressions.

If we still want to merge it as a separate change we must test it on all
DWC host bridges to make sure it does not trigger any issues with
current set-ups, that's not going to be easy though.

Lorenzo

> +
>   bridge->dev.parent = dev;
>   bridge->sysdata = pp;
>   bridge->busnr = pp->root_bus_nr;
> @@ -490,11 +496,20 @@ int dw_pcie_host_init(struct pcie_port *pp)
>   if (pp->ops->scan_bus)
>   pp->ops->scan_bus(pp);
>  
> - pci_bus_size_bridges(pp->root_bus);
> - pci_bus_assign_resources(pp->root_bus);
> + /*
> +  * We insert PCI resources into the iomem_resource and
> +  * ioport_resource trees in either pci_bus_claim_resources()
> +  * or pci_bus_assign_resources().
> +  */
> + if (pci_has_flag(PCI_PROBE_ONLY)) {
> + pci_bus_claim_resources(pp->root_bus);
> + } else {
> + pci_bus_size_bridges(pp->root_bus);
> + pci_bus_assign_resources(pp->root_bus);
>  
> - list_for_each_entry(child, >root_bus->children, node)
> - pcie_bus_configure_settings(child);
> + list_for_each_entry(child, >root_bus->children, node)
> + pcie_bus_configure_settings(child);
> + }
>  
>   pci_bus_add_devices(pp->root_bus);
>   return 0;
> -- 
> 2.17.1
> 


Re: [PATCH] PCI: pci-hyperv: fix build errors on non-SYSFS config

2019-08-07 Thread Lorenzo Pieralisi
On Tue, Jul 23, 2019 at 04:21:07PM -0500, Bjorn Helgaas wrote:
> On Sat, Jul 13, 2019 at 11:03:53AM -0400, Sasha Levin wrote:
> > On Fri, Jul 12, 2019 at 04:04:17PM +, Haiyang Zhang wrote:
> > > > -Original Message-
> > > > From: Randy Dunlap 
> > > > Sent: Friday, July 12, 2019 11:53 AM
> > > > To: linux-pci ; LKML  > > > ker...@vger.kernel.org>
> > > > Cc: Matthew Wilcox ; Jake Oshins
> > > > ; KY Srinivasan ; Haiyang
> > > > Zhang ; Stephen Hemminger
> > > > ; Stephen Hemminger
> > > > ; Sasha Levin ; Bjorn
> > > > Helgaas ; Dexuan Cui 
> > > > Subject: [PATCH] PCI: pci-hyperv: fix build errors on non-SYSFS config
> 
> Whoever merges this (see below), please update the subject line to
> match:
> 
>   $ git log --oneline drivers/pci/controller/pci-hyperv.c | head -5
>   4df591b20b80 PCI: hv: Fix a use-after-free bug in hv_eject_device_work()
>   340d45569940 PCI: hv: Add pci_destroy_slot() in pci_devices_present_work(), 
> if necessary
>   15becc2b56c6 PCI: hv: Add hv_pci_remove_slots() when we unload the driver
>   05f151a73ec2 PCI: hv: Fix a memory leak in hv_eject_device_work()
>   c8ccf7599dda PCI: hv: Refactor hv_irq_unmask() to use cpumask_to_vpset()
> 
> > > > From: Randy Dunlap 
> > > > 
> > > > Fix build errors when building almost-allmodconfig but with SYSFS
> > > > not set (not enabled).  Fixes these build errors:
> > > > 
> > > > ERROR: "pci_destroy_slot" [drivers/pci/controller/pci-hyperv.ko] 
> > > > undefined!
> > > > ERROR: "pci_create_slot" [drivers/pci/controller/pci-hyperv.ko] 
> > > > undefined!
> > > > 
> > > > drivers/pci/slot.o is only built when SYSFS is enabled, so
> > > > pci-hyperv.o has an implicit dependency on SYSFS.
> > > > Make that explicit.
> > > > 
> > > > Also, depending on X86 && X86_64 is not needed, so just change that
> > > > to depend on X86_64.
> > > > 
> > > > Fixes: a15f2c08c708 ("PCI: hv: support reporting serial number as slot
> > > > information")
> > > > 
> > > > Signed-off-by: Randy Dunlap 
> > > > Cc: Matthew Wilcox 
> > > > Cc: Jake Oshins 
> > > > Cc: "K. Y. Srinivasan" 
> > > > Cc: Haiyang Zhang 
> > > > Cc: Stephen Hemminger 
> > > > Cc: Stephen Hemminger 
> > > > Cc: Sasha Levin 
> > > > Cc: Bjorn Helgaas 
> > > > Cc: linux-...@vger.kernel.org
> > > > Cc: linux-hyp...@vger.kernel.org
> > > > Cc: Dexuan Cui 
> > > > ---
> > > > v3: corrected Fixes: tag [Dexuan Cui ]
> > > > This is the Microsoft-preferred version of the patch.
> > > > 
> > > >  drivers/pci/Kconfig |2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > --- lnx-52.orig/drivers/pci/Kconfig
> > > > +++ lnx-52/drivers/pci/Kconfig
> > > > @@ -181,7 +181,7 @@ config PCI_LABEL
> > > > 
> > > >  config PCI_HYPERV
> > > >  tristate "Hyper-V PCI Frontend"
> > > > -depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN
> > > > && X86_64
> > > > +depends on X86_64 && HYPERV && PCI_MSI &&
> > > > PCI_MSI_IRQ_DOMAIN && SYSFS
> > > >  help
> > > >The PCI device frontend driver allows the kernel to import 
> > > > arbitrary
> > > >PCI devices from a PCI backend to support PCI driver domains.
> > > > 
> > > 
> > > Reviewed-by: Haiyang Zhang 
> > 
> > Queued up for hyperv-fixes, thank you!
> 
> What merge strategy do you envision for this?  Previous
> drivers/pci/controller/pci-hyperv.c changes have generally been merged
> by Lorenzo and incorporated into my PCI tree.
> 
> This particular patch doesn't actually touch pci-hyperv.c; it touches
> drivers/pci/Kconfig, so should somehow be coordinated with me.
> 
> Does this need to be tagged for stable?  a15f2c08c708 appeared in
> v4.19, so my first guess is that it's not stable material.

AFAIC Bjorn's question still stands. Who will pick this patch up ?

Thanks,
Lorenzo


Re: [v2,0/2] PCI: mediatek: Add support for MT7629

2019-08-07 Thread Lorenzo Pieralisi
On Fri, Jun 28, 2019 at 03:34:23PM +0800, Jianjun Wang wrote:
> These series patches modify pcie-mediatek.c and dt-bindings compatible
> string to support MT7629 PCIe host.
> 
> Jianjun Wang (2):
>   dt-bindings: PCI: Add support for MT7629
>   PCI: mediatek: Add controller support for MT7629
> 
>  .../devicetree/bindings/pci/mediatek-pcie.txt  |  1 +
>  drivers/pci/controller/pcie-mediatek.c | 18 ++
>  include/linux/pci_ids.h|  1 +
>  3 files changed, 20 insertions(+)

Applied to pci/mediatek for v5.4.

Thanks,
Lorenzo


Re: [PATCH 5/6] ARM: psci: cpuidle: Enable PSCI CPUidle driver

2019-08-06 Thread Lorenzo Pieralisi
On Tue, Aug 06, 2019 at 05:16:24PM +0100, Sudeep Holla wrote:
> On Mon, Jul 22, 2019 at 04:37:44PM +0100, Lorenzo Pieralisi wrote:
> > Allow selection of the PSCI CPUidle in the kernel by adding
> > the required Kconfig options.
> > 
> > Remove PSCI callbacks from ARM/ARM64 generic CPU ops
> > to prevent the PSCI idle driver from clashing with the generic
> > ARM CPUidle driver initialization, that relies on CPU ops
> > to initialize and enter idle states.
> > 
> > Update the affected defconfig files to guarantee seamingless
> > transition from the generic ARM CPUidle to the PSCI CPUidle
> > driver on arch/platforms using it.
> > 
> > Signed-off-by: Lorenzo Pieralisi 
> > Cc: Will Deacon 
> > Cc: Ulf Hansson 
> > Cc: Sudeep Holla 
> > Cc: Daniel Lezcano 
> > Cc: Catalin Marinas 
> > Cc: Mark Rutland 
> > Cc: "Rafael J. Wysocki" 
> > ---
> >  arch/arm/configs/imx_v6_v7_defconfig | 1 +
> >  arch/arm64/configs/defconfig | 1 +
> 
> Better to keep above you as separate patch, though it may cause
> minor issues from bisectibility. It may be needed anyway for merging.

That's a good point, I will split these bits in a separate patch.

> >  arch/arm64/kernel/cpuidle.c  | 7 ---
> >  arch/arm64/kernel/psci.c | 4 
> >  drivers/cpuidle/Kconfig.arm  | 8 ++--
> >  drivers/firmware/psci/psci.c | 9 -
> >  6 files changed, 12 insertions(+), 18 deletions(-)
> > 
> > diff --git a/arch/arm/configs/imx_v6_v7_defconfig 
> > b/arch/arm/configs/imx_v6_v7_defconfig
> > index a53b29251ed4..4174fd1b79e7 100644
> > --- a/arch/arm/configs/imx_v6_v7_defconfig
> > +++ b/arch/arm/configs/imx_v6_v7_defconfig
> > @@ -60,6 +60,7 @@ CONFIG_ARM_IMX6Q_CPUFREQ=y
> >  CONFIG_ARM_IMX_CPUFREQ_DT=y
> >  CONFIG_CPU_IDLE=y
> >  CONFIG_ARM_CPUIDLE=y
> > +CONFIG_ARM_PSCI_CPUIDLE=y
> >  CONFIG_VFP=y
> >  CONFIG_NEON=y
> >  CONFIG_PM_DEBUG=y
> > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > index 0e58ef02880c..c0a7cfe3aebd 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -72,6 +72,7 @@ CONFIG_RANDOMIZE_BASE=y
> >  CONFIG_HIBERNATION=y
> >  CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
> >  CONFIG_ARM_CPUIDLE=y
> > +CONFIG_ARM_PSCI_CPUIDLE=y
> >  CONFIG_CPU_FREQ=y
> >  CONFIG_CPU_FREQ_STAT=y
> >  CONFIG_CPU_FREQ_GOV_POWERSAVE=m
> > diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
> > index d1048173fd8a..4bcd1bca0dfc 100644
> > --- a/arch/arm64/kernel/cpuidle.c
> > +++ b/arch/arm64/kernel/cpuidle.c
> > @@ -11,6 +11,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #include 
> >  #include 
> > @@ -48,15 +49,15 @@ int arm_cpuidle_suspend(int index)
> >  
> >  int acpi_processor_ffh_lpi_probe(unsigned int cpu)
> >  {
> > -   return arm_cpuidle_init(cpu);
> > +   return psci_acpi_cpu_init_idle(cpu);
> 
> This will break build as psci_acpi_cpu_init_idle is introduced in next patch.
> You can simply move it to next patch I assume.

Yes, it is a bisectability issue, I fixed it already but thanks
for spotting it anyway.

> >  }
> >  
> >  int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
> >  {
> > if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
> > -   return CPU_PM_CPU_IDLE_ENTER_RETENTION(arm_cpuidle_suspend,
> > +   return CPU_PM_CPU_IDLE_ENTER_RETENTION(psci_cpu_suspend_enter,
> > lpi->index);
> > else
> > -   return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, lpi->index);
> > +   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, 
> > lpi->index);
> >  }
> >  #endif
> > diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
> > index 85ee7d07889e..a543ab7e007c 100644
> > --- a/arch/arm64/kernel/psci.c
> > +++ b/arch/arm64/kernel/psci.c
> > @@ -105,10 +105,6 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
> >  
> >  const struct cpu_operations cpu_psci_ops = {
> > .name   = "psci",
> > -#ifdef CONFIG_CPU_IDLE
> > -   .cpu_init_idle  = psci_cpu_init_idle,
> > -   .cpu_suspend= psci_cpu_suspend_enter,
> > -#endif
> > .cpu_init   = cpu_psci_cpu_init,
> > .cpu_prepare= cpu_psci_cpu_prepare,
> > .cpu_boot   = cpu_psci_cpu_boot,
> > diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cp

Re: [PATCH 4/6] ARM: psci: cpuidle: Introduce PSCI CPUidle driver

2019-08-06 Thread Lorenzo Pieralisi
On Tue, Aug 06, 2019 at 05:10:33PM +0100, Sudeep Holla wrote:
> On Mon, Jul 22, 2019 at 04:37:43PM +0100, Lorenzo Pieralisi wrote:
> > PSCI firmware is the standard power management control for
> > all ARM64 based platforms and it is also deployed on some
> > ARM 32 bit platforms to date.
> >
> > Idle state entry in PSCI is currently achieved by calling
> > arm_cpuidle_init() and arm_cpuidle_suspend() in a generic
> > idle driver, which in turn relies on ARM/ARM64 CPUidle back-end
> > to relay the call into PSCI firmware if PSCI is the boot method.
> >
> > Given that PSCI is the standard idle entry method on ARM64 systems
> > (which means that no other CPUidle driver are expected on ARM64
> > platforms - so PSCI is already a generic idle driver), in order to
> > simplify idle entry and code maintenance, it makes sense to have a PSCI
> > specific idle driver so that idle code that it is currently living in
> > drivers/firmware directory can be hoisted out of it and moved
> > where it belongs, into a full-fledged PSCI driver, leaving PSCI code
> > in drivers/firmware as a pure firmware interface, as it should be.
> >
> > Implement a PSCI CPUidle driver. By default it is a silent Kconfig entry
> > which is left unselected, since it selection would clash with the
> > generic ARM CPUidle driver that provides a PSCI based idle driver
> > through the arm/arm64 arches back-ends CPU operations.
> >
> > Signed-off-by: Lorenzo Pieralisi 
> > Cc: Ulf Hansson 
> > Cc: Sudeep Holla 
> 
> Once the error path issues pointed by Ulf are resolved,
> 
> Reviewed-by: Sudeep Holla 
> 
> > Cc: Daniel Lezcano 
> > Cc: Mark Rutland 
> > Cc: "Rafael J. Wysocki" 
> > ---
> >  MAINTAINERS|   8 ++
> >  drivers/cpuidle/Kconfig.arm|   3 +
> >  drivers/cpuidle/Makefile   |   1 +
> >  drivers/cpuidle/cpuidle-psci.c | 150 +
> >  4 files changed, 162 insertions(+)
> >  create mode 100644 drivers/cpuidle/cpuidle-psci.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 783569e3c4b4..c2bf8ce65e83 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -4286,6 +4286,14 @@ S:   Supported
> >  F: drivers/cpuidle/cpuidle-exynos.c
> >  F: arch/arm/mach-exynos/pm.c
> >
> > +CPUIDLE DRIVER - ARM PSCI
> > +M: Lorenzo Pieralisi 
> > +M: Sudeep Holla 
> > +L: linux...@vger.kernel.org
> > +L: linux-arm-ker...@lists.infradead.org
> > +S: Supported
> > +F: drivers/cpuidle/cpuidle-psci.c
> > +
> >  CPU IDLE TIME MANAGEMENT FRAMEWORK
> >  M: "Rafael J. Wysocki" 
> >  M: Daniel Lezcano 
> > diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> > index 48cb3d4bb7d1..929b57424ea4 100644
> > --- a/drivers/cpuidle/Kconfig.arm
> > +++ b/drivers/cpuidle/Kconfig.arm
> > @@ -13,6 +13,9 @@ config ARM_CPUIDLE
> >initialized by calling the CPU operations init idle hook
> >provided by architecture code.
> >
> > +config ARM_PSCI_CPUIDLE
> > +   bool
> > +
> 
> [nit] I understand the intention to keep it hidden, but can't we have
> the dependency and selection of other config as part of this patch to
> make it more complete ?

Yes we can, it makes sense.

Thanks,
Lorenzo


Re: [PATCH v3] PCI: aardvark: Fix PCI_EXP_RTCTL register configuration

2019-08-06 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 12:10:59PM +0200, Remi Pommarel wrote:
> PCI_EXP_RTCTL is used to activate PME interrupt only, so writing into it
> should not modify other interrupts' mask. The ISR mask polarity was also
> inverted, when PCI_EXP_RTCTL_PMEIE is set PCIE_MSG_PM_PME_MASK mask bit
> should actually be cleared.
> 
> Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge 
> config space")
> Signed-off-by: Remi Pommarel 
> ---
> Changes since v1:
>  * Improve code readability
>  * Fix mask polarity
>  * PME_MASK shift was off by one
> Changes since v2:
>  * Modify patch title
>  * Change Fixes tag to commit that actually introduces the bug
> ---
>  drivers/pci/controller/pci-aardvark.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)

Thomas, are you OK with this patch ?

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/pci-aardvark.c 
> b/drivers/pci/controller/pci-aardvark.c
> index 134e0306ff00..f6e55c4597b1 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -415,7 +415,7 @@ advk_pci_bridge_emul_pcie_conf_read(struct 
> pci_bridge_emul *bridge,
>  
>   case PCI_EXP_RTCTL: {
>   u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
> - *value = (val & PCIE_MSG_PM_PME_MASK) ? PCI_EXP_RTCTL_PMEIE : 0;
> + *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE;
>   return PCI_BRIDGE_EMUL_HANDLED;
>   }
>  
> @@ -451,10 +451,15 @@ advk_pci_bridge_emul_pcie_conf_write(struct 
> pci_bridge_emul *bridge,
>   advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
>   break;
>  
> - case PCI_EXP_RTCTL:
> - new = (new & PCI_EXP_RTCTL_PMEIE) << 3;
> - advk_writel(pcie, new, PCIE_ISR0_MASK_REG);
> + case PCI_EXP_RTCTL: {
> + /* Only mask/unmask PME interrupt */
> + u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) &
> + ~PCIE_MSG_PM_PME_MASK;
> + if ((new & PCI_EXP_RTCTL_PMEIE) == 0)
> + val |= PCIE_MSG_PM_PME_MASK;
> + advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
>   break;
> + }
>  
>   case PCI_EXP_RTSTA:
>   new = (new & PCI_EXP_RTSTA_PME) >> 9;
> -- 
> 2.20.1
> 


Re: [v2,2/2] PCI: mediatek: Add controller support for MT7629

2019-08-06 Thread Lorenzo Pieralisi
[trim the CC list please to keep only required maintainers]

On Mon, Jul 29, 2019 at 03:38:38PM +0800, Jianjun Wang wrote:
> On Fri, 2019-06-28 at 15:34 +0800, Jianjun Wang wrote:
> > MT7629 is an ARM platform SoC which has the same PCIe IP with MT7622.
> > 
> > The HW default value of its Device ID is invalid, fix its Device ID to
> > match the hardware implementation.
> > 
> > Acked-by: Ryder Lee 
> > Signed-off-by: Jianjun Wang 
> > ---
> >  drivers/pci/controller/pcie-mediatek.c | 18 ++
> >  include/linux/pci_ids.h|  1 +
> >  2 files changed, 19 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pcie-mediatek.c 
> > b/drivers/pci/controller/pcie-mediatek.c
> > index 80601e1b939e..e5e6740b635d 100644
> > --- a/drivers/pci/controller/pcie-mediatek.c
> > +++ b/drivers/pci/controller/pcie-mediatek.c
> > @@ -73,6 +73,7 @@
> >  #define PCIE_MSI_VECTOR0x0c0
> >  
> >  #define PCIE_CONF_VEND_ID  0x100
> > +#define PCIE_CONF_DEVICE_ID0x102
> >  #define PCIE_CONF_CLASS_ID 0x106
> >  
> >  #define PCIE_INT_MASK  0x420
> > @@ -141,12 +142,16 @@ struct mtk_pcie_port;
> >  /**
> >   * struct mtk_pcie_soc - differentiate between host generations
> >   * @need_fix_class_id: whether this host's class ID needed to be fixed or 
> > not
> > + * @need_fix_device_id: whether this host's Device ID needed to be fixed 
> > or not
> > + * @device_id: Device ID which this host need to be fixed
> >   * @ops: pointer to configuration access functions
> >   * @startup: pointer to controller setting functions
> >   * @setup_irq: pointer to initialize IRQ functions
> >   */
> >  struct mtk_pcie_soc {
> > bool need_fix_class_id;
> > +   bool need_fix_device_id;
> > +   unsigned int device_id;
> > struct pci_ops *ops;
> > int (*startup)(struct mtk_pcie_port *port);
> > int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
> > @@ -696,6 +701,9 @@ static int mtk_pcie_startup_port_v2(struct 
> > mtk_pcie_port *port)
> > writew(val, port->base + PCIE_CONF_CLASS_ID);
> > }
> >  
> > +   if (soc->need_fix_device_id)
> > +   writew(soc->device_id, port->base + PCIE_CONF_DEVICE_ID);
> > +
> > /* 100ms timeout value should be enough for Gen1/2 training */
> > err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val,
> >  !!(val & PCIE_PORT_LINKUP_V2), 20,
> > @@ -1216,11 +1224,21 @@ static const struct mtk_pcie_soc 
> > mtk_pcie_soc_mt7622 = {
> > .setup_irq = mtk_pcie_setup_irq,
> >  };
> >  
> > +static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {
> > +   .need_fix_class_id = true,
> > +   .need_fix_device_id = true,
> > +   .device_id = PCI_DEVICE_ID_MEDIATEK_7629,
> > +   .ops = _pcie_ops_v2,
> > +   .startup = mtk_pcie_startup_port_v2,
> > +   .setup_irq = mtk_pcie_setup_irq,
> > +};
> > +
> >  static const struct of_device_id mtk_pcie_ids[] = {
> > { .compatible = "mediatek,mt2701-pcie", .data = _pcie_soc_v1 },
> > { .compatible = "mediatek,mt7623-pcie", .data = _pcie_soc_v1 },
> > { .compatible = "mediatek,mt2712-pcie", .data = _pcie_soc_mt2712 },
> > { .compatible = "mediatek,mt7622-pcie", .data = _pcie_soc_mt7622 },
> > +   { .compatible = "mediatek,mt7629-pcie", .data = _pcie_soc_mt7629 },
> > {},
> >  };
> >  
> > diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> > index 70e86148cb1e..aa32962759b2 100644
> > --- a/include/linux/pci_ids.h
> > +++ b/include/linux/pci_ids.h
> > @@ -2131,6 +2131,7 @@
> >  #define PCI_VENDOR_ID_MYRICOM  0x14c1
> >  
> >  #define PCI_VENDOR_ID_MEDIATEK 0x14c3
> > +#define PCI_DEVICE_ID_MEDIATEK_76290x7629
> >  
> >  #define PCI_VENDOR_ID_TITAN0x14D2
> >  #define PCI_DEVICE_ID_TITAN_010L   0x8001
> 
> Hi Bjorn & Lorenzo,
> 
> Is this patch ok or is there anything I need to fixed?

The commit log need to be fixed and I will do it, the code if
Bjorn is OK with it I can merge it.

Lorenzo


Re: [PATCH V13 12/12] PCI: tegra: Add Tegra194 PCIe support

2019-08-06 Thread Lorenzo Pieralisi
On Mon, Aug 05, 2019 at 10:24:42PM +0530, Vidya Sagar wrote:

[...]

> > > > IRQs are enabled when you call a suspend_noirq() callback, so the
> > > > blocking API can be used as long as the IRQ descriptor backing
> > > > the IRQ that will wake-up the blocked call is marked as
> > > > IRQF_NO_SUSPEND.
> > > > 
> > > > The problem is not IRQs enabled/disabled at CPU level, the problem is
> > > > the IRQ descriptor of the IRQ required to handle the blocking BPMP call,
> > > > mark it as IRQF_NO_SUSPEND and remove the tegra_bpmp_transfer_atomic()
> > > > call from this code (or please give me a concrete example pinpointing
> > > > why it is needed).
> > > Ideally, using tegra_bpmp_transfer() alone in all paths (.probe() as
> > > well as .resume_noirq()) should have worked as the corresponding IRQ
> > > is already flagged as IRQF_NO_SUSPEND, but, because of the way BPMP-FW
> > > driver in kernel making its interface available through
> > > .resume_early(), tegra_bpmp_transfer() wasn't working as expected and
> > > I pushed a patch (CC'ing you) at
> > > http://patchwork.ozlabs.org/patch/1140973/ to make it .resume_noirq()
> > > from .resume_early().  With that in place, we can just use
> > > tegra_bpmp_trasnfer().  I'll push a new patch with this change once my
> > > BPMP-FW driver patch is approved.
> > 
> > Does this leave you with a resume_noirq() callbacks ordering issue to
> > sort out ?
> Not really.
> 
> > 
> > a.k.a How will you guarantee that the BPMP will resume before the host
> > bridge ?
> It is already taken care of in the following way.  PCIe controller's
> device-tree node has an entry with a phandle of BPMP-FW's node to get
> a handle of it and PCIe driver uses tegra_bpmp_get() API for that.
> This API returns -EPROBE_DEFER if BPMP-FW's driver is not ready yet,
> which guarantees that PCIe driver gets loaded only after BPMP-FW's
> driver and this order is followed during noirq phase also.

OK, thanks, this makes much more sense than the original code.

Lorenzo

> > Thanks,
> > Lorenzo
> > 
> > > Thanks,
> > > Vidya Sagar
> > > > 
> > > > Thanks,
> > > > Lorenzo
> > > > 
> > > > > I'll go ahead and make next patch series with this if this looks fine 
> > > > > to you.
> > > > > 
> > > > > > 
> > > > > > > > Actually, if tegra_bpmp_transfer() requires IRQs to be enabled 
> > > > > > > > you may
> > > > > > > > even end up in a situation where that blocking call does not 
> > > > > > > > wake up
> > > > > > > > because the IRQ in question was disabled in the NOIRQ 
> > > > > > > > suspend/resume
> > > > > > > > phase.
> > > > > > > > 
> > > > > > > > [...]
> > > > > > > > 
> > > > > > > > > > > +static int tegra_pcie_dw_probe(struct platform_device 
> > > > > > > > > > > *pdev)
> > > > > > > > > > > +{
> > > > > > > > > > > + const struct tegra_pcie_soc *data;
> > > > > > > > > > > + struct device *dev = >dev;
> > > > > > > > > > > + struct resource *atu_dma_res;
> > > > > > > > > > > + struct tegra_pcie_dw *pcie;
> > > > > > > > > > > + struct resource *dbi_res;
> > > > > > > > > > > + struct pcie_port *pp;
> > > > > > > > > > > + struct dw_pcie *pci;
> > > > > > > > > > > + struct phy **phys;
> > > > > > > > > > > + char *name;
> > > > > > > > > > > + int ret;
> > > > > > > > > > > + u32 i;
> > > > > > > > > > > +
> > > > > > > > > > > + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > > > > > > > > > > + if (!pcie)
> > > > > > > > > > > + return -ENOMEM;
> > > > > > > > > > > +
> > > > > > > > > > > + pci = >pci;
> > > > > > > > > > > + pci->dev = >dev;
> > > > > > > > > > > + pci->ops = _dw_pcie_ops;
> > > > > > > > > > > + pp = >pp;
> > > > > > > > > > > + pcie->dev = >dev;
> > > > > > > > > > > +
> > > > > > > > > > > + data = (struct tegra_pcie_soc 
> > > > > > > > > > > *)of_device_get_match_data(dev);
> > > > > > > > > > > + if (!data)
> > > > > > > > > > > + return -EINVAL;
> > > > > > > > > > > + pcie->mode = (enum dw_pcie_device_mode)data->mode;
> > > > > > > > > > > +
> > > > > > > > > > > + ret = tegra_pcie_dw_parse_dt(pcie);
> > > > > > > > > > > + if (ret < 0) {
> > > > > > > > > > > + dev_err(dev, "Failed to parse device tree: 
> > > > > > > > > > > %d\n", ret);
> > > > > > > > > > > + return ret;
> > > > > > > > > > > + }
> > > > > > > > > > > +
> > > > > > > > > > > + pcie->pex_ctl_supply = devm_regulator_get(dev, 
> > > > > > > > > > > "vddio-pex-ctl");
> > > > > > > > > > > + if (IS_ERR(pcie->pex_ctl_supply)) {
> > > > > > > > > > > + dev_err(dev, "Failed to get regulator: %ld\n",
> > > > > > > > > > > + PTR_ERR(pcie->pex_ctl_supply));
> > > > > > > > > > > + return PTR_ERR(pcie->pex_ctl_supply);
> > > > > > > > > > > + }
> > > > > > > > > > > +
> > > > > > > > > > > + pcie->core_clk = devm_clk_get(dev, "core");
> > > > > > > > > > > + if (IS_ERR(pcie->core_clk)) {
> > > > > > > > > > > + dev_err(dev, "Failed to get core clock: %ld\n",
> > > > > > > > > > > + 

Re: [PATCH V13 12/12] PCI: tegra: Add Tegra194 PCIe support

2019-08-05 Thread Lorenzo Pieralisi
On Fri, Aug 02, 2019 at 05:36:43PM +0530, Vidya Sagar wrote:
> On 7/30/2019 9:19 PM, Lorenzo Pieralisi wrote:
> > On Tue, Jul 23, 2019 at 08:14:08PM +0530, Vidya Sagar wrote:
> > > On 7/16/2019 4:52 PM, Lorenzo Pieralisi wrote:
> > > > On Sat, Jul 13, 2019 at 12:34:34PM +0530, Vidya Sagar wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > > > > > +static int tegra_pcie_bpmp_set_ctrl_state(struct 
> > > > > > > > > tegra_pcie_dw *pcie,
> > > > > > > > > +   bool enable)
> > > > > > > > > +{
> > > > > > > > > + struct mrq_uphy_response resp;
> > > > > > > > > + struct tegra_bpmp_message msg;
> > > > > > > > > + struct mrq_uphy_request req;
> > > > > > > > > + int err;
> > > > > > > > > +
> > > > > > > > > + if (pcie->cid == 5)
> > > > > > > > > + return 0;
> > > > > > > > 
> > > > > > > > What's wrong with cid == 5 ? Explain please.
> > > > > > > Controller with ID=5 doesn't need any programming to enable it 
> > > > > > > which is
> > > > > > > done here through calling firmware API.
> > > > > > > 
> > > > > > > > 
> > > > > > > > > + memset(, 0, sizeof(req));
> > > > > > > > > + memset(, 0, sizeof(resp));
> > > > > > > > > +
> > > > > > > > > + req.cmd = CMD_UPHY_PCIE_CONTROLLER_STATE;
> > > > > > > > > + req.controller_state.pcie_controller = pcie->cid;
> > > > > > > > > + req.controller_state.enable = enable;
> > > > > > > > > +
> > > > > > > > > + memset(, 0, sizeof(msg));
> > > > > > > > > + msg.mrq = MRQ_UPHY;
> > > > > > > > > + msg.tx.data = 
> > > > > > > > > + msg.tx.size = sizeof(req);
> > > > > > > > > + msg.rx.data = 
> > > > > > > > > + msg.rx.size = sizeof(resp);
> > > > > > > > > +
> > > > > > > > > + if (irqs_disabled())
> > > > > > > > 
> > > > > > > > Can you explain to me what this check is meant to achieve 
> > > > > > > > please ?
> > > > > > > Firmware interface provides different APIs to be called when 
> > > > > > > there are
> > > > > > > no interrupts enabled in the system (noirq context) and otherwise
> > > > > > > hence checking that situation here and calling appropriate API.
> > > > > > 
> > > > > > That's what I am questioning. Being called from 
> > > > > > {suspend/resume}_noirq()
> > > > > > callbacks (if that's the code path this check caters for) does not 
> > > > > > mean
> > > > > > irqs_disabled() == true.
> > > > > Agree.
> > > > > Actually, I got a hint of having this check from the following.
> > > > > Both tegra_bpmp_transfer_atomic() and tegra_bpmp_transfer() are 
> > > > > indirectly
> > > > > called by APIs registered with .master_xfer() and 
> > > > > .master_xfer_atomic() hooks of
> > > > > struct i2c_algorithm and the decision to call which one of these is 
> > > > > made using the
> > > > > following check in i2c-core.h file.
> > > > > static inline bool i2c_in_atomic_xfer_mode(void)
> > > > > {
> > > > >   return system_state > SYSTEM_RUNNING && irqs_disabled();
> > > > > }
> > > > > I think I should use this condition as is IIUC.
> > > > > Please let me know if there are any concerns with this.
> > > > 
> > > > It is not a concern, it is just that I don't understand how this code
> > > > can be called with IRQs disabled, if you can give me an execution path I
> > > > am happy to leave the check there. On top of that, when called from
> > > > suspend NOIRQ context, it is likely to use the blocking API (because
> > > > IRQs aren't disabled at CPU level) behin

Re: [PATCH V13 12/12] PCI: tegra: Add Tegra194 PCIe support

2019-07-30 Thread Lorenzo Pieralisi
On Tue, Jul 23, 2019 at 08:14:08PM +0530, Vidya Sagar wrote:
> On 7/16/2019 4:52 PM, Lorenzo Pieralisi wrote:
> > On Sat, Jul 13, 2019 at 12:34:34PM +0530, Vidya Sagar wrote:
> > 
> > [...]
> > 
> > > > > > > +static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw 
> > > > > > > *pcie,
> > > > > > > +   bool enable)
> > > > > > > +{
> > > > > > > + struct mrq_uphy_response resp;
> > > > > > > + struct tegra_bpmp_message msg;
> > > > > > > + struct mrq_uphy_request req;
> > > > > > > + int err;
> > > > > > > +
> > > > > > > + if (pcie->cid == 5)
> > > > > > > + return 0;
> > > > > > 
> > > > > > What's wrong with cid == 5 ? Explain please.
> > > > > Controller with ID=5 doesn't need any programming to enable it which 
> > > > > is
> > > > > done here through calling firmware API.
> > > > > 
> > > > > > 
> > > > > > > + memset(, 0, sizeof(req));
> > > > > > > + memset(, 0, sizeof(resp));
> > > > > > > +
> > > > > > > + req.cmd = CMD_UPHY_PCIE_CONTROLLER_STATE;
> > > > > > > + req.controller_state.pcie_controller = pcie->cid;
> > > > > > > + req.controller_state.enable = enable;
> > > > > > > +
> > > > > > > + memset(, 0, sizeof(msg));
> > > > > > > + msg.mrq = MRQ_UPHY;
> > > > > > > + msg.tx.data = 
> > > > > > > + msg.tx.size = sizeof(req);
> > > > > > > + msg.rx.data = 
> > > > > > > + msg.rx.size = sizeof(resp);
> > > > > > > +
> > > > > > > + if (irqs_disabled())
> > > > > > 
> > > > > > Can you explain to me what this check is meant to achieve please ?
> > > > > Firmware interface provides different APIs to be called when there are
> > > > > no interrupts enabled in the system (noirq context) and otherwise
> > > > > hence checking that situation here and calling appropriate API.
> > > > 
> > > > That's what I am questioning. Being called from {suspend/resume}_noirq()
> > > > callbacks (if that's the code path this check caters for) does not mean
> > > > irqs_disabled() == true.
> > > Agree.
> > > Actually, I got a hint of having this check from the following.
> > > Both tegra_bpmp_transfer_atomic() and tegra_bpmp_transfer() are indirectly
> > > called by APIs registered with .master_xfer() and .master_xfer_atomic() 
> > > hooks of
> > > struct i2c_algorithm and the decision to call which one of these is made 
> > > using the
> > > following check in i2c-core.h file.
> > > static inline bool i2c_in_atomic_xfer_mode(void)
> > > {
> > >   return system_state > SYSTEM_RUNNING && irqs_disabled();
> > > }
> > > I think I should use this condition as is IIUC.
> > > Please let me know if there are any concerns with this.
> > 
> > It is not a concern, it is just that I don't understand how this code
> > can be called with IRQs disabled, if you can give me an execution path I
> > am happy to leave the check there. On top of that, when called from
> > suspend NOIRQ context, it is likely to use the blocking API (because
> > IRQs aren't disabled at CPU level) behind which there is most certainly
> > an IRQ required to wake the thread up and if the IRQ in question was
> > disabled in the suspend NOIRQ phase this code is likely to deadlock.
> > 
> > I want to make sure we can justify adding this check, I do not
> > want to add it because we think it can be needed when it may not
> > be needed at all (and it gets copy and pasted over and over again
> > in other drivers).
> I had a discussion internally about this and the prescribed usage of these 
> APIs
> seem to be that
> use tegra_bpmp_transfer() in .probe() and other paths where interrupts are
> enabled as this API needs interrupts to be enabled for its working.
> Use tegra_bpmp_transfer_atomic() surrounded by 
> local_irq_save()/local_irq_restore()
> in other paths where interrupt servicing is disabled.

Why tegra_bpmp_transfer_atomic() needs IRQs to be disabled ? And why
is it needed in this piece of code where IRQs are _never_ disabled
at CPU level ?

IRQs are enabled

Re: [v2,2/2] PCI: mediatek: Add controller support for MT7629

2019-07-29 Thread Lorenzo Pieralisi
On Mon, Jul 29, 2019 at 03:38:38PM +0800, Jianjun Wang wrote:
> On Fri, 2019-06-28 at 15:34 +0800, Jianjun Wang wrote:
> > MT7629 is an ARM platform SoC which has the same PCIe IP with MT7622.
> > 
> > The HW default value of its Device ID is invalid, fix its Device ID to
> > match the hardware implementation.
> > 
> > Acked-by: Ryder Lee 
> > Signed-off-by: Jianjun Wang 
> > ---
> >  drivers/pci/controller/pcie-mediatek.c | 18 ++
> >  include/linux/pci_ids.h|  1 +
> >  2 files changed, 19 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pcie-mediatek.c 
> > b/drivers/pci/controller/pcie-mediatek.c
> > index 80601e1b939e..e5e6740b635d 100644
> > --- a/drivers/pci/controller/pcie-mediatek.c
> > +++ b/drivers/pci/controller/pcie-mediatek.c
> > @@ -73,6 +73,7 @@
> >  #define PCIE_MSI_VECTOR0x0c0
> >  
> >  #define PCIE_CONF_VEND_ID  0x100
> > +#define PCIE_CONF_DEVICE_ID0x102
> >  #define PCIE_CONF_CLASS_ID 0x106
> >  
> >  #define PCIE_INT_MASK  0x420
> > @@ -141,12 +142,16 @@ struct mtk_pcie_port;
> >  /**
> >   * struct mtk_pcie_soc - differentiate between host generations
> >   * @need_fix_class_id: whether this host's class ID needed to be fixed or 
> > not
> > + * @need_fix_device_id: whether this host's Device ID needed to be fixed 
> > or not
> > + * @device_id: Device ID which this host need to be fixed
> >   * @ops: pointer to configuration access functions
> >   * @startup: pointer to controller setting functions
> >   * @setup_irq: pointer to initialize IRQ functions
> >   */
> >  struct mtk_pcie_soc {
> > bool need_fix_class_id;
> > +   bool need_fix_device_id;
> > +   unsigned int device_id;
> > struct pci_ops *ops;
> > int (*startup)(struct mtk_pcie_port *port);
> > int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
> > @@ -696,6 +701,9 @@ static int mtk_pcie_startup_port_v2(struct 
> > mtk_pcie_port *port)
> > writew(val, port->base + PCIE_CONF_CLASS_ID);
> > }
> >  
> > +   if (soc->need_fix_device_id)
> > +   writew(soc->device_id, port->base + PCIE_CONF_DEVICE_ID);
> > +
> > /* 100ms timeout value should be enough for Gen1/2 training */
> > err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val,
> >  !!(val & PCIE_PORT_LINKUP_V2), 20,
> > @@ -1216,11 +1224,21 @@ static const struct mtk_pcie_soc 
> > mtk_pcie_soc_mt7622 = {
> > .setup_irq = mtk_pcie_setup_irq,
> >  };
> >  
> > +static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {
> > +   .need_fix_class_id = true,
> > +   .need_fix_device_id = true,
> > +   .device_id = PCI_DEVICE_ID_MEDIATEK_7629,
> > +   .ops = _pcie_ops_v2,
> > +   .startup = mtk_pcie_startup_port_v2,
> > +   .setup_irq = mtk_pcie_setup_irq,
> > +};
> > +
> >  static const struct of_device_id mtk_pcie_ids[] = {
> > { .compatible = "mediatek,mt2701-pcie", .data = _pcie_soc_v1 },
> > { .compatible = "mediatek,mt7623-pcie", .data = _pcie_soc_v1 },
> > { .compatible = "mediatek,mt2712-pcie", .data = _pcie_soc_mt2712 },
> > { .compatible = "mediatek,mt7622-pcie", .data = _pcie_soc_mt7622 },
> > +   { .compatible = "mediatek,mt7629-pcie", .data = _pcie_soc_mt7629 },
> > {},
> >  };
> >  
> > diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> > index 70e86148cb1e..aa32962759b2 100644
> > --- a/include/linux/pci_ids.h
> > +++ b/include/linux/pci_ids.h
> > @@ -2131,6 +2131,7 @@
> >  #define PCI_VENDOR_ID_MYRICOM  0x14c1
> >  
> >  #define PCI_VENDOR_ID_MEDIATEK 0x14c3
> > +#define PCI_DEVICE_ID_MEDIATEK_76290x7629
> >  
> >  #define PCI_VENDOR_ID_TITAN0x14D2
> >  #define PCI_DEVICE_ID_TITAN_010L   0x8001
> 
> Hi Bjorn & Lorenzo,
> 
> Is this patch ok or is there anything I need to fixed?

We are getting to it shortly, thanks for your patience.

Lorenzo


Re: [PATCH] arm_pmu: Mark expected switch fall-through

2019-07-26 Thread Lorenzo Pieralisi
On Fri, Jul 26, 2019 at 01:29:56PM +0100, Mark Rutland wrote:
> On Fri, Jul 26, 2019 at 01:27:37PM +0200, Anders Roxell wrote:
> > When fall-through warnings was enabled by default the following warning
> > was starting to show up:
> > 
> > ../drivers/perf/arm_pmu.c: In function ‘cpu_pm_pmu_notify’:
> > ../drivers/perf/arm_pmu.c:726:3: warning: this statement may fall
> >  through [-Wimplicit-fallthrough=]
> >cpu_pm_pmu_setup(armpmu, cmd);
> >^
> > ../drivers/perf/arm_pmu.c:727:2: note: here
> >   case CPU_PM_ENTER_FAILED:
> >   ^~~~
> > 
> > Rework so that the compiler doesn't warn about fall-through.
> > 
> > Fixes: d93512ef0f0e ("Makefile: Globally enable fall-through warning")
> > Signed-off-by: Anders Roxell 
> > ---
> > 
> > I'm not convinced that this is the correct patch to fix this issue.
> > However, I can't see why we do 'armpmu->start(armpmu);' only in 'case
> > CPU_PM_ENTER_FAILED' and why we not call function cpu_pm_pmu_setup()
> > there also, since in cpu_pm_pmu_setup() has a case prepared for
> > CPU_PM_ENTER_FAILED.
> 
> I agree, think that should be:
> 
>   case CPU_PM_EXIT:
>   case CPU_PM_ENTER_FAILED:
>   cpu_pm_pmu_setup(armpmu, cmd);
>   armpmu->start(armpmu);
>   break;
> 
> ... so that we re-start the events before we start the PMU.
> 
> That would be a fix for commit:
> 
>   da4e4f18afe0f372 ("drivers/perf: arm_pmu: implement CPU_PM notifier")

Yes that's correct, apologies. Probably we did not hit it because CPU PM
notifier entry failures are a pretty rare event; regardless:

Acked-by: Lorenzo Pieralisi 

I can send the updated fix, just let me know.

Thanks,
Lorenzo

> Thanks,
> Mark.
> 
> > 
> >  drivers/perf/arm_pmu.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > index 2d06b8095a19..465a15705bab 100644
> > --- a/drivers/perf/arm_pmu.c
> > +++ b/drivers/perf/arm_pmu.c
> > @@ -724,6 +724,7 @@ static int cpu_pm_pmu_notify(struct notifier_block *b, 
> > unsigned long cmd,
> > break;
> > case CPU_PM_EXIT:
> > cpu_pm_pmu_setup(armpmu, cmd);
> > +   /* Fall through */
> > case CPU_PM_ENTER_FAILED:
> > armpmu->start(armpmu);
> > break;
> > -- 
> > 2.20.1
> > 


Re: [PATCH 0/6] ARM: psci: cpuidle: PSCI CPUidle rework

2019-07-23 Thread Lorenzo Pieralisi
On Tue, Jul 23, 2019 at 01:49:15PM +0200, Ulf Hansson wrote:
> On Mon, 22 Jul 2019 at 17:37, Lorenzo Pieralisi
>  wrote:
> >
> > Current PSCI CPUidle driver is built on top of the generic ARM
> > CPUidle infrastructure that relies on the architectural back-end
> > idle operations to initialize and enter idle states.
> >
> > On ARM64 systems, PSCI is the only interface the kernel ever uses
> > to enter idle states, so, having to rely on a generic ARM CPUidle
> > driver when there is and there will always be only one method
> > for entering idle states proved to be overkill, more so given
> > that on ARM 32-bit systems (that can also enable the generic
> > ARM CPUidle driver) only one additional idle back-end was
> > ever added:
> >
> > drivers/soc/qcom/spm.c
> >
> > and it can be easily converted to a full-fledged CPUidle driver
> > without requiring the generic ARM CPUidle framework.
> >
> > Furthermore, the generic ARM CPUidle infrastructure forces the
> > PSCI firmware layer to keep CPUidle specific information in it,
> > which does not really fit its purpose that should be kernel
> > control/data structure agnostic.
> >
> > Lastly, the interface between the generic ARM CPUidle driver and
> > the arch back-end requires an idle state index to be passed to
> > suspend operations, with idle states back-end internals (such
> > as idle state parameters) hidden in architectural back-ends and
> > not available to the generic ARM CPUidle driver.
> >
> > To improve the above mentioned shortcomings, implement a stand
> > alone PSCI CPUidle driver; this improves the current kernel
> > code from several perspective:
> >
> > - Move CPUidle internal knowledge into CPUidle driver out of
> >   the PSCI firmware interface
> > - Give the PSCI CPUidle driver control over power state parameters,
> >   in particular in preparation for PSCI OSI support
> > - Remove generic CPUidle operations infrastructure from the kernel
> >
> > This patchset does not go as far as removing the generic ARM CPUidle
> > infrastructure in order to collect feedback on the new approach
> > before completing the removal from the kernel, the generic and PSCI
> > CPUidle driver are left to co-exist.
> 
> I like the approach and I think this series definitely moves things in
> the right direction.
> 
> Of course, some additional cleanups/re-works on top are needed to show
> its full benefit, but step by step we reach that point.

I pushed code out as we agreed.

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git

branch: cpuidle/psci-driver

I will version the code as I update the patches, I will leave
them on the list for this week before sending a v2.

> > Tested on Juno platform with both DT and ACPI boot firmwares.
> >
> > Cc: Will Deacon 
> > Cc: Ulf Hansson 
> > Cc: Sudeep Holla 
> > Cc: Daniel Lezcano 
> > Cc: Catalin Marinas 
> > Cc: Mark Rutland 
> > Cc: "Rafael J. Wysocki" 
> >
> > Lorenzo Pieralisi (6):
> >   ARM: cpuidle: Remove useless header include
> >   ARM: cpuidle: Remove overzealous error logging
> >   drivers: firmware: psci: Decouple checker from generic ARM CPUidle
> >   ARM: psci: cpuidle: Introduce PSCI CPUidle driver
> >   ARM: psci: cpuidle: Enable PSCI CPUidle driver
> >   PSCI: cpuidle: Refactor CPU suspend power_state parameter handling
> >
> >  MAINTAINERS  |   8 +
> >  arch/arm/configs/imx_v6_v7_defconfig |   1 +
> >  arch/arm64/configs/defconfig |   1 +
> >  arch/arm64/kernel/cpuidle.c  |  50 +-
> >  arch/arm64/kernel/psci.c |   4 -
> >  drivers/cpuidle/Kconfig.arm  |   7 +
> >  drivers/cpuidle/Makefile |   1 +
> >  drivers/cpuidle/cpuidle-arm.c|  13 +-
> >  drivers/cpuidle/cpuidle-psci.c   | 235 +++
> >  drivers/firmware/psci/psci.c | 167 +--
> >  drivers/firmware/psci/psci_checker.c |  16 +-
> >  include/linux/cpuidle.h  |  17 +-
> >  include/linux/psci.h |   4 +-
> >  13 files changed, 338 insertions(+), 186 deletions(-)
> >  create mode 100644 drivers/cpuidle/cpuidle-psci.c
> >
> > --
> > 2.21.0
> >
> 
> For the series, besides the minor comments I had on patch 4, feel free to add:
> 
> Reviewed-by: Ulf Hansson 

Thanks !
Lorenzo


Re: [PATCH 4/6] ARM: psci: cpuidle: Introduce PSCI CPUidle driver

2019-07-23 Thread Lorenzo Pieralisi
On Tue, Jul 23, 2019 at 01:46:56PM +0200, Ulf Hansson wrote:
> [...]
> 
> > +++ b/drivers/cpuidle/cpuidle-psci.c
> > @@ -0,0 +1,150 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * PSCI CPU idle driver.
> > + *
> > + * Copyright (C) 2019 ARM Ltd.
> > + * Author: Lorenzo Pieralisi 
> > + */
> > +
> > +#define pr_fmt(fmt) "CPUidle PSCI: " fmt
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> 
> This should go away, right?

We need to pull in cpu_do_idle() so it will have to stay there.

> > +#include "dt_idle_states.h"
> > +
> > +static int psci_enter_idle_state(struct cpuidle_device *dev,
> > +   struct cpuidle_driver *drv, int idx)
> > +{
> > +   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, idx);
> > +}
> > +
> > +static struct cpuidle_driver psci_idle_driver __initdata = {
> > +   .name = "psci_idle",
> > +   .owner = THIS_MODULE,
> > +   /*
> > +* PSCI idle states relies on architectural WFI to
> > +* be represented as state index 0.
> > +*/
> > +   .states[0] = {
> > +   .enter  = psci_enter_idle_state,
> > +   .exit_latency   = 1,
> > +   .target_residency   = 1,
> > +   .power_usage= UINT_MAX,
> > +   .name   = "WFI",
> > +   .desc   = "ARM WFI",
> > +   }
> > +};
> > +
> > +static const struct of_device_id psci_idle_state_match[] __initconst = {
> > +   { .compatible = "arm,idle-state",
> > + .data = psci_enter_idle_state },
> > +   { },
> > +};
> > +
> > +static int __init psci_idle_init_cpu(int cpu)
> > +{
> > +   struct cpuidle_driver *drv;
> > +   struct device_node *cpu_node;
> > +   const char *enable_method;
> > +   int ret = 0;
> > +
> > +   drv = kmemdup(_idle_driver, sizeof(*drv), GFP_KERNEL);
> > +   if (!drv)
> > +   return -ENOMEM;
> > +
> > +   drv->cpumask = (struct cpumask *)cpumask_of(cpu);
> > +
> > +   cpu_node = of_get_cpu_node(cpu, NULL);
> > +   if (!cpu_node)
> > +   return -ENODEV;
> 
> You should free drv in case of error here (goto out_kfree_drv; etc).
> 
> > +
> > +   /*
> > +* Check whether the enable-method for the cpu is PSCI, fail
> > +* if it is not.
> > +*/
> > +   enable_method = of_get_property(cpu_node, "enable-method", NULL);
> > +   if (!enable_method || (strcmp(enable_method, "psci")))
> > +   ret = -ENODEV;
> > +
> > +   of_node_put(cpu_node);
> > +   if (ret)
> > +   return ret;
> 
> You should free drv in case of error here (goto out_kfree_drv;).

True on both cases, I missed that, thanks.

Lorenzo

> > +
> > +   /*
> > +* Initialize idle states data, starting at index 1, since
> > +* by default idle state 0 is the quiescent state reached
> > +* by the cpu by executing the wfi instruction.
> > +*
> > +* If no DT idle states are detected (ret == 0) let the driver
> > +* initialization fail accordingly since there is no reason to
> > +* initialize the idle driver if only wfi is supported, the
> > +* default archictectural back-end already executes wfi
> > +* on idle entry.
> > +*/
> > +   ret = dt_init_idle_driver(drv, psci_idle_state_match, 1);
> > +   if (ret <= 0) {
> > +   ret = ret ? : -ENODEV;
> > +   goto out_kfree_drv;
> > +   }
> > +
> > +   /*
> > +* Initialize PSCI idle states.
> > +*/
> > +   ret = psci_cpu_init_idle(cpu);
> > +   if (ret) {
> > +   pr_err("CPU %d failed to PSCI idle\n", cpu);
> > +   goto out_kfree_drv;
> > +   }
> > +
> > +   ret = cpuidle_register(drv, NULL);
> > +   if (ret)
> > +   goto out_kfree_drv;
> > +
> > +   return 0;
> > +
> > +out_kfree_drv:
> > +   kfree(drv);
> > +   return ret;
> > +}
> > +
> 
> [...]
> 
> Kind regards
> Uffe


[PATCH] ACPI/IORT: Fix off-by-one check in iort_dev_find_its_id()

2019-07-22 Thread Lorenzo Pieralisi
Static analysis identified that index comparison against ITS entries in
iort_dev_find_its_id() is off by one.

Update the comparison condition and clarify the resulting error
message.

Fixes: 4bf2efd26d76 ("ACPI: Add new IORT functions to support MSI domain 
handling")
Link: https://lore.kernel.org/linux-arm-kernel/20190613065410.GB16334@mwanda/
Reported-by: Dan Carpenter 
Signed-off-by: Lorenzo Pieralisi 
Cc: Dan Carpenter 
Cc: Will Deacon 
Cc: Hanjun Guo 
Cc: Sudeep Holla 
Cc: Catalin Marinas 
Cc: Robin Murphy 
---
 drivers/acpi/arm64/iort.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 15dbfd657d82..5a7551d060f2 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -611,8 +611,8 @@ static int iort_dev_find_its_id(struct device *dev, u32 
req_id,
 
/* Move to ITS specific data */
its = (struct acpi_iort_its_group *)node->node_data;
-   if (idx > its->its_count) {
-   dev_err(dev, "requested ITS ID index [%d] is greater than 
available [%d]\n",
+   if (idx >= its->its_count) {
+   dev_err(dev, "requested ITS ID index [%d] overruns ITS entries 
[%d]\n",
idx, its->its_count);
return -ENXIO;
}
-- 
2.21.0



[PATCH] ACPI/IORT: Rename arm_smmu_v3_set_proximity() 'node' local variable

2019-07-22 Thread Lorenzo Pieralisi
Commit 36a2ba07757d ("ACPI/IORT: Reject platform device creation on NUMA
node mapping failure") introduced a local variable 'node' in
arm_smmu_v3_set_proximity() that shadows the struct acpi_iort_node
pointer function parameter.

Execution was unaffected but it is prone to errors and can lead
to subtle bugs.

Rename the local variable to prevent any issue.

Reported-by: Will Deacon 
Signed-off-by: Lorenzo Pieralisi 
Cc: Will Deacon 
Cc: Hanjun Guo 
Cc: Sudeep Holla 
Cc: Catalin Marinas 
Cc: Robin Murphy 
Cc: Kefeng Wang 
---
 drivers/acpi/arm64/iort.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index d4551e33fa71..15dbfd657d82 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1256,12 +1256,12 @@ static int  __init arm_smmu_v3_set_proximity(struct 
device *dev,
 
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
-   int node = acpi_map_pxm_to_node(smmu->pxm);
+   int dev_node = acpi_map_pxm_to_node(smmu->pxm);
 
-   if (node != NUMA_NO_NODE && !node_online(node))
+   if (dev_node != NUMA_NO_NODE && !node_online(dev_node))
return -EINVAL;
 
-   set_dev_node(dev, node);
+   set_dev_node(dev, dev_node);
pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n",
smmu->base_address,
smmu->pxm);
-- 
2.21.0



[PATCH 1/6] ARM: cpuidle: Remove useless header include

2019-07-22 Thread Lorenzo Pieralisi
The generic ARM CPUidle driver includes  by mistake.

Remove the topology header include.

Signed-off-by: Lorenzo Pieralisi 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: "Rafael J. Wysocki" 
---
 drivers/cpuidle/cpuidle-arm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 5bcd82c35dcf..dc33b3d2954f 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 
-- 
2.21.0



[PATCH 3/6] drivers: firmware: psci: Decouple checker from generic ARM CPUidle

2019-07-22 Thread Lorenzo Pieralisi
The PSCI checker currently relies on the generic ARM CPUidle
infrastructure to enter an idle state, which in turn creates
a dependency that is not really needed.

The PSCI checker code to test PSCI CPU suspend is built on
top of the CPUidle framework and can easily reuse the
struct cpuidle_state.enter() function (previously initialized
by an idle driver, with a PSCI back-end) to trigger an entry
into an idle state, decoupling the PSCI checker from the
generic ARM CPUidle infrastructure and simplyfing the code
in the process.

Convert the PSCI checker suspend entry function to use
the struct cpuidle_state.enter() function callback.

Signed-off-by: Lorenzo Pieralisi 
Cc: Sudeep Holla 
Cc: Mark Rutland 
---
 drivers/firmware/psci/psci_checker.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/psci/psci_checker.c 
b/drivers/firmware/psci/psci_checker.c
index f3659443f8c2..6a445397771c 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -228,8 +228,11 @@ static int hotplug_tests(void)
 
 static void dummy_callback(struct timer_list *unused) {}
 
-static int suspend_cpu(int index, bool broadcast)
+static int suspend_cpu(struct cpuidle_device *dev,
+  struct cpuidle_driver *drv, int index)
 {
+   struct cpuidle_state *state = >states[index];
+   bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
int ret;
 
arch_cpu_idle_enter();
@@ -254,11 +257,7 @@ static int suspend_cpu(int index, bool broadcast)
}
}
 
-   /*
-* Replicate the common ARM cpuidle enter function
-* (arm_enter_idle_state).
-*/
-   ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
+   ret = state->enter(dev, drv, index);
 
if (broadcast)
tick_broadcast_exit();
@@ -301,9 +300,8 @@ static int suspend_test_thread(void *arg)
 * doesn't use PSCI).
 */
for (index = 1; index < drv->state_count; ++index) {
-   struct cpuidle_state *state = >states[index];
-   bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
int ret;
+   struct cpuidle_state *state = >states[index];
 
/*
 * Set the timer to wake this CPU up in some time (which
@@ -318,7 +316,7 @@ static int suspend_test_thread(void *arg)
/* IRQs must be disabled during suspend operations. */
local_irq_disable();
 
-   ret = suspend_cpu(index, broadcast);
+   ret = suspend_cpu(dev, drv, index);
 
/*
 * We have woken up. Re-enable IRQs to handle any
-- 
2.21.0



[PATCH 2/6] ARM: cpuidle: Remove overzealous error logging

2019-07-22 Thread Lorenzo Pieralisi
CPUidle back-end operations are not implemented in some platforms
but this should not be considered an error serious enough to be
logged. Check the arm_cpuidle_init() return value to detect whether
the failure must be reported or not in the kernel log and do
not log it if the platform does not support CPUidle operations.

Signed-off-by: Lorenzo Pieralisi 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: "Rafael J. Wysocki" 
---
 drivers/cpuidle/cpuidle-arm.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index dc33b3d2954f..9e5156d39627 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -105,11 +105,17 @@ static int __init arm_idle_init_cpu(int cpu)
ret = arm_cpuidle_init(cpu);
 
/*
-* Allow the initialization to continue for other CPUs, if the reported
-* failure is a HW misconfiguration/breakage (-ENXIO).
+* Allow the initialization to continue for other CPUs, if the
+* reported failure is a HW misconfiguration/breakage (-ENXIO).
+*
+* Some platforms do not support idle operations
+* (arm_cpuidle_init() returning -EOPNOTSUPP), we should
+* not flag this case as an error, it is a valid
+* configuration.
 */
if (ret) {
-   pr_err("CPU %d failed to init idle CPU ops\n", cpu);
+   if (ret != -EOPNOTSUPP)
+   pr_err("CPU %d failed to init idle CPU ops\n", cpu);
ret = ret == -ENXIO ? 0 : ret;
goto out_kfree_drv;
}
-- 
2.21.0



[PATCH 6/6] PSCI: cpuidle: Refactor CPU suspend power_state parameter handling

2019-07-22 Thread Lorenzo Pieralisi
Current PSCI code handles idle state entry through the
psci_cpu_suspend_enter() API, that takes an idle state index as a
parameter and convert the index into a previously initialized
power_state parameter before calling the PSCI.CPU_SUSPEND() with it.

This is unwieldly, since it forces the PSCI firmware layer to keep track
of power_state parameter for every idle state so that the
index->power_state conversion can be made in the PSCI firmware layer
instead of the CPUidle driver implementations.

Move the power_state handling out of drivers/firmware/psci
into the respective ACPI/DT PSCI CPUidle backends and convert
the psci_cpu_suspend_enter() API to get the power_state
parameter as input, which makes it closer to its firmware
interface PSCI.CPU_SUSPEND() API.

A notable side effect is that the PSCI ACPI/DT CPUidle backends
now can directly handle (and if needed update) power_state
parameters before handing them over to the PSCI firmware
interface to trigger PSCI.CPU_SUSPEND() calls.

Signed-off-by: Lorenzo Pieralisi 
Cc: Will Deacon 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Catalin Marinas 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 
---
 arch/arm64/kernel/cpuidle.c|  47 +-
 drivers/cpuidle/cpuidle-psci.c |  87 +-
 drivers/firmware/psci/psci.c   | 158 ++---
 include/linux/cpuidle.h|  17 +++-
 include/linux/psci.h   |   4 +-
 5 files changed, 153 insertions(+), 160 deletions(-)

diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index 4bcd1bca0dfc..e4d6af2fdec7 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -47,6 +47,44 @@ int arm_cpuidle_suspend(int index)
 
 #define ARM64_LPI_IS_RETENTION_STATE(arch_flags) (!(arch_flags))
 
+static int psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+   int i, count;
+   struct acpi_lpi_state *lpi;
+   struct acpi_processor *pr = per_cpu(processors, cpu);
+
+   /*
+* If the PSCI cpu_suspend function hook has not been initialized
+* idle states must not be enabled, so bail out
+*/
+   if (!psci_ops.cpu_suspend)
+   return -EOPNOTSUPP;
+
+   if (unlikely(!pr || !pr->flags.has_lpi))
+   return -EINVAL;
+
+   count = pr->power.count - 1;
+   if (count <= 0)
+   return -ENODEV;
+
+   for (i = 0; i < count; i++) {
+   u32 state;
+
+   lpi = >power.lpi_states[i + 1];
+   /*
+* Only bits[31:0] represent a PSCI power_state while
+* bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
+*/
+   state = lpi->address;
+   if (!psci_power_state_is_valid(state)) {
+   pr_warn("Invalid PSCI power state %#x\n", state);
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+
 int acpi_processor_ffh_lpi_probe(unsigned int cpu)
 {
return psci_acpi_cpu_init_idle(cpu);
@@ -54,10 +92,13 @@ int acpi_processor_ffh_lpi_probe(unsigned int cpu)
 
 int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
 {
+   u32 state = lpi->address;
+
if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
-   return CPU_PM_CPU_IDLE_ENTER_RETENTION(psci_cpu_suspend_enter,
-   lpi->index);
+   return 
CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(psci_cpu_suspend_enter,
+   lpi->index, state);
else
-   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, 
lpi->index);
+   return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+lpi->index, state);
 }
 #endif
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
index bdf02600e4e2..7485b3abe372 100644
--- a/drivers/cpuidle/cpuidle-psci.c
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -21,10 +21,15 @@
 
 #include "dt_idle_states.h"
 
+static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+
 static int psci_enter_idle_state(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int idx)
 {
-   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, idx);
+   u32 *state = __this_cpu_read(psci_power_state);
+
+   return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+  idx, state[idx - 1]);
 }
 
 static struct cpuidle_driver psci_idle_driver __initdata = {
@@ -50,6 +55,86 @@ static const struct of_device_id psci_idle_state_match[] 
__initconst = {
{ },
 };
 
+static int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
+{
+   int err = of_property_read_u32(np, "arm,psci-suspend-param", state);
+
+   if (err) {
+   pr_warn(&q

[PATCH 0/6] ARM: psci: cpuidle: PSCI CPUidle rework

2019-07-22 Thread Lorenzo Pieralisi
Current PSCI CPUidle driver is built on top of the generic ARM
CPUidle infrastructure that relies on the architectural back-end
idle operations to initialize and enter idle states.

On ARM64 systems, PSCI is the only interface the kernel ever uses
to enter idle states, so, having to rely on a generic ARM CPUidle
driver when there is and there will always be only one method
for entering idle states proved to be overkill, more so given
that on ARM 32-bit systems (that can also enable the generic
ARM CPUidle driver) only one additional idle back-end was
ever added:

drivers/soc/qcom/spm.c

and it can be easily converted to a full-fledged CPUidle driver
without requiring the generic ARM CPUidle framework.

Furthermore, the generic ARM CPUidle infrastructure forces the
PSCI firmware layer to keep CPUidle specific information in it,
which does not really fit its purpose that should be kernel
control/data structure agnostic.

Lastly, the interface between the generic ARM CPUidle driver and
the arch back-end requires an idle state index to be passed to
suspend operations, with idle states back-end internals (such
as idle state parameters) hidden in architectural back-ends and
not available to the generic ARM CPUidle driver.

To improve the above mentioned shortcomings, implement a stand
alone PSCI CPUidle driver; this improves the current kernel
code from several perspective:

- Move CPUidle internal knowledge into CPUidle driver out of
  the PSCI firmware interface
- Give the PSCI CPUidle driver control over power state parameters,
  in particular in preparation for PSCI OSI support
- Remove generic CPUidle operations infrastructure from the kernel

This patchset does not go as far as removing the generic ARM CPUidle
infrastructure in order to collect feedback on the new approach
before completing the removal from the kernel, the generic and PSCI
CPUidle driver are left to co-exist.

Tested on Juno platform with both DT and ACPI boot firmwares.

Cc: Will Deacon 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Catalin Marinas 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 

Lorenzo Pieralisi (6):
  ARM: cpuidle: Remove useless header include
  ARM: cpuidle: Remove overzealous error logging
  drivers: firmware: psci: Decouple checker from generic ARM CPUidle
  ARM: psci: cpuidle: Introduce PSCI CPUidle driver
  ARM: psci: cpuidle: Enable PSCI CPUidle driver
  PSCI: cpuidle: Refactor CPU suspend power_state parameter handling

 MAINTAINERS  |   8 +
 arch/arm/configs/imx_v6_v7_defconfig |   1 +
 arch/arm64/configs/defconfig |   1 +
 arch/arm64/kernel/cpuidle.c  |  50 +-
 arch/arm64/kernel/psci.c |   4 -
 drivers/cpuidle/Kconfig.arm  |   7 +
 drivers/cpuidle/Makefile |   1 +
 drivers/cpuidle/cpuidle-arm.c|  13 +-
 drivers/cpuidle/cpuidle-psci.c   | 235 +++
 drivers/firmware/psci/psci.c | 167 +--
 drivers/firmware/psci/psci_checker.c |  16 +-
 include/linux/cpuidle.h  |  17 +-
 include/linux/psci.h |   4 +-
 13 files changed, 338 insertions(+), 186 deletions(-)
 create mode 100644 drivers/cpuidle/cpuidle-psci.c

-- 
2.21.0



[PATCH 5/6] ARM: psci: cpuidle: Enable PSCI CPUidle driver

2019-07-22 Thread Lorenzo Pieralisi
Allow selection of the PSCI CPUidle in the kernel by adding
the required Kconfig options.

Remove PSCI callbacks from ARM/ARM64 generic CPU ops
to prevent the PSCI idle driver from clashing with the generic
ARM CPUidle driver initialization, that relies on CPU ops
to initialize and enter idle states.

Update the affected defconfig files to guarantee seamingless
transition from the generic ARM CPUidle to the PSCI CPUidle
driver on arch/platforms using it.

Signed-off-by: Lorenzo Pieralisi 
Cc: Will Deacon 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Catalin Marinas 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 
---
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 arch/arm64/configs/defconfig | 1 +
 arch/arm64/kernel/cpuidle.c  | 7 ---
 arch/arm64/kernel/psci.c | 4 
 drivers/cpuidle/Kconfig.arm  | 8 ++--
 drivers/firmware/psci/psci.c | 9 -
 6 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig 
b/arch/arm/configs/imx_v6_v7_defconfig
index a53b29251ed4..4174fd1b79e7 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -60,6 +60,7 @@ CONFIG_ARM_IMX6Q_CPUFREQ=y
 CONFIG_ARM_IMX_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_PM_DEBUG=y
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0e58ef02880c..c0a7cfe3aebd 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -72,6 +72,7 @@ CONFIG_RANDOMIZE_BASE=y
 CONFIG_HIBERNATION=y
 CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
 CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_STAT=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=m
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index d1048173fd8a..4bcd1bca0dfc 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -48,15 +49,15 @@ int arm_cpuidle_suspend(int index)
 
 int acpi_processor_ffh_lpi_probe(unsigned int cpu)
 {
-   return arm_cpuidle_init(cpu);
+   return psci_acpi_cpu_init_idle(cpu);
 }
 
 int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
 {
if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
-   return CPU_PM_CPU_IDLE_ENTER_RETENTION(arm_cpuidle_suspend,
+   return CPU_PM_CPU_IDLE_ENTER_RETENTION(psci_cpu_suspend_enter,
lpi->index);
else
-   return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, lpi->index);
+   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, 
lpi->index);
 }
 #endif
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 85ee7d07889e..a543ab7e007c 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -105,10 +105,6 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 
 const struct cpu_operations cpu_psci_ops = {
.name   = "psci",
-#ifdef CONFIG_CPU_IDLE
-   .cpu_init_idle  = psci_cpu_init_idle,
-   .cpu_suspend= psci_cpu_suspend_enter,
-#endif
.cpu_init   = cpu_psci_cpu_init,
.cpu_prepare= cpu_psci_cpu_prepare,
.cpu_boot   = cpu_psci_cpu_boot,
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 929b57424ea4..b9c56c60ab98 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -14,8 +14,12 @@ config ARM_CPUIDLE
   provided by architecture code.
 
 config ARM_PSCI_CPUIDLE
-   bool
-
+   bool "PSCI CPU idle Driver"
+   depends on ARM_PSCI_FW
+   select DT_IDLE_STATES
+   select CPU_IDLE_MULTIPLE_DRIVERS
+   help
+ Select this to enable PSCI firmware based CPUidle driver for ARM.
 config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors"
depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index f82ccd39a913..bae734d13a52 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -436,15 +436,6 @@ int psci_cpu_suspend_enter(unsigned long index)
 
return ret;
 }
-
-/* ARM specific CPU idle operations */
-#ifdef CONFIG_ARM
-static const struct cpuidle_ops psci_cpuidle_ops __initconst = {
-   .suspend = psci_cpu_suspend_enter,
-   .init = psci_dt_cpu_init_idle,
-};
-
-CPUIDLE_METHOD_OF_DECLARE(psci, "psci", _cpuidle_ops);
 #endif
 #endif
 
-- 
2.21.0



[PATCH 4/6] ARM: psci: cpuidle: Introduce PSCI CPUidle driver

2019-07-22 Thread Lorenzo Pieralisi
PSCI firmware is the standard power management control for
all ARM64 based platforms and it is also deployed on some
ARM 32 bit platforms to date.

Idle state entry in PSCI is currently achieved by calling
arm_cpuidle_init() and arm_cpuidle_suspend() in a generic
idle driver, which in turn relies on ARM/ARM64 CPUidle back-end
to relay the call into PSCI firmware if PSCI is the boot method.

Given that PSCI is the standard idle entry method on ARM64 systems
(which means that no other CPUidle driver are expected on ARM64
platforms - so PSCI is already a generic idle driver), in order to
simplify idle entry and code maintenance, it makes sense to have a PSCI
specific idle driver so that idle code that it is currently living in
drivers/firmware directory can be hoisted out of it and moved
where it belongs, into a full-fledged PSCI driver, leaving PSCI code
in drivers/firmware as a pure firmware interface, as it should be.

Implement a PSCI CPUidle driver. By default it is a silent Kconfig entry
which is left unselected, since it selection would clash with the
generic ARM CPUidle driver that provides a PSCI based idle driver
through the arm/arm64 arches back-ends CPU operations.

Signed-off-by: Lorenzo Pieralisi 
Cc: Ulf Hansson 
Cc: Sudeep Holla 
Cc: Daniel Lezcano 
Cc: Mark Rutland 
Cc: "Rafael J. Wysocki" 
---
 MAINTAINERS|   8 ++
 drivers/cpuidle/Kconfig.arm|   3 +
 drivers/cpuidle/Makefile   |   1 +
 drivers/cpuidle/cpuidle-psci.c | 150 +
 4 files changed, 162 insertions(+)
 create mode 100644 drivers/cpuidle/cpuidle-psci.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 783569e3c4b4..c2bf8ce65e83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4286,6 +4286,14 @@ S:   Supported
 F: drivers/cpuidle/cpuidle-exynos.c
 F: arch/arm/mach-exynos/pm.c
 
+CPUIDLE DRIVER - ARM PSCI
+M:     Lorenzo Pieralisi 
+M: Sudeep Holla 
+L: linux...@vger.kernel.org
+L: linux-arm-ker...@lists.infradead.org
+S: Supported
+F: drivers/cpuidle/cpuidle-psci.c
+
 CPU IDLE TIME MANAGEMENT FRAMEWORK
 M: "Rafael J. Wysocki" 
 M: Daniel Lezcano 
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 48cb3d4bb7d1..929b57424ea4 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -13,6 +13,9 @@ config ARM_CPUIDLE
   initialized by calling the CPU operations init idle hook
   provided by architecture code.
 
+config ARM_PSCI_CPUIDLE
+   bool
+
 config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors"
depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 9d7176cee3d3..40d016339b29 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)  += cpuidle-at91.o
 obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)+= cpuidle-exynos.o
 obj-$(CONFIG_ARM_CPUIDLE)  += cpuidle-arm.o
+obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
 
 ###
 # MIPS drivers
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
new file mode 100644
index ..bdf02600e4e2
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PSCI CPU idle driver.
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ * Author: Lorenzo Pieralisi 
+ */
+
+#define pr_fmt(fmt) "CPUidle PSCI: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dt_idle_states.h"
+
+static int psci_enter_idle_state(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv, int idx)
+{
+   return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, idx);
+}
+
+static struct cpuidle_driver psci_idle_driver __initdata = {
+   .name = "psci_idle",
+   .owner = THIS_MODULE,
+   /*
+* PSCI idle states relies on architectural WFI to
+* be represented as state index 0.
+*/
+   .states[0] = {
+   .enter  = psci_enter_idle_state,
+   .exit_latency   = 1,
+   .target_residency   = 1,
+   .power_usage= UINT_MAX,
+   .name   = "WFI",
+   .desc   = "ARM WFI",
+   }
+};
+
+static const struct of_device_id psci_idle_state_match[] __initconst = {
+   { .compatible = "arm,idle-state",
+ .data = psci_enter_idle_state },
+   { },
+};
+
+static int __init psci_idle_init_cpu(int cpu)
+{
+   struct cpuidle_driver *drv;
+   struct device_node *cpu_node;
+   const char *enable_method;
+   int 

Re: [PATCH AUTOSEL 4.14 41/60] PCI: tegra: Enable Relaxed Ordering only for Tegra20 & Tegra30

2019-07-19 Thread Lorenzo Pieralisi
On Fri, Jul 19, 2019 at 12:10:50AM -0400, Sasha Levin wrote:
> From: Vidya Sagar 
> 
> [ Upstream commit 7be142caabc4780b13a522c485abc806de5c4114 ]
> 
> The PCI Tegra controller conversion to a device tree configurable
> driver in commit d1523b52bff3 ("PCI: tegra: Move PCIe driver
> to drivers/pci/host") implied that code for the driver can be
> compiled in for a kernel supporting multiple platforms.
> 
> Unfortunately, a blind move of the code did not check that some of the
> quirks that were applied in arch/arm (eg enabling Relaxed Ordering on
> all PCI devices - since the quirk hook erroneously matches PCI_ANY_ID
> for both Vendor-ID and Device-ID) are now applied in all kernels that
> compile the PCI Tegra controlled driver, DT and ACPI alike.
> 
> This is completely wrong, in that enablement of Relaxed Ordering is only
> required by default in Tegra20 platforms as described in the Tegra20
> Technical Reference Manual (available at
> https://developer.nvidia.com/embedded/downloads#?search=tegra%202 in
> Section 34.1, where it is mentioned that Relaxed Ordering bit needs to
> be enabled in its root ports to avoid deadlock in hardware) and in the
> Tegra30 platforms for the same reasons (unfortunately not documented
> in the TRM).
> 
> There is no other strict requirement on PCI devices Relaxed Ordering
> enablement on any other Tegra platforms or PCI host bridge driver.
> 
> Fix this quite upsetting situation by limiting the vendor and device IDs
> to which the Relaxed Ordering quirk applies to the root ports in
> question, reported above.
> 
> Signed-off-by: Vidya Sagar 
> [lorenzo.pieral...@arm.com: completely rewrote the commit log/fixes tag]
> Signed-off-by: Lorenzo Pieralisi 
> Acked-by: Thierry Reding 
> Signed-off-by: Sasha Levin 

Hi Sasha,

as Jon requested, please drop this patch from the autosel patch
queue, thank you very much.

Lorenzo

> ---
>  drivers/pci/host/pci-tegra.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
> index 1987fec1f126..d2ad76ef3e83 100644
> --- a/drivers/pci/host/pci-tegra.c
> +++ b/drivers/pci/host/pci-tegra.c
> @@ -607,12 +607,15 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, 
> tegra_pcie_fixup_class);
>  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, 
> tegra_pcie_fixup_class);
>  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, 
> tegra_pcie_fixup_class);
>  
> -/* Tegra PCIE requires relaxed ordering */
> +/* Tegra20 and Tegra30 PCIE requires relaxed ordering */
>  static void tegra_pcie_relax_enable(struct pci_dev *dev)
>  {
>   pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
>  }
> -DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf0, 
> tegra_pcie_relax_enable);
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, 
> tegra_pcie_relax_enable);
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, 
> tegra_pcie_relax_enable);
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, 
> tegra_pcie_relax_enable);
>  
>  static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
>  {
> -- 
> 2.20.1
> 


Re: [PATCH 01/18] dt: psci: Update DT bindings to support hierarchical PSCI states

2019-07-19 Thread Lorenzo Pieralisi
On Mon, May 13, 2019 at 09:22:43PM +0200, Ulf Hansson wrote:
> From: Lina Iyer 
> 
> Update DT bindings to represent hierarchical CPU and CPU PM domain idle
> states for PSCI. Also update the PSCI examples to clearly show how
> flattened and hierarchical idle states can be represented in DT.
> 
> Signed-off-by: Lina Iyer 
> Reviewed-by: Rob Herring 
> Reviewed-by: Sudeep Holla 
> Co-developed-by: Ulf Hansson 
> Signed-off-by: Ulf Hansson 
> ---
> 
> Changes:
>   - None.
> 
> ---
>  .../devicetree/bindings/arm/psci.txt  | 166 ++
>  1 file changed, 166 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/psci.txt 
> b/Documentation/devicetree/bindings/arm/psci.txt
> index a2c4f1d52492..e6d3553c8df8 100644
> --- a/Documentation/devicetree/bindings/arm/psci.txt
> +++ b/Documentation/devicetree/bindings/arm/psci.txt
> @@ -105,7 +105,173 @@ Case 3: PSCI v0.2 and PSCI v0.1.
>   ...
>   };
>  
> +ARM systems can have multiple cores sometimes in hierarchical arrangement.
> +This often, but not always, maps directly to the processor power topology of
> +the system. Individual nodes in a topology have their own specific power 
> states
> +and can be better represented in DT hierarchically.
> +
> +For these cases, the definitions of the idle states for the CPUs and the CPU
> +topology, must conform to the domain idle state specification [3]. The domain
> +idle states themselves, must be compatible with the defined 
> 'domain-idle-state'
> +binding [1], and also need to specify the arm,psci-suspend-param property for
> +each idle state.
> +
> +DT allows representing CPUs and CPU idle states in two different ways -
> +
> +The flattened model as given in Example 1, lists CPU's idle states followed 
> by
> +the domain idle state that the CPUs may choose. Note that the idle states are
> +all compatible with "arm,idle-state". Additionally, for the domain idle state
> +the "arm,psci-suspend-param" represents a superset of the CPU's idle state.
> +
> +Example 2 represents the hierarchical model of CPUs and domain idle states.
> +CPUs define their domain provider in their psci DT node. The domain controls
> +the power to the CPU and possibly other h/w blocks that would enter an idle
> +state along with the CPU. The CPU's idle states may therefore be considered 
> as
> +the domain's idle states and have the compatible "arm,idle-state". Such 
> domains
> +may also be embedded within another domain that may represent common h/w 
> blocks
> +between these CPUs. The idle states of the CPU topology shall be represented 
> as
> +the domain's idle states. Note that for the domain idle state, the
> +"arm,psci-suspend-param" represents idle states hierarchically.
> +
> +In PSCI firmware v1.0, the OS-Initiated mode is introduced. However, the
> +flattened vs hierarchical DT representation is orthogonal to the OS-Initiated
> +vs the platform-coordinated PSCI CPU suspend modes, thus should be considered
> +independent of each other.
> +
> +The hierarchical representation helps and makes it easy to implement OSI mode
> +and OS implementations may choose to mandate it. For the default platform-
> +coordinated mode, both representations are viable options.
> +
> +Example 1: Flattened representation of CPU and domain idle states
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + CPU0: cpu@0 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a53", "arm,armv8";
> + reg = <0x0>;
> + enable-method = "psci";
> + cpu-idle-states = <_PWRDN>, <_RET>,
> +   <_PWRDN>;
> + };
> +
> + CPU1: cpu@1 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a57", "arm,armv8";
> + reg = <0x100>;
> + enable-method = "psci";
> + cpu-idle-states = <_PWRDN>, <_RET>,
> +   <_PWRDN>;
> + };
> +
> + idle-states {
> + CPU_PWRDN: cpu-power-down {
> + compatible = "arm,idle-state";
> + arm,psci-suspend-param = <0x001>;

This value is wrong, StateType must be 1 for CPU power down states.

> + entry-latency-us = <10>;
> + exit-latency-us = <10>;
> + min-residency-us = <100>;
> + };
> +
> + CLUSTER_RET: cluster-retention {
> + compatible = "arm,idle-state";
> + arm,psci-suspend-param = <0x111>;

It must be made crystal clear that this is the *full* power_state
that is passed to the CPU_SUSPEND call. It is already specified
in the bindings.

As Sudeep pointed out already, OR'ing 

Re: [PATCH 14/18] drivers: firmware: psci: Manage runtime PM in the idle path for CPUs

2019-07-19 Thread Lorenzo Pieralisi
On Thu, Jul 18, 2019 at 11:49:11PM +0200, Ulf Hansson wrote:
> On Thu, 18 Jul 2019 at 19:41, Lina Iyer  wrote:
> >
> > On Thu, Jul 18 2019 at 10:55 -0600, Ulf Hansson wrote:
> > >On Thu, 18 Jul 2019 at 15:31, Lorenzo Pieralisi
> > > wrote:
> > >>
> > >> On Thu, Jul 18, 2019 at 12:35:07PM +0200, Ulf Hansson wrote:
> > >> > On Tue, 16 Jul 2019 at 17:53, Lorenzo Pieralisi
> > >> >  wrote:
> > >> > >
> > >> > > On Mon, May 13, 2019 at 09:22:56PM +0200, Ulf Hansson wrote:
> > >> > > > When the hierarchical CPU topology layout is used in DT, let's 
> > >> > > > allow the
> > >> > > > CPU to be power managed through its PM domain, via deploying 
> > >> > > > runtime PM
> > >> > > > support.
> > >> > > >
> > >> > > > To know for which idle states runtime PM reference counting is 
> > >> > > > needed,
> > >> > > > let's store the index of deepest idle state for the CPU, in a per 
> > >> > > > CPU
> > >> > > > variable. This allows psci_cpu_suspend_enter() to compare this 
> > >> > > > index with
> > >> > > > the requested idle state index and then act accordingly.
> > >> > >
> > >> > > I do not see why a system with two CPU CPUidle states, say CPU 
> > >> > > retention
> > >> > > and CPU shutdown, should not be calling runtime PM on CPU retention
> > >> > > entry.
> > >> >
> > >> > If the CPU idle governor did select the CPU retention for the CPU, it
> > >> > was probably because the target residency for the CPU shutdown state
> > >> > could not be met.
> > >>
> > >> The kernel does not know what those cpu states represent, so, this is an
> > >> assumption you are making and it must be made clear that this code works
> > >> as long as your assumption is valid.
> > >>
> > >> If eg a "cluster" retention state has lower target_residency than
> > >> the deepest CPU idle state this assumption is wrong.
> > >
> > >Good point, you are right. I try to find a place to document this 
> > >assumption.
> > >
> > >>
> > >> And CPUidle and genPD governor decisions are not synced anyway so,
> > >> again, this is an assumption, not a certainty.
> > >>
> > >> > In this case, there is no point in allowing any other deeper idle
> > >> > states for cluster/package/system, since those have even greater
> > >> > residencies, hence calling runtime PM doesn't make sense.
> > >>
> > >> On the systems you are testing on.
> > >
> > >So what you are saying typically means, that if all CPUs in the same
> > >cluster have entered the CPU retention state, on some system the
> > >cluster may also put into a cluster retention state (assuming the
> > >target residency is met)?
> > >
> > >Do you know of any systems that has these characteristics?
> > >
> > Many QCOM SoCs can do that. But with the hardware improving, the
> > power-performance benefits skew the results in favor of powering off
> > the cluster than keeping the CPU and cluster in retention.
> >
> > Kevin H and I thought of this problem earlier on. But that is a second
> > level problem to solve and definitely to be thought of after we have the
> > support for the deepest states in the kernel. We left that out for a
> > later date. The idea would have been to setup the allowable state(s) in
> > the DT for CPU and cluster state definitions and have the genpd take
> > that into consideration when deciding the idle state for the domain.
> 
> Thanks for confirming.
> 
> This more or less means we need to improve the hierarchical support in
> genpd to support more levels, such that it makes sense to have a genpd
> governor assigned at more than one level. This doesn't work well
> today. As I also have stated, this is on my todo list for genpd.
> 
> However, I also agree with your standpoint, that let's start simple to
> enable the deepest state as a start with, then we can improve things
> on top.

How to solve this in the kernel I don't know but please do make sure
that the DT bindings allow you to describe what's needed, once they are
merged you won't be able to change them and I won't bodge the code to
make things fit, so if anything let's focus on getting them right as a
matter of priority to get this done please.

Thanks,
Lorenzo


Re: [PATCH 10/18] drivers: firmware: psci: Add hierarchical domain idle states converter

2019-07-18 Thread Lorenzo Pieralisi
On Thu, Jul 18, 2019 at 01:43:44PM +0200, Ulf Hansson wrote:

[...]

> > > Anyway, as a suggestion to address your concern, how about this:
> > >
> > > 1. Move some things out to a PSCI cpuidle driver. We need to decide
> > > more exactly on what to move and find the right level for the
> > > interfaces.
> >
> > I will do it and post patches asap.
> 
> Okay, so I will wait for you to converting the cpuidle-arm driver into
> a cpuidle-psci driver (and all the changes that comes with it) and
> then base my re-base my series on top.
> 
> Then, would you mind sharing (even in an early phase) a
> branch/git-tree so I can start re-basing my series on top?

Sure, I should be able to post at -rc1 and will publish a branch
here [1].

> > > 2. Don't attach the CPU to the PM domain topology in case the PSCI PC
> > > mode is used. I think this makes it easier, at least as a first step,
> > > to understand when runtime PM needs to be used/enabled.
> >
> > In the PSCI CPUidle driver we can have two distinct struct
> > cpuidle_state->enter functions for PC and OSI, no overhead
> > for PC, runtime PM for OSI, decoupling done.
> 
> Good idea!
> 
> >
> > We can choose one or the other depending on whether:
> >
> > OSI iff:
> > - OSI is available
> > - hierarchical idle states are present in DT
> >
> > otherwise PC.
> >
> > That's what this patch does but we will do it in a unified file.
> 
> Sure, it makes sense.
> 
> >
> > > 3. Would it help if I volunteer to help you guys as a maintainer for
> > > PSCI. At least for the part of the new code that becomes introduced?
> >
> > We will do as described above if that makes sense.
> 
> Yep, I am okay with your suggestions, assuming I have understood them 
> correctly.
> 
> BTW, have you considered to host a git tree for PSCI so we can have
> changes pre-integrated and tested in Stephen Rothwell's linux-next
> tree?

I will ask Stephen to pull when needed a branch in the tree below[1]

[1] https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git/


Re: [PATCH 14/18] drivers: firmware: psci: Manage runtime PM in the idle path for CPUs

2019-07-18 Thread Lorenzo Pieralisi
On Thu, Jul 18, 2019 at 12:35:07PM +0200, Ulf Hansson wrote:
> On Tue, 16 Jul 2019 at 17:53, Lorenzo Pieralisi
>  wrote:
> >
> > On Mon, May 13, 2019 at 09:22:56PM +0200, Ulf Hansson wrote:
> > > When the hierarchical CPU topology layout is used in DT, let's allow the
> > > CPU to be power managed through its PM domain, via deploying runtime PM
> > > support.
> > >
> > > To know for which idle states runtime PM reference counting is needed,
> > > let's store the index of deepest idle state for the CPU, in a per CPU
> > > variable. This allows psci_cpu_suspend_enter() to compare this index with
> > > the requested idle state index and then act accordingly.
> >
> > I do not see why a system with two CPU CPUidle states, say CPU retention
> > and CPU shutdown, should not be calling runtime PM on CPU retention
> > entry.
> 
> If the CPU idle governor did select the CPU retention for the CPU, it
> was probably because the target residency for the CPU shutdown state
> could not be met.

The kernel does not know what those cpu states represent, so, this is an
assumption you are making and it must be made clear that this code works
as long as your assumption is valid.

If eg a "cluster" retention state has lower target_residency than
the deepest CPU idle state this assumption is wrong.

And CPUidle and genPD governor decisions are not synced anyway so,
again, this is an assumption, not a certainty.

> In this case, there is no point in allowing any other deeper idle
> states for cluster/package/system, since those have even greater
> residencies, hence calling runtime PM doesn't make sense.

On the systems you are testing on.

Lorenzo

> > The question then is what cluster/package/system states
> > are allowed for a given CPU idle state, to understand
> > what idle states can be actually entered at any hierarchy
> > level given the choice made for the CPU idle state.
> >
> > In the case above, a CPU entering retention state should prevent
> > runtime PM selecting a cluster shutdown state; most likely firmware
> > would demote the request to cluster retention but still, we should
> > find a way to describe these dependencies.
> 
> See above.
> 
> [...]
> 
> Kind regards
> Uffe


Re: [PATCH 14/18] drivers: firmware: psci: Manage runtime PM in the idle path for CPUs

2019-07-16 Thread Lorenzo Pieralisi
On Mon, May 13, 2019 at 09:22:56PM +0200, Ulf Hansson wrote:
> When the hierarchical CPU topology layout is used in DT, let's allow the
> CPU to be power managed through its PM domain, via deploying runtime PM
> support.
> 
> To know for which idle states runtime PM reference counting is needed,
> let's store the index of deepest idle state for the CPU, in a per CPU
> variable. This allows psci_cpu_suspend_enter() to compare this index with
> the requested idle state index and then act accordingly.

I do not see why a system with two CPU CPUidle states, say CPU retention
and CPU shutdown, should not be calling runtime PM on CPU retention
entry.

The question then is what cluster/package/system states
are allowed for a given CPU idle state, to understand
what idle states can be actually entered at any hierarchy
level given the choice made for the CPU idle state.

In the case above, a CPU entering retention state should prevent
runtime PM selecting a cluster shutdown state; most likely firmware
would demote the request to cluster retention but still, we should
find a way to describe these dependencies.

Thanks,
Lorenzo

> Signed-off-by: Ulf Hansson 
> ---
> 
> Changes:
>   - Simplify the code by using the new per CPU struct, that stores the
> needed struct device*.
> 
> ---
>  drivers/firmware/psci/psci.c | 22 --
>  1 file changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
> index 54e23d4ed0ea..2c4157d3a616 100644
> --- a/drivers/firmware/psci/psci.c
> +++ b/drivers/firmware/psci/psci.c
> @@ -20,6 +20,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -298,6 +299,7 @@ static int __init psci_features(u32 psci_func_id)
>  
>  struct psci_cpuidle_data {
>   u32 *psci_states;
> + u32 rpm_state_id;
>   struct device *dev;
>  };
>  
> @@ -385,6 +387,7 @@ static int psci_dt_cpu_init_idle(struct cpuidle_driver 
> *drv,
>   goto free_mem;
>  
>   data->dev = dev;
> + data->rpm_state_id = drv->state_count - 1;
>   }
>  
>   /* Idle states parsed correctly, store them in the per-cpu struct. */
> @@ -481,8 +484,11 @@ static int psci_suspend_finisher(unsigned long index)
>  int psci_cpu_suspend_enter(unsigned long index)
>  {
>   int ret;
> - u32 *state = __this_cpu_read(psci_cpuidle_data.psci_states);
> - u32 composite_state = state[index - 1] | psci_get_domain_state();
> + struct psci_cpuidle_data *data = this_cpu_ptr(_cpuidle_data);
> + u32 *states = data->psci_states;
> + struct device *dev = data->dev;
> + bool runtime_pm = (dev && data->rpm_state_id == index);
> + u32 composite_state;
>  
>   /*
>* idle state index 0 corresponds to wfi, should never be called
> @@ -491,11 +497,23 @@ int psci_cpu_suspend_enter(unsigned long index)
>   if (WARN_ON_ONCE(!index))
>   return -EINVAL;
>  
> + /*
> +  * Do runtime PM if we are using the hierarchical CPU toplogy, but only
> +  * when cpuidle have selected the deepest idle state for the CPU.
> +  */
> + if (runtime_pm)
> + pm_runtime_put_sync_suspend(dev);
> +
> + composite_state = states[index - 1] | psci_get_domain_state();
> +
>   if (!psci_power_state_loses_context(composite_state))
>   ret = psci_ops.cpu_suspend(composite_state, 0);
>   else
>   ret = cpu_suspend(index, psci_suspend_finisher);
>  
> + if (runtime_pm)
> + pm_runtime_get_sync(dev);
> +
>   /* Clear the domain state to start fresh when back from idle. */
>   psci_set_domain_state(0);
>  
> -- 
> 2.17.1
> 


Re: [PATCH 10/18] drivers: firmware: psci: Add hierarchical domain idle states converter

2019-07-16 Thread Lorenzo Pieralisi
On Tue, Jul 16, 2019 at 10:45:49AM +0200, Ulf Hansson wrote:

[...]

> > > +static void psci_pd_convert_states(struct cpuidle_state *idle_state,
> > > + u32 *psci_state, struct genpd_power_state *state)
> > > +{
> > > + u32 *state_data = state->data;
> > > + u64 target_residency_us = state->residency_ns;
> > > + u64 exit_latency_us = state->power_on_latency_ns +
> > > + state->power_off_latency_ns;
> > > +
> > > + *psci_state = *state_data;
> > > + do_div(target_residency_us, 1000);
> > > + idle_state->target_residency = target_residency_us;
> > > + do_div(exit_latency_us, 1000);
> > > + idle_state->exit_latency = exit_latency_us;
> > > + idle_state->enter = _pd_enter_pc;
> > > + idle_state->enter_s2idle = _pd_enter_s2idle_pc;
> > > + idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;
> >
> > This is arbitrary and not necessarily true.
> 
> The arbitrary thing you refer to here, is that the
> CPUIDLE_FLAG_TIMER_STOP? Or are you referring to the complete function
> psci_pd_convert_states()?

I refer to CPUIDLE_FLAG_TIMER_STOP. I think that on platform coordinated
system we should not bother about the hierarchical representation of the
states (I understand I asked you to make it work but it has become too
complex, I would rather focus on making the hierarchical representation
work for all idle states combination in OSI mode).

Plus side, another level of complexity removed.

> > I think that this patch is useful to represent my reservations about the
> > current approach. As a matter of fact, idle state entry will always be a
> > CPUidle decision.
> >
> > You only need PM domain information to understand when all CPUs
> > in a power domain are actually idle but that's all genPD can do
> > in this respect.
> >
> > I think this patchset would be much simpler if both CPUidle and
> > genPD governor would work on *one* set of idle states, globally
> > indexed (and that would be true for PSCI suspend parameters too).
> >
> > To work with a unified set of idle states between CPUidle and genPD
> > (tossing some ideas around):
> >
> > - We can implement a genPD CPUidle governor that in its select method
> >   takes into account genPD information (for instance by avoiding
> >   selection of idle states that require multiple cpus to be in idle
> >   to be effectively active)
> > - We can use genPD to enable/disable CPUidle states through runtime
> >   PM information
> 
> I don't understand how to make this work.
> 
> The CPUidle governor works on per CPU basis. The genpd governor works
> on per PM domain basis, which typically can be a group of CPUs (and
> even other devices) via subdomains, for example.
> 
> 1.
> In case of Linux being in *charge* of what idle state to pick for a
> group of CPUs, that decision is best done by the genpd governor as it
> operates on "groups" of CPUs. This is used for PSCI OSI mode. Of
> course, there are idle states also per CPU, which potentially could be
> managed by the genpd governor as well, but at this point I decided to
> re-use the cpuidle governor as it's already doing the job.
> 
> 2. In case the decision of what idle state to enter for the group is
> done by the FW, we can rely solely on the cpuidle governor and let it
> select states per CPU basis. This is used for PSCI PC mode.
> 
> >
> > There may be other ways. My point is that current code, with two (or
> > more if the hierarchy grows) sets of idle states across two subsystems
> > (CPUidle and genPD) is not very well defined and honestly very hard to
> > grasp and prone to errors.
> 
> The complexity is there, I admit that.
> 
> I guess some deeper insight about genpd+its governor+runtime PM are
> needed when reviewing this, of course. As an option, you may also have
> a look at my slides [1] from OSPM (Pisa) in May this year, which via
> flow charts try to describes things in more detail.
> 
> In our offlist meeting, we discussed that perhaps moving some of the
> new PSCI code introduced in this series, into a cpuidle driver
> instead, could make things more clear. For sure, I can explore that
> option, but before I go there, I think we should agree on it publicly.

I will do it but given that the generic idle infrastructure basically
is there for PSCI and:

drivers/soc/qcom/spm.c

if we create a PSCI CPUidle driver we can write one for qcom-spm and
remove the generic idle infrastructure, there would not be much
point in keeping it in the kernel; at least on ARM64 not using
PSCI for CPUidle is not even an option.

> In principle what it means is to invent a special cpuidle driver for
> PSCI, so we would need access to some of the PSCI internal functions,
> for example.

Yes.

> One thing though, the initialization of the PSCI PM domain topology is
> a separate step, managed via the new initcall, psci_dt_topology_init()
> (introduced in patch 11). That part still seems to be belong to the
> PSCI code, don't you think?

Yes but at least we can 

Re: [PATCH V13 12/12] PCI: tegra: Add Tegra194 PCIe support

2019-07-16 Thread Lorenzo Pieralisi
On Sat, Jul 13, 2019 at 12:34:34PM +0530, Vidya Sagar wrote:

[...]

> > > > > +static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw *pcie,
> > > > > +   bool enable)
> > > > > +{
> > > > > + struct mrq_uphy_response resp;
> > > > > + struct tegra_bpmp_message msg;
> > > > > + struct mrq_uphy_request req;
> > > > > + int err;
> > > > > +
> > > > > + if (pcie->cid == 5)
> > > > > + return 0;
> > > > 
> > > > What's wrong with cid == 5 ? Explain please.
> > > Controller with ID=5 doesn't need any programming to enable it which is
> > > done here through calling firmware API.
> > > 
> > > > 
> > > > > + memset(, 0, sizeof(req));
> > > > > + memset(, 0, sizeof(resp));
> > > > > +
> > > > > + req.cmd = CMD_UPHY_PCIE_CONTROLLER_STATE;
> > > > > + req.controller_state.pcie_controller = pcie->cid;
> > > > > + req.controller_state.enable = enable;
> > > > > +
> > > > > + memset(, 0, sizeof(msg));
> > > > > + msg.mrq = MRQ_UPHY;
> > > > > + msg.tx.data = 
> > > > > + msg.tx.size = sizeof(req);
> > > > > + msg.rx.data = 
> > > > > + msg.rx.size = sizeof(resp);
> > > > > +
> > > > > + if (irqs_disabled())
> > > > 
> > > > Can you explain to me what this check is meant to achieve please ?
> > > Firmware interface provides different APIs to be called when there are
> > > no interrupts enabled in the system (noirq context) and otherwise
> > > hence checking that situation here and calling appropriate API.
> > 
> > That's what I am questioning. Being called from {suspend/resume}_noirq()
> > callbacks (if that's the code path this check caters for) does not mean
> > irqs_disabled() == true.
> Agree.
> Actually, I got a hint of having this check from the following.
> Both tegra_bpmp_transfer_atomic() and tegra_bpmp_transfer() are indirectly
> called by APIs registered with .master_xfer() and .master_xfer_atomic() hooks 
> of
> struct i2c_algorithm and the decision to call which one of these is made 
> using the
> following check in i2c-core.h file.
> static inline bool i2c_in_atomic_xfer_mode(void)
> {
>   return system_state > SYSTEM_RUNNING && irqs_disabled();
> }
> I think I should use this condition as is IIUC.
> Please let me know if there are any concerns with this.

It is not a concern, it is just that I don't understand how this code
can be called with IRQs disabled, if you can give me an execution path I
am happy to leave the check there. On top of that, when called from
suspend NOIRQ context, it is likely to use the blocking API (because
IRQs aren't disabled at CPU level) behind which there is most certainly
an IRQ required to wake the thread up and if the IRQ in question was
disabled in the suspend NOIRQ phase this code is likely to deadlock.

I want to make sure we can justify adding this check, I do not
want to add it because we think it can be needed when it may not
be needed at all (and it gets copy and pasted over and over again
in other drivers).

> > Actually, if tegra_bpmp_transfer() requires IRQs to be enabled you may
> > even end up in a situation where that blocking call does not wake up
> > because the IRQ in question was disabled in the NOIRQ suspend/resume
> > phase.
> > 
> > [...]
> > 
> > > > > +static int tegra_pcie_dw_probe(struct platform_device *pdev)
> > > > > +{
> > > > > + const struct tegra_pcie_soc *data;
> > > > > + struct device *dev = >dev;
> > > > > + struct resource *atu_dma_res;
> > > > > + struct tegra_pcie_dw *pcie;
> > > > > + struct resource *dbi_res;
> > > > > + struct pcie_port *pp;
> > > > > + struct dw_pcie *pci;
> > > > > + struct phy **phys;
> > > > > + char *name;
> > > > > + int ret;
> > > > > + u32 i;
> > > > > +
> > > > > + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > > > > + if (!pcie)
> > > > > + return -ENOMEM;
> > > > > +
> > > > > + pci = >pci;
> > > > > + pci->dev = >dev;
> > > > > + pci->ops = _dw_pcie_ops;
> > > > > + pp = >pp;
> > > > > + pcie->dev = >dev;
> > > > > +
> > > > > + data = (struct tegra_pcie_soc *)of_device_get_match_data(dev);
> > > > > + if (!data)
> > > > > + return -EINVAL;
> > > > > + pcie->mode = (enum dw_pcie_device_mode)data->mode;
> > > > > +
> > > > > + ret = tegra_pcie_dw_parse_dt(pcie);
> > > > > + if (ret < 0) {
> > > > > + dev_err(dev, "Failed to parse device tree: %d\n", ret);
> > > > > + return ret;
> > > > > + }
> > > > > +
> > > > > + pcie->pex_ctl_supply = devm_regulator_get(dev, "vddio-pex-ctl");
> > > > > + if (IS_ERR(pcie->pex_ctl_supply)) {
> > > > > + dev_err(dev, "Failed to get regulator: %ld\n",
> > > > > + PTR_ERR(pcie->pex_ctl_supply));
> > > > > + return PTR_ERR(pcie->pex_ctl_supply);
> > > > > + }
> > > > > +
> > > > > + pcie->core_clk = devm_clk_get(dev, "core");
> > > > > +  

Re: [PATCH V13 12/12] PCI: tegra: Add Tegra194 PCIe support

2019-07-12 Thread Lorenzo Pieralisi
On Fri, Jul 12, 2019 at 09:02:49PM +0530, Vidya Sagar wrote:

[...]

> > > +static irqreturn_t tegra_pcie_irq_handler(int irq, void *arg)
> > > +{
> > > + struct tegra_pcie_dw *pcie = arg;
> > > +
> > > + if (pcie->mode == DW_PCIE_RC_TYPE)
> > > + return tegra_pcie_rp_irq_handler(pcie);
> > 
> > What's the point of registering the handler if mode != DW_PCIE_RC_TYPE ?
> Currently this driver supports only root port mode but we have a plan
> to add support for endpoint mode (as Tegra194 as dual mode
> controllers) also in future and when that happens, we'll have a
> corresponding tegra_pcie_ep_irq_handler() to take care of ep specific
> interrupts.

Sure, that's why you should add tegra_pcie_dw->mode when it is needed,
not in this patch.

[...]

> > > +static int tegra_pcie_dw_host_init(struct pcie_port *pp)
> > > +{
> > > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > + struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
> > > + u32 val, tmp, offset, speed;
> > > + unsigned int count;
> > > + u16 val_w;
> > > +
> > > +core_init:
> > 
> > I think it would be cleaner to include all registers programming
> > within a function and we remove this label (and goto) below.
> Some background: As per spec r4.0 v1.0, downstream ports that support
> 16.0 GT/s must support Scaled Flow Control (sec 3.4.2) and Tegra194's
> downstream ports being 16.0 GT/s capable, enable scaled flow control
> by having Data Link Feature (sec 7.7.4) enabled by default. There is
> one endpoint (ASMedia USB3.0 controller) that doesn't link up with
> root port because of this (i.e. DLF being enabled). The way we are
> detecting this situation is to check for partial linkup i.e. one of
> application logic registers (i.e. from "appl" region) says link is up
> but the same is not reflected in configuration space of root port.
> Recommendation from our hardware team in this situation is to disable
> DLF in root port and try link up with endpoint again.  To achieve
> this, we put the core through reset cycle, disable DLF and proceed
> with configuring all other registers and check for link up.
> 
> Initially in Patch-1, I didn't have goto statement but a recursion
> with depth-1 (as the above situation occurs only once). It was
> reviewed @ http://patchwork.ozlabs.org/patch/1065707/ and Thierry said
> it would be simpler to use a goto instead of calling the same function
> again. So, I modified the code accordingly. Please do let me know if
> you strongly feel we should call tegra_pcie_dw_host_init() instead of
> goto here. I'll change it.

I did not say we should call tegra_pcie_dw_host_init(), sorry for
not being clear. What I asked is factoring out registers programming
in a function and call it where core_init: label is and call it
again if DLF enablement causes link up to fail.

[...]

> > > +static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw *pcie,
> > > +   bool enable)
> > > +{
> > > + struct mrq_uphy_response resp;
> > > + struct tegra_bpmp_message msg;
> > > + struct mrq_uphy_request req;
> > > + int err;
> > > +
> > > + if (pcie->cid == 5)
> > > + return 0;
> > 
> > What's wrong with cid == 5 ? Explain please.
> Controller with ID=5 doesn't need any programming to enable it which is
> done here through calling firmware API.
> 
> > 
> > > + memset(, 0, sizeof(req));
> > > + memset(, 0, sizeof(resp));
> > > +
> > > + req.cmd = CMD_UPHY_PCIE_CONTROLLER_STATE;
> > > + req.controller_state.pcie_controller = pcie->cid;
> > > + req.controller_state.enable = enable;
> > > +
> > > + memset(, 0, sizeof(msg));
> > > + msg.mrq = MRQ_UPHY;
> > > + msg.tx.data = 
> > > + msg.tx.size = sizeof(req);
> > > + msg.rx.data = 
> > > + msg.rx.size = sizeof(resp);
> > > +
> > > + if (irqs_disabled())
> > 
> > Can you explain to me what this check is meant to achieve please ?
> Firmware interface provides different APIs to be called when there are
> no interrupts enabled in the system (noirq context) and otherwise
> hence checking that situation here and calling appropriate API.

That's what I am questioning. Being called from {suspend/resume}_noirq()
callbacks (if that's the code path this check caters for) does not mean
irqs_disabled() == true.

Actually, if tegra_bpmp_transfer() requires IRQs to be enabled you may
even end up in a situation where that blocking call does not wake up
because the IRQ in question was disabled in the NOIRQ suspend/resume
phase.

[...]

> > > +static int tegra_pcie_dw_probe(struct platform_device *pdev)
> > > +{
> > > + const struct tegra_pcie_soc *data;
> > > + struct device *dev = >dev;
> > > + struct resource *atu_dma_res;
> > > + struct tegra_pcie_dw *pcie;
> > > + struct resource *dbi_res;
> > > + struct pcie_port *pp;
> > > + struct dw_pcie *pci;
> > > + struct phy **phys;
> > > + char *name;
> > > + int ret;
> > > + u32 i;
> > > +
> > > + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > > + if (!pcie)
> > > + return -ENOMEM;
> > > +
> > > + 

Re: [PATCH V13 12/12] PCI: tegra: Add Tegra194 PCIe support

2019-07-11 Thread Lorenzo Pieralisi
On Wed, Jul 10, 2019 at 11:52:12AM +0530, Vidya Sagar wrote:

[...]

> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c 
> b/drivers/pci/controller/dwc/pcie-tegra194.c
> new file mode 100644
> index ..189779edd976
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -0,0 +1,1632 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * PCIe host controller driver for Tegra194 SoC
> + *
> + * Copyright (C) 2019 NVIDIA Corporation.
> + *
> + * Author: Vidya Sagar 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

What do you need these two headers for ?

[...]

> +struct tegra_pcie_dw {
> + struct device *dev;
> + struct resource *appl_res;
> + struct resource *dbi_res;
> + struct resource *atu_dma_res;
> + void __iomem *appl_base;
> + struct clk *core_clk;
> + struct reset_control *core_apb_rst;
> + struct reset_control *core_rst;
> + struct dw_pcie pci;
> + enum dw_pcie_device_mode mode;
> + struct tegra_bpmp *bpmp;
> +
> + bool supports_clkreq;
> + bool enable_cdm_check;
> + u8 init_link_width;
> + bool link_state;
> + u32 msi_ctrl_int;
> + u32 num_lanes;
> + u32 max_speed;
> + u32 cid;
> + bool update_fc_fixup;
> + u32 cfg_link_cap_l1sub;
> + u32 pcie_cap_base;
> + u32 aspm_cmrt;
> + u32 aspm_pwr_on_t;
> + u32 aspm_l0s_enter_lat;o

Nit: You should try to group variables according to their usage,
it would make sense to group booleans together.

> + struct regulator *pex_ctl_supply;
> +
> + unsigned int phy_count;
> + struct phy **phys;
> +
> + struct dentry *debugfs;
> +};
> +
> +static inline struct tegra_pcie_dw *to_tegra_pcie(struct dw_pcie *pci)
> +{
> + return container_of(pci, struct tegra_pcie_dw, pci);
> +}
> +
> +static inline void appl_writel(struct tegra_pcie_dw *pcie, const u32 value,
> +const u32 reg)
> +{
> + writel_relaxed(value, pcie->appl_base + reg);
> +}
> +
> +static inline u32 appl_readl(struct tegra_pcie_dw *pcie, const u32 reg)
> +{
> + return readl_relaxed(pcie->appl_base + reg);
> +}
> +
> +struct tegra_pcie_soc {
> + enum dw_pcie_device_mode mode;
> +};
> +
> +static void apply_bad_link_workaround(struct pcie_port *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
> + u32 current_link_width;
> + u16 val;
> +
> + /*
> +  * NOTE:- Since this scenario is uncommon and link as such is not
> +  * stable anyway, not waiting to confirm if link is really
> +  * transitioning to Gen-2 speed
> +  */
> + val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA);
> + if (val & PCI_EXP_LNKSTA_LBMS) {
> + current_link_width = (val & PCI_EXP_LNKSTA_NLW) >>
> +  PCI_EXP_LNKSTA_NLW_SHIFT;
> + if (pcie->init_link_width > current_link_width) {
> + dev_warn(pci->dev, "PCIe link is bad, width reduced\n");
> + val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base +
> + PCI_EXP_LNKCTL2);
> + val &= ~PCI_EXP_LNKCTL2_TLS;
> + val |= PCI_EXP_LNKCTL2_TLS_2_5GT;
> + dw_pcie_writew_dbi(pci, pcie->pcie_cap_base +
> +PCI_EXP_LNKCTL2, val);
> +
> + val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base +
> + PCI_EXP_LNKCTL);
> + val |= PCI_EXP_LNKCTL_RL;
> + dw_pcie_writew_dbi(pci, pcie->pcie_cap_base +
> +PCI_EXP_LNKCTL, val);
> + }
> + }
> +}
> +
> +static irqreturn_t tegra_pcie_rp_irq_handler(struct tegra_pcie_dw *pcie)
> +{
> + struct dw_pcie *pci = >pci;
> + struct pcie_port *pp = >pp;
> + u32 val, tmp;
> + u16 val_w;
> +
> + val = appl_readl(pcie, APPL_INTR_STATUS_L0);
> + if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
> + val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
> + if (val & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
> + appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
> +
> + /* SBR & Surprise Link Down WAR */
> + val = appl_readl(pcie, APPL_CAR_RESET_OVRD);
> + val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N;
> + appl_writel(pcie, val, APPL_CAR_RESET_OVRD);
> + udelay(1);
> + val = appl_readl(pcie, APPL_CAR_RESET_OVRD);
> + val |= APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N;
> + appl_writel(pcie, val, APPL_CAR_RESET_OVRD);
> +
> + val = dw_pcie_readl_dbi(pci, 

Re: [PATCH 5/8] dt-bindings: PCI: Add Amazon's Annapurna Labs PCIe host bridge binding

2019-07-11 Thread Lorenzo Pieralisi
On Thu, Jul 11, 2019 at 10:12:35AM +0300, Shenhar, Talel wrote:
> 
> On 7/10/2019 7:45 PM, Jonathan Chocron wrote:
> > Document Amazon's Annapurna Labs PCIe host bridge.
> 
> That is the way! (best to keep same wordings (Amazon's)

Guys,

as a heads-up, the original posting, for whatever reason, did not hit
linux-pci@vger, which means that from a PCI patches queue review point
of view it does not exist.

It ought to be fixed otherwise we won't be able to review the code.

Lorenzo

> > 
> > Signed-off-by: Jonathan Chocron 
> > ---
> >   .../devicetree/bindings/pci/pcie-al.txt   | 45 +++
> >   MAINTAINERS   |  1 +
> >   2 files changed, 46 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/pci/pcie-al.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/pci/pcie-al.txt 
> > b/Documentation/devicetree/bindings/pci/pcie-al.txt
> > new file mode 100644
> > index ..d92cc529490e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/pcie-al.txt
> > @@ -0,0 +1,45 @@
> > +* Amazon Annapurna Labs PCIe host bridge
> > +
> > +Annapurna Labs' PCIe Host Controller is based on the Synopsys DesignWare
> 
> Amazon's
> 
> 
> and what is the s' ? should it be for all
> 
> > +Example:
> > +
> > +   pcie-external0 {
> probably should have a reference with the address
> > +   compatible = "amazon,al-pcie";
> > +   reg = <0x0 0xfb60 0x0 0x0010
> > +  0x0 0xfd80 0x0 0x0001
> > +  0x0 0xfd81 0x0 0x1000>;
> > +   reg-names = "config", "controller", "dbi";
> > +   bus-range = <0 255>;
> > +   device_type = "pci";
> > +   #address-cells = <3>;
> > +   #size-cells = <2>;
> > +   #interrupt-cells = <1>;
> > +   interrupts = ;
> > +   interrupt-map-mask = <0x00 0 0 7>;
> > +   interrupt-map = <0x 0 0 1 _main GIC_SPI 41 
> > IRQ_TYPE_LEVEL_HIGH>; /* INTa */
> gic_main->gic
> > +   ranges = <0x0200 0x0 0xc001 0x0 0xc001 0x0 
> > 0x07ff>;
> > +   };
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 5a6137df3f0e..d555beb794bb 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -12205,6 +12205,7 @@ PCIE DRIVER FOR ANNAPURNA LABS
> AMAZON!
> >   M:Jonathan Chocron 
> >   L:linux-...@vger.kernel.org
> >   S:Maintained
> > +F: Documentation/devicetree/bindings/pci/pcie-al.txt
> >   F:drivers/pci/controller/dwc/pcie-al.c
> >   PCIE DRIVER FOR AMLOGIC MESON


Re: [PATCH V13 12/12] PCI: tegra: Add Tegra194 PCIe support

2019-07-10 Thread Lorenzo Pieralisi
On Wed, Jul 10, 2019 at 11:52:12AM +0530, Vidya Sagar wrote:

[...]

> +#if defined(CONFIG_PCIEASPM)
> +static void disable_aspm_l11(struct tegra_pcie_dw *pcie)
> +{
> + u32 val;
> +
> + val = dw_pcie_readl_dbi(>pci, pcie->cfg_link_cap_l1sub);
> + val &= ~PCI_L1SS_CAP_ASPM_L1_1;
> + dw_pcie_writel_dbi(>pci, pcie->cfg_link_cap_l1sub, val);
> +}
> +
> +static void disable_aspm_l12(struct tegra_pcie_dw *pcie)
> +{
> + u32 val;
> +
> + val = dw_pcie_readl_dbi(>pci, pcie->cfg_link_cap_l1sub);
> + val &= ~PCI_L1SS_CAP_ASPM_L1_2;
> + dw_pcie_writel_dbi(>pci, pcie->cfg_link_cap_l1sub, val);
> +}
> +
> +static inline u32 event_counter_prog(struct tegra_pcie_dw *pcie, u32 event)
> +{
> + u32 val;
> +
> + val = dw_pcie_readl_dbi(>pci, event_cntr_ctrl_offset[pcie->cid]);
> + val &= ~(EVENT_COUNTER_EVENT_SEL_MASK << EVENT_COUNTER_EVENT_SEL_SHIFT);
> + val |= EVENT_COUNTER_GROUP_5 << EVENT_COUNTER_GROUP_SEL_SHIFT;
> + val |= event << EVENT_COUNTER_EVENT_SEL_SHIFT;
> + val |= EVENT_COUNTER_ENABLE_ALL << EVENT_COUNTER_ENABLE_SHIFT;
> + dw_pcie_writel_dbi(>pci, event_cntr_ctrl_offset[pcie->cid], val);
> + val = dw_pcie_readl_dbi(>pci, event_cntr_data_offset[pcie->cid]);
> + return val;
> +}
> +
> +static int aspm_state_cnt(struct seq_file *s, void *data)
> +{
> + struct tegra_pcie_dw *pcie = (struct tegra_pcie_dw *)
> +  dev_get_drvdata(s->private);
> + u32 val;
> +
> + seq_printf(s, "Tx L0s entry count : %u\n",
> +event_counter_prog(pcie, EVENT_COUNTER_EVENT_Tx_L0S));
> +
> + seq_printf(s, "Rx L0s entry count : %u\n",
> +event_counter_prog(pcie, EVENT_COUNTER_EVENT_Rx_L0S));
> +
> + seq_printf(s, "Link L1 entry count : %u\n",
> +event_counter_prog(pcie, EVENT_COUNTER_EVENT_L1));
> +
> + seq_printf(s, "Link L1.1 entry count : %u\n",
> +event_counter_prog(pcie, EVENT_COUNTER_EVENT_L1_1));
> +
> + seq_printf(s, "Link L1.2 entry count : %u\n",
> +event_counter_prog(pcie, EVENT_COUNTER_EVENT_L1_2));
> +
> + /* Clear all counters */
> + dw_pcie_writel_dbi(>pci, event_cntr_ctrl_offset[pcie->cid],
> +EVENT_COUNTER_ALL_CLEAR);
> +
> + /* Re-enable counting */
> + val = EVENT_COUNTER_ENABLE_ALL << EVENT_COUNTER_ENABLE_SHIFT;
> + val |= EVENT_COUNTER_GROUP_5 << EVENT_COUNTER_GROUP_SEL_SHIFT;
> + dw_pcie_writel_dbi(>pci, event_cntr_ctrl_offset[pcie->cid], val);
> +
> + return 0;
> +}
> +#endif
> +
> +static int init_debugfs(struct tegra_pcie_dw *pcie)
> +{
> +#if defined(CONFIG_PCIEASPM)
> + struct dentry *d;
> +
> + d = debugfs_create_devm_seqfile(pcie->dev, "aspm_state_cnt",
> + pcie->debugfs, aspm_state_cnt);
> + if (IS_ERR_OR_NULL(d))
> + dev_err(pcie->dev,
> + "Failed to create debugfs file \"aspm_state_cnt\"\n");
> +#endif
> + return 0;
> +}

I prefer writing it:

#if defined(CONFIG_PCIEASPM)
static void disable_aspm_l11(struct tegra_pcie_dw *pcie)
{
...
}

static void disable_aspm_l12(struct tegra_pcie_dw *pcie)
{
...
}

static inline u32 event_counter_prog(struct tegra_pcie_dw *pcie, u32 event)
{
...
}

static int aspm_state_cnt(struct seq_file *s, void *data)
{
...
}

static int init_debugfs(struct tegra_pcie_dw *pcie)
{
struct dentry *d;

d = debugfs_create_devm_seqfile(pcie->dev, "aspm_state_cnt",
pcie->debugfs, aspm_state_cnt);
if (IS_ERR_OR_NULL(d))
dev_err(pcie->dev,
"Failed to create debugfs file \"aspm_state_cnt\"\n");
return 0;
}
#else
static inline int init_debugfs(struct tegra_pcie_dw *pcie) { return 0; }
#endif

> +
> +static void tegra_pcie_enable_system_interrupts(struct pcie_port *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
> + u32 val;
> + u16 val_w;
> +
> + val = appl_readl(pcie, APPL_INTR_EN_L0_0);
> + val |= APPL_INTR_EN_L0_0_LINK_STATE_INT_EN;
> + appl_writel(pcie, val, APPL_INTR_EN_L0_0);
> +
> + val = appl_readl(pcie, APPL_INTR_EN_L1_0_0);
> + val |= APPL_INTR_EN_L1_0_0_LINK_REQ_RST_NOT_INT_EN;
> + appl_writel(pcie, val, APPL_INTR_EN_L1_0_0);
> +
> + if (pcie->enable_cdm_check) {
> + val = appl_readl(pcie, APPL_INTR_EN_L0_0);
> + val |= APPL_INTR_EN_L0_0_CDM_REG_CHK_INT_EN;
> + appl_writel(pcie, val, APPL_INTR_EN_L0_0);
> +
> + val = appl_readl(pcie, APPL_INTR_EN_L1_18);
> + val |= APPL_INTR_EN_L1_18_CDM_REG_CHK_CMP_ERR;
> + val |= APPL_INTR_EN_L1_18_CDM_REG_CHK_LOGIC_ERR;
> + appl_writel(pcie, val, APPL_INTR_EN_L1_18);
> + }
> +
> + val_w = dw_pcie_readw_dbi(>pci, pcie->pcie_cap_base +
> +   PCI_EXP_LNKSTA);
> + 

Re: [PATCH V13 08/12] dt-bindings: Add PCIe supports-clkreq property

2019-07-10 Thread Lorenzo Pieralisi
On Wed, Jul 10, 2019 at 11:52:08AM +0530, Vidya Sagar wrote:
> Some host controllers need to know the existence of clkreq signal routing to
> downstream devices to be able to advertise low power features like ASPM L1
> substates. Without clkreq signal routing being present, enabling ASPM L1 sub
> states might lead to downstream devices falling off the bus. Hence a new 
> device

You mean "being disconnected from the bus" right ? I will update it.

Lorenzo

> tree property 'supports-clkreq' is added to make such host controllers
> aware of clkreq signal routing to downstream devices.
> 
> Signed-off-by: Vidya Sagar 
> Reviewed-by: Rob Herring 
> Reviewed-by: Thierry Reding 
> ---
> V13:
> * None
> 
> V12:
> * Rebased on top of linux-next top of the tree
> 
> V11:
> * None
> 
> V10:
> * None
> 
> V9:
> * None
> 
> V8:
> * None
> 
> V7:
> * None
> 
> V6:
> * s/Documentation\/devicetree/dt-bindings/ in the subject
> 
> V5:
> * None
> 
> V4:
> * Rebased on top of linux-next top of the tree
> 
> V3:
> * None
> 
> V2:
> * This is a new patch in v2 series
> 
>  Documentation/devicetree/bindings/pci/pci.txt | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/pci.txt 
> b/Documentation/devicetree/bindings/pci/pci.txt
> index 2a5d91024059..29bcbd88f457 100644
> --- a/Documentation/devicetree/bindings/pci/pci.txt
> +++ b/Documentation/devicetree/bindings/pci/pci.txt
> @@ -27,6 +27,11 @@ driver implementation may support the following properties:
>  - reset-gpios:
> If present this property specifies PERST# GPIO. Host drivers can parse the
> GPIO and apply fundamental reset to endpoints.
> +- supports-clkreq:
> +   If present this property specifies that CLKREQ signal routing exists from
> +   root port to downstream device and host bridge drivers can do programming
> +   which depends on CLKREQ signal existence. For example, programming root 
> port
> +   not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal.
>  
>  PCI-PCI Bridge properties
>  -
> -- 
> 2.17.1
> 


Re: [PATCH V13 05/12] PCI: dwc: Add ext config space capability search API

2019-07-10 Thread Lorenzo Pieralisi
On Wed, Jul 10, 2019 at 04:57:23PM +0530, Vidya Sagar wrote:
> On 7/10/2019 4:07 PM, Lorenzo Pieralisi wrote:
> > On Wed, Jul 10, 2019 at 11:52:05AM +0530, Vidya Sagar wrote:
> > > Add extended configuration space capability search API using struct 
> > > dw_pcie *
> > > pointer
> > 
> > Sentences are terminated with a period and this is v13 not v1, which
> > proves that you do not read the commit logs you write.
> > 
> > I need you guys to understand that I can't rewrite commit logs all
> > the time, I do not want to go as far as not accepting your patches
> > anymore so please do pay attention to commit log details they
> > are as important as the code itself.
> > 
> > https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com/
> My sincere apologies.
> Since I didn't touch this patch much all through this series, I missed it.
> I'll make a point to not make such mistakes again.
> Do you want me to send a new version fixing it?

I will update it, I just wanted to get the point across, no
problems.

Lorenzo

> Thanks,
> Vidya Sagar
> 
> > 
> > Thanks,
> > Lorenzo
> > 
> > > Signed-off-by: Vidya Sagar 
> > > Acked-by: Gustavo Pimentel 
> > > Acked-by: Thierry Reding 
> > > ---
> > > V13:
> > > * None
> > > 
> > > V12:
> > > * None
> > > 
> > > V11:
> > > * None
> > > 
> > > V10:
> > > * None
> > > 
> > > V9:
> > > * Added Acked-by from Thierry
> > > 
> > > V8:
> > > * Changed data types of return and arguments to be inline with data being 
> > > returned
> > >and passed.
> > > 
> > > V7:
> > > * None
> > > 
> > > V6:
> > > * None
> > > 
> > > V5:
> > > * None
> > > 
> > > V4:
> > > * None
> > > 
> > > V3:
> > > * None
> > > 
> > > V2:
> > > * This is a new patch in v2 series
> > > 
> > >   drivers/pci/controller/dwc/pcie-designware.c | 41 
> > >   drivers/pci/controller/dwc/pcie-designware.h |  1 +
> > >   2 files changed, 42 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware.c 
> > > b/drivers/pci/controller/dwc/pcie-designware.c
> > > index 7818b4febb08..181449e342f1 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > > @@ -53,6 +53,47 @@ u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
> > >   }
> > >   EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
> > > +static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 
> > > start,
> > > + u8 cap)
> > > +{
> > > + u32 header;
> > > + int ttl;
> > > + int pos = PCI_CFG_SPACE_SIZE;
> > > +
> > > + /* minimum 8 bytes per capability */
> > > + ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
> > > +
> > > + if (start)
> > > + pos = start;
> > > +
> > > + header = dw_pcie_readl_dbi(pci, pos);
> > > + /*
> > > +  * If we have no capabilities, this is indicated by cap ID,
> > > +  * cap version and next pointer all being 0.
> > > +  */
> > > + if (header == 0)
> > > + return 0;
> > > +
> > > + while (ttl-- > 0) {
> > > + if (PCI_EXT_CAP_ID(header) == cap && pos != start)
> > > + return pos;
> > > +
> > > + pos = PCI_EXT_CAP_NEXT(header);
> > > + if (pos < PCI_CFG_SPACE_SIZE)
> > > + break;
> > > +
> > > + header = dw_pcie_readl_dbi(pci, pos);
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
> > > +{
> > > + return dw_pcie_find_next_ext_capability(pci, 0, cap);
> > > +}
> > > +EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability);
> > > +
> > >   int dw_pcie_read(void __iomem *addr, int size, u32 *val)
> > >   {
> > >   if (!IS_ALIGNED((uintptr_t)addr, size)) {
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> > > b/drivers/pci/controller/dwc/pcie-designware.h
> > > index d8c66a6827dc..11c223471416 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > > @@ -252,6 +252,7 @@ struct dw_pcie {
> > >   container_of((endpoint), struct dw_pcie, ep)
> > >   u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
> > > +u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);
> > >   int dw_pcie_read(void __iomem *addr, int size, u32 *val);
> > >   int dw_pcie_write(void __iomem *addr, int size, u32 val);
> > > -- 
> > > 2.17.1
> > > 
> 


Re: [PATCH V13 05/12] PCI: dwc: Add ext config space capability search API

2019-07-10 Thread Lorenzo Pieralisi
On Wed, Jul 10, 2019 at 11:52:05AM +0530, Vidya Sagar wrote:
> Add extended configuration space capability search API using struct dw_pcie *
> pointer

Sentences are terminated with a period and this is v13 not v1, which
proves that you do not read the commit logs you write.

I need you guys to understand that I can't rewrite commit logs all
the time, I do not want to go as far as not accepting your patches
anymore so please do pay attention to commit log details they
are as important as the code itself.

https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com/

Thanks,
Lorenzo

> Signed-off-by: Vidya Sagar 
> Acked-by: Gustavo Pimentel 
> Acked-by: Thierry Reding 
> ---
> V13:
> * None
> 
> V12:
> * None
> 
> V11:
> * None
> 
> V10:
> * None
> 
> V9:
> * Added Acked-by from Thierry
> 
> V8:
> * Changed data types of return and arguments to be inline with data being 
> returned
>   and passed.
> 
> V7:
> * None
> 
> V6:
> * None
> 
> V5:
> * None
> 
> V4:
> * None
> 
> V3:
> * None
> 
> V2:
> * This is a new patch in v2 series
> 
>  drivers/pci/controller/dwc/pcie-designware.c | 41 
>  drivers/pci/controller/dwc/pcie-designware.h |  1 +
>  2 files changed, 42 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c 
> b/drivers/pci/controller/dwc/pcie-designware.c
> index 7818b4febb08..181449e342f1 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -53,6 +53,47 @@ u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
>  
> +static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
> + u8 cap)
> +{
> + u32 header;
> + int ttl;
> + int pos = PCI_CFG_SPACE_SIZE;
> +
> + /* minimum 8 bytes per capability */
> + ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
> +
> + if (start)
> + pos = start;
> +
> + header = dw_pcie_readl_dbi(pci, pos);
> + /*
> +  * If we have no capabilities, this is indicated by cap ID,
> +  * cap version and next pointer all being 0.
> +  */
> + if (header == 0)
> + return 0;
> +
> + while (ttl-- > 0) {
> + if (PCI_EXT_CAP_ID(header) == cap && pos != start)
> + return pos;
> +
> + pos = PCI_EXT_CAP_NEXT(header);
> + if (pos < PCI_CFG_SPACE_SIZE)
> + break;
> +
> + header = dw_pcie_readl_dbi(pci, pos);
> + }
> +
> + return 0;
> +}
> +
> +u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
> +{
> + return dw_pcie_find_next_ext_capability(pci, 0, cap);
> +}
> +EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability);
> +
>  int dw_pcie_read(void __iomem *addr, int size, u32 *val)
>  {
>   if (!IS_ALIGNED((uintptr_t)addr, size)) {
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> b/drivers/pci/controller/dwc/pcie-designware.h
> index d8c66a6827dc..11c223471416 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -252,6 +252,7 @@ struct dw_pcie {
>   container_of((endpoint), struct dw_pcie, ep)
>  
>  u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
> +u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);
>  
>  int dw_pcie_read(void __iomem *addr, int size, u32 *val);
>  int dw_pcie_write(void __iomem *addr, int size, u32 val);
> -- 
> 2.17.1
> 


Re: [PATCH] PCI: dwc: pci-dra7xx: Add missing include file

2019-07-09 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 11:40:44PM +0800, YueHaibing wrote:
> Fix build error:
> 
> drivers/pci/controller/dwc/pci-dra7xx.c:
>  In function dra7xx_pcie_probe:
> drivers/pci/controller/dwc/pci-dra7xx.c:777:10:
>  error: implicit declaration of function devm_gpiod_get_optional;
>  did you mean devm_regulator_get_optional? 
> [-Werror=implicit-function-declaration]
> 
>   reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
> 
> Reported-by: Hulk Robot 
> Signed-off-by: YueHaibing 
> ---
>  drivers/pci/controller/dwc/pci-dra7xx.c | 1 +
>  1 file changed, 1 insertion(+)

Applied to pci/dwc for v5.3, thanks.

Lorenzo

> diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c 
> b/drivers/pci/controller/dwc/pci-dra7xx.c
> index 419451e..4234ddb 100644
> --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> @@ -26,6 +26,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "../../pci.h"
>  #include "pcie-designware.h"
> -- 
> 2.7.4
> 
> 


Re: [PATCH 10/18] drivers: firmware: psci: Add hierarchical domain idle states converter

2019-07-09 Thread Lorenzo Pieralisi
On Mon, May 13, 2019 at 09:22:52PM +0200, Ulf Hansson wrote:
> If the hierarchical CPU topology is used, but the OS initiated mode isn't
> supported, we need to rely solely on the regular cpuidle framework to
> manage the idle state selection, rather than using genpd and its governor.
> 
> For this reason, introduce a new PSCI DT helper function,
> psci_dt_pm_domains_parse_states(), which parses and converts the
> hierarchically described domain idle states from DT, into regular flattened
> cpuidle states. The converted states are added to the existing cpuidle
> driver's array of idle states, which make them available for cpuidle.
> 
> Signed-off-by: Ulf Hansson 
> ---
> 
> Changes:
>   - Some simplification of the code.
> 
> ---
>  drivers/firmware/psci/psci.h   |   5 ++
>  drivers/firmware/psci/psci_pm_domain.c | 118 +
>  2 files changed, 123 insertions(+)
> 
> diff --git a/drivers/firmware/psci/psci.h b/drivers/firmware/psci/psci.h
> index 00d2e3dcef49..c36e0e6649e9 100644
> --- a/drivers/firmware/psci/psci.h
> +++ b/drivers/firmware/psci/psci.h
> @@ -3,6 +3,7 @@
>  #ifndef __PSCI_H
>  #define __PSCI_H
>  
> +struct cpuidle_driver;
>  struct device_node;
>  
>  int psci_set_osi_mode(void);
> @@ -13,8 +14,12 @@ void psci_set_domain_state(u32 state);
>  int psci_dt_parse_state_node(struct device_node *np, u32 *state);
>  #ifdef CONFIG_PM_GENERIC_DOMAINS_OF
>  int psci_dt_init_pm_domains(struct device_node *np);
> +int psci_dt_pm_domains_parse_states(struct cpuidle_driver *drv,
> + struct device_node *cpu_node, u32 *psci_states);
>  #else
>  static inline int psci_dt_init_pm_domains(struct device_node *np) { return 
> 0; }
> +static inline int psci_dt_pm_domains_parse_states(struct cpuidle_driver *drv,
> + struct device_node *cpu_node, u32 *psci_states) { return 0; }
>  #endif
>  #endif
>  
> diff --git a/drivers/firmware/psci/psci_pm_domain.c 
> b/drivers/firmware/psci/psci_pm_domain.c
> index 3c6ca846caf4..3aa645dba81b 100644
> --- a/drivers/firmware/psci/psci_pm_domain.c
> +++ b/drivers/firmware/psci/psci_pm_domain.c
> @@ -14,6 +14,10 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
> +
> +#include 
>  
>  #include "psci.h"
>  
> @@ -104,6 +108,53 @@ static void psci_pd_free_states(struct genpd_power_state 
> *states,
>   kfree(states);
>  }
>  
> +static int psci_pd_enter_pc(struct cpuidle_device *dev,
> + struct cpuidle_driver *drv, int idx)
> +{
> + return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, idx);
> +}
> +
> +static void psci_pd_enter_s2idle_pc(struct cpuidle_device *dev,
> + struct cpuidle_driver *drv, int idx)
> +{
> + psci_pd_enter_pc(dev, drv, idx);
> +}
> +
> +static void psci_pd_convert_states(struct cpuidle_state *idle_state,
> + u32 *psci_state, struct genpd_power_state *state)
> +{
> + u32 *state_data = state->data;
> + u64 target_residency_us = state->residency_ns;
> + u64 exit_latency_us = state->power_on_latency_ns +
> + state->power_off_latency_ns;
> +
> + *psci_state = *state_data;
> + do_div(target_residency_us, 1000);
> + idle_state->target_residency = target_residency_us;
> + do_div(exit_latency_us, 1000);
> + idle_state->exit_latency = exit_latency_us;
> + idle_state->enter = _pd_enter_pc;
> + idle_state->enter_s2idle = _pd_enter_s2idle_pc;
> + idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP;

This is arbitrary and not necessarily true.

I think that this patch is useful to represent my reservations about the
current approach. As a matter of fact, idle state entry will always be a
CPUidle decision.

You only need PM domain information to understand when all CPUs
in a power domain are actually idle but that's all genPD can do
in this respect.

I think this patchset would be much simpler if both CPUidle and
genPD governor would work on *one* set of idle states, globally
indexed (and that would be true for PSCI suspend parameters too).

To work with a unified set of idle states between CPUidle and genPD
(tossing some ideas around):

- We can implement a genPD CPUidle governor that in its select method
  takes into account genPD information (for instance by avoiding
  selection of idle states that require multiple cpus to be in idle
  to be effectively active)
- We can use genPD to enable/disable CPUidle states through runtime
  PM information

There may be other ways. My point is that current code, with two (or
more if the hierarchy grows) sets of idle states across two subsystems
(CPUidle and genPD) is not very well defined and honestly very hard to
grasp and prone to errors.

> +
> + strncpy(idle_state->name, to_of_node(state->fwnode)->name,
> + CPUIDLE_NAME_LEN - 1);
> + strncpy(idle_state->desc, to_of_node(state->fwnode)->name,
> + CPUIDLE_NAME_LEN - 1);
> +}
> +
> +static bool psci_pd_is_provider(struct device_node *np)
> +{
> + 

Re: [PATCHv6 00/28] PCI: mobiveil: fixes for Mobiveil PCIe Host Bridge IP driver

2019-07-08 Thread Lorenzo Pieralisi
On Fri, Jul 05, 2019 at 05:56:28PM +0800, Hou Zhiqiang wrote:
> This patch set is to add fixes for Mobiveil PCIe Host driver.
> Splited #2, #3, #9 and #10 of v5 patches.
> 
> Hou Zhiqiang (28):
>   PCI: mobiveil: Unify register accessors
>   PCI: mobiveil: Remove the flag MSI_FLAG_MULTI_PCI_MSI
>   PCI: mobiveil: Fix PCI base address in MEM/IO outbound windows
>   PCI: mobiveil: Update the resource list traversal function
>   PCI: mobiveil: Use WIN_NUM_0 explicitly for CFG outbound window
>   PCI: mobiveil: Use the 1st inbound window for MEM inbound
> transactions
>   PCI: mobiveil: Fix the Class Code field
>   PCI: mobiveil: Move the link up waiting out of mobiveil_host_init()
>   PCI: mobiveil: Move IRQ chained handler setup out of DT parse
>   PCI: mobiveil: Initialize Primary/Secondary/Subordinate bus numbers
>   PCI: mobiveil: Fix devfn check in mobiveil_pcie_valid_device()
>   dt-bindings: PCI: mobiveil: Change gpio_slave and apb_csr to optional
>   PCI: mobiveil: Reformat the code for readability
>   PCI: mobiveil: Make the register updating more readable
>   PCI: mobiveil: Revise the MEM/IO outbound window initialization
>   PCI: mobiveil: Fix the returned error number
>   PCI: mobiveil: Remove an unnecessary return value check
>   PCI: mobiveil: Remove redundant var definitions and register read
> operations
>   PCI: mobiveil: Fix the valid check for inbound and outbound window
>   PCI: mobiveil: Add the statistic of initialized inbound windows
>   PCI: mobiveil: Clear the target fields before updating the register
>   PCI: mobiveil: Mask out the lower 10-bit hardcode window size
>   PCI: mobiveil: Add upper 32-bit CPU base address setup in outbound
> window
>   PCI: mobiveil: Add upper 32-bit PCI base address setup in inbound
> window
>   PCI: mobiveil: Fix the CPU base address setup in inbound window
>   PCI: mobiveil: Move PCIe PIO enablement out of inbound window routine
>   PCI: mobiveil: Fix infinite-loop in the INTx process
>   PCI: mobiveil: Fix the potential INTx missing problem
> 
>  .../devicetree/bindings/pci/mobiveil-pcie.txt  |2 +
>  drivers/pci/controller/pcie-mobiveil.c |  529 
> 
>  2 files changed, 318 insertions(+), 213 deletions(-)
> 

OK, I rewrote most of commit logs, dropped patch 25 since I do not
understand the commit log, pushed to pci/mobiveil tentatively for
v5.3.

Having said that, you should improve commit logs writing it took
me too much time to check them all and rewrite them.

Never ever again post a massive series like this mixing refactoring
fixes and clean-ups it was painful to review/rebase, please split
patch series into small chunks to make my life much easier.

Please check my pci/mobiveil branch and report back if something
is not in order.

Lorenzo


Re: [PATCH] PCI: dwc: pci-dra7xx: Add missing include file

2019-07-05 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 11:40:44PM +0800, YueHaibing wrote:
> Fix build error:
> 
> drivers/pci/controller/dwc/pci-dra7xx.c:
>  In function dra7xx_pcie_probe:
> drivers/pci/controller/dwc/pci-dra7xx.c:777:10:
>  error: implicit declaration of function devm_gpiod_get_optional;
>  did you mean devm_regulator_get_optional? 
> [-Werror=implicit-function-declaration]
> 
>   reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);

Adding the reason (in particular the config options) that triggers
this error would not hurt.

Kishon please let me know if I can merge it (ACK it if so).

Thanks,
Lorenzo

> Reported-by: Hulk Robot 
> Signed-off-by: YueHaibing 
> ---
>  drivers/pci/controller/dwc/pci-dra7xx.c | 1 +
>  1 file changed, 1 insertion(+)


> 
> diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c 
> b/drivers/pci/controller/dwc/pci-dra7xx.c
> index 419451e..4234ddb 100644
> --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> @@ -26,6 +26,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "../../pci.h"
>  #include "pcie-designware.h"
> -- 
> 2.7.4
> 
> 


Re: [PATCH] PCI: tegra: Fix support for GPIO based PERST#

2019-07-05 Thread Lorenzo Pieralisi
On Fri, Jul 05, 2019 at 09:48:50AM +0100, Jon Hunter wrote:
> Commit 5e5e9c23f82a ("PCI: tegra: Add support for GPIO based PERST#")
> calls the function devm_gpiod_get_from_of_node() to request a GPIO.
> Unfortunately, around the same time this was merged, commit 025bf37725f1
> ("gpio: Fix return value mismatch of function gpiod_get_from_of_node()")
> was also merged to fix the return value of the function
> devm_gpiod_get_from_of_node() that was incorrectly returning NULL
> instead of an error pointer encoded with -ENOENT if no GPIO was found.
> When this fix for the GPIO subsystem was merged, PCI support for Tegra
> devices that did not provide a GPIO for the PERST# (which is optional)
> broke because the Tegra PCI driver was expecting NULL to be returned if
> no GPIO was present and not -ENOENT.
> 
> Fix this by checking to see if -ENOENT is returned from the function
> devm_gpiod_get_from_of_node(), to indicate there is no GPIO for PERST#
> present, and if this is the case set the variable 'reset_gpio' to NULL.
> If the variable 'reset_gpio' is NULL then the Tegra PCI driver will
> fallback to using the AFI register to toggle the PERST#. Finally,
> correct the comment now that NULL is no longer returned from
> devm_gpiod_get_from_of_node().
> 
> Fixes: 5e5e9c23f82a ("PCI: tegra: Add support for GPIO based PERST#")
> Signed-off-by: Jon Hunter 
> ---
>  drivers/pci/controller/pci-tegra.c | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)

Can I squash this in the original commit (ie Fixes: tag above) ? I do
not think there is any issue with that, if there is please do let me
know.

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/pci-tegra.c 
> b/drivers/pci/controller/pci-tegra.c
> index 9cc03a2549c0..ff8a346f3e04 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -2295,18 +2295,22 @@ static int tegra_pcie_parse_dt(struct tegra_pcie 
> *pcie)
>   }
>  
>   /*
> -  * Returns null if reset-gpios property is not populated and
> -  * fall back to using AFI per port register to toggle PERST#
> -  * SFIO line.
> +  * Returns -ENOENT if reset-gpios property is not populated
> +  * and in this case fall back to using AFI per port register
> +  * to toggle PERST# SFIO line.
>*/
>   rp->reset_gpio = devm_gpiod_get_from_of_node(dev, port,
>"reset-gpios", 0,
>GPIOD_OUT_LOW,
>label);
>   if (IS_ERR(rp->reset_gpio)) {
> - err = PTR_ERR(rp->reset_gpio);
> - dev_err(dev, "failed to get reset GPIO: %d\n", err);
> - return err;
> + if (PTR_ERR(rp->reset_gpio) == -ENOENT) {
> + rp->reset_gpio = NULL;
> + } else {
> + dev_err(dev, "failed to get reset GPIO: %d\n",
> + err);
> + return PTR_ERR(rp->reset_gpio);
> + }
>   }
>  
>   list_add_tail(>list, >ports);
> -- 
> 2.17.1
> 


Re: [PATCHv5 02/20] PCI: mobiveil: Format the code without functionality change

2019-07-04 Thread Lorenzo Pieralisi
On Thu, Jul 04, 2019 at 03:00:37AM +, Z.q. Hou wrote:

[...]

> > If you can manage to rebase patches on pci/mobiveil on top of v5.2-rc1,
> > send them separately so that I can merge them as a base for the subsequent
> > patches to be applied.
> 
> You meant send the patches one by one, which you requested to split, and
> other patches without any changes can be send together, right?

First step, rebase my branch above against v5.2-rc1 *without* this
patch. Then apply all the patches I requested to split (inclusive of
this one) on top of it and send the whole patch series in one go.

Please let me know if that's still unclear.

Thanks,
Lorenzo

> > If you have any questions please ask, do not post patches if there is
> > something that is not clear.
> 
> Yes, I'll, thanks for your guide again!
> 
> B.R,
> Zhiqiang
> 
> > 
> > Lorenzo
> > 
> > > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > > b/drivers/pci/controller/pcie-mobiveil.c
> > > index d55c7e780c6e..b87471f08a40 100644
> > > --- a/drivers/pci/controller/pcie-mobiveil.c
> > > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > > @@ -31,38 +31,40 @@
> > >   * translation tables are grouped into windows, each window registers
> > are
> > >   * grouped into blocks of 4 or 16 registers each
> > >   */
> > > -#define PAB_REG_BLOCK_SIZE   16
> > > -#define PAB_EXT_REG_BLOCK_SIZE   4
> > > +#define PAB_REG_BLOCK_SIZE   16
> > > +#define PAB_EXT_REG_BLOCK_SIZE   4
> > >
> > > -#define PAB_REG_ADDR(offset, win) (offset + (win *
> > > PAB_REG_BLOCK_SIZE)) -#define PAB_EXT_REG_ADDR(offset, win) (offset
> > +
> > > (win * PAB_EXT_REG_BLOCK_SIZE))
> > > +#define PAB_REG_ADDR(offset, win)\
> > > + (offset + (win * PAB_REG_BLOCK_SIZE))
> > > +#define PAB_EXT_REG_ADDR(offset, win)\
> > > + (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
> > >
> > > -#define LTSSM_STATUS 0x0404
> > > -#define  LTSSM_STATUS_L0_MASK0x3f
> > > -#define  LTSSM_STATUS_L0 0x2d
> > > +#define LTSSM_STATUS 0x0404
> > > +#define  LTSSM_STATUS_L0_MASK0x3f
> > > +#define  LTSSM_STATUS_L0 0x2d
> > >
> > > -#define PAB_CTRL 0x0808
> > > -#define  AMBA_PIO_ENABLE_SHIFT   0
> > > -#define  PEX_PIO_ENABLE_SHIFT1
> > > -#define  PAGE_SEL_SHIFT  13
> > > -#define  PAGE_SEL_MASK   0x3f
> > > -#define  PAGE_LO_MASK0x3ff
> > > -#define  PAGE_SEL_OFFSET_SHIFT   10
> > > +#define PAB_CTRL 0x0808
> > > +#define  AMBA_PIO_ENABLE_SHIFT   0
> > > +#define  PEX_PIO_ENABLE_SHIFT1
> > > +#define  PAGE_SEL_SHIFT  13
> > > +#define  PAGE_SEL_MASK   0x3f
> > > +#define  PAGE_LO_MASK0x3ff
> > > +#define  PAGE_SEL_OFFSET_SHIFT   10
> > >
> > > -#define PAB_AXI_PIO_CTRL 0x0840
> > > -#define  APIO_EN_MASK0xf
> > > +#define PAB_AXI_PIO_CTRL 0x0840
> > > +#define  APIO_EN_MASK0xf
> > >
> > > -#define PAB_PEX_PIO_CTRL 0x08c0
> > > -#define  PIO_ENABLE_SHIFT0
> > > +#define PAB_PEX_PIO_CTRL 0x08c0
> > > +#define  PIO_ENABLE_SHIFT0
> > >
> > >  #define PAB_INTP_AMBA_MISC_ENB   0x0b0c
> > > -#define PAB_INTP_AMBA_MISC_STAT  0x0b1c
> > > +#define PAB_INTP_AMBA_MISC_STAT  0x0b1c
> > >  #define  PAB_INTP_INTX_MASK  0x01e0
> > >  #define  PAB_INTP_MSI_MASK   0x8
> > >
> > > -#define PAB_AXI_AMAP_CTRL(win)   PAB_REG_ADDR(0x0ba0, win)
> > > -#define  WIN_ENABLE_SHIFT0
> > > -#define  WIN_TYPE_SHIFT  1
> > > +#define PAB_AXI_AMAP_CTRL(win)   PAB_REG_ADDR(0x0ba0, win)
> > > +#define  WIN_ENABLE_SHIFT0
> > > +#define  WIN_TYPE_SHIFT  1
> > >
> > >  #define PAB_EXT_AXI_AMAP_SIZE(win)   PAB_EXT_REG_ADDR(0xbaf0,
> > win)
> > >
> > > @@ -70,16 +72,16 @@
> > >  #define  AXI_WINDOW_ALIGN_MASK   3
> > >
> > >  #define PAB_AXI_AMAP_PEX_WIN_L(win)  PAB_REG_ADDR(0x0ba8,
> > win)
> > > -#define  PAB_BUS_SHIFT   24
> > > -#define  PAB_DEVICE_SHIFT19
> > > -#define  PAB_FUNCTION_SHIFT  16
> > > +#define  PAB_BUS_SHIFT   24
> > > +#define  PAB_DEVICE_SHIFT19
> > > +#define  PAB_FUNCTION_SHIFT  16
> > >
> > >  #define PAB_AXI_AMAP_PEX_WIN_H(win)  PAB_REG_ADDR(0x0bac,
> > win)
> > >  #define PAB_INTP_AXI_PIO_CLASS   0x474
> > >
> > > -#define PAB_PEX_AMAP_CTRL(win)   PAB_REG_ADDR(0x4ba0, win)
> > > -#define  AMAP_CTRL_EN_SHIFT  0
> > > -#define  AMAP_CTRL_TYPE_SHIFT1
> > > +#define PAB_PEX_AMAP_CTRL(win)   PAB_REG_ADDR(0x4ba0,
> > win)
> > > +#define  AMAP_CTRL_EN_SHIFT  0
> > > +#define  AMAP_CTRL_TYPE_SHIFT1
> > >
> > >  #define PAB_EXT_PEX_AMAP_SIZEN(win)  PAB_EXT_REG_ADDR(0xbef0,
> > win)
> > >  #define PAB_PEX_AMAP_AXI_WIN(win)PAB_REG_ADDR(0x4ba4,
> > win)
> > > @@ -87,39 +89,39 @@
> > >  #define PAB_PEX_AMAP_PEX_WIN_H(win) 

Re: [PATCHv5 02/20] PCI: mobiveil: Format the code without functionality change

2019-07-03 Thread Lorenzo Pieralisi
On Wed, Jul 03, 2019 at 04:19:05PM +0100, Lorenzo Pieralisi wrote:
> On Fri, Apr 12, 2019 at 08:35:24AM +, Z.q. Hou wrote:
> > From: Hou Zhiqiang 
> > 
> > Just format the code without functionality change.
> > 
> > Signed-off-by: Hou Zhiqiang 
> > Reviewed-by: Minghuan Lian 
> > ---
> > V5:
> >  - Retouched the subject.
> > 
> >  drivers/pci/controller/pcie-mobiveil.c | 261 +
> >  1 file changed, 137 insertions(+), 124 deletions(-)
> 
> Ok, dropping this patch means that everything else should be
> rebased. So what I am going to do:
> 
> - I will publish a branch (pci/mobiveil) where I added the patches
>   that are ready to be merged with commit logs rewritten; this patch
>   is part of it but in the final version it must be split as requested.
> - You have to split this patch and the other patches I requested
>   you to split but do NOT modify the patches with my commit logs
>   rewritten in pci/mobiveil, it took me time to rewrite them.
> 
> If you can manage to rebase patches on pci/mobiveil on top
> of v5.2-rc1, send them separately so that I can merge them
> as a base for the subsequent patches to be applied.
> 
> If you have any questions please ask, do not post patches
> if there is something that is not clear.

This is the branch mentioned above:

https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/log/?h=not-to-merge/pci/mobiveil

> Lorenzo
> 
> > diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> > b/drivers/pci/controller/pcie-mobiveil.c
> > index d55c7e780c6e..b87471f08a40 100644
> > --- a/drivers/pci/controller/pcie-mobiveil.c
> > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > @@ -31,38 +31,40 @@
> >   * translation tables are grouped into windows, each window registers are
> >   * grouped into blocks of 4 or 16 registers each
> >   */
> > -#define PAB_REG_BLOCK_SIZE 16
> > -#define PAB_EXT_REG_BLOCK_SIZE 4
> > +#define PAB_REG_BLOCK_SIZE 16
> > +#define PAB_EXT_REG_BLOCK_SIZE 4
> >  
> > -#define PAB_REG_ADDR(offset, win) (offset + (win * PAB_REG_BLOCK_SIZE))
> > -#define PAB_EXT_REG_ADDR(offset, win) (offset + (win * 
> > PAB_EXT_REG_BLOCK_SIZE))
> > +#define PAB_REG_ADDR(offset, win)  \
> > +   (offset + (win * PAB_REG_BLOCK_SIZE))
> > +#define PAB_EXT_REG_ADDR(offset, win)  \
> > +   (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
> >  
> > -#define LTSSM_STATUS   0x0404
> > -#define  LTSSM_STATUS_L0_MASK  0x3f
> > -#define  LTSSM_STATUS_L0   0x2d
> > +#define LTSSM_STATUS   0x0404
> > +#define  LTSSM_STATUS_L0_MASK  0x3f
> > +#define  LTSSM_STATUS_L0   0x2d
> >  
> > -#define PAB_CTRL   0x0808
> > -#define  AMBA_PIO_ENABLE_SHIFT 0
> > -#define  PEX_PIO_ENABLE_SHIFT  1
> > -#define  PAGE_SEL_SHIFT13
> > -#define  PAGE_SEL_MASK 0x3f
> > -#define  PAGE_LO_MASK  0x3ff
> > -#define  PAGE_SEL_OFFSET_SHIFT 10
> > +#define PAB_CTRL   0x0808
> > +#define  AMBA_PIO_ENABLE_SHIFT 0
> > +#define  PEX_PIO_ENABLE_SHIFT  1
> > +#define  PAGE_SEL_SHIFT13
> > +#define  PAGE_SEL_MASK 0x3f
> > +#define  PAGE_LO_MASK  0x3ff
> > +#define  PAGE_SEL_OFFSET_SHIFT 10
> >  
> > -#define PAB_AXI_PIO_CTRL   0x0840
> > -#define  APIO_EN_MASK  0xf
> > +#define PAB_AXI_PIO_CTRL   0x0840
> > +#define  APIO_EN_MASK  0xf
> >  
> > -#define PAB_PEX_PIO_CTRL   0x08c0
> > -#define  PIO_ENABLE_SHIFT  0
> > +#define PAB_PEX_PIO_CTRL   0x08c0
> > +#define  PIO_ENABLE_SHIFT  0
> >  
> >  #define PAB_INTP_AMBA_MISC_ENB 0x0b0c
> > -#define PAB_INTP_AMBA_MISC_STAT0x0b1c
> > +#define PAB_INTP_AMBA_MISC_STAT0x0b1c
> >  #define  PAB_INTP_INTX_MASK0x01e0
> >  #define  PAB_INTP_MSI_MASK 0x8
> >  
> > -#define PAB_AXI_AMAP_CTRL(win) PAB_REG_ADDR(0x0ba0, win)
> > -#define  WIN_ENABLE_SHIFT  0
> > -#define  WIN_TYPE_SHIFT1
> > +#define PAB_AXI_AMAP_CTRL(win) PAB_REG_ADDR(0x0ba0, win)
> > +#define  WIN_ENABLE_SHIFT  0
> > +#define  WIN_TYPE_SHIFT1
> >  
> >  #define PAB_EXT_AXI_AMAP_SIZE(win) PAB_EXT_REG_ADDR(0xbaf0, win)
> >  
> > @@ -70,16 +72,16 @@
> >  #define  AXI_WINDOW_ALIGN_MASK 3
> >  
> >  #define PAB_AXI_AMAP_PEX_

Re: [PATCHv5 02/20] PCI: mobiveil: Format the code without functionality change

2019-07-03 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:35:24AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> Just format the code without functionality change.
> 
> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> ---
> V5:
>  - Retouched the subject.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 261 +
>  1 file changed, 137 insertions(+), 124 deletions(-)

Ok, dropping this patch means that everything else should be
rebased. So what I am going to do:

- I will publish a branch (pci/mobiveil) where I added the patches
  that are ready to be merged with commit logs rewritten; this patch
  is part of it but in the final version it must be split as requested.
- You have to split this patch and the other patches I requested
  you to split but do NOT modify the patches with my commit logs
  rewritten in pci/mobiveil, it took me time to rewrite them.

If you can manage to rebase patches on pci/mobiveil on top
of v5.2-rc1, send them separately so that I can merge them
as a base for the subsequent patches to be applied.

If you have any questions please ask, do not post patches
if there is something that is not clear.

Lorenzo

> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index d55c7e780c6e..b87471f08a40 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -31,38 +31,40 @@
>   * translation tables are grouped into windows, each window registers are
>   * grouped into blocks of 4 or 16 registers each
>   */
> -#define PAB_REG_BLOCK_SIZE   16
> -#define PAB_EXT_REG_BLOCK_SIZE   4
> +#define PAB_REG_BLOCK_SIZE   16
> +#define PAB_EXT_REG_BLOCK_SIZE   4
>  
> -#define PAB_REG_ADDR(offset, win) (offset + (win * PAB_REG_BLOCK_SIZE))
> -#define PAB_EXT_REG_ADDR(offset, win) (offset + (win * 
> PAB_EXT_REG_BLOCK_SIZE))
> +#define PAB_REG_ADDR(offset, win)\
> + (offset + (win * PAB_REG_BLOCK_SIZE))
> +#define PAB_EXT_REG_ADDR(offset, win)\
> + (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
>  
> -#define LTSSM_STATUS 0x0404
> -#define  LTSSM_STATUS_L0_MASK0x3f
> -#define  LTSSM_STATUS_L0 0x2d
> +#define LTSSM_STATUS 0x0404
> +#define  LTSSM_STATUS_L0_MASK0x3f
> +#define  LTSSM_STATUS_L0 0x2d
>  
> -#define PAB_CTRL 0x0808
> -#define  AMBA_PIO_ENABLE_SHIFT   0
> -#define  PEX_PIO_ENABLE_SHIFT1
> -#define  PAGE_SEL_SHIFT  13
> -#define  PAGE_SEL_MASK   0x3f
> -#define  PAGE_LO_MASK0x3ff
> -#define  PAGE_SEL_OFFSET_SHIFT   10
> +#define PAB_CTRL 0x0808
> +#define  AMBA_PIO_ENABLE_SHIFT   0
> +#define  PEX_PIO_ENABLE_SHIFT1
> +#define  PAGE_SEL_SHIFT  13
> +#define  PAGE_SEL_MASK   0x3f
> +#define  PAGE_LO_MASK0x3ff
> +#define  PAGE_SEL_OFFSET_SHIFT   10
>  
> -#define PAB_AXI_PIO_CTRL 0x0840
> -#define  APIO_EN_MASK0xf
> +#define PAB_AXI_PIO_CTRL 0x0840
> +#define  APIO_EN_MASK0xf
>  
> -#define PAB_PEX_PIO_CTRL 0x08c0
> -#define  PIO_ENABLE_SHIFT0
> +#define PAB_PEX_PIO_CTRL 0x08c0
> +#define  PIO_ENABLE_SHIFT0
>  
>  #define PAB_INTP_AMBA_MISC_ENB   0x0b0c
> -#define PAB_INTP_AMBA_MISC_STAT  0x0b1c
> +#define PAB_INTP_AMBA_MISC_STAT  0x0b1c
>  #define  PAB_INTP_INTX_MASK  0x01e0
>  #define  PAB_INTP_MSI_MASK   0x8
>  
> -#define PAB_AXI_AMAP_CTRL(win)   PAB_REG_ADDR(0x0ba0, win)
> -#define  WIN_ENABLE_SHIFT0
> -#define  WIN_TYPE_SHIFT  1
> +#define PAB_AXI_AMAP_CTRL(win)   PAB_REG_ADDR(0x0ba0, win)
> +#define  WIN_ENABLE_SHIFT0
> +#define  WIN_TYPE_SHIFT  1
>  
>  #define PAB_EXT_AXI_AMAP_SIZE(win)   PAB_EXT_REG_ADDR(0xbaf0, win)
>  
> @@ -70,16 +72,16 @@
>  #define  AXI_WINDOW_ALIGN_MASK   3
>  
>  #define PAB_AXI_AMAP_PEX_WIN_L(win)  PAB_REG_ADDR(0x0ba8, win)
> -#define  PAB_BUS_SHIFT   24
> -#define  PAB_DEVICE_SHIFT19
> -#define  PAB_FUNCTION_SHIFT  16
> +#define  PAB_BUS_SHIFT   24
> +#define  PAB_DEVICE_SHIFT19
> +#define  PAB_FUNCTION_SHIFT  16
>  
>  #define PAB_AXI_AMAP_PEX_WIN_H(win)  PAB_REG_ADDR(0x0bac, win)
>  #define PAB_INTP_AXI_PIO_CLASS   0x474
>  
> -#define PAB_PEX_AMAP_CTRL(win)   PAB_REG_ADDR(0x4ba0, win)
> -#define  AMAP_CTRL_EN_SHIFT  0
> -#define  AMAP_CTRL_TYPE_SHIFT1
> +#define PAB_PEX_AMAP_CTRL(win)   PAB_REG_ADDR(0x4ba0, win)
> +#define  AMAP_CTRL_EN_SHIFT  0
> +#define  AMAP_CTRL_TYPE_SHIFT1
>  
>  #define PAB_EXT_PEX_AMAP_SIZEN(win)  PAB_EXT_REG_ADDR(0xbef0, win)
>  #define PAB_PEX_AMAP_AXI_WIN(win)PAB_REG_ADDR(0x4ba4, win)
> @@ -87,39 +89,39 @@
>  #define 

Re: [PATCHv5 02/20] PCI: mobiveil: Format the code without functionality change

2019-07-03 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:35:24AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> Just format the code without functionality change.
> 
> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> ---
> V5:
>  - Retouched the subject.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 261 +
>  1 file changed, 137 insertions(+), 124 deletions(-)

Again, I will drop this patch. You tend to do multiple changes
in one single patch, I understand this patch is just
reformatting/renaming variables but at least I would separate
indentation changes from changes where eg you add local variables.

At least try to group the changes you are making instead of mixing
them all up.

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index d55c7e780c6e..b87471f08a40 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -31,38 +31,40 @@
>   * translation tables are grouped into windows, each window registers are
>   * grouped into blocks of 4 or 16 registers each
>   */
> -#define PAB_REG_BLOCK_SIZE   16
> -#define PAB_EXT_REG_BLOCK_SIZE   4
> +#define PAB_REG_BLOCK_SIZE   16
> +#define PAB_EXT_REG_BLOCK_SIZE   4
>  
> -#define PAB_REG_ADDR(offset, win) (offset + (win * PAB_REG_BLOCK_SIZE))
> -#define PAB_EXT_REG_ADDR(offset, win) (offset + (win * 
> PAB_EXT_REG_BLOCK_SIZE))
> +#define PAB_REG_ADDR(offset, win)\
> + (offset + (win * PAB_REG_BLOCK_SIZE))
> +#define PAB_EXT_REG_ADDR(offset, win)\
> + (offset + (win * PAB_EXT_REG_BLOCK_SIZE))
>  
> -#define LTSSM_STATUS 0x0404
> -#define  LTSSM_STATUS_L0_MASK0x3f
> -#define  LTSSM_STATUS_L0 0x2d
> +#define LTSSM_STATUS 0x0404
> +#define  LTSSM_STATUS_L0_MASK0x3f
> +#define  LTSSM_STATUS_L0 0x2d
>  
> -#define PAB_CTRL 0x0808
> -#define  AMBA_PIO_ENABLE_SHIFT   0
> -#define  PEX_PIO_ENABLE_SHIFT1
> -#define  PAGE_SEL_SHIFT  13
> -#define  PAGE_SEL_MASK   0x3f
> -#define  PAGE_LO_MASK0x3ff
> -#define  PAGE_SEL_OFFSET_SHIFT   10
> +#define PAB_CTRL 0x0808
> +#define  AMBA_PIO_ENABLE_SHIFT   0
> +#define  PEX_PIO_ENABLE_SHIFT1
> +#define  PAGE_SEL_SHIFT  13
> +#define  PAGE_SEL_MASK   0x3f
> +#define  PAGE_LO_MASK0x3ff
> +#define  PAGE_SEL_OFFSET_SHIFT   10
>  
> -#define PAB_AXI_PIO_CTRL 0x0840
> -#define  APIO_EN_MASK0xf
> +#define PAB_AXI_PIO_CTRL 0x0840
> +#define  APIO_EN_MASK0xf
>  
> -#define PAB_PEX_PIO_CTRL 0x08c0
> -#define  PIO_ENABLE_SHIFT0
> +#define PAB_PEX_PIO_CTRL 0x08c0
> +#define  PIO_ENABLE_SHIFT0
>  
>  #define PAB_INTP_AMBA_MISC_ENB   0x0b0c
> -#define PAB_INTP_AMBA_MISC_STAT  0x0b1c
> +#define PAB_INTP_AMBA_MISC_STAT  0x0b1c
>  #define  PAB_INTP_INTX_MASK  0x01e0
>  #define  PAB_INTP_MSI_MASK   0x8
>  
> -#define PAB_AXI_AMAP_CTRL(win)   PAB_REG_ADDR(0x0ba0, win)
> -#define  WIN_ENABLE_SHIFT0
> -#define  WIN_TYPE_SHIFT  1
> +#define PAB_AXI_AMAP_CTRL(win)   PAB_REG_ADDR(0x0ba0, win)
> +#define  WIN_ENABLE_SHIFT0
> +#define  WIN_TYPE_SHIFT  1
>  
>  #define PAB_EXT_AXI_AMAP_SIZE(win)   PAB_EXT_REG_ADDR(0xbaf0, win)
>  
> @@ -70,16 +72,16 @@
>  #define  AXI_WINDOW_ALIGN_MASK   3
>  
>  #define PAB_AXI_AMAP_PEX_WIN_L(win)  PAB_REG_ADDR(0x0ba8, win)
> -#define  PAB_BUS_SHIFT   24
> -#define  PAB_DEVICE_SHIFT19
> -#define  PAB_FUNCTION_SHIFT  16
> +#define  PAB_BUS_SHIFT   24
> +#define  PAB_DEVICE_SHIFT19
> +#define  PAB_FUNCTION_SHIFT  16
>  
>  #define PAB_AXI_AMAP_PEX_WIN_H(win)  PAB_REG_ADDR(0x0bac, win)
>  #define PAB_INTP_AXI_PIO_CLASS   0x474
>  
> -#define PAB_PEX_AMAP_CTRL(win)   PAB_REG_ADDR(0x4ba0, win)
> -#define  AMAP_CTRL_EN_SHIFT  0
> -#define  AMAP_CTRL_TYPE_SHIFT1
> +#define PAB_PEX_AMAP_CTRL(win)   PAB_REG_ADDR(0x4ba0, win)
> +#define  AMAP_CTRL_EN_SHIFT  0
> +#define  AMAP_CTRL_TYPE_SHIFT1
>  
>  #define PAB_EXT_PEX_AMAP_SIZEN(win)  PAB_EXT_REG_ADDR(0xbef0, win)
>  #define PAB_PEX_AMAP_AXI_WIN(win)PAB_REG_ADDR(0x4ba4, win)
> @@ -87,39 +89,39 @@
>  #define PAB_PEX_AMAP_PEX_WIN_H(win)  PAB_REG_ADDR(0x4bac, win)
>  
>  /* starting offset of INTX bits in status register */
> -#define PAB_INTX_START   5
> +#define PAB_INTX_START   5
>  
>  /* supported number of MSI interrupts */
> -#define PCI_NUM_MSI  16
> +#define PCI_NUM_MSI  16
>  
>  /* MSI registers */
> -#define MSI_BASE_LO_OFFSET   0x04
> -#define MSI_BASE_HI_OFFSET   0x08
> -#define MSI_SIZE_OFFSET  0x0c
> 

Re: [PATCHv5 03/20] PCI: mobiveil: Correct the returned error number

2019-07-03 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:35:30AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> This patch corrects the returned error number by convention,
> and removes an unnecessary error check.

Two distinct changes, two patches, please split and repost.

Lorenzo

> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - Corrected and retouched the subject and changelog.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 8 +++-
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index b87471f08a40..563210e731d3 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -819,7 +819,7 @@ static int mobiveil_pcie_init_irq_domain(struct 
> mobiveil_pcie *pcie)
>  
>   if (!pcie->intx_domain) {
>   dev_err(dev, "Failed to get a INTx IRQ domain\n");
> - return -ENODEV;
> + return -ENOMEM;
>   }
>  
>   raw_spin_lock_init(>intx_mask_lock);
> @@ -845,11 +845,9 @@ static int mobiveil_pcie_probe(struct platform_device 
> *pdev)
>   /* allocate the PCIe port */
>   bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
>   if (!bridge)
> - return -ENODEV;
> + return -ENOMEM;
>  
>   pcie = pci_host_bridge_priv(bridge);
> - if (!pcie)
> - return -ENOMEM;
>  
>   pcie->pdev = pdev;
>  
> @@ -866,7 +864,7 @@ static int mobiveil_pcie_probe(struct platform_device 
> *pdev)
>   >resources, );
>   if (ret) {
>   dev_err(dev, "Getting bridge resources failed\n");
> - return -ENOMEM;
> + return ret;
>   }
>  
>   /*
> -- 
> 2.17.1
> 


Re: [PATCHv5 00/20] PCI: mobiveil: fixes for Mobiveil PCIe Host Bridge IP driver

2019-07-03 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:35:11AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> This patch set is to add fixes for Mobiveil PCIe Host driver.
> And these patches are splited from the thread below:
> http://patchwork.ozlabs.org/project/linux-pci/list/?series=96417
> 
> Hou Zhiqiang (20):
>   PCI: mobiveil: Unify register accessors
>   PCI: mobiveil: Format the code without functionality change
>   PCI: mobiveil: Correct the returned error number
>   PCI: mobiveil: Remove the flag MSI_FLAG_MULTI_PCI_MSI
>   PCI: mobiveil: Correct PCI base address in MEM/IO outbound windows
>   PCI: mobiveil: Replace the resource list iteration function
>   PCI: mobiveil: Use WIN_NUM_0 explicitly for CFG outbound window
>   PCI: mobiveil: Use the 1st inbound window for MEM inbound transactions
>   PCI: mobiveil: Correct inbound/outbound window setup routines
>   PCI: mobiveil: Fix the INTx process errors
>   PCI: mobiveil: Correct the fixup of Class Code field
>   PCI: mobiveil: Move the link up waiting out of mobiveil_host_init()
>   PCI: mobiveil: Move IRQ chained handler setup out of DT parse
>   PCI: mobiveil: Initialize Primary/Secondary/Subordinate bus numbers
>   PCI: mobiveil: Fix the checking of valid device
>   PCI: mobiveil: Add link up condition check
>   PCI: mobiveil: Complete initialization of host even if no PCIe link
>   PCI: mobiveil: Disable IB and OB windows set by bootloader
>   PCI: mobiveil: Add 8-bit and 16-bit register accessors
>   dt-bindings: PCI: mobiveil: Change gpio_slave and apb_csr to optional
> 
>  .../devicetree/bindings/pci/mobiveil-pcie.txt |   2 +
>  drivers/pci/controller/pcie-mobiveil.c| 578 +++---
>  2 files changed, 368 insertions(+), 212 deletions(-)

I am putting together a branch with the patches I would like
to queue, for the ones I requested to split please wait for
me, I will publish the branch and will ask you to rebase
on top of it.

Lorenzo


Re: [PATCHv5 10/20] PCI: mobiveil: Fix the INTx process errors

2019-06-28 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:36:12AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> In the loop block, there is not code to update the loop key,
> this patch updates the loop key by re-read the INTx status
> register.
> 
> This patch also add the clearing of the handled INTx status.

This is two bugs and that requires two patches, each of them fixing a
specific issue.

So split the patch into two and repost it.

Lorenzo

> Note: Need MV to test this fix.
> 
> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver")
> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - Corrected and retouched the subject and changelog.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index 4ba458474e42..78e575e71f4d 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -361,6 +361,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>   /* Handle INTx */
>   if (intr_status & PAB_INTP_INTX_MASK) {
>   shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT);
> + shifted_status &= PAB_INTP_INTX_MASK;
>   shifted_status >>= PAB_INTX_START;
>   do {
>   for_each_set_bit(bit, _status, PCI_NUM_INTX) {
> @@ -372,12 +373,16 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>   dev_err_ratelimited(dev, "unexpected 
> IRQ, INT%d\n",
>   bit);
>  
> - /* clear interrupt */
> - csr_writel(pcie,
> -shifted_status << PAB_INTX_START,
> + /* clear interrupt handled */
> + csr_writel(pcie, 1 << (PAB_INTX_START + bit),
>  PAB_INTP_AMBA_MISC_STAT);
>   }
> - } while ((shifted_status >> PAB_INTX_START) != 0);
> +
> + shifted_status = csr_readl(pcie,
> +PAB_INTP_AMBA_MISC_STAT);
> + shifted_status &= PAB_INTP_INTX_MASK;
> + shifted_status >>= PAB_INTX_START;
> + } while (shifted_status != 0);
>   }
>  
>   /* read extra MSI status register */
> -- 
> 2.17.1
> 


Re: [PATCHv5 09/20] PCI: mobiveil: Correct inbound/outbound window setup routines

2019-06-28 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:36:06AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> Outbound window routine:
>  - Remove unused var definitions and register read operations.
>  - Add the upper 32-bit cpu address setup of the window.
>  - Instead of blindly write, only change the fields specified.
>  - Mask the lower bits of window size in case override the
>control bits.
>  - Check if the passing window number is available, instead of
>the total number of the initialized windows.
> 
> Inbound window routine:
>  - Add parameter 'u64 cpu_addr' to specify the cpu address
>of the window instead of using 'pci_addr'.
>  - Change 'int pci_addr' to 'u64 pci_addr', and add setup
>of the upper 32-bit PCI address of the window.
>  - Move the PCIe PIO master enablement to mobiveil_host_init().
>  - Instead of blindly write, only change the fields specified.
>  - Mask the lower bits of window size in case override the
>control bits.
>  - Check if the passing window number is available, instead of
>the total number of the initialized windows.
>  - And add the statistic of initialized inbound windows.
> 
> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver")
> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - Corrected and retouched the subject and changelog.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 70 +++---
>  1 file changed, 42 insertions(+), 28 deletions(-)

There are two things to be done here:

1) Separate fixes from refactoring
2) Each fix should be standalone and solve one problem only

The commit log is a list of changes, some of which I can't
parse.

You should split this patch as described above and repost it
separately but first I will try to merge what I can from this
series, do not repost as yet.

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index e88afc792a5c..4ba458474e42 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -65,9 +65,13 @@
>  #define PAB_AXI_AMAP_CTRL(win)   PAB_REG_ADDR(0x0ba0, win)
>  #define  WIN_ENABLE_SHIFT0
>  #define  WIN_TYPE_SHIFT  1
> +#define  WIN_TYPE_MASK   0x3
> +#define  WIN_SIZE_SHIFT  10
> +#define  WIN_SIZE_MASK   0x3f
>  
>  #define PAB_EXT_AXI_AMAP_SIZE(win)   PAB_EXT_REG_ADDR(0xbaf0, win)
>  
> +#define PAB_EXT_AXI_AMAP_AXI_WIN(win)PAB_EXT_REG_ADDR(0x80a0, win)
>  #define PAB_AXI_AMAP_AXI_WIN(win)PAB_REG_ADDR(0x0ba4, win)
>  #define  AXI_WINDOW_ALIGN_MASK   3
>  
> @@ -82,8 +86,10 @@
>  #define PAB_PEX_AMAP_CTRL(win)   PAB_REG_ADDR(0x4ba0, win)
>  #define  AMAP_CTRL_EN_SHIFT  0
>  #define  AMAP_CTRL_TYPE_SHIFT1
> +#define  AMAP_CTRL_TYPE_MASK 3
>  
>  #define PAB_EXT_PEX_AMAP_SIZEN(win)  PAB_EXT_REG_ADDR(0xbef0, win)
> +#define PAB_EXT_PEX_AMAP_AXI_WIN(win)PAB_EXT_REG_ADDR(0xb4a0, win)
>  #define PAB_PEX_AMAP_AXI_WIN(win)PAB_REG_ADDR(0x4ba4, win)
>  #define PAB_PEX_AMAP_PEX_WIN_L(win)  PAB_REG_ADDR(0x4ba8, win)
>  #define PAB_PEX_AMAP_PEX_WIN_H(win)  PAB_REG_ADDR(0x4bac, win)
> @@ -455,49 +461,51 @@ static int mobiveil_pcie_parse_dt(struct mobiveil_pcie 
> *pcie)
>  }
>  
>  static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
> -int pci_addr, u32 type, u64 size)
> +u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
>  {
> - int pio_ctrl_val;
> - int amap_ctrl_dw;
> + u32 value;
>   u64 size64 = ~(size - 1);
>  
> - if ((pcie->ib_wins_configured + 1) > pcie->ppio_wins) {
> + if (win_num >= pcie->ppio_wins) {
>   dev_err(>pdev->dev,
>   "ERROR: max inbound windows reached !\n");
>   return;
>   }
>  
> - pio_ctrl_val = csr_readl(pcie, PAB_PEX_PIO_CTRL);
> - pio_ctrl_val |= 1 << PIO_ENABLE_SHIFT;
> - csr_writel(pcie, pio_ctrl_val, PAB_PEX_PIO_CTRL);
> -
> - amap_ctrl_dw = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> - amap_ctrl_dw |= (type << AMAP_CTRL_TYPE_SHIFT) |
> - (1 << AMAP_CTRL_EN_SHIFT) |
> - lower_32_bits(size64);
> - csr_writel(pcie, amap_ctrl_dw, PAB_PEX_AMAP_CTRL(win_num));
> + value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
> + value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT |
> +  WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> + value |= (type << AMAP_CTRL_TYPE_SHIFT) | (1 << AMAP_CTRL_EN_SHIFT) |
> +  (lower_32_bits(size64) & WIN_SIZE_MASK << WIN_SIZE_SHIFT);
> + csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
>  
>   csr_writel(pcie, upper_32_bits(size64),
>  PAB_EXT_PEX_AMAP_SIZEN(win_num));
>  
> - csr_writel(pcie, pci_addr, 

Re: [PATCHv5 08/20] PCI: mobiveil: Use the 1st inbound window for MEM inbound transactions

2019-06-28 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:36:00AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> The inbound windows have independent register set against outbound windows.
> This patch change the MEM inbound window to the first one.

You mean that windows 0 can be used as well as window 1 for inbound
windows so it is better to opt for window 0 for consistency ?

Lorenzo

> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - Corrected and retouched the subject and changelog.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index df71c11b4810..e88afc792a5c 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -616,7 +616,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>  CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));
>  
>   /* memory inbound translation window */
> - program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
> + program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
>  
>   /* Get the I/O and memory ranges from DT */
>   resource_list_for_each_entry(win, >resources) {
> -- 
> 2.17.1
> 


Re: [PATCHv5 04/20] PCI: mobiveil: Remove the flag MSI_FLAG_MULTI_PCI_MSI

2019-06-28 Thread Lorenzo Pieralisi
On Mon, Jun 17, 2019 at 10:34:35AM +, Z.q. Hou wrote:

[...]

> > There is nothing obvious. Write what you are fixing in the commit log and I 
> > will
> > apply the patch, I won't write the commit log for you. Anyone should be able
> > to understand why a patch was needed by reading the commit log, it is as
> > important as writing the code itself.
> 
> With the flag MSI_FLAG_MULTI_PCI_MSI, when the Endpoint allocates
> multiple MSI, it will trigger the "WARN_ON(nr_irqs != 1);" in
> mobiveil_irq_msi_domain_alloc(), this is the issue this patch want to
> fix. 

And that's wrong. Marc explained why this controller does not support
Multi MSI and that's what should go in the commit log, triggering
a WARN_ON is the least of the problems (and the WARN_ON can even
be removed after this patch is applied), if it was used as a bandaid
to prevent allocating Multi MSI it is even more broken.

Lorenzo

> Thanks,
> Zhiqiang
> 
> > 
> > Thanks,
> > Lorenzo
> > 
> > > Thanks,
> > > Zhiqiang
> > >
> > > >
> > > > Lorenzo
> > > >
> > > > > Subbu, did you test with Endpoint supporting multi MSI?
> > > > >
> > > > > Thanks,
> > > > > Zhiqiang
> > > > >
> > > > > >
> > > > > > Thanks,
> > > > > > Lorenzo
> > > > > >
> > > > > > > Fixes: 1e913e58335f ("PCI: mobiveil: Add MSI support")
> > > > > > > Signed-off-by: Hou Zhiqiang 
> > > > > > > Reviewed-by: Minghuan Lian 
> > > > > > > ---
> > > > > > > V5:
> > > > > > >  - Corrected the subject.
> > > > > > >
> > > > > > >  drivers/pci/controller/pcie-mobiveil.c | 2 +-
> > > > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > > >
> > > > > > > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > > > > > > b/drivers/pci/controller/pcie-mobiveil.c
> > > > > > > index 563210e731d3..a0dd337c6214 100644
> > > > > > > --- a/drivers/pci/controller/pcie-mobiveil.c
> > > > > > > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > > > > > > @@ -703,7 +703,7 @@ static struct irq_chip
> > > > > > > mobiveil_msi_irq_chip = {
> > > > > > >
> > > > > > >  static struct msi_domain_info mobiveil_msi_domain_info = {
> > > > > > >   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS |
> > > > > > MSI_FLAG_USE_DEF_CHIP_OPS |
> > > > > > > -MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
> > > > > > > +MSI_FLAG_PCI_MSIX),
> > > > > > >   .chip   = _msi_irq_chip,
> > > > > > >  };
> > > > > > >
> > > > > > > --
> > > > > > > 2.17.1
> > > > > > >


Re: [PATCH] pci: tegra: use correct gpio/consumer.h header

2019-06-28 Thread Lorenzo Pieralisi
On Fri, Jun 28, 2019 at 12:29:45PM +0200, Arnd Bergmann wrote:
> linux/gpio.h is not the correct header for modern interfaces and
> causes a build failure without CONFIG_GPIOLIB:
> 
> drivers/pci/controller/pci-tegra.c: In function 'tegra_pcie_port_reset':
> drivers/pci/controller/pci-tegra.c:551:3: error: implicit declaration of 
> function 'gpiod_set_value'; did you mean 'gpio_set_value'? 
> [-Werror=implicit-function-declaration]
>gpiod_set_value(port->reset_gpio, 1);
>^~~
> 
> Use linux/gpio/consumer.h instead.
> 
> Fixes: 5e5e9c23f82a ("PCI: tegra: Add support for GPIO based PERST#")
> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/pci/controller/pci-tegra.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Squashed in the respective commit in pci/tegra, thanks for the fix
Arnd.

Lorenzo

> diff --git a/drivers/pci/controller/pci-tegra.c 
> b/drivers/pci/controller/pci-tegra.c
> index 9cc03a2549c0..1775b88c0aec 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -17,7 +17,7 @@
>  #include 
>  #include 
>  #include 
> -#include 
> +#include 
>  #include 
>  #include 
>  #include 
> -- 
> 2.20.0
> 


Re: [PATCH V11 03/12] PCI: dwc: Perform dbi regs write lock towards the end

2019-06-27 Thread Lorenzo Pieralisi
On Thu, Jun 27, 2019 at 09:03:08PM +0530, Vidya Sagar wrote:
> On 6/27/2019 8:28 PM, Lorenzo Pieralisi wrote:
> > On Mon, Jun 24, 2019 at 02:44:56PM +0530, Vidya Sagar wrote:
> > > Remove multiple write enable and disable sequences of dbi registers as
> > > Tegra194 implements writes to BAR-0 register (offset: 0x10) controlled by
> > > DBI write-lock enable bit thereby not allowing any further writes to BAR-0
> > > register in config space to take place. Hence enabling write permission at
> > > the start of function and disabling the same only towards the end.
> > 
> > I do not understand what this patch does, I would like to rephrase
> > the commit log in a way that is easier to parse.
> > 
> > In particular I do not get what you mean in relation to BAR-0, I am
> > confused, please clarify.
> > 
> > Lorenzo
> Well, some of the Synopsys DesignWare core's DBI registers are
> protected with a lock without which, they are read-only by default.
> Existing code in dw_pcie_setup_rc() API tries to unlock and lock
> multiple times whenever it wants to update those write-protected
> registers. This patch attempts to unlock all such write-protected
> registers for writing once in the beginning of the function and lock
> them back towards the end.  As far as BAR-0 register (which is at
> offset 0x10 in DBI space... nothing but the config space) in Tegra194
> is concerned, it is one of those registers to which writes are
> protected. I could have added unlock/lock pair around accessing this
> register, but that would bloat this API with one more pair of
> unlock/lock, instead I chose to remove unlock/lock pairs for all
> protected registers and have unlock in the beginning and lock towards
> the end.

Ok, so DBI space registers that require write permissions are per-IP.
This is clearer so the commit log must be rewritten, it is not clear at
all in this respect at least not as-is, if you read it you will
notice ;-)

Lorenzo

> 
> -Vidya Sagar
> 
> > 
> > > Signed-off-by: Vidya Sagar 
> > > Reviewed-by: Thierry Reding 
> > > Acked-by: Jingoo Han 
> > > ---
> > > Changes since [v10]:
> > > * None
> > > 
> > > Changes since [v9]:
> > > * None
> > > 
> > > Changes since [v8]:
> > > * None
> > > 
> > > Changes since [v7]:
> > > * None
> > > 
> > > Changes since [v6]:
> > > * None
> > > 
> > > Changes since [v5]:
> > > * Moved write enable to the beginning of the API and write disable to the 
> > > end
> > > 
> > > Changes since [v4]:
> > > * None
> > > 
> > > Changes since [v3]:
> > > * None
> > > 
> > > Changes since [v2]:
> > > * None
> > > 
> > > Changes since [v1]:
> > > * None
> > > 
> > >   drivers/pci/controller/dwc/pcie-designware-host.c | 14 --
> > >   1 file changed, 8 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c 
> > > b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index f93252d0da5b..d3156446ff27 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -628,6 +628,12 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
> > >   u32 val, ctrl, num_ctrls;
> > >   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > + /*
> > > +  * Enable DBI read-only registers for writing/updating configuration.
> > > +  * Write permission gets disabled towards the end of this function.
> > > +  */
> > > + dw_pcie_dbi_ro_wr_en(pci);
> > > +
> > >   dw_pcie_setup(pci);
> > >   if (!pp->ops->msi_host_init) {
> > > @@ -650,12 +656,10 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
> > >   dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x);
> > >   /* Setup interrupt pins */
> > > - dw_pcie_dbi_ro_wr_en(pci);
> > >   val = dw_pcie_readl_dbi(pci, PCI_INTERRUPT_LINE);
> > >   val &= 0x00ff;
> > >   val |= 0x0100;
> > >   dw_pcie_writel_dbi(pci, PCI_INTERRUPT_LINE, val);
> > > - dw_pcie_dbi_ro_wr_dis(pci);
> > >   /* Setup bus numbers */
> > >   val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
> > > @@ -687,15 +691,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
> > >   dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > > - /* Enable write permission for the DBI read-only register */
> > > - dw_pcie_dbi_ro_wr_en(pci);
> > >   /* Program correct class for RC */
> > >   dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, 
> > > PCI_CLASS_BRIDGE_PCI);
> > > - /* Better disable write permission right after the update */
> > > - dw_pcie_dbi_ro_wr_dis(pci);
> > >   dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, );
> > >   val |= PORT_LOGIC_SPEED_CHANGE;
> > >   dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> > > +
> > > + dw_pcie_dbi_ro_wr_dis(pci);
> > >   }
> > >   EXPORT_SYMBOL_GPL(dw_pcie_setup_rc);
> > > -- 
> > > 2.17.1
> > > 
> 


Re: [PATCH V11 03/12] PCI: dwc: Perform dbi regs write lock towards the end

2019-06-27 Thread Lorenzo Pieralisi
On Mon, Jun 24, 2019 at 02:44:56PM +0530, Vidya Sagar wrote:
> Remove multiple write enable and disable sequences of dbi registers as
> Tegra194 implements writes to BAR-0 register (offset: 0x10) controlled by
> DBI write-lock enable bit thereby not allowing any further writes to BAR-0
> register in config space to take place. Hence enabling write permission at
> the start of function and disabling the same only towards the end.

I do not understand what this patch does, I would like to rephrase
the commit log in a way that is easier to parse.

In particular I do not get what you mean in relation to BAR-0, I am
confused, please clarify.

Lorenzo

> Signed-off-by: Vidya Sagar 
> Reviewed-by: Thierry Reding 
> Acked-by: Jingoo Han 
> ---
> Changes since [v10]:
> * None
> 
> Changes since [v9]:
> * None
> 
> Changes since [v8]:
> * None
> 
> Changes since [v7]:
> * None
> 
> Changes since [v6]:
> * None
> 
> Changes since [v5]:
> * Moved write enable to the beginning of the API and write disable to the end
> 
> Changes since [v4]:
> * None
> 
> Changes since [v3]:
> * None
> 
> Changes since [v2]:
> * None
> 
> Changes since [v1]:
> * None
> 
>  drivers/pci/controller/dwc/pcie-designware-host.c | 14 --
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c 
> b/drivers/pci/controller/dwc/pcie-designware-host.c
> index f93252d0da5b..d3156446ff27 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -628,6 +628,12 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
>   u32 val, ctrl, num_ctrls;
>   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  
> + /*
> +  * Enable DBI read-only registers for writing/updating configuration.
> +  * Write permission gets disabled towards the end of this function.
> +  */
> + dw_pcie_dbi_ro_wr_en(pci);
> +
>   dw_pcie_setup(pci);
>  
>   if (!pp->ops->msi_host_init) {
> @@ -650,12 +656,10 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
>   dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x);
>  
>   /* Setup interrupt pins */
> - dw_pcie_dbi_ro_wr_en(pci);
>   val = dw_pcie_readl_dbi(pci, PCI_INTERRUPT_LINE);
>   val &= 0x00ff;
>   val |= 0x0100;
>   dw_pcie_writel_dbi(pci, PCI_INTERRUPT_LINE, val);
> - dw_pcie_dbi_ro_wr_dis(pci);
>  
>   /* Setup bus numbers */
>   val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
> @@ -687,15 +691,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
>  
>   dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
>  
> - /* Enable write permission for the DBI read-only register */
> - dw_pcie_dbi_ro_wr_en(pci);
>   /* Program correct class for RC */
>   dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI);
> - /* Better disable write permission right after the update */
> - dw_pcie_dbi_ro_wr_dis(pci);
>  
>   dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, );
>   val |= PORT_LOGIC_SPEED_CHANGE;
>   dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> +
> + dw_pcie_dbi_ro_wr_dis(pci);
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_setup_rc);
> -- 
> 2.17.1
> 


Re: [PATCH V11 01/12] PCI: Add #defines for some of PCIe spec r4.0 features

2019-06-27 Thread Lorenzo Pieralisi
On Mon, Jun 24, 2019 at 02:44:54PM +0530, Vidya Sagar wrote:
> Add #defines only for the Data Link Feature and Physical Layer 16.0 GT/s
> features.
> 
> Signed-off-by: Vidya Sagar 
> Reviewed-by: Thierry Reding 
> ---
> Changes since [v10]:
> * None
> 
> Changes since [v9]:
> * None
> 
> Changes since [v8]:
> * None
> 
> Changes since [v7]:
> * None
> 
> Changes since [v6]:
> * None
> 
> Changes since [v5]:
> * None
> 
> Changes since [v4]:
> * None
> 
> Changes since [v3]:
> * None
> 
> Changes since [v2]:
> * Updated commit message and description to explicitly mention that defines 
> are
>   added only for some of the features and not all.
> 
> Changes since [v1]:
> * None
> 
>  include/uapi/linux/pci_regs.h | 22 +-
>  1 file changed, 21 insertions(+), 1 deletion(-)

I need Bjorn's ACK to merge this patch.

Lorenzo

> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index f28e562d7ca8..1c79f6a097d2 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -713,7 +713,9 @@
>  #define PCI_EXT_CAP_ID_DPC   0x1D/* Downstream Port Containment */
>  #define PCI_EXT_CAP_ID_L1SS  0x1E/* L1 PM Substates */
>  #define PCI_EXT_CAP_ID_PTM   0x1F/* Precision Time Measurement */
> -#define PCI_EXT_CAP_ID_MAX   PCI_EXT_CAP_ID_PTM
> +#define PCI_EXT_CAP_ID_DLF   0x25/* Data Link Feature */
> +#define PCI_EXT_CAP_ID_PL0x26/* Physical Layer 16.0 GT/s */
> +#define PCI_EXT_CAP_ID_MAX   PCI_EXT_CAP_ID_PL
>  
>  #define PCI_EXT_CAP_DSN_SIZEOF   12
>  #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
> @@ -1053,4 +1055,22 @@
>  #define  PCI_L1SS_CTL1_LTR_L12_TH_SCALE  0xe000  /* 
> LTR_L1.2_THRESHOLD_Scale */
>  #define PCI_L1SS_CTL20x0c/* Control 2 Register */
>  
> +/* Data Link Feature */
> +#define PCI_DLF_CAP  0x04/* Capabilities Register */
> +#define  PCI_DLF_LOCAL_DLF_SUP_MASK  0x007f  /* Local Data Link Feature 
> Supported */
> +#define  PCI_DLF_EXCHANGE_ENABLE 0x8000  /* Data Link Feature 
> Exchange Enable */
> +#define PCI_DLF_STS  0x08/* Status Register */
> +#define  PCI_DLF_REMOTE_DLF_SUP_MASK 0x007f  /* Remote Data Link Feature 
> Supported */
> +#define  PCI_DLF_REMOTE_DLF_SUP_VALID0x8000  /* Remote Data Link 
> Feature Support Valid */
> +
> +/* Physical Layer 16.0 GT/s */
> +#define PCI_PL_16GT_CAP  0x04/* Capabilities Register */
> +#define PCI_PL_16GT_CTRL 0x08/* Control Register */
> +#define PCI_PL_16GT_STS  0x0c/* Status Register */
> +#define PCI_PL_16GT_LDPM_STS 0x10/* Local Data Parity Mismatch Status 
> Register */
> +#define PCI_PL_16GT_FRDPM_STS0x14/* First Retimer Data Parity 
> Mismatch Status Register */
> +#define PCI_PL_16GT_SRDPM_STS0x18/* Second Retimer Data Parity 
> Mismatch Status Register */
> +#define PCI_PL_16GT_RSVD 0x1C/* Reserved */
> +#define PCI_PL_16GT_LE_CTRL  0x20/* Lane Equalization Control Register */
> +
>  #endif /* LINUX_PCI_REGS_H */
> -- 
> 2.17.1
> 


Re: [PATCH v3] PCI: aardvark: Fix PCI_EXP_RTCTL register configuration

2019-06-27 Thread Lorenzo Pieralisi
On Mon, Jun 17, 2019 at 01:43:36PM +0100, Lorenzo Pieralisi wrote:
> On Fri, Jun 14, 2019 at 12:10:59PM +0200, Remi Pommarel wrote:
> > PCI_EXP_RTCTL is used to activate PME interrupt only, so writing into it
> > should not modify other interrupts' mask. The ISR mask polarity was also
> > inverted, when PCI_EXP_RTCTL_PMEIE is set PCIE_MSG_PM_PME_MASK mask bit
> > should actually be cleared.
> > 
> > Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge 
> > config space")
> > Signed-off-by: Remi Pommarel 
> > ---
> > Changes since v1:
> >  * Improve code readability
> >  * Fix mask polarity
> >  * PME_MASK shift was off by one
> > Changes since v2:
> >  * Modify patch title
> >  * Change Fixes tag to commit that actually introduces the bug
> > ---
> >  drivers/pci/controller/pci-aardvark.c | 13 +
> >  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> I need Thomas' ACK to apply it, thanks.

I still need it :), thanks.

Lorenzo

> Lorenzo
> 
> > diff --git a/drivers/pci/controller/pci-aardvark.c 
> > b/drivers/pci/controller/pci-aardvark.c
> > index 134e0306ff00..f6e55c4597b1 100644
> > --- a/drivers/pci/controller/pci-aardvark.c
> > +++ b/drivers/pci/controller/pci-aardvark.c
> > @@ -415,7 +415,7 @@ advk_pci_bridge_emul_pcie_conf_read(struct 
> > pci_bridge_emul *bridge,
> >  
> > case PCI_EXP_RTCTL: {
> > u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
> > -   *value = (val & PCIE_MSG_PM_PME_MASK) ? PCI_EXP_RTCTL_PMEIE : 0;
> > +   *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE;
> > return PCI_BRIDGE_EMUL_HANDLED;
> > }
> >  
> > @@ -451,10 +451,15 @@ advk_pci_bridge_emul_pcie_conf_write(struct 
> > pci_bridge_emul *bridge,
> > advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
> > break;
> >  
> > -   case PCI_EXP_RTCTL:
> > -   new = (new & PCI_EXP_RTCTL_PMEIE) << 3;
> > -   advk_writel(pcie, new, PCIE_ISR0_MASK_REG);
> > +   case PCI_EXP_RTCTL: {
> > +   /* Only mask/unmask PME interrupt */
> > +   u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) &
> > +   ~PCIE_MSG_PM_PME_MASK;
> > +   if ((new & PCI_EXP_RTCTL_PMEIE) == 0)
> > +   val |= PCIE_MSG_PM_PME_MASK;
> > +   advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
> > break;
> > +   }
> >  
> > case PCI_EXP_RTSTA:
> > new = (new & PCI_EXP_RTSTA_PME) >> 9;
> > -- 
> > 2.20.1
> > 


Re: [PATCH V9 1/3] PCI: dwc: Add API support to de-initialize host

2019-06-27 Thread Lorenzo Pieralisi
On Tue, Jun 25, 2019 at 02:52:36PM +0530, Vidya Sagar wrote:
> Add an API to group all the tasks to be done to de-initialize host which
> can then be called by any DesignWare core based driver implementations
> while adding .remove() support in their respective drivers.
> 
> Signed-off-by: Vidya Sagar 
> Acked-by: Gustavo Pimentel 
> ---
> Changes from v8:
> * None
> 
> Changes from v7:
> * None
> 
> Changes from v6:
> * None
> 
> Changes from v5:
> * None
> 
> Changes from v4:
> * None
> 
> Changes from v3:
> * Added check if (pci_msi_enabled() && !pp->ops->msi_host_init) before calling
>   dw_pcie_free_msi() API to mimic init path
> 
> Changes from v2:
> * Rebased on top of linux-next top of the tree branch
> 
> Changes from v1:
> * s/Designware/DesignWare
> 
>  drivers/pci/controller/dwc/pcie-designware-host.c | 8 
>  drivers/pci/controller/dwc/pcie-designware.h  | 5 +
>  2 files changed, 13 insertions(+)

I have applied the series in pci/dwc for v5.3, thanks.

Lorenzo

> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c 
> b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 77db32529319..d069e4290180 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -496,6 +496,14 @@ int dw_pcie_host_init(struct pcie_port *pp)
>   return ret;
>  }
>  
> +void dw_pcie_host_deinit(struct pcie_port *pp)
> +{
> + pci_stop_root_bus(pp->root_bus);
> + pci_remove_root_bus(pp->root_bus);
> + if (pci_msi_enabled() && !pp->ops->msi_host_init)
> + dw_pcie_free_msi(pp);
> +}
> +
>  static int dw_pcie_access_other_conf(struct pcie_port *pp, struct pci_bus 
> *bus,
>u32 devfn, int where, int size, u32 *val,
>bool write)
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> b/drivers/pci/controller/dwc/pcie-designware.h
> index b8993f2b78df..14762e262758 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -351,6 +351,7 @@ void dw_pcie_msi_init(struct pcie_port *pp);
>  void dw_pcie_free_msi(struct pcie_port *pp);
>  void dw_pcie_setup_rc(struct pcie_port *pp);
>  int dw_pcie_host_init(struct pcie_port *pp);
> +void dw_pcie_host_deinit(struct pcie_port *pp);
>  int dw_pcie_allocate_domains(struct pcie_port *pp);
>  #else
>  static inline irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
> @@ -375,6 +376,10 @@ static inline int dw_pcie_host_init(struct pcie_port *pp)
>   return 0;
>  }
>  
> +static inline void dw_pcie_host_deinit(struct pcie_port *pp)
> +{
> +}
> +
>  static inline int dw_pcie_allocate_domains(struct pcie_port *pp)
>  {
>   return 0;
> -- 
> 2.17.1
> 


Re: linux-next: Fixes tag needs some work in the pci tree

2019-06-26 Thread Lorenzo Pieralisi
On Sat, Jun 22, 2019 at 11:40:29PM +1000, Stephen Rothwell wrote:
> Hi all,
> 
> In commit
> 
>   46c1bfcfcd87 ("PCI: xilinx-nwl: Fix Multi MSI data programming")
> 
> Fixes tag
> 
>   Fixes: ab597d35ef11 ("PCI: xilinx-nwl: Add support for Xilinx NWL PCIe
> 
> has these problem(s):
> 
>   - Subject has leading but no trailing parentheses
>   - Subject has leading but no trailing quotes
> 
> Please do not split Fixes tags across more than one line.

Sorry, I do not know how I managed not to run your script on this
commit log. Log updated on my pci/xilinx branch, Bjorn please pull
it when you have time.

Thanks,
Lorenzo


Re: [PATCH V6 2/3] PCI: dwc: Cleanup DBI read and write APIs

2019-06-21 Thread Lorenzo Pieralisi
On Fri, Jun 21, 2019 at 04:39:59PM +0530, Vidya Sagar wrote:
> Cleanup DBI read and write APIs by removing "__" (underscore) from their
> names as there are no no-underscore versions and the underscore versions
> are already doing what no-underscore versions typically do. It also removes
> passing dbi/dbi2 base address as one of the arguments as the same can be
> derived with in read and write APIs.
> 
> Signed-off-by: Vidya Sagar 
> ---
> Changes from v5:
> * Removed passing base address as one of the arguments as the same can be 
> derived within
>   the API itself.
> * Modified ATU read/write APIs to call dw_pcie_{write/read}() API
> 
> Changes from v4:
> * This is a new patch in this series
> 
>  drivers/pci/controller/dwc/pcie-designware.c | 28 ++---
>  drivers/pci/controller/dwc/pcie-designware.h | 43 
>  2 files changed, 37 insertions(+), 34 deletions(-)

Gustavo, Jingoo,

please ACK this patch if you are OK with it so that I can merge
the series, thanks.

Lorenzo

> diff --git a/drivers/pci/controller/dwc/pcie-designware.c 
> b/drivers/pci/controller/dwc/pcie-designware.c
> index 9d7c51c32b3b..0b383feb13de 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -52,64 +52,60 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val)
>   return PCIBIOS_SUCCESSFUL;
>  }
>  
> -u32 __dw_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
> -size_t size)
> +u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size)
>  {
>   int ret;
>   u32 val;
>  
>   if (pci->ops->read_dbi)
> - return pci->ops->read_dbi(pci, base, reg, size);
> + return pci->ops->read_dbi(pci, pci->dbi_base, reg, size);
>  
> - ret = dw_pcie_read(base + reg, size, );
> + ret = dw_pcie_read(pci->dbi_base + reg, size, );
>   if (ret)
>   dev_err(pci->dev, "Read DBI address failed\n");
>  
>   return val;
>  }
>  
> -void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
> -  size_t size, u32 val)
> +void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val)
>  {
>   int ret;
>  
>   if (pci->ops->write_dbi) {
> - pci->ops->write_dbi(pci, base, reg, size, val);
> + pci->ops->write_dbi(pci, pci->dbi_base, reg, size, val);
>   return;
>   }
>  
> - ret = dw_pcie_write(base + reg, size, val);
> + ret = dw_pcie_write(pci->dbi_base + reg, size, val);
>   if (ret)
>   dev_err(pci->dev, "Write DBI address failed\n");
>  }
>  
> -u32 __dw_pcie_read_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg,
> - size_t size)
> +u32 dw_pcie_read_dbi2(struct dw_pcie *pci, u32 reg, size_t size)
>  {
>   int ret;
>   u32 val;
>  
>   if (pci->ops->read_dbi2)
> - return pci->ops->read_dbi2(pci, base, reg, size);
> + return pci->ops->read_dbi2(pci, pci->dbi_base2, reg, size);
>  
> - ret = dw_pcie_read(base + reg, size, );
> + ret = dw_pcie_read(pci->dbi_base2 + reg, size, );
>   if (ret)
>   dev_err(pci->dev, "read DBI address failed\n");
>  
>   return val;
>  }
>  
> -void __dw_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg,
> -   size_t size, u32 val)
> +void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val)
>  {
>   int ret;
>  
>   if (pci->ops->write_dbi2) {
> - pci->ops->write_dbi2(pci, base, reg, size, val);
> + pci->ops->write_dbi2(pci, pci->dbi_base2, reg, size, val);
>   return;
>   }
>  
> - ret = dw_pcie_write(base + reg, size, val);
> + ret = dw_pcie_write(pci->dbi_base2 + reg, size, val);
>   if (ret)
>   dev_err(pci->dev, "write DBI address failed\n");
>  }
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> b/drivers/pci/controller/dwc/pcie-designware.h
> index 14762e262758..88300b445a4d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -254,14 +254,10 @@ struct dw_pcie {
>  int dw_pcie_read(void __iomem *addr, int size, u32 *val);
>  int dw_pcie_write(void __iomem *addr, int size, u32 val);
>  
> -u32 __dw_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
> -size_t size);
> -void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
> -  size_t size, u32 val);
> -u32 __dw_pcie_read_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg,
> - size_t size);
> -void __dw_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg,
> -   size_t size, u32 val);
> +u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size);
> +void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
> +u32 

Re: [PATCH V4 1/2] PCI: dwc: Add API support to de-initialize host

2019-06-20 Thread Lorenzo Pieralisi
On Wed, Jun 19, 2019 at 10:41:26AM +0530, Kishon Vijay Abraham I wrote:
> Hi Lorenzo,
> 
> On 18/06/19 7:58 PM, Lorenzo Pieralisi wrote:
> > On Tue, Jun 18, 2019 at 04:21:17PM +0530, Vidya Sagar wrote:
> > 
> > [...]
> > 
> >>> 2) It is not related to this patch but I fail to see the reasoning
> >>> behind the __ in __dw_pci_read_dbi(), there is no no-underscore
> >>> equivalent so its definition is somewhat questionable, maybe
> >>> we should clean-it up (for dbi2 alike).
> >> Separate no-underscore versions are present in pcie-designware.h for
> >> each width (i.e. l/w/b) as inline and are calling __ versions passing
> >> size as argument.
> > 
> > I understand - the __ prologue was added in b50b2db266d8 maybe
> > Kishon can help us understand the __ rationale.
> > 
> > I am happy to merge it as is, I was just curious about the
> > __ annotation (not related to this patch).
> 
> In commit b50b2db266d8a8c303e8d88590 ("PCI: dwc: all: Modify dbi accessors to
> take dbi_base as argument"), dbi accessors was modified to take dbi_base as
> argument (since we wanted to write to dbics2 address space). We didn't want to
> change all the drivers invoking dbi accessors to pass the dbi_base. So we 
> added
> "__" variant to take dbi_base as argument and the drivers continued to invoke
> existing dbi accessors which in-turn invoked "__" version with dbi_base as
> argument.
> 
> I agree there could be some cleanup since in commit
> a509d7d9af5ebf86ffbefa98e49761d ("PCI: dwc: all: Modify dbi accessors to 
> access
> data of 4/2/1 bytes"), we modified __dw_pcie_readl_dbi() to
> __dw_pcie_write_dbi() when it could have been directly modified to
> dw_pcie_write_dbi().

Thanks. Vidya can do it as a preliminary patch, I will merge then
code to export the symbols.

Lorenzo


Re: [PATCH 3/4] arm_pmu: acpi: spe: Add initial MADT/SPE probing

2019-06-18 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 08:09:09PM -0500, Jeremy Linton wrote:
> ACPI 6.3 adds additional fields to the MADT GICC
> structure to describe SPE PPI's. We pick these out
> of the cached reference to the madt_gicc structure
> similarly to the core PMU code. We then create a platform
> device referring to the IRQ and let the user/module loader
> decide whether to load the SPE driver.
> 
> Signed-off-by: Jeremy Linton 
> ---
>  arch/arm64/include/asm/acpi.h |  3 ++
>  drivers/perf/arm_pmu_acpi.c   | 75 +++
>  include/linux/perf/arm_pmu.h  |  2 +
>  3 files changed, 80 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 7628efbe6c12..d10399b9f998 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -41,6 +41,9 @@
>   (!(entry) || (entry)->header.length < ACPI_MADT_GICC_MIN_LENGTH || \
>   (unsigned long)(entry) + (entry)->header.length > (end))
>  
> +#define ACPI_MADT_GICC_SPE  (ACPI_OFFSET(struct acpi_madt_generic_interrupt, 
> \
> + spe_interrupt) + sizeof(u16))
> +

Nit: Do we really need this to be in a header file ?

>  /* Basic configuration for ACPI */
>  #ifdef   CONFIG_ACPI
>  pgprot_t __acpi_get_mem_attribute(phys_addr_t addr);
> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c
> index 0f197516d708..f5df100bc4f4 100644
> --- a/drivers/perf/arm_pmu_acpi.c
> +++ b/drivers/perf/arm_pmu_acpi.c
> @@ -74,6 +74,79 @@ static void arm_pmu_acpi_unregister_irq(int cpu)
>   acpi_unregister_gsi(gsi);
>  }
>  
> +#if IS_ENABLED(CONFIG_ARM_SPE_PMU)
> +static struct resource spe_resources[] = {
> + {
> + /* irq */
> + .flags  = IORESOURCE_IRQ,
> + }
> +};
> +
> +static struct platform_device spe_dev = {
> + .name = ARMV8_SPE_PDEV_NAME,
> + .id = -1,
> + .resource = spe_resources,
> + .num_resources = ARRAY_SIZE(spe_resources)
> +};
> +
> +/*
> + * For lack of a better place, hook the normal PMU MADT walk
> + * and create a SPE device if we detect a recent MADT with
> + * a homogeneous PPI mapping.
> + */
> +static int arm_spe_acpi_register_device(void)
> +{
> + int cpu, hetid, irq, ret;
> + bool first = true;
> + u16 gsi = 0;
> +
> + /*
> +  * sanity check all the GICC tables for the same interrupt number
> +  * for now we only support homogeneous ACPI/SPE machines.
> +  */
> + for_each_possible_cpu(cpu) {
> + struct acpi_madt_generic_interrupt *gicc;
> +
> + gicc = acpi_cpu_get_madt_gicc(cpu);
> + if (gicc->header.length < ACPI_MADT_GICC_SPE)
> + return -ENODEV;
> +
> + if (first) {
> + gsi = gicc->spe_interrupt;
> + if (!gsi)
> + return -ENODEV;
> + hetid = find_acpi_cpu_topology_hetero_id(cpu);
> + first = false;
> + } else if ((gsi != gicc->spe_interrupt) ||
> +(hetid != find_acpi_cpu_topology_hetero_id(cpu))) {
> + pr_warn("ACPI: SPE must be homogeneous\n");
> + return -EINVAL;
> + }
> + }
> +
> + irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE,
> + ACPI_ACTIVE_HIGH);
> + if (irq < 0) {
> + pr_warn("ACPI: SPE Unable to register interrupt: %d\n", gsi);
> + return irq;
> + }
> +
> + spe_resources[0].start = irq;
> + ret = platform_device_register(_dev);
> + if (ret < 0) {
> + pr_warn("ACPI: SPE: Unable to register device\n");
> + acpi_unregister_gsi(gsi);
> + }
> +
> + return ret;
> +}
> +#else
> +static inline int arm_spe_acpi_register_device(void)
> +{
> + return -ENODEV;
> +}
> +#endif /* CONFIG_ARM_SPE_PMU */
> +
>  static int arm_pmu_acpi_parse_irqs(void)
>  {
>   int irq, cpu, irq_cpu, err;
> @@ -279,6 +352,8 @@ static int arm_pmu_acpi_init(void)
>   if (acpi_disabled)
>   return 0;
>  
> + arm_spe_acpi_register_device(); /* failures are expected */

Sounds ominous and it is false, ACPI never fails :)

Nit: if we don't check the return value what's the point of
returning it.

Nothing problematic, if you manage to update the code before
merging it is a plus.

Reviewed-by: Lorenzo Pieralisi 

>   ret = arm_pmu_acpi_parse_irqs();
>   if (ret)
>   return ret;
> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
> index 4641e850b204..784bc58f165a 100644
> --- a/include/linux/perf/arm_pmu.h
> +++ b/include/linux/perf/arm_pmu.h
> @@ -175,4 +175,6 @@ void armpmu_free_irq(int irq, int cpu);
>  
>  #endif /* CONFIG_ARM_PMU */
>  
> +#define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
> +
>  #endif /* __ARM_PMU_H__ */
> -- 
> 2.21.0
> 


Re: [PATCH V4 1/2] PCI: dwc: Add API support to de-initialize host

2019-06-18 Thread Lorenzo Pieralisi
On Tue, Jun 18, 2019 at 04:21:17PM +0530, Vidya Sagar wrote:

[...]

> > 2) It is not related to this patch but I fail to see the reasoning
> > behind the __ in __dw_pci_read_dbi(), there is no no-underscore
> > equivalent so its definition is somewhat questionable, maybe
> > we should clean-it up (for dbi2 alike).
> Separate no-underscore versions are present in pcie-designware.h for
> each width (i.e. l/w/b) as inline and are calling __ versions passing
> size as argument.

I understand - the __ prologue was added in b50b2db266d8 maybe
Kishon can help us understand the __ rationale.

I am happy to merge it as is, I was just curious about the
__ annotation (not related to this patch).

Lorenzo

> > Lorenzo
> > 
> > > Thanks,
> > > Vidya Sagar
> > > 
> > > > 
> > > > > 
> > > > > > > 
> > > > > > > > 
> > > > > > > > > 
> > > > > > > > > Thanks,
> > > > > > > > > Lorenzo
> > > > > > > > > 
> > > > > > > > > > diff --git 
> > > > > > > > > > a/drivers/pci/controller/dwc/pcie-designware-host.c 
> > > > > > > > > > b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > > > > > > index 77db32529319..d069e4290180 100644
> > > > > > > > > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > > > > > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > > > > > > @@ -496,6 +496,14 @@ int dw_pcie_host_init(struct pcie_port 
> > > > > > > > > > *pp)
> > > > > > > > > >    return ret;
> > > > > > > > > >    }
> > > > > > > > > > +void dw_pcie_host_deinit(struct pcie_port *pp)
> > > > > > > > > > +{
> > > > > > > > > > +    pci_stop_root_bus(pp->root_bus);
> > > > > > > > > > +    pci_remove_root_bus(pp->root_bus);
> > > > > > > > > > +    if (pci_msi_enabled() && !pp->ops->msi_host_init)
> > > > > > > > > > +    dw_pcie_free_msi(pp);
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > >    static int dw_pcie_access_other_conf(struct pcie_port 
> > > > > > > > > > *pp, struct pci_bus *bus,
> > > > > > > > > >     u32 devfn, int where, int size, u32 
> > > > > > > > > > *val,
> > > > > > > > > >     bool write)
> > > > > > > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> > > > > > > > > > b/drivers/pci/controller/dwc/pcie-designware.h
> > > > > > > > > > index deab426affd3..4f48ec78c7b9 100644
> > > > > > > > > > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > > > > > > > > > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > > > > > > > > > @@ -348,6 +348,7 @@ void dw_pcie_msi_init(struct pcie_port 
> > > > > > > > > > *pp);
> > > > > > > > > >    void dw_pcie_free_msi(struct pcie_port *pp);
> > > > > > > > > >    void dw_pcie_setup_rc(struct pcie_port *pp);
> > > > > > > > > >    int dw_pcie_host_init(struct pcie_port *pp);
> > > > > > > > > > +void dw_pcie_host_deinit(struct pcie_port *pp);
> > > > > > > > > >    int dw_pcie_allocate_domains(struct pcie_port *pp);
> > > > > > > > > >    #else
> > > > > > > > > >    static inline irqreturn_t dw_handle_msi_irq(struct 
> > > > > > > > > > pcie_port *pp)
> > > > > > > > > > @@ -372,6 +373,10 @@ static inline int 
> > > > > > > > > > dw_pcie_host_init(struct pcie_port *pp)
> > > > > > > > > >    return 0;
> > > > > > > > > >    }
> > > > > > > > > > +static inline void dw_pcie_host_deinit(struct pcie_port 
> > > > > > > > > > *pp)
> > > > > > > > > > +{
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > >    static inline int dw_pcie_allocate_domains(struct 
> > > > > > > > > > pcie_port *pp)
> > > > > > > > > >    {
> > > > > > > > > >    return 0;
> > > > > > > > > > -- 
> > > > > > > > > > 2.17.1
> > > > > > > > > > 
> > > > > > > > 
> > > > > > > 
> > > > > > 
> > > > > 
> > > > 
> > > 
> 


Re: [PATCH v4] PCI: xilinx-nwl: Fix Multi MSI data programming

2019-06-18 Thread Lorenzo Pieralisi
On Tue, Jun 18, 2019 at 12:28:02PM +, Bharat Kumar Gogada wrote:

[...]

> > Applied to pci/xilinx for v5.3, please have a look and check if the commit 
> > log
> > I wrote provides a clear description of the issue.
> > 
> > Lorenzo
> Thanks Lorenzo and Marc.
> Lorenzo, can you please point to link for above commit.

I did already.

Anyway:

https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/commit/?h=pci/xilinx=46c1bfcfcd873f8754f733e4258121748bcae3a3

> Regards,
> Bharat
> > > diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c
> > > b/drivers/pci/controller/pcie-xilinx-nwl.c
> > > index 81538d7..a9e07b8 100644
> > > --- a/drivers/pci/controller/pcie-xilinx-nwl.c
> > > +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
> > > @@ -483,15 +483,13 @@ static int nwl_irq_domain_alloc(struct
> > irq_domain *domain, unsigned int virq,
> > >   int i;
> > >
> > >   mutex_lock(>lock);
> > > - bit = bitmap_find_next_zero_area(msi->bitmap, INT_PCI_MSI_NR, 0,
> > > -  nr_irqs, 0);
> > > - if (bit >= INT_PCI_MSI_NR) {
> > > + bit = bitmap_find_free_region(msi->bitmap, INT_PCI_MSI_NR,
> > > +   get_count_order(nr_irqs));
> > > + if (bit < 0) {
> > >   mutex_unlock(>lock);
> > >   return -ENOSPC;
> > >   }
> > >
> > > - bitmap_set(msi->bitmap, bit, nr_irqs);
> > > -
> > >   for (i = 0; i < nr_irqs; i++) {
> > >   irq_domain_set_info(domain, virq + i, bit + i, _irq_chip,
> > >   domain->host_data, handle_simple_irq, @@
> > -509,7 +507,8 @@ static
> > > void nwl_irq_domain_free(struct irq_domain *domain, unsigned int virq,
> > >   struct nwl_msi *msi = >msi;
> > >
> > >   mutex_lock(>lock);
> > > - bitmap_clear(msi->bitmap, data->hwirq, nr_irqs);
> > > + bitmap_release_region(msi->bitmap, data->hwirq,
> > > +   get_count_order(nr_irqs));
> > >   mutex_unlock(>lock);
> > >  }
> > >
> > > --
> > > 2.7.4
> > >


Re: [PATCH V4 1/2] PCI: dwc: Add API support to de-initialize host

2019-06-18 Thread Lorenzo Pieralisi
On Tue, Jun 18, 2019 at 10:19:14AM +0530, Vidya Sagar wrote:

[...]

> Sorry for pinging again. Please let me know if these patches need to
> be sent again.

No problem. We can merge the code as-is even though I have a couple
of questions.

1) What about dbi2 interfaces (what an horrible name it is :() ? It
   is true that it is probably best to export just what we need.
2) It is not related to this patch but I fail to see the reasoning
   behind the __ in __dw_pci_read_dbi(), there is no no-underscore
   equivalent so its definition is somewhat questionable, maybe
   we should clean-it up (for dbi2 alike).

Lorenzo

> Thanks,
> Vidya Sagar
> 
> > 
> > > 
> > > > > 
> > > > > > 
> > > > > > > 
> > > > > > > Thanks,
> > > > > > > Lorenzo
> > > > > > > 
> > > > > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c 
> > > > > > > > b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > > > > index 77db32529319..d069e4290180 100644
> > > > > > > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > > > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > > > > > @@ -496,6 +496,14 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > > > > > >   return ret;
> > > > > > > >   }
> > > > > > > > +void dw_pcie_host_deinit(struct pcie_port *pp)
> > > > > > > > +{
> > > > > > > > +    pci_stop_root_bus(pp->root_bus);
> > > > > > > > +    pci_remove_root_bus(pp->root_bus);
> > > > > > > > +    if (pci_msi_enabled() && !pp->ops->msi_host_init)
> > > > > > > > +    dw_pcie_free_msi(pp);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > >   static int dw_pcie_access_other_conf(struct pcie_port *pp, 
> > > > > > > > struct pci_bus *bus,
> > > > > > > >    u32 devfn, int where, int size, u32 *val,
> > > > > > > >    bool write)
> > > > > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> > > > > > > > b/drivers/pci/controller/dwc/pcie-designware.h
> > > > > > > > index deab426affd3..4f48ec78c7b9 100644
> > > > > > > > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > > > > > > > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > > > > > > > @@ -348,6 +348,7 @@ void dw_pcie_msi_init(struct pcie_port *pp);
> > > > > > > >   void dw_pcie_free_msi(struct pcie_port *pp);
> > > > > > > >   void dw_pcie_setup_rc(struct pcie_port *pp);
> > > > > > > >   int dw_pcie_host_init(struct pcie_port *pp);
> > > > > > > > +void dw_pcie_host_deinit(struct pcie_port *pp);
> > > > > > > >   int dw_pcie_allocate_domains(struct pcie_port *pp);
> > > > > > > >   #else
> > > > > > > >   static inline irqreturn_t dw_handle_msi_irq(struct pcie_port 
> > > > > > > > *pp)
> > > > > > > > @@ -372,6 +373,10 @@ static inline int dw_pcie_host_init(struct 
> > > > > > > > pcie_port *pp)
> > > > > > > >   return 0;
> > > > > > > >   }
> > > > > > > > +static inline void dw_pcie_host_deinit(struct pcie_port *pp)
> > > > > > > > +{
> > > > > > > > +}
> > > > > > > > +
> > > > > > > >   static inline int dw_pcie_allocate_domains(struct pcie_port 
> > > > > > > > *pp)
> > > > > > > >   {
> > > > > > > >   return 0;
> > > > > > > > -- 
> > > > > > > > 2.17.1
> > > > > > > > 
> > > > > > 
> > > > > 
> > > > 
> > > 
> > 
> 


Re: [PATCH] ACPI: PM: Export the function acpi_sleep_state_supported()

2019-06-17 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 10:19:02PM +, Dexuan Cui wrote:
> > -Original Message-
> > From: Michael Kelley 
> > Sent: Friday, June 14, 2019 1:48 PM
> > To: Dexuan Cui ; linux-a...@vger.kernel.org;
> > r...@rjwysocki.net; l...@kernel.org; robert.mo...@intel.com;
> > erik.schma...@intel.com
> > Cc: linux-hyp...@vger.kernel.org; linux-kernel@vger.kernel.org; KY 
> > Srinivasan
> > ; Stephen Hemminger ;
> > Haiyang Zhang ; Sasha Levin
> > ; o...@aepfle.de; a...@canonical.com;
> > jasow...@redhat.com; vkuznets ;
> > marcelo.ce...@canonical.com
> > Subject: RE: [PATCH] ACPI: PM: Export the function
> > acpi_sleep_state_supported()
> > 
> > From: Dexuan Cui   Sent: Friday, June 14, 2019 11:19
> > AM
> > >
> > > In a Linux VM running on Hyper-V, when ACPI S4 is enabled, the balloon
> > > driver (drivers/hv/hv_balloon.c) needs to ask the host not to do memory
> > > hot-add/remove.
> > >
> > > So let's export acpi_sleep_state_supported() for the hv_balloon driver.
> > > This might also be useful to the other drivers in the future.
> > >
> > > Signed-off-by: Dexuan Cui 
> > > ---
> > >  drivers/acpi/sleep.c| 3 ++-
> > >  include/acpi/acpi_bus.h | 2 ++
> > >  2 files changed, 4 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
> > > index a34deccd7317..69755411e008 100644
> > > --- a/drivers/acpi/sleep.c
> > > +++ b/drivers/acpi/sleep.c
> > > @@ -79,7 +79,7 @@ static int acpi_sleep_prepare(u32 acpi_state)
> > >   return 0;
> > >  }
> > >
> > > -static bool acpi_sleep_state_supported(u8 sleep_state)
> > > +bool acpi_sleep_state_supported(u8 sleep_state)
> > >  {
> > >   acpi_status status;
> > >   u8 type_a, type_b;
> > > @@ -89,6 +89,7 @@ static bool acpi_sleep_state_supported(u8 sleep_state)
> > >   || (acpi_gbl_FADT.sleep_control.address
> > >   && acpi_gbl_FADT.sleep_status.address));
> > >  }
> > > +EXPORT_SYMBOL_GPL(acpi_sleep_state_supported);
> > >
> > >  #ifdef CONFIG_ACPI_SLEEP
> > >  static u32 acpi_target_sleep_state = ACPI_STATE_S0;
> > > diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> > > index 31b6c87d6240..5b102e7bbf25 100644
> > > --- a/include/acpi/acpi_bus.h
> > > +++ b/include/acpi/acpi_bus.h
> > > @@ -651,6 +651,8 @@ static inline int acpi_pm_set_bridge_wakeup(struct
> > device *dev,
> > > bool enable)
> > >  }
> > >  #endif
> > >
> > > +bool acpi_sleep_state_supported(u8 sleep_state);
> > > +
> > >  #ifdef CONFIG_ACPI_SLEEP
> > >  u32 acpi_target_system_state(void);
> > >  #else
> > > --
> > > 2.19.1
> > 
> > It seems that sleep.c isn't built when on the ARM64 architecture.  Using
> > acpi_sleep_state_supported() directly in hv_balloon.c will be problematic
> > since hv_balloon.c needs to be architecture independent when the
> > Hyper-V ARM64 support is added.  If that doesn't change, a per-architecture
> > wrapper will be needed to give hv_balloon.c the correct information.  This
> > may affect whether acpi_sleep_state_supported() needs to be exported vs.
> > just removing the "static".   I'm not sure what the best approach is.
> > 
> > Michael
> 
> + some ARM experts who worked on arch/arm/kernel/hibernate.c.
> 
> drivers/acpi/sleep.c is only built if ACPI_SYSTEM_POWER_STATES_SUPPORT
> is defined, but it looks this option is not defined on ARM.
> 
> It looks ARM does not support the ACPI S4 state, then how do we know 
> if an ARM host supports hibernation or not?

Maybe we should start from understanding why you need to know whether
Hibernate is possible to answer your question ?

On ARM64 platforms system states are entered through PSCI firmware
interface that works for ACPI and device tree alike.

Lorenzo


Re: [PATCH v3] PCI: aardvark: Fix PCI_EXP_RTCTL register configuration

2019-06-17 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 12:10:59PM +0200, Remi Pommarel wrote:
> PCI_EXP_RTCTL is used to activate PME interrupt only, so writing into it
> should not modify other interrupts' mask. The ISR mask polarity was also
> inverted, when PCI_EXP_RTCTL_PMEIE is set PCIE_MSG_PM_PME_MASK mask bit
> should actually be cleared.
> 
> Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge 
> config space")
> Signed-off-by: Remi Pommarel 
> ---
> Changes since v1:
>  * Improve code readability
>  * Fix mask polarity
>  * PME_MASK shift was off by one
> Changes since v2:
>  * Modify patch title
>  * Change Fixes tag to commit that actually introduces the bug
> ---
>  drivers/pci/controller/pci-aardvark.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)

I need Thomas' ACK to apply it, thanks.

Lorenzo

> diff --git a/drivers/pci/controller/pci-aardvark.c 
> b/drivers/pci/controller/pci-aardvark.c
> index 134e0306ff00..f6e55c4597b1 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -415,7 +415,7 @@ advk_pci_bridge_emul_pcie_conf_read(struct 
> pci_bridge_emul *bridge,
>  
>   case PCI_EXP_RTCTL: {
>   u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
> - *value = (val & PCIE_MSG_PM_PME_MASK) ? PCI_EXP_RTCTL_PMEIE : 0;
> + *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE;
>   return PCI_BRIDGE_EMUL_HANDLED;
>   }
>  
> @@ -451,10 +451,15 @@ advk_pci_bridge_emul_pcie_conf_write(struct 
> pci_bridge_emul *bridge,
>   advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
>   break;
>  
> - case PCI_EXP_RTCTL:
> - new = (new & PCI_EXP_RTCTL_PMEIE) << 3;
> - advk_writel(pcie, new, PCIE_ISR0_MASK_REG);
> + case PCI_EXP_RTCTL: {
> + /* Only mask/unmask PME interrupt */
> + u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) &
> + ~PCIE_MSG_PM_PME_MASK;
> + if ((new & PCI_EXP_RTCTL_PMEIE) == 0)
> + val |= PCIE_MSG_PM_PME_MASK;
> + advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
>   break;
> + }
>  
>   case PCI_EXP_RTSTA:
>   new = (new & PCI_EXP_RTSTA_PME) >> 9;
> -- 
> 2.20.1
> 


Re: [PATCH v2] PCI: altera: Fix configuration type based on secondary number

2019-06-17 Thread Lorenzo Pieralisi
On Wed, Jun 12, 2019 at 02:42:00PM +0800, Ley Foon Tan wrote:
> This fix issue when access config from PCIe switch.
> 
> Stratix 10 PCIe controller does not support Type 1 to Type 0 conversion
> as previous version (V1) does.
> 
> The PCIe controller need to send Type 0 config TLP if the targeting bus
> matches with the secondary bus number, which is when the TLP is targeting
> the immediate device on the link.
> 
> The PCIe controller send Type 1 config TLP if the targeting bus is
> larger than the secondary bus, which is when the TLP is targeting the
> device not immediate on the link.
> 
> Signed-off-by: Ley Foon Tan 
> 
> ---
> v2:
> - Add get_tlp_header() function.
> ---
>  drivers/pci/controller/pcie-altera.c | 41 ++--
>  1 file changed, 27 insertions(+), 14 deletions(-)

Applied to pci/altera for v5.3, thanks.

Lorenzo

> diff --git a/drivers/pci/controller/pcie-altera.c 
> b/drivers/pci/controller/pcie-altera.c
> index 27222071ace7..d2497ca43828 100644
> --- a/drivers/pci/controller/pcie-altera.c
> +++ b/drivers/pci/controller/pcie-altera.c
> @@ -44,6 +44,8 @@
>  #define S10_RP_RXCPL_STATUS  0x200C
>  #define S10_RP_CFG_ADDR(pcie, reg)   \
>   (((pcie)->hip_base) + (reg) + (1 << 20))
> +#define S10_RP_SECONDARY(pcie)   \
> + readb(S10_RP_CFG_ADDR(pcie, PCI_SECONDARY_BUS))
>  
>  /* TLP configuration type 0 and 1 */
>  #define TLP_FMTTYPE_CFGRD0   0x04/* Configuration Read Type 0 */
> @@ -55,14 +57,9 @@
>  #define TLP_WRITE_TAG0x10
>  #define RP_DEVFN 0
>  #define TLP_REQ_ID(bus, devfn)   (((bus) << 8) | (devfn))
> -#define TLP_CFGRD_DW0(pcie, bus) \
> - bus == pcie->root_bus_nr) ? pcie->pcie_data->cfgrd0 \
> - : pcie->pcie_data->cfgrd1) << 24) | \
> - TLP_PAYLOAD_SIZE)
> -#define TLP_CFGWR_DW0(pcie, bus) \
> - bus == pcie->root_bus_nr) ? pcie->pcie_data->cfgwr0 \
> - : pcie->pcie_data->cfgwr1) << 24) | \
> - TLP_PAYLOAD_SIZE)
> +#define TLP_CFG_DW0(pcie, cfg)   \
> + (((cfg) << 24) |\
> +   TLP_PAYLOAD_SIZE)
>  #define TLP_CFG_DW1(pcie, tag, be)   \
>   (((TLP_REQ_ID(pcie->root_bus_nr,  RP_DEVFN)) << 16) | (tag << 8) | (be))
>  #define TLP_CFG_DW2(bus, devfn, offset)  \
> @@ -322,14 +319,31 @@ static void s10_tlp_write_packet(struct altera_pcie 
> *pcie, u32 *headers,
>   s10_tlp_write_tx(pcie, data, RP_TX_EOP);
>  }
>  
> +static void get_tlp_header(struct altera_pcie *pcie, u8 bus, u32 devfn,
> +int where, u8 byte_en, bool read, u32 *headers)
> +{
> + u8 cfg;
> + u8 cfg0 = read ? pcie->pcie_data->cfgrd0 : pcie->pcie_data->cfgwr0;
> + u8 cfg1 = read ? pcie->pcie_data->cfgrd1 : pcie->pcie_data->cfgwr1;
> + u8 tag = read ? TLP_READ_TAG : TLP_WRITE_TAG;
> +
> + if (pcie->pcie_data->version == ALTERA_PCIE_V1)
> + cfg = (bus == pcie->root_bus_nr) ? cfg0 : cfg1;
> + else
> + cfg = (bus > S10_RP_SECONDARY(pcie)) ? cfg0 : cfg1;
> +
> + headers[0] = TLP_CFG_DW0(pcie, cfg);
> + headers[1] = TLP_CFG_DW1(pcie, tag, byte_en);
> + headers[2] = TLP_CFG_DW2(bus, devfn, where);
> +}
> +
>  static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
> int where, u8 byte_en, u32 *value)
>  {
>   u32 headers[TLP_HDR_SIZE];
>  
> - headers[0] = TLP_CFGRD_DW0(pcie, bus);
> - headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
> - headers[2] = TLP_CFG_DW2(bus, devfn, where);
> + get_tlp_header(pcie, bus, devfn, where, byte_en, true,
> +headers);
>  
>   pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, 0, false);
>  
> @@ -342,9 +356,8 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, 
> u8 bus, u32 devfn,
>   u32 headers[TLP_HDR_SIZE];
>   int ret;
>  
> - headers[0] = TLP_CFGWR_DW0(pcie, bus);
> - headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
> - headers[2] = TLP_CFG_DW2(bus, devfn, where);
> + get_tlp_header(pcie, bus, devfn, where, byte_en, false,
> +headers);
>  
>   /* check alignment to Qword */
>   if ((where & 0x7) == 0)
> -- 
> 2.19.0
> 


Re: [PATCHv5 04/20] PCI: mobiveil: Remove the flag MSI_FLAG_MULTI_PCI_MSI

2019-06-17 Thread Lorenzo Pieralisi
On Sat, Jun 15, 2019 at 01:30:39AM +, Z.q. Hou wrote:
> Hi Lorenzo,
> 
> > -Original Message-
> > From: Lorenzo Pieralisi [mailto:lorenzo.pieral...@arm.com]
> > Sent: 2019年6月12日 21:08
> > To: Z.q. Hou 
> > Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > bhelg...@google.com; robh...@kernel.org; mark.rutl...@arm.com;
> > l.subrahma...@mobiveil.co.in; shawn...@kernel.org; Leo Li
> > ; catalin.mari...@arm.com; will.dea...@arm.com;
> > Mingkai Hu ; M.h. Lian ;
> > Xiaowei Bao 
> > Subject: Re: [PATCHv5 04/20] PCI: mobiveil: Remove the flag
> > MSI_FLAG_MULTI_PCI_MSI
> > 
> > On Wed, Jun 12, 2019 at 11:34:51AM +, Z.q. Hou wrote:
> > > Hi Lorenzo,
> > >
> > > Thanks a lot for your comments!
> > >
> > > > -Original Message-
> > > > From: Lorenzo Pieralisi 
> > > > Sent: 2019年6月12日 1:00
> > > > To: Z.q. Hou 
> > > > Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> > > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > > bhelg...@google.com; robh...@kernel.org; mark.rutl...@arm.com;
> > > > l.subrahma...@mobiveil.co.in; shawn...@kernel.org; Leo Li
> > > > ; catalin.mari...@arm.com;
> > will.dea...@arm.com;
> > > > Mingkai Hu ; M.h. Lian
> > ;
> > > > Xiaowei Bao 
> > > > Subject: Re: [PATCHv5 04/20] PCI: mobiveil: Remove the flag
> > > > MSI_FLAG_MULTI_PCI_MSI
> > > >
> > > > On Fri, Apr 12, 2019 at 08:35:36AM +, Z.q. Hou wrote:
> > > > > From: Hou Zhiqiang 
> > > > >
> > > > > The current code does not support multiple MSIs, so remove the
> > > > > corresponding flag from the msi_domain_info structure.
> > > >
> > > > Please explain me what's the problem before removing multi MSI support.
> > >
> > > NXP LX2 PCIe use the GIC-ITS instead of Mobiveil IP internal MSI
> > > controller, so, I didn't encounter problem.
> > 
> > Well, you sent a patch to fix an issue, explain me the issue you are fixing 
> > then,
> > aka what have you sent this patch for ?
> 
> I did not face issue, as I have explained NXP does not use the
> Mobiveil IP's MSI controller.  But obviously the MSI allocate function
> does not support multiple MSI, so I submitted this patch.

There is nothing obvious. Write what you are fixing in the commit log
and I will apply the patch, I won't write the commit log for you. Anyone
should be able to understand why a patch was needed by reading the
commit log, it is as important as writing the code itself.

Thanks,
Lorenzo

> Thanks,
> Zhiqiang
> 
> > 
> > Lorenzo
> > 
> > > Subbu, did you test with Endpoint supporting multi MSI?
> > >
> > > Thanks,
> > > Zhiqiang
> > >
> > > >
> > > > Thanks,
> > > > Lorenzo
> > > >
> > > > > Fixes: 1e913e58335f ("PCI: mobiveil: Add MSI support")
> > > > > Signed-off-by: Hou Zhiqiang 
> > > > > Reviewed-by: Minghuan Lian 
> > > > > ---
> > > > > V5:
> > > > >  - Corrected the subject.
> > > > >
> > > > >  drivers/pci/controller/pcie-mobiveil.c | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > > > > b/drivers/pci/controller/pcie-mobiveil.c
> > > > > index 563210e731d3..a0dd337c6214 100644
> > > > > --- a/drivers/pci/controller/pcie-mobiveil.c
> > > > > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > > > > @@ -703,7 +703,7 @@ static struct irq_chip mobiveil_msi_irq_chip =
> > > > > {
> > > > >
> > > > >  static struct msi_domain_info mobiveil_msi_domain_info = {
> > > > >   .flags  = (MSI_FLAG_USE_DEF_DOM_OPS |
> > > > MSI_FLAG_USE_DEF_CHIP_OPS |
> > > > > -MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
> > > > > +MSI_FLAG_PCI_MSIX),
> > > > >   .chip   = _msi_irq_chip,
> > > > >  };
> > > > >
> > > > > --
> > > > > 2.17.1
> > > > >


Re: [PATCHv5 18/20] PCI: mobiveil: Disable IB and OB windows set by bootloader

2019-06-17 Thread Lorenzo Pieralisi
On Sat, Jun 15, 2019 at 05:03:33AM +, Z.q. Hou wrote:
> Hi Lorenzo,
> 
> > -Original Message-
> > From: Lorenzo Pieralisi [mailto:lorenzo.pieral...@arm.com]
> > Sent: 2019年6月13日 0:24
> > To: Z.q. Hou ; bhelg...@google.com
> > Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > robh...@kernel.org; mark.rutl...@arm.com; l.subrahma...@mobiveil.co.in;
> > shawn...@kernel.org; Leo Li ;
> > catalin.mari...@arm.com; will.dea...@arm.com; Mingkai Hu
> > ; M.h. Lian ; Xiaowei Bao
> > 
> > Subject: Re: [PATCHv5 18/20] PCI: mobiveil: Disable IB and OB windows set
> > by bootloader
> > 
> > On Fri, Apr 12, 2019 at 08:37:00AM +, Z.q. Hou wrote:
> > > From: Hou Zhiqiang 
> > >
> > > Disable all inbound and outbound windows before set up the windows in
> > > kernel, in case transactions match the window set by bootloader.
> > 
> > There must be no PCI transactions ongoing at bootloader<->OS handover.
> >
> 
> Yes, exact.
>  
> > The bootloader needs fixing and this patch should be dropped, the host 
> > bridge
> > driver assumes the host bridge state is disabled,
> 
> The host bridge driver should not assumes the host state is disabled,
> actually u-boot enable/initialize the host and without disabling it
> when transfer the control to Linux.

Fix the bootloader and drop this patch, I explain to you why.

> > it will program the bridge
> > apertures from scratch with no ongoing transactions, anything deviating from
> > this behaviour is a bootloader bug and a recipe for disaster.
> 
> The point of this patch is not to fix the ongoing transaction issue,
> it is to avoid a potential issue which is caused by the outbound
> window enabled by bootloader overlapping with Linux enabled.

See above.

Lorenzo

> Thanks,
> Zhiqiang
>  
> > Lorenzo
> > 
> > > Signed-off-by: Hou Zhiqiang 
> > > Reviewed-by: Minghuan Lian 
> > > Reviewed-by: Subrahmanya Lingappa 
> > > ---
> > > V5:
> > >  - No functionality change.
> > >
> > >  drivers/pci/controller/pcie-mobiveil.c | 25 +
> > >  1 file changed, 25 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > > b/drivers/pci/controller/pcie-mobiveil.c
> > > index 8dc87c7a600e..411e9779da12 100644
> > > --- a/drivers/pci/controller/pcie-mobiveil.c
> > > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > > @@ -565,6 +565,24 @@ static int mobiveil_bringup_link(struct
> > mobiveil_pcie *pcie)
> > >   return -ETIMEDOUT;
> > >  }
> > >
> > > +static void mobiveil_pcie_disable_ib_win(struct mobiveil_pcie *pcie,
> > > +int idx) {
> > > + u32 val;
> > > +
> > > + val = csr_readl(pcie, PAB_PEX_AMAP_CTRL(idx));
> > > + val &= ~(1 << AMAP_CTRL_EN_SHIFT);
> > > + csr_writel(pcie, val, PAB_PEX_AMAP_CTRL(idx)); }
> > > +
> > > +static void mobiveil_pcie_disable_ob_win(struct mobiveil_pcie *pcie,
> > > +int idx) {
> > > + u32 val;
> > > +
> > > + val = csr_readl(pcie, PAB_AXI_AMAP_CTRL(idx));
> > > + val &= ~(1 << WIN_ENABLE_SHIFT);
> > > + csr_writel(pcie, val, PAB_AXI_AMAP_CTRL(idx)); }
> > > +
> > >  static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)  {
> > >   phys_addr_t msg_addr = pcie->pcie_reg_base; @@ -585,6 +603,13 @@
> > > static int mobiveil_host_init(struct mobiveil_pcie *pcie)  {
> > >   u32 value, pab_ctrl, type;
> > >   struct resource_entry *win;
> > > + int i;
> > > +
> > > + /* Disable all inbound/outbound windows */
> > > + for (i = 0; i < pcie->apio_wins; i++)
> > > + mobiveil_pcie_disable_ob_win(pcie, i);
> > > + for (i = 0; i < pcie->ppio_wins; i++)
> > > + mobiveil_pcie_disable_ib_win(pcie, i);
> > >
> > >   /* setup bus numbers */
> > >   value = csr_readl(pcie, PCI_PRIMARY_BUS);
> > > --
> > > 2.17.1
> > >


Re: [PATCHv5 19/20] PCI: mobiveil: Add 8-bit and 16-bit register accessors

2019-06-17 Thread Lorenzo Pieralisi
On Sat, Jun 15, 2019 at 01:13:48AM +, Z.q. Hou wrote:
> Hi Lorenzo,
> 
> > -Original Message-
> > From: Lorenzo Pieralisi [mailto:lorenzo.pieral...@arm.com]
> > Sent: 2019年6月12日 21:54
> > To: Z.q. Hou 
> > Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > bhelg...@google.com; robh...@kernel.org; mark.rutl...@arm.com;
> > l.subrahma...@mobiveil.co.in; shawn...@kernel.org; Leo Li
> > ; catalin.mari...@arm.com; will.dea...@arm.com;
> > Mingkai Hu ; M.h. Lian ;
> > Xiaowei Bao 
> > Subject: Re: [PATCHv5 19/20] PCI: mobiveil: Add 8-bit and 16-bit register
> > accessors
> > 
> > On Fri, Apr 12, 2019 at 08:37:05AM +, Z.q. Hou wrote:
> > > From: Hou Zhiqiang 
> > >
> > > There are some 8-bit and 16-bit registers in PCIe configuration space,
> > > so add accessors for them.
> > >
> > > Signed-off-by: Hou Zhiqiang 
> > > Reviewed-by: Minghuan Lian 
> > > Reviewed-by: Subrahmanya Lingappa 
> > > ---
> > > V5:
> > >  - Corrected and retouched the subject and changelog.
> > >  - No functionality change.
> > >
> > >  drivers/pci/controller/pcie-mobiveil.c | 20 
> > >  1 file changed, 20 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/pcie-mobiveil.c
> > > b/drivers/pci/controller/pcie-mobiveil.c
> > > index 411e9779da12..456adfee393c 100644
> > > --- a/drivers/pci/controller/pcie-mobiveil.c
> > > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > > @@ -268,11 +268,31 @@ static u32 csr_readl(struct mobiveil_pcie *pcie,
> > u32 off)
> > >   return csr_read(pcie, off, 0x4);
> > >  }
> > >
> > > +static u32 csr_readw(struct mobiveil_pcie *pcie, u32 off) {
> > > + return csr_read(pcie, off, 0x2);
> > > +}
> > > +
> > > +static u32 csr_readb(struct mobiveil_pcie *pcie, u32 off) {
> > > + return csr_read(pcie, off, 0x1);
> > > +}
> > > +
> > >  static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off)
> > > {
> > >   csr_write(pcie, val, off, 0x4);
> > >  }
> > >
> > > +static void csr_writew(struct mobiveil_pcie *pcie, u32 val, u32 off)
> > > +{
> > > + csr_write(pcie, val, off, 0x2);
> > > +}
> > > +
> > > +static void csr_writeb(struct mobiveil_pcie *pcie, u32 val, u32 off)
> > > +{
> > > + csr_write(pcie, val, off, 0x1);
> > > +}
> > > +
> > 
> > They are not used so you should drop this patch.
> 
> NXP Layerscape PCIe Gen4 controller driver will use them, so don't
> drop it.

You add functions when they are needed, so drop this patch and
squash it to the patch that use these functions.

Lorenzo

> Thanks,
> Zhiqiang
> 
> > 
> > Lorenzo
> > 
> > >  static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie)  {
> > >   return (csr_readl(pcie, LTSSM_STATUS) &
> > > --
> > > 2.17.1
> > >


Re: [PATCH v4] PCI: xilinx-nwl: Fix Multi MSI data programming

2019-06-17 Thread Lorenzo Pieralisi
On Wed, Jun 12, 2019 at 03:47:59PM +0530, Bharat Kumar Gogada wrote:
> The current Multi MSI data programming fails if multiple end points
> requesting MSI and multi MSI are connected with switch, i.e the current
> multi MSI data being given is not considering the number of vectors
> being requested in case of multi MSI.
> Ex: Two EP's connected via switch, EP1 requesting single MSI first,
> EP2 requesting Multi MSI of count four. The current code gives
> MSI data 0x0 to EP1 and 0x1 to EP2, but EP2 can modify lower two bits
> due to which EP2 also sends interrupt with MSI data 0x0 which results
> in always invoking virq of EP1 due to which EP2 MSI interrupt never
> gets handled.
> 
> Fix Multi MSI data programming with required alignment by
> using number of vectors being requested.
> 
> Fixes: ab597d35ef11 ("PCI: xilinx-nwl: Add support for Xilinx NWL PCIe
> Host Controller")
> 
> Signed-off-by: Bharat Kumar Gogada 
> ---
> V4:
>  - Using a different bitmap registration API whcih serves single and multi
>MSI requests.
> ---
>  drivers/pci/controller/pcie-xilinx-nwl.c | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)

Applied to pci/xilinx for v5.3, please have a look and check if
the commit log I wrote provides a clear description of the issue.

Lorenzo

> diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c 
> b/drivers/pci/controller/pcie-xilinx-nwl.c
> index 81538d7..a9e07b8 100644
> --- a/drivers/pci/controller/pcie-xilinx-nwl.c
> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
> @@ -483,15 +483,13 @@ static int nwl_irq_domain_alloc(struct irq_domain 
> *domain, unsigned int virq,
>   int i;
>  
>   mutex_lock(>lock);
> - bit = bitmap_find_next_zero_area(msi->bitmap, INT_PCI_MSI_NR, 0,
> -  nr_irqs, 0);
> - if (bit >= INT_PCI_MSI_NR) {
> + bit = bitmap_find_free_region(msi->bitmap, INT_PCI_MSI_NR,
> +   get_count_order(nr_irqs));
> + if (bit < 0) {
>   mutex_unlock(>lock);
>   return -ENOSPC;
>   }
>  
> - bitmap_set(msi->bitmap, bit, nr_irqs);
> -
>   for (i = 0; i < nr_irqs; i++) {
>   irq_domain_set_info(domain, virq + i, bit + i, _irq_chip,
>   domain->host_data, handle_simple_irq,
> @@ -509,7 +507,8 @@ static void nwl_irq_domain_free(struct irq_domain 
> *domain, unsigned int virq,
>   struct nwl_msi *msi = >msi;
>  
>   mutex_lock(>lock);
> - bitmap_clear(msi->bitmap, data->hwirq, nr_irqs);
> + bitmap_release_region(msi->bitmap, data->hwirq,
> +   get_count_order(nr_irqs));
>   mutex_unlock(>lock);
>  }
>  
> -- 
> 2.7.4
> 


Re: [PATCH] PCI: hv: Fix build error without CONFIG_SYSFS

2019-06-14 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 10:19:10PM +0800, Yuehaibing wrote:
> Hi all,
> 
> Friendly ping...

We should address Michael's question:

https://lore.kernel.org/linux-pci/byapr21mb12211eea95200f437c8e37ecd7...@byapr21mb1221.namprd21.prod.outlook.com/

Lorenzo

> On 2019/5/31 23:09, YueHaibing wrote:
> > while building without CONFIG_SYSFS, fails as below:
> > 
> > drivers/pci/controller/pci-hyperv.o: In function 'hv_pci_assign_slots':
> > pci-hyperv.c:(.text+0x40a): undefined reference to 'pci_create_slot'
> > drivers/pci/controller/pci-hyperv.o: In function 'pci_devices_present_work':
> > pci-hyperv.c:(.text+0xc02): undefined reference to 'pci_destroy_slot'
> > drivers/pci/controller/pci-hyperv.o: In function 'hv_pci_remove':
> > pci-hyperv.c:(.text+0xe50): undefined reference to 'pci_destroy_slot'
> > drivers/pci/controller/pci-hyperv.o: In function 'hv_eject_device_work':
> > pci-hyperv.c:(.text+0x11f9): undefined reference to 'pci_destroy_slot'
> > 
> > Select SYSFS while PCI_HYPERV is set to fix this.
> > 
> > Reported-by: Hulk Robot 
> > Fixes: a15f2c08c708 ("PCI: hv: support reporting serial number as slot 
> > information")
> > Signed-off-by: YueHaibing 
> > ---
> >  drivers/pci/Kconfig | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> > index 2ab9240..6722952 100644
> > --- a/drivers/pci/Kconfig
> > +++ b/drivers/pci/Kconfig
> > @@ -182,6 +182,7 @@ config PCI_LABEL
> >  config PCI_HYPERV
> >  tristate "Hyper-V PCI Frontend"
> >  depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64
> > +   select SYSFS
> >  help
> >The PCI device frontend driver allows the kernel to import 
> > arbitrary
> >PCI devices from a PCI backend to support PCI driver domains.
> > 
> 


Re: [PATCHv5 10/20] PCI: mobiveil: Fix the INTx process errors

2019-06-14 Thread Lorenzo Pieralisi
On Fri, Jun 14, 2019 at 12:38:51PM +0530, Karthikeyan Mitran wrote:
> Hi Lorenzo and Hou Zhiqiang
>  PAB_INTP_AMBA_MISC_STAT does have other status in the higher bits, it
> should have been masked before checking for the status

You are the maintainer for this driver, so if there is something to be
changed you must post a patch to that extent, I do not understand what
the above means, write the code to fix it, I won't do it.

I am getting a bit annoyed with this Mobiveil driver so either you guys
sort this out or I will have to remove it from the kernel.

> Acked-by: Karthikeyan Mitran 

Ok I assume this means you tested it but according to what you
say above, are there still issues with this code path ? Should
we update the patch ?

Moreover:

https://kernelnewbies.org/PatchCulture

Please read it and never top-post.

Thanks,
Lorenzo

> On Wed, Jun 12, 2019 at 8:38 PM Lorenzo Pieralisi
>  wrote:
> >
> > On Fri, Apr 12, 2019 at 08:36:12AM +, Z.q. Hou wrote:
> > > From: Hou Zhiqiang 
> > >
> > > In the loop block, there is not code to update the loop key,
> > > this patch updates the loop key by re-read the INTx status
> > > register.
> > >
> > > This patch also add the clearing of the handled INTx status.
> > >
> > > Note: Need MV to test this fix.
> >
> > This means INTX were never tested and current code handling them is,
> > AFAICS, an infinite loop which is very very bad.
> >
> > This is a gross bug and must be fixed as soon as possible.
> >
> > I want Karthikeyan ACK and Tested-by on this patch.
> >
> > Lorenzo
> >
> > > Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP 
> > > driver")
> > > Signed-off-by: Hou Zhiqiang 
> > > Reviewed-by: Minghuan Lian 
> > > Reviewed-by: Subrahmanya Lingappa 
> > > ---
> > > V5:
> > >  - Corrected and retouched the subject and changelog.
> > >
> > >  drivers/pci/controller/pcie-mobiveil.c | 13 +
> > >  1 file changed, 9 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> > > b/drivers/pci/controller/pcie-mobiveil.c
> > > index 4ba458474e42..78e575e71f4d 100644
> > > --- a/drivers/pci/controller/pcie-mobiveil.c
> > > +++ b/drivers/pci/controller/pcie-mobiveil.c
> > > @@ -361,6 +361,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
> > >   /* Handle INTx */
> > >   if (intr_status & PAB_INTP_INTX_MASK) {
> > >   shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT);
> > > + shifted_status &= PAB_INTP_INTX_MASK;
> > >   shifted_status >>= PAB_INTX_START;
> > >   do {
> > >   for_each_set_bit(bit, _status, 
> > > PCI_NUM_INTX) {
> > > @@ -372,12 +373,16 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
> > >   dev_err_ratelimited(dev, 
> > > "unexpected IRQ, INT%d\n",
> > >   bit);
> > >
> > > - /* clear interrupt */
> > > - csr_writel(pcie,
> > > -shifted_status << PAB_INTX_START,
> > > + /* clear interrupt handled */
> > > + csr_writel(pcie, 1 << (PAB_INTX_START + 
> > > bit),
> > >  PAB_INTP_AMBA_MISC_STAT);
> > >   }
> > > - } while ((shifted_status >> PAB_INTX_START) != 0);
> > > +
> > > + shifted_status = csr_readl(pcie,
> > > +PAB_INTP_AMBA_MISC_STAT);
> > > + shifted_status &= PAB_INTP_INTX_MASK;
> > > + shifted_status >>= PAB_INTX_START;
> > > + } while (shifted_status != 0);
> > >   }
> > >
> > >   /* read extra MSI status register */
> > > --
> > > 2.17.1
> > >
> 
> 
> 
> -- 
> Thanks,
> Regards,
> Karthikeyan Mitran
> 
> -- 
> Mobiveil INC., CONFIDENTIALITY NOTICE: This e-mail message, including any 
> attachments, is for the sole use of the intended recipient(s) and may 
> contain proprietary confidential or privileged information or otherwise be 
> protected by law. Any unauthorized review, use, disclosure or distribution 
> is prohibited. If you are not the intended recipient, please notify the 
> sender and destroy all copies and the original message.


Re: [PATCH] PCI: aardvark: Fix PCI_EXP_RTCTL conf register writing

2019-06-13 Thread Lorenzo Pieralisi
On Wed, May 22, 2019 at 11:33:49PM +0200, Remi Pommarel wrote:
> PCI_EXP_RTCTL is used to activate PME interrupt only, so writing into it
> should not modify other interrupts' mask (such as ISR0).
> 
> Fixes: 6302bf3ef78d ("PCI: Init PCIe feature bits for managed host bridge 
> alloc")
> Signed-off-by: Remi Pommarel 
> ---
> Please note that I will unlikely be able to answer any comments from May
> 24th to June 10th.
> ---
>  drivers/pci/controller/pci-aardvark.c | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-aardvark.c 
> b/drivers/pci/controller/pci-aardvark.c
> index 134e0306ff00..27102d3b4f9c 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -451,10 +451,14 @@ advk_pci_bridge_emul_pcie_conf_write(struct 
> pci_bridge_emul *bridge,
>   advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
>   break;
>  
> - case PCI_EXP_RTCTL:
> - new = (new & PCI_EXP_RTCTL_PMEIE) << 3;
> - advk_writel(pcie, new, PCIE_ISR0_MASK_REG);
> + case PCI_EXP_RTCTL: {
> + /* Only mask/unmask PME interrupt */
> + u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) &
> + ~PCIE_MSG_PM_PME_MASK;
> + val |= (new & PCI_EXP_RTCTL_PMEIE) << 3;

I know you have not introduced this code but maybe we can
take an opportunity to clarify it (that << 3 shift obfuscates
a bit):

u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) &
~PCIE_MSG_PM_PME_MASK;

if (new & PCI_EXP_RTCTL_PMEIE)
val |= PCIE_MSG_PM_PME_MASK;

advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
break;

Or I am not reading the code correctly ?

Regardless, I need Thomas' ACK to proceed.

Lorenzo

> + advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
>   break;
> + }
>  
>   case PCI_EXP_RTSTA:
>   new = (new & PCI_EXP_RTSTA_PME) >> 9;
> -- 
> 2.20.1
> 


Re: [PATCH v4] PCI: xilinx-nwl: Fix Multi MSI data programming

2019-06-12 Thread Lorenzo Pieralisi
On Wed, Jun 12, 2019 at 02:01:56PM +0100, Marc Zyngier wrote:
> On Wed, 12 Jun 2019 11:17:59 +0100,
> Bharat Kumar Gogada  wrote:
> > 
> > The current Multi MSI data programming fails if multiple end points
> > requesting MSI and multi MSI are connected with switch, i.e the current
> > multi MSI data being given is not considering the number of vectors
> > being requested in case of multi MSI.
> > Ex: Two EP's connected via switch, EP1 requesting single MSI first,
> > EP2 requesting Multi MSI of count four. The current code gives
> > MSI data 0x0 to EP1 and 0x1 to EP2, but EP2 can modify lower two bits
> > due to which EP2 also sends interrupt with MSI data 0x0 which results
> > in always invoking virq of EP1 due to which EP2 MSI interrupt never
> > gets handled.
> 
> I think there is a much simpler explanation for this: Multi-MSI
> mandates that the base interrupt number is naturally aligned to its
> size. Having switches in the middle is just a way to expose the issue,
> but you could see it failing with a single end-point and two MSIs that
> are assigned on an odd boundary.

Agreed, I will rewrite the commit log with a link to the specs,
a switch has no role to play in this bug.

Lorenzo

> > Fix Multi MSI data programming with required alignment by
> > using number of vectors being requested.
> > 
> > Fixes: ab597d35ef11 ("PCI: xilinx-nwl: Add support for Xilinx NWL PCIe
> > Host Controller")
> > 
> > Signed-off-by: Bharat Kumar Gogada 
> > ---
> > V4:
> >  - Using a different bitmap registration API whcih serves single and multi
> >MSI requests.
> > ---
> >  drivers/pci/controller/pcie-xilinx-nwl.c | 11 +--
> >  1 file changed, 5 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c 
> > b/drivers/pci/controller/pcie-xilinx-nwl.c
> > index 81538d7..a9e07b8 100644
> > --- a/drivers/pci/controller/pcie-xilinx-nwl.c
> > +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
> > @@ -483,15 +483,13 @@ static int nwl_irq_domain_alloc(struct irq_domain 
> > *domain, unsigned int virq,
> > int i;
> >  
> > mutex_lock(>lock);
> > -   bit = bitmap_find_next_zero_area(msi->bitmap, INT_PCI_MSI_NR, 0,
> > -nr_irqs, 0);
> > -   if (bit >= INT_PCI_MSI_NR) {
> > +   bit = bitmap_find_free_region(msi->bitmap, INT_PCI_MSI_NR,
> > + get_count_order(nr_irqs));
> > +   if (bit < 0) {
> > mutex_unlock(>lock);
> > return -ENOSPC;
> > }
> >  
> > -   bitmap_set(msi->bitmap, bit, nr_irqs);
> > -
> > for (i = 0; i < nr_irqs; i++) {
> > irq_domain_set_info(domain, virq + i, bit + i, _irq_chip,
> > domain->host_data, handle_simple_irq,
> > @@ -509,7 +507,8 @@ static void nwl_irq_domain_free(struct irq_domain 
> > *domain, unsigned int virq,
> > struct nwl_msi *msi = >msi;
> >  
> > mutex_lock(>lock);
> > -   bitmap_clear(msi->bitmap, data->hwirq, nr_irqs);
> > +   bitmap_release_region(msi->bitmap, data->hwirq,
> > + get_count_order(nr_irqs));
> > mutex_unlock(>lock);
> >  }
> >  
> > -- 
> > 2.7.4
> > 
> 
> As for the body of the patch:
> 
> Suggested-by: Marc Zyngier 
> Acked-by: Marc Zyngier 
> 
> Thanks,
> 
>   M.
> 
> -- 
> Jazz is not dead, it just smells funny.


Re: [PATCHv5 18/20] PCI: mobiveil: Disable IB and OB windows set by bootloader

2019-06-12 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:37:00AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> Disable all inbound and outbound windows before set up the windows
> in kernel, in case transactions match the window set by bootloader.

There must be no PCI transactions ongoing at bootloader<->OS handover.

The bootloader needs fixing and this patch should be dropped, the host
bridge driver assumes the host bridge state is disabled, it will
program the bridge apertures from scratch with no ongoing transactions,
anything deviating from this behaviour is a bootloader bug and a recipe
for disaster.

Lorenzo

> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - No functionality change.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 25 +
>  1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index 8dc87c7a600e..411e9779da12 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -565,6 +565,24 @@ static int mobiveil_bringup_link(struct mobiveil_pcie 
> *pcie)
>   return -ETIMEDOUT;
>  }
>  
> +static void mobiveil_pcie_disable_ib_win(struct mobiveil_pcie *pcie, int idx)
> +{
> + u32 val;
> +
> + val = csr_readl(pcie, PAB_PEX_AMAP_CTRL(idx));
> + val &= ~(1 << AMAP_CTRL_EN_SHIFT);
> + csr_writel(pcie, val, PAB_PEX_AMAP_CTRL(idx));
> +}
> +
> +static void mobiveil_pcie_disable_ob_win(struct mobiveil_pcie *pcie, int idx)
> +{
> + u32 val;
> +
> + val = csr_readl(pcie, PAB_AXI_AMAP_CTRL(idx));
> + val &= ~(1 << WIN_ENABLE_SHIFT);
> + csr_writel(pcie, val, PAB_AXI_AMAP_CTRL(idx));
> +}
> +
>  static void mobiveil_pcie_enable_msi(struct mobiveil_pcie *pcie)
>  {
>   phys_addr_t msg_addr = pcie->pcie_reg_base;
> @@ -585,6 +603,13 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>  {
>   u32 value, pab_ctrl, type;
>   struct resource_entry *win;
> + int i;
> +
> + /* Disable all inbound/outbound windows */
> + for (i = 0; i < pcie->apio_wins; i++)
> + mobiveil_pcie_disable_ob_win(pcie, i);
> + for (i = 0; i < pcie->ppio_wins; i++)
> + mobiveil_pcie_disable_ib_win(pcie, i);
>  
>   /* setup bus numbers */
>   value = csr_readl(pcie, PCI_PRIMARY_BUS);
> -- 
> 2.17.1
> 


Re: [PATCHv5 07/20] PCI: mobiveil: Use WIN_NUM_0 explicitly for CFG outbound window

2019-06-12 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:35:54AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> As the .map_bus() use the WIN_NUM_0 for CFG transactions,
> it's better passing WIN_NUM_0 explicitly when initialize
> the CFG outbound window.
> 
> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - Corrected the subject.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index b2cc9c097fc9..df71c11b4810 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -612,9 +612,8 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie)
>*/
>  
>   /* config outbound translation window */
> - program_ob_windows(pcie, pcie->ob_wins_configured,
> -pcie->ob_io_res->start, 0, CFG_WINDOW_TYPE,
> -resource_size(pcie->ob_io_res));
> + program_ob_windows(pcie, WIN_NUM_0, pcie->ob_io_res->start, 0,
> +CFG_WINDOW_TYPE, resource_size(pcie->ob_io_res));

This makes sense - current code is quite obscure and prone to
bugs.

Lorenzo

>   /* memory inbound translation window */
>   program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
> -- 
> 2.17.1
> 


Re: [PATCHv5 10/20] PCI: mobiveil: Fix the INTx process errors

2019-06-12 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:36:12AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> In the loop block, there is not code to update the loop key,
> this patch updates the loop key by re-read the INTx status
> register.
> 
> This patch also add the clearing of the handled INTx status.
> 
> Note: Need MV to test this fix.

This means INTX were never tested and current code handling them is,
AFAICS, an infinite loop which is very very bad.

This is a gross bug and must be fixed as soon as possible.

I want Karthikeyan ACK and Tested-by on this patch.

Lorenzo

> Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver")
> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - Corrected and retouched the subject and changelog.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index 4ba458474e42..78e575e71f4d 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -361,6 +361,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>   /* Handle INTx */
>   if (intr_status & PAB_INTP_INTX_MASK) {
>   shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT);
> + shifted_status &= PAB_INTP_INTX_MASK;
>   shifted_status >>= PAB_INTX_START;
>   do {
>   for_each_set_bit(bit, _status, PCI_NUM_INTX) {
> @@ -372,12 +373,16 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
>   dev_err_ratelimited(dev, "unexpected 
> IRQ, INT%d\n",
>   bit);
>  
> - /* clear interrupt */
> - csr_writel(pcie,
> -shifted_status << PAB_INTX_START,
> + /* clear interrupt handled */
> + csr_writel(pcie, 1 << (PAB_INTX_START + bit),
>  PAB_INTP_AMBA_MISC_STAT);
>   }
> - } while ((shifted_status >> PAB_INTX_START) != 0);
> +
> + shifted_status = csr_readl(pcie,
> +PAB_INTP_AMBA_MISC_STAT);
> + shifted_status &= PAB_INTP_INTX_MASK;
> + shifted_status >>= PAB_INTX_START;
> + } while (shifted_status != 0);
>   }
>  
>   /* read extra MSI status register */
> -- 
> 2.17.1
> 


Re: [PATCHv5 17/20] PCI: mobiveil: Complete initialization of host even if no PCIe link

2019-06-12 Thread Lorenzo Pieralisi
On Fri, Apr 12, 2019 at 08:36:54AM +, Z.q. Hou wrote:
> From: Hou Zhiqiang 
> 
> Sometimes there is not a PCIe Endpoint stalled in the slot,
> so do not exit when the PCIe link is not up. And degrade the
> print level of link up info.

So what's the point of probing if the link does not initialize ?

Lorenzo

> Signed-off-by: Hou Zhiqiang 
> Reviewed-by: Minghuan Lian 
> Reviewed-by: Subrahmanya Lingappa 
> ---
> V5:
>  - Corrected and retouched the subject and changelog.
> 
>  drivers/pci/controller/pcie-mobiveil.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mobiveil.c 
> b/drivers/pci/controller/pcie-mobiveil.c
> index 1ee3ea2570c0..8dc87c7a600e 100644
> --- a/drivers/pci/controller/pcie-mobiveil.c
> +++ b/drivers/pci/controller/pcie-mobiveil.c
> @@ -560,7 +560,7 @@ static int mobiveil_bringup_link(struct mobiveil_pcie 
> *pcie)
>   usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
>   }
>  
> - dev_err(>pdev->dev, "link never came up\n");
> + dev_info(>pdev->dev, "link never came up\n");
>  
>   return -ETIMEDOUT;
>  }
> @@ -926,10 +926,8 @@ static int mobiveil_pcie_probe(struct platform_device 
> *pdev)
>   bridge->swizzle_irq = pci_common_swizzle;
>  
>   ret = mobiveil_bringup_link(pcie);
> - if (ret) {
> + if (ret)
>   dev_info(dev, "link bring-up failed\n");
> - goto error;
> - }
>  
>   /* setup the kernel resources for the newly added PCIe root bus */
>   ret = pci_scan_root_bus_bridge(bridge);
> -- 
> 2.17.1
> 


<    1   2   3   4   5   6   7   8   9   10   >