[PATCH] Make PCIe hotplug work with Freescale PCIe controllers
Kumar Gala
galak at kernel.crashing.org
Wed Mar 13 07:44:07 EST 2013
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 at 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, <ssm);
> + 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. "
>
More information about the Linuxppc-dev
mailing list