Re: [PATCH v5 1/8] powerpc/pci: Access PCI config space directly w/o pci_dn

2019-04-29 Thread Oliver
On Mon, Mar 11, 2019 at 10:52 PM Sergey Miroshnichenko
 wrote:
>
> To fetch an updated DT for the newly hotplugged device, OS must explicitly
> request it from the firmware via the pnv_php driver.
>
> If pnv_php wasn't triggered/loaded, it is still possible to discover new
> devices if PCIe I/O will not stop in absence of the pci_dn structure.
>
> Signed-off-by: Sergey Miroshnichenko 
> ---
>  arch/powerpc/kernel/rtas_pci.c   | 97 +++-
>  arch/powerpc/platforms/powernv/pci.c | 64 --
>  2 files changed, 109 insertions(+), 52 deletions(-)
>
> diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
> index c2b148b1634a..f675b5ecb5bc 100644
> --- a/arch/powerpc/kernel/rtas_pci.c
> +++ b/arch/powerpc/kernel/rtas_pci.c
> @@ -55,10 +55,26 @@ static inline int config_access_valid(struct pci_dn *dn, 
> int where)
> return 0;
>  }
>
> -int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
> +static int rtas_read_raw_config(unsigned long buid, int busno, unsigned int 
> devfn,
> +   int where, int size, u32 *val)
>  {
> int returnval = -1;
> -   unsigned long buid, addr;
> +   unsigned long addr = rtas_config_addr(busno, devfn, where);
> +   int ret;
> +
> +   if (buid) {
> +   ret = rtas_call(ibm_read_pci_config, 4, 2, ,
> +   addr, BUID_HI(buid), BUID_LO(buid), size);
> +   } else {
> +   ret = rtas_call(read_pci_config, 2, 2, , addr, 
> size);
> +   }
> +   *val = returnval;
> +
> +   return ret;
> +}
> +
> +int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
> +{
> int ret;
>
> if (!pdn)
> @@ -71,16 +87,8 @@ int rtas_read_config(struct pci_dn *pdn, int where, int 
> size, u32 *val)
> return PCIBIOS_SET_FAILED;
>  #endif
>
> -   addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
> -   buid = pdn->phb->buid;
> -   if (buid) {
> -   ret = rtas_call(ibm_read_pci_config, 4, 2, ,
> -   addr, BUID_HI(buid), BUID_LO(buid), size);
> -   } else {
> -   ret = rtas_call(read_pci_config, 2, 2, , addr, 
> size);
> -   }
> -   *val = returnval;
> -
> +   ret = rtas_read_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
> +  where, size, val);
> if (ret)
> return PCIBIOS_DEVICE_NOT_FOUND;
>
> @@ -98,18 +106,44 @@ static int rtas_pci_read_config(struct pci_bus *bus,
>
> pdn = pci_get_pdn_by_devfn(bus, devfn);
>
> -   /* Validity of pdn is checked in here */
> -   ret = rtas_read_config(pdn, where, size, val);
> -   if (*val == EEH_IO_ERROR_VALUE(size) &&
> -   eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
> -   return PCIBIOS_DEVICE_NOT_FOUND;
> +   if (pdn) {
> +   /* Validity of pdn is checked in here */
> +   ret = rtas_read_config(pdn, where, size, val);
> +
> +   if (*val == EEH_IO_ERROR_VALUE(size) &&
> +   eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
> +   ret = PCIBIOS_DEVICE_NOT_FOUND;
> +   } else {
> +   struct pci_controller *phb = pci_bus_to_host(bus);
> +
> +   ret = rtas_read_raw_config(phb->buid, bus->number, devfn,
> +  where, size, val);
> +   }
>
> return ret;
>  }
>
> +static int rtas_write_raw_config(unsigned long buid, int busno, unsigned int 
> devfn,
> +int where, int size, u32 val)
> +{
> +   unsigned long addr = rtas_config_addr(busno, devfn, where);
> +   int ret;
> +
> +   if (buid) {
> +   ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
> +   BUID_HI(buid), BUID_LO(buid), size, 
> (ulong)val);
> +   } else {
> +   ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, 
> (ulong)val);
> +   }
> +
> +   if (ret)
> +   return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +   return PCIBIOS_SUCCESSFUL;
> +}
> +
>  int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
>  {
> -   unsigned long buid, addr;
> int ret;
>
> if (!pdn)
> @@ -122,15 +156,8 @@ int rtas_write_config(struct pci_dn *pdn, int where, int 
> size, u32 val)
> return PCIBIOS_SET_FAILED;
>  #endif
>
> -   addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
> -   buid = pdn->phb->buid;
> -   if (buid) {
> -   ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
> -   BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
> -   } else {
> -   ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, 
> (ulong)val);
> -   }
> -
> +   ret = rtas_write_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
> + 

[PATCH v5 1/8] powerpc/pci: Access PCI config space directly w/o pci_dn

2019-03-11 Thread Sergey Miroshnichenko
To fetch an updated DT for the newly hotplugged device, OS must explicitly
request it from the firmware via the pnv_php driver.

If pnv_php wasn't triggered/loaded, it is still possible to discover new
devices if PCIe I/O will not stop in absence of the pci_dn structure.

Signed-off-by: Sergey Miroshnichenko 
---
 arch/powerpc/kernel/rtas_pci.c   | 97 +++-
 arch/powerpc/platforms/powernv/pci.c | 64 --
 2 files changed, 109 insertions(+), 52 deletions(-)

diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index c2b148b1634a..f675b5ecb5bc 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -55,10 +55,26 @@ static inline int config_access_valid(struct pci_dn *dn, 
int where)
return 0;
 }
 
-int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
+static int rtas_read_raw_config(unsigned long buid, int busno, unsigned int 
devfn,
+   int where, int size, u32 *val)
 {
int returnval = -1;
-   unsigned long buid, addr;
+   unsigned long addr = rtas_config_addr(busno, devfn, where);
+   int ret;
+
+   if (buid) {
+   ret = rtas_call(ibm_read_pci_config, 4, 2, ,
+   addr, BUID_HI(buid), BUID_LO(buid), size);
+   } else {
+   ret = rtas_call(read_pci_config, 2, 2, , addr, size);
+   }
+   *val = returnval;
+
+   return ret;
+}
+
+int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
+{
int ret;
 
if (!pdn)
@@ -71,16 +87,8 @@ int rtas_read_config(struct pci_dn *pdn, int where, int 
size, u32 *val)
return PCIBIOS_SET_FAILED;
 #endif
 
-   addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
-   buid = pdn->phb->buid;
-   if (buid) {
-   ret = rtas_call(ibm_read_pci_config, 4, 2, ,
-   addr, BUID_HI(buid), BUID_LO(buid), size);
-   } else {
-   ret = rtas_call(read_pci_config, 2, 2, , addr, size);
-   }
-   *val = returnval;
-
+   ret = rtas_read_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
+  where, size, val);
if (ret)
return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -98,18 +106,44 @@ static int rtas_pci_read_config(struct pci_bus *bus,
 
pdn = pci_get_pdn_by_devfn(bus, devfn);
 
-   /* Validity of pdn is checked in here */
-   ret = rtas_read_config(pdn, where, size, val);
-   if (*val == EEH_IO_ERROR_VALUE(size) &&
-   eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
-   return PCIBIOS_DEVICE_NOT_FOUND;
+   if (pdn) {
+   /* Validity of pdn is checked in here */
+   ret = rtas_read_config(pdn, where, size, val);
+
+   if (*val == EEH_IO_ERROR_VALUE(size) &&
+   eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
+   ret = PCIBIOS_DEVICE_NOT_FOUND;
+   } else {
+   struct pci_controller *phb = pci_bus_to_host(bus);
+
+   ret = rtas_read_raw_config(phb->buid, bus->number, devfn,
+  where, size, val);
+   }
 
return ret;
 }
 
+static int rtas_write_raw_config(unsigned long buid, int busno, unsigned int 
devfn,
+int where, int size, u32 val)
+{
+   unsigned long addr = rtas_config_addr(busno, devfn, where);
+   int ret;
+
+   if (buid) {
+   ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
+   BUID_HI(buid), BUID_LO(buid), size, (ulong)val);
+   } else {
+   ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, 
(ulong)val);
+   }
+
+   if (ret)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   return PCIBIOS_SUCCESSFUL;
+}
+
 int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
 {
-   unsigned long buid, addr;
int ret;
 
if (!pdn)
@@ -122,15 +156,8 @@ int rtas_write_config(struct pci_dn *pdn, int where, int 
size, u32 val)
return PCIBIOS_SET_FAILED;
 #endif
 
-   addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
-   buid = pdn->phb->buid;
-   if (buid) {
-   ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
-   BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
-   } else {
-   ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, 
(ulong)val);
-   }
-
+   ret = rtas_write_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
+   where, size, val);
if (ret)
return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -141,12 +168,20 @@ static int rtas_pci_write_config(struct pci_bus *bus,
 unsigned int devfn,
 int where, int size, u32 val)
 {
-   struct