Skip to content

Commit

Permalink
Merge branch 'pci/controller/endpoint'
Browse files Browse the repository at this point in the history
- Change "PCI Endpoint Virtual NTB driver" Kconfig prompt to be different
  from "PCI Endpoint NTB driver" (Shunsuke Mie)

- Automatically create a function specific attributes group for endpoint
  drivers to avoid reference counting issues (Damien Le Moal)

- Move and unexport pci_epf_type_add_cfs() (Damien Le Moal)

- Reinitialize EPF test DMA transfer completion before submitting it to
  avoid losing the completion notification (Damien Le Moal)

- Fix EPF test DMA transfer completion detection (Damien Le Moal)

- Submit EPF test DMA transfers with dmaengine_submit(), not tx_submit()
  (Damien Le Moal)

- Simplify EPF test read/write/copy functions (Damien Le Moal)

- Simplify EPF test "raise IRQ" interface (Damien Le Moal)

- Simplify EPF test IRQ command execution (Damien Le Moal)

- Improve EPF test command/status register handling (Damien Le Moal)

- Free IRQs before removing device (Damien Le Moal)

- Reinitialize IRQ completions for every test (Damien Le Moal)

- Don't write status in IRQ handler to avoid race (Damien Le Moal)

- Fix dma_chan direction in data transfer test (Yoshihiro Shimoda)

- Return pci_epf_type_add_cfs() error if EPF has no driver (Damien Le Moal)

- Add kernel-doc for pci_epc_raise_irq() and pci_epc_map_msi_irq() MSI
  vector parameters (Manivannan Sadhasivam)

- Pass EPF device ID to driver probe functions (Manivannan Sadhasivam)

- Return -EALREADY if EPC has already been started/stopped (Manivannan
  Sadhasivam)

- Add linkdown notifier support and use it in qcom-ep (Manivannan
  Sadhasivam)

- Add Bus Master Enable event support and use it in qcom-ep (Manivannan
  Sadhasivam)

- Add Qualcomm Modem Host Interface (MHI) endpoint driver (Manivannan
  Sadhasivam)

- Add Layerscape PME interrupt handling to manage link-up notification
  (Frank Li)

* pci/controller/endpoint:
  PCI: layerscape: Add the endpoint linkup notifier support
  PCI: endpoint: pci-epf-vntb: Fix typo in comments
  MAINTAINERS: Add PCI MHI endpoint function driver under MHI bus
  PCI: endpoint: Add PCI Endpoint function driver for MHI bus
  PCI: qcom-ep: Add support for BME notification
  PCI: qcom-ep: Add support for Link down notification
  PCI: endpoint: Add BME notifier support
  PCI: endpoint: Add linkdown notifier support
  PCI: endpoint: Return error if EPC is started/stopped multiple times
  PCI: endpoint: Pass EPF device ID to the probe function
  PCI: endpoint: Add missing documentation about the MSI/MSI-X range
  PCI: endpoint: Improve pci_epf_type_add_cfs()
  PCI: endpoint: functions/pci-epf-test: Fix dma_chan direction
  misc: pci_endpoint_test: Simplify pci_endpoint_test_msi_irq()
  misc: pci_endpoint_test: Do not write status in IRQ handler
  misc: pci_endpoint_test: Re-init completion for every test
  misc: pci_endpoint_test: Free IRQs before removing the device
  PCI: epf-test: Simplify transfers result print
  PCI: epf-test: Simplify DMA support checks
  PCI: epf-test: Cleanup request result handling
  PCI: epf-test: Cleanup pci_epf_test_cmd_handler()
  PCI: epf-test: Improve handling of command and status registers
  PCI: epf-test: Simplify IRQ test commands execution
  PCI: epf-test: Simplify pci_epf_test_raise_irq()
  PCI: epf-test: Simplify read/write/copy test functions
  PCI: epf-test: Use dmaengine_submit() to initiate DMA transfer
  PCI: epf-test: Fix DMA transfer completion detection
  PCI: epf-test: Fix DMA transfer completion initialization
  PCI: endpoint: Move pci_epf_type_add_cfs() code
  PCI: endpoint: Automatically create a function specific attributes group
  PCI: endpoint: Fix a Kconfig prompt of vNTB driver
  • Loading branch information
Bjorn Helgaas committed Jun 26, 2023
2 parents b5abb12 + 061cbfa commit d8c226a
Show file tree
Hide file tree
Showing 17 changed files with 848 additions and 246 deletions.
11 changes: 4 additions & 7 deletions Documentation/PCI/endpoint/pci-ntb-howto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,10 @@ commands can be used::
# echo 0x104c > functions/pci_epf_ntb/func1/vendorid
# echo 0xb00d > functions/pci_epf_ntb/func1/deviceid

In order to configure NTB specific attributes, a new sub-directory to func1
should be created::

# mkdir functions/pci_epf_ntb/func1/pci_epf_ntb.0/

The NTB function driver will populate this directory with various attributes
that can be configured by the user::
The PCI endpoint framework also automatically creates a sub-directory in the
function attribute directory. This sub-directory has the same name as the name
of the function device and is populated with the following NTB specific
attributes that can be configured by the user::

# ls functions/pci_epf_ntb/func1/pci_epf_ntb.0/
db_count mw1 mw2 mw3 mw4 num_mws
Expand Down
11 changes: 4 additions & 7 deletions Documentation/PCI/endpoint/pci-vntb-howto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,10 @@ commands can be used::
# echo 0x1957 > functions/pci_epf_vntb/func1/vendorid
# echo 0x0809 > functions/pci_epf_vntb/func1/deviceid

In order to configure NTB specific attributes, a new sub-directory to func1
should be created::

# mkdir functions/pci_epf_vntb/func1/pci_epf_vntb.0/

The NTB function driver will populate this directory with various attributes
that can be configured by the user::
The PCI endpoint framework also automatically creates a sub-directory in the
function attribute directory. This sub-directory has the same name as the name
of the function device and is populated with the following NTB specific
attributes that can be configured by the user::

# ls functions/pci_epf_vntb/func1/pci_epf_vntb.0/
db_count mw1 mw2 mw3 mw4 num_mws
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -13629,6 +13629,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git
F: Documentation/ABI/stable/sysfs-bus-mhi
F: Documentation/mhi/
F: drivers/bus/mhi/
F: drivers/pci/endpoint/functions/pci-epf-mhi.c
F: include/linux/mhi.h

MICROBLAZE ARCHITECTURE
Expand Down
25 changes: 11 additions & 14 deletions drivers/misc/pci_endpoint_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,7 @@ static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
if (reg & STATUS_IRQ_RAISED) {
test->last_irq = irq;
complete(&test->irq_raised);
reg &= ~STATUS_IRQ_RAISED;
}
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS,
reg);

return IRQ_HANDLED;
}
Expand Down Expand Up @@ -316,21 +313,17 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
struct pci_dev *pdev = test->pdev;

pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
msix == false ? IRQ_TYPE_MSI :
IRQ_TYPE_MSIX);
msix ? IRQ_TYPE_MSIX : IRQ_TYPE_MSI);
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
msix == false ? COMMAND_RAISE_MSI_IRQ :
COMMAND_RAISE_MSIX_IRQ);
msix ? COMMAND_RAISE_MSIX_IRQ :
COMMAND_RAISE_MSI_IRQ);
val = wait_for_completion_timeout(&test->irq_raised,
msecs_to_jiffies(1000));
if (!val)
return false;

if (pci_irq_vector(pdev, msi_num - 1) == test->last_irq)
return true;

return false;
return pci_irq_vector(pdev, msi_num - 1) == test->last_irq;
}

static int pci_endpoint_test_validate_xfer_params(struct device *dev,
Expand Down Expand Up @@ -729,6 +722,10 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
struct pci_dev *pdev = test->pdev;

mutex_lock(&test->mutex);

reinit_completion(&test->irq_raised);
test->last_irq = -ENODATA;

switch (cmd) {
case PCITEST_BAR:
bar = arg;
Expand Down Expand Up @@ -938,6 +935,9 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
if (id < 0)
return;

pci_endpoint_test_release_irq(test);
pci_endpoint_test_free_irq_vectors(test);

misc_deregister(&test->miscdev);
kfree(misc_device->name);
kfree(test->name);
Expand All @@ -947,9 +947,6 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
pci_iounmap(pdev, test->bar[bar]);
}

pci_endpoint_test_release_irq(test);
pci_endpoint_test_free_irq_vectors(test);

pci_release_regions(pdev);
pci_disable_device(pdev);
}
Expand Down
100 changes: 99 additions & 1 deletion drivers/pci/controller/dwc/pci-layerscape-ep.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@

#include "pcie-designware.h"

#define PEX_PF0_CONFIG 0xC0014
#define PEX_PF0_CFG_READY BIT(0)

/* PEX PFa PCIE PME and message interrupt registers*/
#define PEX_PF0_PME_MES_DR 0xC0020
#define PEX_PF0_PME_MES_DR_LUD BIT(7)
#define PEX_PF0_PME_MES_DR_LDD BIT(9)
#define PEX_PF0_PME_MES_DR_HRD BIT(10)

#define PEX_PF0_PME_MES_IER 0xC0028
#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)

#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)

struct ls_pcie_ep_drvdata {
Expand All @@ -30,8 +44,84 @@ struct ls_pcie_ep {
struct dw_pcie *pci;
struct pci_epc_features *ls_epc;
const struct ls_pcie_ep_drvdata *drvdata;
int irq;
bool big_endian;
};

static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
{
struct dw_pcie *pci = pcie->pci;

if (pcie->big_endian)
return ioread32be(pci->dbi_base + offset);
else
return ioread32(pci->dbi_base + offset);
}

static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset, u32 value)
{
struct dw_pcie *pci = pcie->pci;

if (pcie->big_endian)
iowrite32be(value, pci->dbi_base + offset);
else
iowrite32(value, pci->dbi_base + offset);
}

static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
{
struct ls_pcie_ep *pcie = dev_id;
struct dw_pcie *pci = pcie->pci;
u32 val, cfg;

val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);

if (!val)
return IRQ_NONE;

if (val & PEX_PF0_PME_MES_DR_LUD) {
cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
cfg |= PEX_PF0_CFG_READY;
ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
dw_pcie_ep_linkup(&pci->ep);

dev_dbg(pci->dev, "Link up\n");
} else if (val & PEX_PF0_PME_MES_DR_LDD) {
dev_dbg(pci->dev, "Link down\n");
} else if (val & PEX_PF0_PME_MES_DR_HRD) {
dev_dbg(pci->dev, "Hot reset\n");
}

return IRQ_HANDLED;
}

static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
struct platform_device *pdev)
{
u32 val;
int ret;

pcie->irq = platform_get_irq_byname(pdev, "pme");
if (pcie->irq < 0)
return pcie->irq;

ret = devm_request_irq(&pdev->dev, pcie->irq, ls_pcie_ep_event_handler,
IRQF_SHARED, pdev->name, pcie);
if (ret) {
dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
return ret;
}

/* Enable interrupts */
val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
PEX_PF0_PME_MES_IER_LUDIE;
ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);

return 0;
}

static const struct pci_epc_features*
ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
Expand Down Expand Up @@ -125,6 +215,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
struct ls_pcie_ep *pcie;
struct pci_epc_features *ls_epc;
struct resource *dbi_base;
int ret;

pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
if (!pcie)
Expand All @@ -144,6 +235,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ops = pcie->drvdata->dw_pcie_ops;

ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
ls_epc->linkup_notifier = true;

pcie->pci = pci;
pcie->ls_epc = ls_epc;
Expand All @@ -155,9 +247,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)

pci->ep.ops = &ls_pcie_ep_ops;

pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian");

platform_set_drvdata(pdev, pcie);

return dw_pcie_ep_init(&pci->ep);
ret = dw_pcie_ep_init(&pci->ep);
if (ret)
return ret;

return ls_pcie_ep_interrupt_init(pcie, pdev);
}

static struct platform_driver ls_pcie_ep_driver = {
Expand Down
2 changes: 2 additions & 0 deletions drivers/pci/controller/dwc/pcie-qcom-ep.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,9 +569,11 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int irq, void *data)
if (FIELD_GET(PARF_INT_ALL_LINK_DOWN, status)) {
dev_dbg(dev, "Received Linkdown event\n");
pcie_ep->link_status = QCOM_PCIE_EP_LINK_DOWN;
pci_epc_linkdown(pci->ep.epc);
} else if (FIELD_GET(PARF_INT_ALL_BME, status)) {
dev_dbg(dev, "Received BME event. Link is enabled!\n");
pcie_ep->link_status = QCOM_PCIE_EP_LINK_ENABLED;
pci_epc_bme_notify(pci->ep.epc);
} else if (FIELD_GET(PARF_INT_ALL_PM_TURNOFF, status)) {
dev_dbg(dev, "Received PM Turn-off event! Entering L23\n");
val = readl_relaxed(pcie_ep->parf + PARF_PM_CTRL);
Expand Down
12 changes: 11 additions & 1 deletion drivers/pci/endpoint/functions/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ config PCI_EPF_NTB
If in doubt, say "N" to disable Endpoint NTB driver.

config PCI_EPF_VNTB
tristate "PCI Endpoint NTB driver"
tristate "PCI Endpoint Virtual NTB driver"
depends on PCI_ENDPOINT
depends on NTB
select CONFIGFS_FS
Expand All @@ -37,3 +37,13 @@ config PCI_EPF_VNTB
between PCI Root Port and PCIe Endpoint.

If in doubt, say "N" to disable Endpoint NTB driver.

config PCI_EPF_MHI
tristate "PCI Endpoint driver for MHI bus"
depends on PCI_ENDPOINT && MHI_BUS_EP
help
Enable this configuration option to enable the PCI Endpoint
driver for Modem Host Interface (MHI) bus in Qualcomm Endpoint
devices such as SDX55.

If in doubt, say "N" to disable Endpoint driver for MHI bus.
1 change: 1 addition & 0 deletions drivers/pci/endpoint/functions/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
obj-$(CONFIG_PCI_EPF_TEST) += pci-epf-test.o
obj-$(CONFIG_PCI_EPF_NTB) += pci-epf-ntb.o
obj-$(CONFIG_PCI_EPF_VNTB) += pci-epf-vntb.o
obj-$(CONFIG_PCI_EPF_MHI) += pci-epf-mhi.o
Loading

0 comments on commit d8c226a

Please sign in to comment.