Commit df5dd337 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/controller/qcom'

- Use devm_clk_bulk_get_all() to get all the clocks from DT to avoid
  writing out all the clock names (Manivannan Sadhasivam)

- Add DT binding and driver support for the SA8775P SoC (Mrinmay Sarkar)

- Refactor dw_pcie_edma_find_chip() to enable adding support for Hyper DMA
  (HDMA) (Manivannan Sadhasivam)

- Enable drivers to supply the eDMA channel count since some can't auto
  detect this (Manivannan Sadhasivam)

- Add HDMA support for the SA8775P SoC (Mrinmay Sarkar)

- Override the SA8775P NO_SNOOP default to avoid possible memory corruption
  (Mrinmay Sarkar)

- Make sure resources are disabled during PERST# assertion, even if the
  link is already disabled (Manivannan Sadhasivam)

- Vote for the CPU-PCIe ICC (interconnect) path to ensure it stays active
  even if other drivers don't vote for it (Krishna chaitanya chundru)

- Add Operating Performance Points (OPP) to scale performance state based
  on aggregate link bandwidth to improve SoC power efficiency (Krishna
  chaitanya chundru)

- Return failure instead of success if dev_pm_opp_find_freq_floor() fails
  (Dan Carpenter)

- Avoid an error pointer dereference if dev_pm_opp_find_freq_exact() fails
  (Dan Carpenter)

- Prevent use of uninitialized data in qcom_pcie_suspend_noirq() (Dan
  Carpenter)

* pci/controller/qcom:
  PCI: qcom: Prevent use of uninitialized data in qcom_pcie_suspend_noirq()
  PCI: qcom: Prevent potential error pointer dereference
  PCI: qcom: Fix missing error code in qcom_pcie_probe()
  PCI: qcom: Add OPP support to scale performance
  PCI: Bring the PCIe speed to MBps logic to new pcie_dev_speed_mbps()
  PCI: qcom: Add ICC bandwidth vote for CPU to PCIe path
  PCI: qcom-ep: Disable resources unconditionally during PERST# assert
  PCI: qcom-ep: Override NO_SNOOP attribute for SA8775P EP
  PCI: qcom: Override NO_SNOOP attribute for SA8775P RC
  PCI: epf-mhi: Enable HDMA for SA8775P SoC
  PCI: qcom-ep: Add HDMA support for SA8775P SoC
  PCI: dwc: Pass the eDMA mapping format flag directly from glue drivers
  PCI: dwc: Skip finding eDMA channels count for HDMA platforms
  PCI: dwc: Refactor dw_pcie_edma_find_chip() API
  PCI: qcom-ep: Add support for SA8775P SOC
  dt-bindings: PCI: qcom-ep: Add support for SA8775P SoC
  PCI: qcom: Use devm_clk_bulk_get_all() API
parents 325b9a3e 044b45be
...@@ -13,6 +13,7 @@ properties: ...@@ -13,6 +13,7 @@ properties:
compatible: compatible:
oneOf: oneOf:
- enum: - enum:
- qcom,sa8775p-pcie-ep
- qcom,sdx55-pcie-ep - qcom,sdx55-pcie-ep
- qcom,sm8450-pcie-ep - qcom,sm8450-pcie-ep
- items: - items:
...@@ -20,6 +21,7 @@ properties: ...@@ -20,6 +21,7 @@ properties:
- const: qcom,sdx55-pcie-ep - const: qcom,sdx55-pcie-ep
reg: reg:
minItems: 6
items: items:
- description: Qualcomm-specific PARF configuration registers - description: Qualcomm-specific PARF configuration registers
- description: DesignWare PCIe registers - description: DesignWare PCIe registers
...@@ -27,8 +29,10 @@ properties: ...@@ -27,8 +29,10 @@ properties:
- description: Address Translation Unit (ATU) registers - description: Address Translation Unit (ATU) registers
- description: Memory region used to map remote RC address space - description: Memory region used to map remote RC address space
- description: BAR memory region - description: BAR memory region
- description: DMA register space
reg-names: reg-names:
minItems: 6
items: items:
- const: parf - const: parf
- const: dbi - const: dbi
...@@ -36,13 +40,14 @@ properties: ...@@ -36,13 +40,14 @@ properties:
- const: atu - const: atu
- const: addr_space - const: addr_space
- const: mmio - const: mmio
- const: dma
clocks: clocks:
minItems: 7 minItems: 5
maxItems: 8 maxItems: 8
clock-names: clock-names:
minItems: 7 minItems: 5
maxItems: 8 maxItems: 8
qcom,perst-regs: qcom,perst-regs:
...@@ -57,14 +62,18 @@ properties: ...@@ -57,14 +62,18 @@ properties:
- description: Perst separation enable offset - description: Perst separation enable offset
interrupts: interrupts:
minItems: 2
items: items:
- description: PCIe Global interrupt - description: PCIe Global interrupt
- description: PCIe Doorbell interrupt - description: PCIe Doorbell interrupt
- description: DMA interrupt
interrupt-names: interrupt-names:
minItems: 2
items: items:
- const: global - const: global
- const: doorbell - const: doorbell
- const: dma
reset-gpios: reset-gpios:
description: GPIO used as PERST# input signal description: GPIO used as PERST# input signal
...@@ -125,6 +134,10 @@ allOf: ...@@ -125,6 +134,10 @@ allOf:
- qcom,sdx55-pcie-ep - qcom,sdx55-pcie-ep
then: then:
properties: properties:
reg:
maxItems: 6
reg-names:
maxItems: 6
clocks: clocks:
items: items:
- description: PCIe Auxiliary clock - description: PCIe Auxiliary clock
...@@ -143,6 +156,10 @@ allOf: ...@@ -143,6 +156,10 @@ allOf:
- const: slave_q2a - const: slave_q2a
- const: sleep - const: sleep
- const: ref - const: ref
interrupts:
maxItems: 2
interrupt-names:
maxItems: 2
- if: - if:
properties: properties:
...@@ -152,6 +169,10 @@ allOf: ...@@ -152,6 +169,10 @@ allOf:
- qcom,sm8450-pcie-ep - qcom,sm8450-pcie-ep
then: then:
properties: properties:
reg:
maxItems: 6
reg-names:
maxItems: 6
clocks: clocks:
items: items:
- description: PCIe Auxiliary clock - description: PCIe Auxiliary clock
...@@ -172,6 +193,45 @@ allOf: ...@@ -172,6 +193,45 @@ allOf:
- const: ref - const: ref
- const: ddrss_sf_tbu - const: ddrss_sf_tbu
- const: aggre_noc_axi - const: aggre_noc_axi
interrupts:
maxItems: 2
interrupt-names:
maxItems: 2
- if:
properties:
compatible:
contains:
enum:
- qcom,sa8775p-pcie-ep
then:
properties:
reg:
minItems: 7
maxItems: 7
reg-names:
minItems: 7
maxItems: 7
clocks:
items:
- description: PCIe Auxiliary clock
- description: PCIe CFG AHB clock
- description: PCIe Master AXI clock
- description: PCIe Slave AXI clock
- description: PCIe Slave Q2A AXI clock
clock-names:
items:
- const: aux
- const: cfg
- const: bus_master
- const: bus_slave
- const: slave_q2a
interrupts:
minItems: 3
maxItems: 3
interrupt-names:
minItems: 3
maxItems: 3
unevaluatedProperties: false unevaluatedProperties: false
......
...@@ -870,30 +870,40 @@ static struct dw_edma_plat_ops dw_pcie_edma_ops = { ...@@ -870,30 +870,40 @@ static struct dw_edma_plat_ops dw_pcie_edma_ops = {
.irq_vector = dw_pcie_edma_irq_vector, .irq_vector = dw_pcie_edma_irq_vector,
}; };
static int dw_pcie_edma_find_chip(struct dw_pcie *pci) static void dw_pcie_edma_init_data(struct dw_pcie *pci)
{
pci->edma.dev = pci->dev;
if (!pci->edma.ops)
pci->edma.ops = &dw_pcie_edma_ops;
pci->edma.flags |= DW_EDMA_CHIP_LOCAL;
}
static int dw_pcie_edma_find_mf(struct dw_pcie *pci)
{ {
u32 val; u32 val;
/*
* Bail out finding the mapping format if it is already set by the glue
* driver. Also ensure that the edma.reg_base is pointing to a valid
* memory region.
*/
if (pci->edma.mf != EDMA_MF_EDMA_LEGACY)
return pci->edma.reg_base ? 0 : -ENODEV;
/* /*
* Indirect eDMA CSRs access has been completely removed since v5.40a * Indirect eDMA CSRs access has been completely removed since v5.40a
* thus no space is now reserved for the eDMA channels viewport and * thus no space is now reserved for the eDMA channels viewport and
* former DMA CTRL register is no longer fixed to FFs. * former DMA CTRL register is no longer fixed to FFs.
*
* Note that Renesas R-Car S4-8's PCIe controllers for unknown reason
* have zeros in the eDMA CTRL register even though the HW-manual
* explicitly states there must FFs if the unrolled mapping is enabled.
* For such cases the low-level drivers are supposed to manually
* activate the unrolled mapping to bypass the auto-detection procedure.
*/ */
if (dw_pcie_ver_is_ge(pci, 540A) || dw_pcie_cap_is(pci, EDMA_UNROLL)) if (dw_pcie_ver_is_ge(pci, 540A))
val = 0xFFFFFFFF; val = 0xFFFFFFFF;
else else
val = dw_pcie_readl_dbi(pci, PCIE_DMA_VIEWPORT_BASE + PCIE_DMA_CTRL); val = dw_pcie_readl_dbi(pci, PCIE_DMA_VIEWPORT_BASE + PCIE_DMA_CTRL);
if (val == 0xFFFFFFFF && pci->edma.reg_base) { if (val == 0xFFFFFFFF && pci->edma.reg_base) {
pci->edma.mf = EDMA_MF_EDMA_UNROLL; pci->edma.mf = EDMA_MF_EDMA_UNROLL;
val = dw_pcie_readl_dma(pci, PCIE_DMA_CTRL);
} else if (val != 0xFFFFFFFF) { } else if (val != 0xFFFFFFFF) {
pci->edma.mf = EDMA_MF_EDMA_LEGACY; pci->edma.mf = EDMA_MF_EDMA_LEGACY;
...@@ -902,15 +912,25 @@ static int dw_pcie_edma_find_chip(struct dw_pcie *pci) ...@@ -902,15 +912,25 @@ static int dw_pcie_edma_find_chip(struct dw_pcie *pci)
return -ENODEV; return -ENODEV;
} }
pci->edma.dev = pci->dev; return 0;
}
if (!pci->edma.ops) static int dw_pcie_edma_find_channels(struct dw_pcie *pci)
pci->edma.ops = &dw_pcie_edma_ops; {
u32 val;
pci->edma.flags |= DW_EDMA_CHIP_LOCAL; /*
* Autodetect the read/write channels count only for non-HDMA platforms.
* HDMA platforms with native CSR mapping doesn't support autodetect,
* so the glue drivers should've passed the valid count already. If not,
* the below sanity check will catch it.
*/
if (pci->edma.mf != EDMA_MF_HDMA_NATIVE) {
val = dw_pcie_readl_dma(pci, PCIE_DMA_CTRL);
pci->edma.ll_wr_cnt = FIELD_GET(PCIE_DMA_NUM_WR_CHAN, val); pci->edma.ll_wr_cnt = FIELD_GET(PCIE_DMA_NUM_WR_CHAN, val);
pci->edma.ll_rd_cnt = FIELD_GET(PCIE_DMA_NUM_RD_CHAN, val); pci->edma.ll_rd_cnt = FIELD_GET(PCIE_DMA_NUM_RD_CHAN, val);
}
/* Sanity check the channels count if the mapping was incorrect */ /* Sanity check the channels count if the mapping was incorrect */
if (!pci->edma.ll_wr_cnt || pci->edma.ll_wr_cnt > EDMA_MAX_WR_CH || if (!pci->edma.ll_wr_cnt || pci->edma.ll_wr_cnt > EDMA_MAX_WR_CH ||
...@@ -920,6 +940,19 @@ static int dw_pcie_edma_find_chip(struct dw_pcie *pci) ...@@ -920,6 +940,19 @@ static int dw_pcie_edma_find_chip(struct dw_pcie *pci)
return 0; return 0;
} }
static int dw_pcie_edma_find_chip(struct dw_pcie *pci)
{
int ret;
dw_pcie_edma_init_data(pci);
ret = dw_pcie_edma_find_mf(pci);
if (ret)
return ret;
return dw_pcie_edma_find_channels(pci);
}
static int dw_pcie_edma_irq_verify(struct dw_pcie *pci) static int dw_pcie_edma_irq_verify(struct dw_pcie *pci)
{ {
struct platform_device *pdev = to_platform_device(pci->dev); struct platform_device *pdev = to_platform_device(pci->dev);
......
...@@ -51,9 +51,8 @@ ...@@ -51,9 +51,8 @@
/* DWC PCIe controller capabilities */ /* DWC PCIe controller capabilities */
#define DW_PCIE_CAP_REQ_RES 0 #define DW_PCIE_CAP_REQ_RES 0
#define DW_PCIE_CAP_EDMA_UNROLL 1 #define DW_PCIE_CAP_IATU_UNROLL 1
#define DW_PCIE_CAP_IATU_UNROLL 2 #define DW_PCIE_CAP_CDM_CHECK 2
#define DW_PCIE_CAP_CDM_CHECK 3
#define dw_pcie_cap_is(_pci, _cap) \ #define dw_pcie_cap_is(_pci, _cap) \
test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps) test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps)
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#define PARF_DBI_BASE_ADDR_HI 0x354 #define PARF_DBI_BASE_ADDR_HI 0x354
#define PARF_SLV_ADDR_SPACE_SIZE 0x358 #define PARF_SLV_ADDR_SPACE_SIZE 0x358
#define PARF_SLV_ADDR_SPACE_SIZE_HI 0x35c #define PARF_SLV_ADDR_SPACE_SIZE_HI 0x35c
#define PARF_NO_SNOOP_OVERIDE 0x3d4
#define PARF_ATU_BASE_ADDR 0x634 #define PARF_ATU_BASE_ADDR 0x634
#define PARF_ATU_BASE_ADDR_HI 0x638 #define PARF_ATU_BASE_ADDR_HI 0x638
#define PARF_SRIS_MODE 0x644 #define PARF_SRIS_MODE 0x644
...@@ -86,6 +87,10 @@ ...@@ -86,6 +87,10 @@
#define PARF_DEBUG_INT_CFG_BUS_MASTER_EN BIT(2) #define PARF_DEBUG_INT_CFG_BUS_MASTER_EN BIT(2)
#define PARF_DEBUG_INT_RADM_PM_TURNOFF BIT(3) #define PARF_DEBUG_INT_RADM_PM_TURNOFF BIT(3)
/* PARF_NO_SNOOP_OVERIDE register fields */
#define WR_NO_SNOOP_OVERIDE_EN BIT(1)
#define RD_NO_SNOOP_OVERIDE_EN BIT(3)
/* PARF_DEVICE_TYPE register fields */ /* PARF_DEVICE_TYPE register fields */
#define PARF_DEVICE_TYPE_EP 0x0 #define PARF_DEVICE_TYPE_EP 0x0
...@@ -149,6 +154,16 @@ enum qcom_pcie_ep_link_status { ...@@ -149,6 +154,16 @@ enum qcom_pcie_ep_link_status {
QCOM_PCIE_EP_LINK_DOWN, QCOM_PCIE_EP_LINK_DOWN,
}; };
/**
* struct qcom_pcie_ep_cfg - Per SoC config struct
* @hdma_support: HDMA support on this SoC
* @override_no_snoop: Override NO_SNOOP attribute in TLP to enable cache snooping
*/
struct qcom_pcie_ep_cfg {
bool hdma_support;
bool override_no_snoop;
};
/** /**
* struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller * struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller
* @pci: Designware PCIe controller struct * @pci: Designware PCIe controller struct
...@@ -167,6 +182,7 @@ enum qcom_pcie_ep_link_status { ...@@ -167,6 +182,7 @@ enum qcom_pcie_ep_link_status {
* @num_clks: PCIe clocks count * @num_clks: PCIe clocks count
* @perst_en: Flag for PERST enable * @perst_en: Flag for PERST enable
* @perst_sep_en: Flag for PERST separation enable * @perst_sep_en: Flag for PERST separation enable
* @cfg: PCIe EP config struct
* @link_status: PCIe Link status * @link_status: PCIe Link status
* @global_irq: Qualcomm PCIe specific Global IRQ * @global_irq: Qualcomm PCIe specific Global IRQ
* @perst_irq: PERST# IRQ * @perst_irq: PERST# IRQ
...@@ -194,6 +210,7 @@ struct qcom_pcie_ep { ...@@ -194,6 +210,7 @@ struct qcom_pcie_ep {
u32 perst_en; u32 perst_en;
u32 perst_sep_en; u32 perst_sep_en;
const struct qcom_pcie_ep_cfg *cfg;
enum qcom_pcie_ep_link_status link_status; enum qcom_pcie_ep_link_status link_status;
int global_irq; int global_irq;
int perst_irq; int perst_irq;
...@@ -489,6 +506,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) ...@@ -489,6 +506,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
val |= BIT(8); val |= BIT(8);
writel_relaxed(val, pcie_ep->parf + PARF_LTSSM); writel_relaxed(val, pcie_ep->parf + PARF_LTSSM);
if (pcie_ep->cfg && pcie_ep->cfg->override_no_snoop)
writel_relaxed(WR_NO_SNOOP_OVERIDE_EN | RD_NO_SNOOP_OVERIDE_EN,
pcie_ep->parf + PARF_NO_SNOOP_OVERIDE);
return 0; return 0;
err_disable_resources: err_disable_resources:
...@@ -500,12 +521,6 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) ...@@ -500,12 +521,6 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
static void qcom_pcie_perst_assert(struct dw_pcie *pci) static void qcom_pcie_perst_assert(struct dw_pcie *pci)
{ {
struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci); struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci);
struct device *dev = pci->dev;
if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED) {
dev_dbg(dev, "Link is already disabled\n");
return;
}
pci_epc_deinit_notify(pci->ep.epc); pci_epc_deinit_notify(pci->ep.epc);
dw_pcie_ep_cleanup(&pci->ep); dw_pcie_ep_cleanup(&pci->ep);
...@@ -817,6 +832,14 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev) ...@@ -817,6 +832,14 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
pcie_ep->pci.ops = &pci_ops; pcie_ep->pci.ops = &pci_ops;
pcie_ep->pci.ep.ops = &pci_ep_ops; pcie_ep->pci.ep.ops = &pci_ep_ops;
pcie_ep->pci.edma.nr_irqs = 1; pcie_ep->pci.edma.nr_irqs = 1;
pcie_ep->cfg = of_device_get_match_data(dev);
if (pcie_ep->cfg && pcie_ep->cfg->hdma_support) {
pcie_ep->pci.edma.ll_wr_cnt = 8;
pcie_ep->pci.edma.ll_rd_cnt = 8;
pcie_ep->pci.edma.mf = EDMA_MF_HDMA_NATIVE;
}
platform_set_drvdata(pdev, pcie_ep); platform_set_drvdata(pdev, pcie_ep);
ret = qcom_pcie_ep_get_resources(pdev, pcie_ep); ret = qcom_pcie_ep_get_resources(pdev, pcie_ep);
...@@ -875,7 +898,13 @@ static void qcom_pcie_ep_remove(struct platform_device *pdev) ...@@ -875,7 +898,13 @@ static void qcom_pcie_ep_remove(struct platform_device *pdev)
qcom_pcie_disable_resources(pcie_ep); qcom_pcie_disable_resources(pcie_ep);
} }
static const struct qcom_pcie_ep_cfg cfg_1_34_0 = {
.hdma_support = true,
.override_no_snoop = true,
};
static const struct of_device_id qcom_pcie_ep_match[] = { static const struct of_device_id qcom_pcie_ep_match[] = {
{ .compatible = "qcom,sa8775p-pcie-ep", .data = &cfg_1_34_0},
{ .compatible = "qcom,sdx55-pcie-ep", }, { .compatible = "qcom,sdx55-pcie-ep", },
{ .compatible = "qcom,sm8450-pcie-ep", }, { .compatible = "qcom,sm8450-pcie-ep", },
{ } { }
......
This diff is collapsed.
...@@ -255,7 +255,7 @@ static struct rcar_gen4_pcie *rcar_gen4_pcie_alloc(struct platform_device *pdev) ...@@ -255,7 +255,7 @@ static struct rcar_gen4_pcie *rcar_gen4_pcie_alloc(struct platform_device *pdev)
rcar->dw.ops = &dw_pcie_ops; rcar->dw.ops = &dw_pcie_ops;
rcar->dw.dev = dev; rcar->dw.dev = dev;
rcar->pdev = pdev; rcar->pdev = pdev;
dw_pcie_cap_set(&rcar->dw, EDMA_UNROLL); rcar->dw.edma.mf = EDMA_MF_EDMA_UNROLL;
dw_pcie_cap_set(&rcar->dw, REQ_RES); dw_pcie_cap_set(&rcar->dw, REQ_RES);
platform_set_drvdata(pdev, rcar); platform_set_drvdata(pdev, rcar);
......
...@@ -137,6 +137,7 @@ static const struct pci_epf_mhi_ep_info sa8775p_info = { ...@@ -137,6 +137,7 @@ static const struct pci_epf_mhi_ep_info sa8775p_info = {
.epf_flags = PCI_BASE_ADDRESS_MEM_TYPE_32, .epf_flags = PCI_BASE_ADDRESS_MEM_TYPE_32,
.msi_count = 32, .msi_count = 32,
.mru = 0x8000, .mru = 0x8000,
.flags = MHI_EPF_USE_DMA,
}; };
struct pci_epf_mhi { struct pci_epf_mhi {
......
...@@ -6100,24 +6100,7 @@ int pcie_link_speed_mbps(struct pci_dev *pdev) ...@@ -6100,24 +6100,7 @@ int pcie_link_speed_mbps(struct pci_dev *pdev)
if (err) if (err)
return err; return err;
switch (to_pcie_link_speed(lnksta)) { return pcie_dev_speed_mbps(to_pcie_link_speed(lnksta));
case PCIE_SPEED_2_5GT:
return 2500;
case PCIE_SPEED_5_0GT:
return 5000;
case PCIE_SPEED_8_0GT:
return 8000;
case PCIE_SPEED_16_0GT:
return 16000;
case PCIE_SPEED_32_0GT:
return 32000;
case PCIE_SPEED_64_0GT:
return 64000;
default:
break;
}
return -EINVAL;
} }
EXPORT_SYMBOL(pcie_link_speed_mbps); EXPORT_SYMBOL(pcie_link_speed_mbps);
......
...@@ -326,6 +326,28 @@ void pci_bus_put(struct pci_bus *bus); ...@@ -326,6 +326,28 @@ void pci_bus_put(struct pci_bus *bus);
(speed) == PCIE_SPEED_2_5GT ? 2500*8/10 : \ (speed) == PCIE_SPEED_2_5GT ? 2500*8/10 : \
0) 0)
static inline int pcie_dev_speed_mbps(enum pci_bus_speed speed)
{
switch (speed) {
case PCIE_SPEED_2_5GT:
return 2500;
case PCIE_SPEED_5_0GT:
return 5000;
case PCIE_SPEED_8_0GT:
return 8000;
case PCIE_SPEED_16_0GT:
return 16000;
case PCIE_SPEED_32_0GT:
return 32000;
case PCIE_SPEED_64_0GT:
return 64000;
default:
break;
}
return -EINVAL;
}
const char *pci_speed_string(enum pci_bus_speed speed); const char *pci_speed_string(enum pci_bus_speed speed);
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev); enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev);
enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment