On Thu, Sep 12, 2019 at 10:23:31, Dilip Kota <eswara.kota@xxxxxxxxxxxxxxx> wrote: > Quoting Andrew Murray: > Quoting Gustavo Pimentel: > > On 9/12/2019 4:25 PM, Andrew Murray wrote: > > [...] > >>>>>>>>>> +static void intel_pcie_max_link_width_setup(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + u32 mask, val; > >>>>>>>>>> + > >>>>>>>>>> + /* HW auto bandwidth negotiation must be enabled */ > >>>>>>>>>> + pcie_rc_cfg_wr_mask(lpp, PCIE_LCTLSTS_HW_AW_DIS, 0, PCIE_LCTLSTS); > >>>>>>>>>> + > >>>>>>>>>> + mask = PCIE_DIRECT_LINK_WIDTH_CHANGE | PCIE_TARGET_LINK_WIDTH; > >>>>>>>>>> + val = PCIE_DIRECT_LINK_WIDTH_CHANGE | lpp->lanes; > >>>>>>>>>> + pcie_rc_cfg_wr_mask(lpp, mask, val, PCIE_MULTI_LANE_CTRL); > >>>>>>>>> Is this identical functionality to the writing of PCIE_PORT_LINK_CONTROL > >>>>>>>>> in dw_pcie_setup? > >>>>>>>>> > >>>>>>>>> I ask because if the user sets num-lanes in the DT, will it have the > >>>>>>>>> desired effect? > >>>>>>>> intel_pcie_max_link_width_setup() function will be called by sysfs attribute pcie_width_store() to change on the fly. > >>>>>>> Indeed, but a user may also set num-lanes in the device tree. I'm wondering > >>>>>>> if, when set in device-tree, it will have the desired effect. Because I don't > >>>>>>> see anything similar to PCIE_LCTLSTS_HW_AW_DIS in dw_pcie_setup which is what > >>>>>>> your function does here. > >>>>>>> > >>>>>>> I guess I'm trying to avoid the suitation where num-lanes doesn't have the > >>>>>>> desired effect and the only way to set the num-lanes is throught the sysfs > >>>>>>> control. > >>>>>> I will check this and get back to you. > >>>> intel_pcie_max_link_width_setup() is doing the lane resizing which is > >>>> different from the link up/establishment happening during probe. Also > >>>> PCIE_LCTLSTS_HW_AW_DIS default value is 0 so not setting during the probe or > >>>> dw_pcie_setup. > >>>> > >>>> intel_pcie_max_link_width_setup() is programming as per the designware PCIe > >>>> controller databook instructions for lane resizing. > >>>> > >>>> Below lines are from Designware PCIe databook for lane resizing. > >>>> > >>>> Program the TARGET_LINK_WIDTH[5:0] field of the MULTI_LANE_CONTROL_OFF > >>>> register. > >>>> Program the DIRECT_LINK_WIDTH_CHANGE2 field of the MULTI_LANE_CONTROL_OFF > >>>> register. > >>>> It is assumed that the PCIE_CAP_HW_AUTO_WIDTH_DISABLE field in the > >>>> LINK_CONTROL_LINK_STATUS_REG register is 0. > >>> OK, so there is a difference between initial training and then resizing > >>> of the link. Given that this is not Intel specific, should this function > >>> exist within the designware driver for the benefit of others? > >> I am ok to add if maintainer agrees with it. > > Gustavo Pimentel, > > Could you please let us know your opinion on this. Hi, I just return from parental leave, therefore I still trying to get the pace in mailing list discussion. However your suggestion looks good, I agree that can go into DesignWare driver to be available to all. Just a small request, please do in general: s/designware/DesignWare Regards, Gustavo > > [...] > > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static void intel_pcie_port_logic_setup(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + u32 val, mask, fts; > >>>>>>>>>> + > >>>>>>>>>> + switch (lpp->max_speed) { > >>>>>>>>>> + case PCIE_LINK_SPEED_GEN1: > >>>>>>>>>> + case PCIE_LINK_SPEED_GEN2: > >>>>>>>>>> + fts = PCIE_AFR_GEN12_FTS_NUM_DFT; > >>>>>>>>>> + break; > [...] > >>>>>>>>>> + > >>>>>>>>>> + if (device_property_read_u32(dev, "max-link-speed", &lpp->link_gen)) > >>>>>>>>>> + lpp->link_gen = 0; /* Fallback to auto */ > >>>>>>>>> Is it possible to use of_pci_get_max_link_speed here instead? > >>>>>>>> Thanks for pointing it. of_pci_get_max_link_speed() can be used here. I will > >>>>>>>> update it in the next patch revision. > >>>> I just remember, earlier we were using of_pci_get_max_link_speed() itself. > >>>> As per reviewer comments changed to device_property_read_u32() to maintain > >>>> symmetry in parsing device tree properties from device node. > >>>> Let me know your view. > >>> I couldn't find an earlier version of this series that used of_pci_get_max_link_speed, > >>> have I missed it somewhere? > >> It happened in our internal review. > >> What's your suggestion please, either to go with symmetry in parsing > >> "device_property_read_u32()" or with pci helper function > >> "of_pci_get_max_link_speed"? > > I'd prefer the helper, the added benefit of this is additional error checking. > > It also means users can be confident that max-link-speed will behave in the > > same way as other host controllers that use this field. > Ok, i will update it in the next patch version. > > > Regards, > > Dilip > > > > > Thanks, > > > > Andrew Murray > > > >>>>>>>>>> + > >>>>>>>>>> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "app"); > >>>>>>>>>> + if (!res) > >>>>>>>>>> + return -ENXIO; > >>>>>>>>>> + > >>>>>>>>>> + lpp->app_base = devm_ioremap_resource(dev, res); > >>>>>>>>>> + if (IS_ERR(lpp->app_base)) > >>>>>>>>>> + return PTR_ERR(lpp->app_base); > >>>>>>>>>> + > >>>>>>>>>> + ret = intel_pcie_ep_rst_init(lpp); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + return ret; > >>>>>>>>> Given that this is called from a function '..._get_resources' I don't think > >>>>>>>>> we should be resetting anything here. > >>>>>>>> Agree. I will move it out of get_resources(). > >>>>>>>>>> + > >>>>>>>>>> + lpp->phy = devm_phy_get(dev, "pciephy"); > >>>>>>>>>> + if (IS_ERR(lpp->phy)) { > >>>>>>>>>> + ret = PTR_ERR(lpp->phy); > >>>>>>>>>> + if (ret != -EPROBE_DEFER) > >>>>>>>>>> + dev_err(dev, "couldn't get pcie-phy: %d\n", ret); > >>>>>>>>>> + return ret; > >>>>>>>>>> + } > >>>>>>>>>> + return 0; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static void intel_pcie_deinit_phy(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + phy_exit(lpp->phy); > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static int intel_pcie_wait_l2(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + u32 value; > >>>>>>>>>> + int ret; > >>>>>>>>>> + > >>>>>>>>>> + if (lpp->max_speed < PCIE_LINK_SPEED_GEN3) > >>>>>>>>>> + return 0; > >>>>>>>>>> + > >>>>>>>>>> + /* Send PME_TURN_OFF message */ > >>>>>>>>>> + pcie_app_wr_mask(lpp, PCIE_APP_MSG_XMT_PM_TURNOFF, > >>>>>>>>>> + PCIE_APP_MSG_XMT_PM_TURNOFF, PCIE_APP_MSG_CR); > >>>>>>>>>> + > >>>>>>>>>> + /* Read PMC status and wait for falling into L2 link state */ > >>>>>>>>>> + ret = readl_poll_timeout(lpp->app_base + PCIE_APP_PMC, value, > >>>>>>>>>> + (value & PCIE_APP_PMC_IN_L2), 20, > >>>>>>>>>> + jiffies_to_usecs(5 * HZ)); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + dev_err(lpp->pci.dev, "PCIe link enter L2 timeout!\n"); > >>>>>>>>>> + > >>>>>>>>>> + return ret; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static void intel_pcie_turn_off(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + if (dw_pcie_link_up(&lpp->pci)) > >>>>>>>>>> + intel_pcie_wait_l2(lpp); > >>>>>>>>>> + > >>>>>>>>>> + /* Put EP in reset state */ > >>>>>>>>> EP? > >>>>>>>> End point device. I will update it. > >>>>>>> Is this not a host bridge controller? > >>>>>> It is PERST#, signals hardware reset to the End point . > >>>>>> /* Put EP in reset state */ > >>>>>> intel_pcie_device_rst_assert(lpp); > >>>>> OK. > >>>>> > >>>>>>>>>> + intel_pcie_device_rst_assert(lpp); > >>>>>>>>>> + pcie_rc_cfg_wr_mask(lpp, PCI_COMMAND_MEMORY, 0, PCI_COMMAND); > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static int intel_pcie_host_setup(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + int ret; > >>>>>>>>>> + > >>>>>>>>>> + intel_pcie_core_rst_assert(lpp); > >>>>>>>>>> + intel_pcie_device_rst_assert(lpp); > >>>>>>>>>> + > >>>>>>>>>> + ret = phy_init(lpp->phy); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + return ret; > >>>>>>>>>> + > >>>>>>>>>> + intel_pcie_core_rst_deassert(lpp); > >>>>>>>>>> + > >>>>>>>>>> + ret = clk_prepare_enable(lpp->core_clk); > >>>>>>>>>> + if (ret) { > >>>>>>>>>> + dev_err(lpp->pci.dev, "Core clock enable failed: %d\n", ret); > >>>>>>>>>> + goto clk_err; > >>>>>>>>>> + } > >>>>>>>>>> + > >>>>>>>>>> + intel_pcie_rc_setup(lpp); > >>>>>>>>>> + ret = intel_pcie_app_logic_setup(lpp); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + goto app_init_err; > >>>>>>>>>> + > >>>>>>>>>> + ret = intel_pcie_setup_irq(lpp); > >>>>>>>>>> + if (!ret) > >>>>>>>>>> + return ret; > >>>>>>>>>> + > >>>>>>>>>> + intel_pcie_turn_off(lpp); > >>>>>>>>>> +app_init_err: > >>>>>>>>>> + clk_disable_unprepare(lpp->core_clk); > >>>>>>>>>> +clk_err: > >>>>>>>>>> + intel_pcie_core_rst_assert(lpp); > >>>>>>>>>> + intel_pcie_deinit_phy(lpp); > >>>>>>>>>> + return ret; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static ssize_t > >>>>>>>>>> +pcie_link_status_show(struct device *dev, struct device_attribute *attr, > >>>>>>>>>> + char *buf) > >>>>>>>>>> +{ > >>>>>>>>>> + u32 reg, width, gen; > >>>>>>>>>> + struct intel_pcie_port *lpp; > >>>>>>>>>> + > >>>>>>>>>> + lpp = dev_get_drvdata(dev); > >>>>>>>>>> + > >>>>>>>>>> + reg = pcie_rc_cfg_rd(lpp, PCIE_LCTLSTS); > >>>>>>>>>> + width = FIELD_GET(PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH, reg); > >>>>>>>>>> + gen = FIELD_GET(PCIE_LCTLSTS_LINK_SPEED, reg); > >>>>>>>>>> + if (gen > lpp->max_speed) > >>>>>>>>>> + return -EINVAL; > >>>>>>>>>> + > >>>>>>>>>> + return sprintf(buf, "Port %2u Width x%u Speed %s GT/s\n", lpp->id, > >>>>>>>>>> + width, pcie_link_gen_to_str(gen)); > >>>>>>>>>> +} > >>>>>>>>>> +static DEVICE_ATTR_RO(pcie_link_status); > >>>>>>>>>> + > >>>>>>>>>> +static ssize_t pcie_speed_store(struct device *dev, > >>>>>>>>>> + struct device_attribute *attr, > >>>>>>>>>> + const char *buf, size_t len) > >>>>>>>>>> +{ > >>>>>>>>>> + struct intel_pcie_port *lpp; > >>>>>>>>>> + unsigned long val; > >>>>>>>>>> + int ret; > >>>>>>>>>> + > >>>>>>>>>> + lpp = dev_get_drvdata(dev); > >>>>>>>>>> + > >>>>>>>>>> + ret = kstrtoul(buf, 10, &val); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + return ret; > >>>>>>>>>> + > >>>>>>>>>> + if (val > lpp->max_speed) > >>>>>>>>>> + return -EINVAL; > >>>>>>>>>> + > >>>>>>>>>> + lpp->link_gen = val; > >>>>>>>>>> + intel_pcie_max_speed_setup(lpp); > >>>>>>>>>> + intel_pcie_speed_change_disable(lpp); > >>>>>>>>>> + intel_pcie_speed_change_enable(lpp); > >>>>>>>>>> + > >>>>>>>>>> + return len; > >>>>>>>>>> +} > >>>>>>>>>> +static DEVICE_ATTR_WO(pcie_speed); > >>>>>>>>>> + > >>>>>>>>>> +/* > >>>>>>>>>> + * Link width change on the fly is not always successful. > >>>>>>>>>> + * It also depends on the partner. > >>>>>>>>>> + */ > >>>>>>>>>> +static ssize_t pcie_width_store(struct device *dev, > >>>>>>>>>> + struct device_attribute *attr, > >>>>>>>>>> + const char *buf, size_t len) > >>>>>>>>>> +{ > >>>>>>>>>> + struct intel_pcie_port *lpp; > >>>>>>>>>> + unsigned long val; > >>>>>>>>>> + > >>>>>>>>>> + lpp = dev_get_drvdata(dev); > >>>>>>>>>> + > >>>>>>>>>> + if (kstrtoul(buf, 10, &val)) > >>>>>>>>>> + return -EINVAL; > >>>>>>>>>> + > >>>>>>>>>> + if (val > lpp->max_width) > >>>>>>>>>> + return -EINVAL; > >>>>>>>>>> + > >>>>>>>>>> + lpp->lanes = val; > >>>>>>>>>> + intel_pcie_max_link_width_setup(lpp); > >>>>>>>>>> + > >>>>>>>>>> + return len; > >>>>>>>>>> +} > >>>>>>>>>> +static DEVICE_ATTR_WO(pcie_width); > >>>>>>>>> You mentioned that a use-case for changing width/speed on the fly was to > >>>>>>>>> control power consumption (and this also helps debugging issues). As I > >>>>>>>>> understand there is no current support for this in the kernel - yet it is > >>>>>>>>> something that would provide value. > >>>>>>>>> > >>>>>>>>> I haven't looked in much detail, however as I understand the PCI spec > >>>>>>>>> allows an upstream partner to change the link speed and retrain. (I'm not > >>>>>>>>> sure about link width). Given that we already have > >>>>>>>>> [current,max]_link_[speed,width] is sysfs for each PCI device, it would > >>>>>>>>> seem natural to extend this to allow for writing a max width or speed. > >>>>>>>>> > >>>>>>>>> So ideally this type of thing would be moved to the core or at least in > >>>>>>>>> the dwc driver. This way the benefits can be applied to more devices on > >>>>>>>>> larger PCI fabrics - Though perhaps others here will have a different view > >>>>>>>>> and I'm keen to hear them. > >>>>>>>>> > >>>>>>>>> I'm keen to limit the differences between the DWC controller drivers and > >>>>>>>>> unify common code - thus it would be helpful to have a justification as to > >>>>>>>>> why this is only relevant for this controller. > >>>>>>>>> > >>>>>>>>> For user-space only control, it is possible to achieve what you have here > >>>>>>>>> with userspace utilities (something like setpci) (assuming the standard > >>>>>>>>> looking registers you currently access are exposed in the normal config > >>>>>>>>> space way - though PCIe capabilities). > >>>>>>>>> > >>>>>>>>> My suggestion would be to drop these changes and later add something that > >>>>>>>>> can benefit more devices. In any case if these changes stay within this > >>>>>>>>> driver then it would be helpful to move them to a separate patch. > >>>>>>>> Sure, i will submit these entity in separate patch. > >>>>>>> Please ensure that all supporting macros, functions and defines go with that > >>>>>>> other patch as well please. > >>>>>> Sure. > >>>>>>>>>> + > >>>>>>>>>> +static struct attribute *pcie_cfg_attrs[] = { > >>>>>>>>>> + &dev_attr_pcie_link_status.attr, > >>>>>>>>>> + &dev_attr_pcie_speed.attr, > >>>>>>>>>> + &dev_attr_pcie_width.attr, > >>>>>>>>>> + NULL, > >>>>>>>>>> +}; > >>>>>>>>>> +ATTRIBUTE_GROUPS(pcie_cfg); > >>>>>>>>>> + > >>>>>>>>>> +static int intel_pcie_sysfs_init(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + return devm_device_add_groups(lpp->pci.dev, pcie_cfg_groups); > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static void __intel_pcie_remove(struct intel_pcie_port *lpp) > >>>>>>>>>> +{ > >>>>>>>>>> + pcie_rc_cfg_wr_mask(lpp, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, > >>>>>>>>>> + 0, PCI_COMMAND); > >>>>>>>>>> + intel_pcie_core_irq_disable(lpp); > >>>>>>>>>> + intel_pcie_turn_off(lpp); > >>>>>>>>>> + clk_disable_unprepare(lpp->core_clk); > >>>>>>>>>> + intel_pcie_core_rst_assert(lpp); > >>>>>>>>>> + intel_pcie_deinit_phy(lpp); > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static int intel_pcie_remove(struct platform_device *pdev) > >>>>>>>>>> +{ > >>>>>>>>>> + struct intel_pcie_port *lpp = platform_get_drvdata(pdev); > >>>>>>>>>> + struct pcie_port *pp = &lpp->pci.pp; > >>>>>>>>>> + > >>>>>>>>>> + dw_pcie_host_deinit(pp); > >>>>>>>>>> + __intel_pcie_remove(lpp); > >>>>>>>>>> + > >>>>>>>>>> + return 0; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static int __maybe_unused intel_pcie_suspend_noirq(struct device *dev) > >>>>>>>>>> +{ > >>>>>>>>>> + struct intel_pcie_port *lpp = dev_get_drvdata(dev); > >>>>>>>>>> + int ret; > >>>>>>>>>> + > >>>>>>>>>> + intel_pcie_core_irq_disable(lpp); > >>>>>>>>>> + ret = intel_pcie_wait_l2(lpp); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + return ret; > >>>>>>>>>> + > >>>>>>>>>> + intel_pcie_deinit_phy(lpp); > >>>>>>>>>> + clk_disable_unprepare(lpp->core_clk); > >>>>>>>>>> + return ret; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static int __maybe_unused intel_pcie_resume_noirq(struct device *dev) > >>>>>>>>>> +{ > >>>>>>>>>> + struct intel_pcie_port *lpp = dev_get_drvdata(dev); > >>>>>>>>>> + > >>>>>>>>>> + return intel_pcie_host_setup(lpp); > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static int intel_pcie_rc_init(struct pcie_port *pp) > >>>>>>>>>> +{ > >>>>>>>>>> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > >>>>>>>>>> + struct intel_pcie_port *lpp = dev_get_drvdata(pci->dev); > >>>>>>>>>> + int ret; > >>>>>>>>>> + > >>>>>>>>>> + /* RC/host initialization */ > >>>>>>>>>> + ret = intel_pcie_host_setup(lpp); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + return ret; > >>>>>>>>> Insert new line here. > >>>>>>>> Ok. > >>>>>>>>>> + ret = intel_pcie_sysfs_init(lpp); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + __intel_pcie_remove(lpp); > >>>>>>>>>> + return ret; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +int intel_pcie_msi_init(struct pcie_port *pp) > >>>>>>>>>> +{ > >>>>>>>>>> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > >>>>>>>>>> + > >>>>>>>>>> + dev_dbg(pci->dev, "PCIe MSI/MSIx is handled by MSI in x86 processor\n"); > >>>>>>>>> What about other processors? (Noting that this driver doesn't depend on > >>>>>>>>> any specific ARCH in the KConfig). > >>>>>>>> Agree. i will mark the dependency in Kconfig. > >>>>>>> OK, please also see how other drivers use the COMPILE_TEST Kconfig option. > >>>>>> Ok sure. > >>>>>>> I'd suggest that the dev_dbg just becomes a code comment. > >>>> Ok > >>>>>>>>>> + return 0; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +u64 intel_pcie_cpu_addr(struct dw_pcie *pcie, u64 cpu_addr) > >>>>>>>>>> +{ > >>>>>>>>>> + return cpu_addr + BUS_IATU_OFFS; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static const struct dw_pcie_ops intel_pcie_ops = { > >>>>>>>>>> + .cpu_addr_fixup = intel_pcie_cpu_addr, > >>>>>>>>>> +}; > >>>>>>>>>> + > >>>>>>>>>> +static const struct dw_pcie_host_ops intel_pcie_dw_ops = { > >>>>>>>>>> + .host_init = intel_pcie_rc_init, > >>>>>>>>>> + .msi_host_init = intel_pcie_msi_init, > >>>>>>>>>> +}; > >>>>>>>>>> + > >>>>>>>>>> +static const struct intel_pcie_soc pcie_data = { > >>>>>>>>>> + .pcie_ver = 0x520A, > >>>>>>>>>> + .pcie_atu_offset = 0xC0000, > >>>>>>>>>> + .num_viewport = 3, > >>>>>>>>>> +}; > >>>>>>>>>> + > >>>>>>>>>> +static int intel_pcie_probe(struct platform_device *pdev) > >>>>>>>>>> +{ > >>>>>>>>>> + const struct intel_pcie_soc *data; > >>>>>>>>>> + struct device *dev = &pdev->dev; > >>>>>>>>>> + struct intel_pcie_port *lpp; > >>>>>>>>>> + struct pcie_port *pp; > >>>>>>>>>> + struct dw_pcie *pci; > >>>>>>>>>> + int ret; > >>>>>>>>>> + > >>>>>>>>>> + lpp = devm_kzalloc(dev, sizeof(*lpp), GFP_KERNEL); > >>>>>>>>>> + if (!lpp) > >>>>>>>>>> + return -ENOMEM; > >>>>>>>>>> + > >>>>>>>>>> + platform_set_drvdata(pdev, lpp); > >>>>>>>>>> + pci = &lpp->pci; > >>>>>>>>>> + pci->dev = dev; > >>>>>>>>>> + pp = &pci->pp; > >>>>>>>>>> + > >>>>>>>>>> + ret = intel_pcie_get_resources(pdev); > >>>>>>>>>> + if (ret) > >>>>>>>>>> + return ret; > >>>>>>>>>> + > >>>>>>>>>> + data = device_get_match_data(dev); > >>>>>>>>>> + pci->ops = &intel_pcie_ops; > >>>>>>>>>> + pci->version = data->pcie_ver; > >>>>>>>>>> + pci->atu_base = pci->dbi_base + data->pcie_atu_offset; > >>>>>>>>>> + pp->ops = &intel_pcie_dw_ops; > >>>>>>>>>> + > >>>>>>>>>> + ret = dw_pcie_host_init(pp); > >>>>>>>>>> + if (ret) { > >>>>>>>>>> + dev_err(dev, "cannot initialize host\n"); > >>>>>>>>>> + return ret; > >>>>>>>>>> + } > >>>>>>>>> Add a new line after the closing brace. > >>>>>>>> Ok > >>>>>>>>>> + /* Intel PCIe doesn't configure IO region, so configure > >>>>>>>>>> + * viewport to not to access IO region during register > >>>>>>>>>> + * read write operations. > >>>>>>>>>> + */ > >>>>>>>>>> + pci->num_viewport = data->num_viewport; > >>>>>>>>>> + dev_info(dev, > >>>>>>>>>> + "Intel AXI PCIe Root Complex Port %d Init Done\n", lpp->id); > >>>>>>>>>> + return ret; > >>>>>>>>>> +} > >>>>>>>>>> + > >>>>>>>>>> +static const struct dev_pm_ops intel_pcie_pm_ops = { > >>>>>>>>>> + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(intel_pcie_suspend_noirq, > >>>>>>>>>> + intel_pcie_resume_noirq) > >>>>>>>>>> +}; > >>>>>>>>>> + > >>>>>>>>>> +static const struct of_device_id of_intel_pcie_match[] = { > >>>>>>>>>> + { .compatible = "intel,lgm-pcie", .data = &pcie_data }, > >>>>>>>>>> + {} > >>>>>>>>>> +}; > >>>>>>>>>> + > >>>>>>>>>> +static struct platform_driver intel_pcie_driver = { > >>>>>>>>>> + .probe = intel_pcie_probe, > >>>>>>>>>> + .remove = intel_pcie_remove, > >>>>>>>>>> + .driver = { > >>>>>>>>>> + .name = "intel-lgm-pcie", > >>>>>>>>> Is there a reason why the we use intel-lgm-pcie here and pcie-intel-axi > >>>>>>>>> elsewhere? What does lgm mean? > >>>>>>>> lgm is the name of intel SoC. I will name it to pcie-intel-axi to be > >>>>>>>> generic. > >>>>>>> I'm keen to ensure that it is consistently named. I've seen other comments > >>>>>>> regarding what the name should be - I don't have a strong opinion though > >>>>>>> I do think that *-axi may be too generic. > >>>> This PCIe driver is for the Intel Gateway SoCs. So how about naming it is as > >>>> "pcie-intel-gw"; pcie-intel-gw.c and Kconfig as PCIE_INTEL_GW. > >>> I don't have a problem with this, though others may have differing views. > >> Sure. thank you. > >>> Thanks, > >>> > >>> Andrew Murray > >>> > >>>> Regards, > >>>> Dilip > >>>> > >>>>>> Ok, i will check and get back to you on this. > >>>>>> Regards, > >>>>> Thanks, > >>>>> > >>>>> Andrew Murray > >>>>> > >>>>>> Dilip > >>>>>> > >>>>>>> Thanks, > >>>>>>> > >>>>>>> Andrew Murray > >>>>>>> > >>>>>>>>> Thanks, > >>>>>>>>> > >>>>>>>>> Andrew Murray > >>>>>>>>> > >>>>>>>>>> + .of_match_table = of_intel_pcie_match, > >>>>>>>>>> + .pm = &intel_pcie_pm_ops, > >>>>>>>>>> + }, > >>>>>>>>>> +}; > >>>>>>>>>> +builtin_platform_driver(intel_pcie_driver); > >>>>>>>>>> -- > >>>>>>>>>> 2.11.0 > >>>>>>>>>>