[PATCH] Make PCIe hotplug work with Freescale PCIe controllers
Kumar Gala
galak at kernel.crashing.org
Wed Mar 13 07:48:01 EST 2013
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 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. "
>>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
More information about the Linuxppc-dev
mailing list