Patchwork Make PCIe hotplug work with Freescale PCIe controllers

login
register
mail settings
Submitter Rojhalat Ibrahim
Date March 12, 2013, 9:23 a.m.
Message ID <2399353.017i5G1tnZ@pcimr>
Download mbox | patch
Permalink /patch/226864/
State Superseded
Delegated to: Kumar Gala
Headers show

Comments

Rojhalat Ibrahim - March 12, 2013, 9:23 a.m.
On Monday 11 March 2013 12:17:42 Kumar Gala wrote:
> 
> Rather than do it this way, we should do something like:
> 
> fsl_indirect_read_config() {
> 	link check
> 	if (link)
> 		indirect_read_config()
> }
> 
> and just add fsl_indirect_{r,w}_config into fsl_pci.c
> 
> - k
> 

Ok, how about this:


Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
---
 arch/powerpc/sysdev/fsl_pci.c |   49 
++++++++++++++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 4 deletions(-)

 #define MAX_PHYS_ADDR_BITS	40
@@ -461,8 +502,8 @@ int __init fsl_add_bridge(struct platform_device *pdev, 
int is_primary)
 	hose->first_busno = bus_range ? bus_range[0] : 0x0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
-	setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
-		PPC_INDIRECT_TYPE_BIG_ENDIAN);
+	fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
+			       PPC_INDIRECT_TYPE_BIG_ENDIAN);
 
 	if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
 		/* For PCIE read HEADER_TYPE to identify controler mode */
@@ -766,8 +807,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
 		if (ret)
 			goto err0;
 	} else {
-		setup_indirect_pci(hose, rsrc_cfg.start,
-				   rsrc_cfg.start + 4, 0);
+		fsl_setup_indirect_pci(hose, rsrc_cfg.start,
+				       rsrc_cfg.start + 4, 0);
 	}
 
 	printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
Kumar Gala - March 12, 2013, 8:44 p.m.
On Mar 12, 2013, at 4:23 AM, Rojhalat Ibrahim wrote:

> On Monday 11 March 2013 12:17:42 Kumar Gala wrote:
>> 
>> Rather than do it this way, we should do something like:
>> 
>> fsl_indirect_read_config() {
>> 	link check
>> 	if (link)
>> 		indirect_read_config()
>> }
>> 
>> and just add fsl_indirect_{r,w}_config into fsl_pci.c
>> 
>> - k
>> 
> 
> Ok, how about this:
> 

I'd rather we just export indirect_read_config() & indirect_write_config() from indirect_pci.c and call the functions directly.  Adding a global and call them via a function pointer seems wrong to me.

- k

> 
> Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
> ---
> arch/powerpc/sysdev/fsl_pci.c |   49 
> ++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 45 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
> index 682084d..693db9f 100644
> --- a/arch/powerpc/sysdev/fsl_pci.c
> +++ b/arch/powerpc/sysdev/fsl_pci.c
> @@ -36,6 +36,8 @@
> 
> static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
> 
> +static struct pci_ops *indirect_pci_ops;
> +
> static void quirk_fsl_pcie_header(struct pci_dev *dev)
> {
> 	u8 hdr_type;
> @@ -64,6 +66,45 @@ static int __init fsl_pcie_check_link(struct pci_controller 
> *hose)
> 	return 0;
> }
> 
> +static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
> +				    int offset, int len, u32 *val)
> +{
> +	struct pci_controller *hose = pci_bus_to_host(bus);
> +	
> +	// check the link status
> +	if ((bus->number == hose->first_busno) && (devfn == 0)) {
> +		u32 ltssm = 0;
> +		indirect_pci_ops->read(bus, 0, PCIE_LTSSM, 4, &ltssm);
> +		if (ltssm < PCIE_LTSSM_L0) {
> +			hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
> +		} else {
> +			hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
> +		}
> +	}
> +	return indirect_pci_ops->read(bus, devfn, offset, len, val);
> +}
> +
> +static int fsl_indirect_write_config(struct pci_bus *bus, unsigned int devfn,
> +				     int offset, int len, u32 val)
> +{
> +	return indirect_pci_ops->write(bus, devfn, offset, len, val);
> +}
> +
> +static struct pci_ops fsl_indirect_pci_ops =
> +{
> +	.read = fsl_indirect_read_config,
> +	.write = fsl_indirect_write_config,
> +};
> +
> +static void __init fsl_setup_indirect_pci(struct pci_controller* hose,
> +					  resource_size_t cfg_addr,
> +					  resource_size_t cfg_data, u32 flags)
> +{
> +	setup_indirect_pci(hose, cfg_addr, cfg_data, flags);
> +	indirect_pci_ops = hose->ops;
> +	hose->ops = &fsl_indirect_pci_ops;
> +}
> +
> #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
> 
> #define MAX_PHYS_ADDR_BITS	40
> @@ -461,8 +502,8 @@ int __init fsl_add_bridge(struct platform_device *pdev, 
> int is_primary)
> 	hose->first_busno = bus_range ? bus_range[0] : 0x0;
> 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
> 
> -	setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
> -		PPC_INDIRECT_TYPE_BIG_ENDIAN);
> +	fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
> +			       PPC_INDIRECT_TYPE_BIG_ENDIAN);
> 
> 	if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
> 		/* For PCIE read HEADER_TYPE to identify controler mode */
> @@ -766,8 +807,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
> 		if (ret)
> 			goto err0;
> 	} else {
> -		setup_indirect_pci(hose, rsrc_cfg.start,
> -				   rsrc_cfg.start + 4, 0);
> +		fsl_setup_indirect_pci(hose, rsrc_cfg.start,
> +				       rsrc_cfg.start + 4, 0);
> 	}
> 
> 	printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
>
Kumar Gala - March 12, 2013, 8:48 p.m.
On Mar 12, 2013, at 3:44 PM, Kumar Gala wrote:

> 
> On Mar 12, 2013, at 4:23 AM, Rojhalat Ibrahim wrote:
> 
>> On Monday 11 March 2013 12:17:42 Kumar Gala wrote:
>>> 
>>> Rather than do it this way, we should do something like:
>>> 
>>> fsl_indirect_read_config() {
>>> 	link check
>>> 	if (link)
>>> 		indirect_read_config()
>>> }
>>> 
>>> and just add fsl_indirect_{r,w}_config into fsl_pci.c
>>> 
>>> - k
>>> 
>> 
>> Ok, how about this:
>> 
> 
> I'd rather we just export indirect_read_config() & indirect_write_config() from indirect_pci.c and call the functions directly.  Adding a global and call them via a function pointer seems wrong to me.
> 
> - k

Also, can you base this patch on my powerpc.git next branch as fsl_pci.{c,h} have some changes in them.

- k

> 
>> 
>> Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
>> ---
>> arch/powerpc/sysdev/fsl_pci.c |   49 
>> ++++++++++++++++++++++++++++++++++++++----
>> 1 file changed, 45 insertions(+), 4 deletions(-)
>> 
>> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
>> index 682084d..693db9f 100644
>> --- a/arch/powerpc/sysdev/fsl_pci.c
>> +++ b/arch/powerpc/sysdev/fsl_pci.c
>> @@ -36,6 +36,8 @@
>> 
>> static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
>> 
>> +static struct pci_ops *indirect_pci_ops;
>> +
>> static void quirk_fsl_pcie_header(struct pci_dev *dev)
>> {
>> 	u8 hdr_type;
>> @@ -64,6 +66,45 @@ static int __init fsl_pcie_check_link(struct pci_controller 
>> *hose)
>> 	return 0;
>> }
>> 
>> +static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
>> +				    int offset, int len, u32 *val)
>> +{
>> +	struct pci_controller *hose = pci_bus_to_host(bus);
>> +	
>> +	// check the link status
>> +	if ((bus->number == hose->first_busno) && (devfn == 0)) {
>> +		u32 ltssm = 0;
>> +		indirect_pci_ops->read(bus, 0, PCIE_LTSSM, 4, &ltssm);
>> +		if (ltssm < PCIE_LTSSM_L0) {
>> +			hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
>> +		} else {
>> +			hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
>> +		}
>> +	}
>> +	return indirect_pci_ops->read(bus, devfn, offset, len, val);
>> +}
>> +
>> +static int fsl_indirect_write_config(struct pci_bus *bus, unsigned int devfn,
>> +				     int offset, int len, u32 val)
>> +{
>> +	return indirect_pci_ops->write(bus, devfn, offset, len, val);
>> +}
>> +
>> +static struct pci_ops fsl_indirect_pci_ops =
>> +{
>> +	.read = fsl_indirect_read_config,
>> +	.write = fsl_indirect_write_config,
>> +};
>> +
>> +static void __init fsl_setup_indirect_pci(struct pci_controller* hose,
>> +					  resource_size_t cfg_addr,
>> +					  resource_size_t cfg_data, u32 flags)
>> +{
>> +	setup_indirect_pci(hose, cfg_addr, cfg_data, flags);
>> +	indirect_pci_ops = hose->ops;
>> +	hose->ops = &fsl_indirect_pci_ops;
>> +}
>> +
>> #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
>> 
>> #define MAX_PHYS_ADDR_BITS	40
>> @@ -461,8 +502,8 @@ int __init fsl_add_bridge(struct platform_device *pdev, 
>> int is_primary)
>> 	hose->first_busno = bus_range ? bus_range[0] : 0x0;
>> 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
>> 
>> -	setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
>> -		PPC_INDIRECT_TYPE_BIG_ENDIAN);
>> +	fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
>> +			       PPC_INDIRECT_TYPE_BIG_ENDIAN);
>> 
>> 	if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
>> 		/* For PCIE read HEADER_TYPE to identify controler mode */
>> @@ -766,8 +807,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
>> 		if (ret)
>> 			goto err0;
>> 	} else {
>> -		setup_indirect_pci(hose, rsrc_cfg.start,
>> -				   rsrc_cfg.start + 4, 0);
>> +		fsl_setup_indirect_pci(hose, rsrc_cfg.start,
>> +				       rsrc_cfg.start + 4, 0);
>> 	}
>> 
>> 	printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
>> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

Patch

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 682084d..693db9f 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -36,6 +36,8 @@ 
 
 static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
 
+static struct pci_ops *indirect_pci_ops;
+
 static void quirk_fsl_pcie_header(struct pci_dev *dev)
 {
 	u8 hdr_type;
@@ -64,6 +66,45 @@  static int __init fsl_pcie_check_link(struct pci_controller 
*hose)
 	return 0;
 }
 
+static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
+				    int offset, int len, u32 *val)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	
+	// check the link status
+	if ((bus->number == hose->first_busno) && (devfn == 0)) {
+		u32 ltssm = 0;
+		indirect_pci_ops->read(bus, 0, PCIE_LTSSM, 4, &ltssm);
+		if (ltssm < PCIE_LTSSM_L0) {
+			hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+		} else {
+			hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+		}
+	}
+	return indirect_pci_ops->read(bus, devfn, offset, len, val);
+}
+
+static int fsl_indirect_write_config(struct pci_bus *bus, unsigned int devfn,
+				     int offset, int len, u32 val)
+{
+	return indirect_pci_ops->write(bus, devfn, offset, len, val);
+}
+
+static struct pci_ops fsl_indirect_pci_ops =
+{
+	.read = fsl_indirect_read_config,
+	.write = fsl_indirect_write_config,
+};
+
+static void __init fsl_setup_indirect_pci(struct pci_controller* hose,
+					  resource_size_t cfg_addr,
+					  resource_size_t cfg_data, u32 flags)
+{
+	setup_indirect_pci(hose, cfg_addr, cfg_data, flags);
+	indirect_pci_ops = hose->ops;
+	hose->ops = &fsl_indirect_pci_ops;
+}
+
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)