Date   

[RFC PATCH 4.19.y-cip 18/50] PCI: endpoint: Set endpoint controller pointer to NULL

Lad Prabhakar
 

From: Alan Mikhak <alan.mikhak@...>

commit db7a62482d2f6a63f36f30f62c4cbf1e53035719 upstream.

Set endpoint controller pointer to NULL in pci_epc_remove_epf()
to avoid -EBUSY on subsequent call to pci_epc_add_epf().

Add a check for NULL endpoint function pointer.

Signed-off-by: Alan Mikhak <alan.mikhak@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Acked-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/pci-epc-core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index e4712a0f249c..2091508c1620 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -519,11 +519,12 @@ void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf)
{
unsigned long flags;

- if (!epc || IS_ERR(epc))
+ if (!epc || IS_ERR(epc) || !epf)
return;

spin_lock_irqsave(&epc->lock, flags);
list_del(&epf->list);
+ epf->epc = NULL;
spin_unlock_irqrestore(&epc->lock, flags);
}
EXPORT_SYMBOL_GPL(pci_epc_remove_epf);
--
2.17.1


[RFC PATCH 4.19.y-cip 17/50] PCI: endpoint: Add support to specify alignment for buffers allocated to BARs

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 2a9a801620efac92885fc9cd53594c0b9aba87a4 upstream.

The address that is allocated using pci_epf_alloc_space() is
directly written to the target address of the Inbound Address
Translation unit (ie the HW component implementing inbound address
decoding) on endpoint controllers.

Designware IP [1] has a configuration parameter (CX_ATU_MIN_REGION_SIZE
[2]) which has 64KB as default value and the lower 16 bits of the Base,
Limit and Target registers of the Inbound ATU are fixed to zero. If the
programmed memory address is not aligned to 64 KB boundary this causes
memory corruption.

Modify pci_epf_alloc_space() API to take alignment size as argument in
order to allocate buffers to be mapped to BARs with an alignment that
suits the platform where they are used.

Add an 'align' parameter to epc_features which can be used by platform
drivers to specify the BAR allocation alignment requirements and use
this while invoking pci_epf_alloc_space().

[1] "I/O and MEM Match Modes" section in DesignWare Cores PCI Express
Controller Databook version 4.90a
[2] http://www.ti.com/lit/ug/spruid7c/spruid7c.pdf

Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 5 +++--
drivers/pci/endpoint/pci-epf-core.c | 10 ++++++++--
include/linux/pci-epc.h | 2 ++
include/linux/pci-epf.h | 3 ++-
4 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index ed5cd28b9572..27806987e93b 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -438,7 +438,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
epc_features = epf_test->epc_features;

base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
- test_reg_bar);
+ test_reg_bar, epc_features->align);
if (!base) {
dev_err(dev, "Failed to allocated register space\n");
return -ENOMEM;
@@ -453,7 +453,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
if (!!(epc_features->reserved_bar & (1 << bar)))
continue;

- base = pci_epf_alloc_space(epf, bar_size[bar], bar);
+ base = pci_epf_alloc_space(epf, bar_size[bar], bar,
+ epc_features->align);
if (!base)
dev_err(dev, "Failed to allocate space for BAR%d\n",
bar);
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 8bfdcd291196..fb1306de8f40 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -109,10 +109,12 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space);
* pci_epf_alloc_space() - allocate memory for the PCI EPF register space
* @size: the size of the memory that has to be allocated
* @bar: the BAR number corresponding to the allocated register space
+ * @align: alignment size for the allocation region
*
* Invoke to allocate memory for the PCI EPF register space.
*/
-void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
+void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
+ size_t align)
{
void *space;
struct device *dev = epf->epc->dev.parent;
@@ -120,7 +122,11 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)

if (size < 128)
size = 128;
- size = roundup_pow_of_two(size);
+
+ if (align)
+ size = ALIGN(size, align);
+ else
+ size = roundup_pow_of_two(size);

space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
if (!space) {
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index b3a3c0805603..0c12d69dde92 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -112,6 +112,7 @@ struct pci_epc {
* @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
* @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs
* @bar_fixed_size: Array specifying the size supported by each BAR
+ * @align: alignment size required for BAR buffer allocation
*/
struct pci_epc_features {
unsigned int linkup_notifier : 1;
@@ -120,6 +121,7 @@ struct pci_epc_features {
u8 reserved_bar;
u8 bar_fixed_64bit;
u64 bar_fixed_size[BAR_5 + 1];
+ size_t align;
};

#define to_pci_epc(device) container_of((device), struct pci_epc, dev)
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index ec02f58758c8..2d6f07556682 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -149,7 +149,8 @@ void pci_epf_destroy(struct pci_epf *epf);
int __pci_epf_register_driver(struct pci_epf_driver *driver,
struct module *owner);
void pci_epf_unregister_driver(struct pci_epf_driver *driver);
-void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar);
+void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
+ size_t align);
void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar);
int pci_epf_bind(struct pci_epf *epf);
void pci_epf_unbind(struct pci_epf *epf);
--
2.17.1


[RFC PATCH 4.19.y-cip 16/50] PCI: endpoint: Fix a potential NULL pointer dereference

Lad Prabhakar
 

From: Kangjie Lu <kjlu@...>

commit 507b820009a457afa78202da337bcb56791fbb12 upstream.

In case alloc_workqueue() fails, return -ENOMEM to avoid
potential NULL pointer dereferences.

Signed-off-by: Kangjie Lu <kjlu@...>
[lorenzo.pieralisi@...: commit log and code update]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index d0b91da49bf4..ed5cd28b9572 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -591,6 +591,11 @@ static int __init pci_epf_test_init(void)

kpcitest_workqueue = alloc_workqueue("kpcitest",
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
+ if (!kpcitest_workqueue) {
+ pr_err("Failed to allocate the kpcitest work queue\n");
+ return -ENOMEM;
+ }
+
ret = pci_epf_register_driver(&test_driver);
if (ret) {
pr_err("Failed to register pci epf test driver --> %d\n", ret);
--
2.17.1


[RFC PATCH 4.19.y-cip 15/50] PCI: endpoint: Remove features member in struct pci_epc

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 35ce0d7922d68021062a955407740d262f9ac811 upstream.

Since EPC features are now implemented using pci_epc_features and
all the EPC drivers are moved to using pci_epc_features, remove
features member in struct pci_epc and all the helper macros for
configuring the features.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
include/linux/pci-epc.h | 9 ---------
1 file changed, 9 deletions(-)

diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index dcaecf715b1c..b3a3c0805603 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -102,7 +102,6 @@ struct pci_epc {
struct config_group *group;
/* spinlock to protect against concurrent access of EP controller */
spinlock_t lock;
- unsigned int features;
};

/**
@@ -123,14 +122,6 @@ struct pci_epc_features {
u64 bar_fixed_size[BAR_5 + 1];
};

-#define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0)
-#define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3))
-#define EPC_FEATURE_MSIX_AVAILABLE BIT(4)
-#define EPC_FEATURE_SET_BAR(features, bar) \
- (features |= (EPC_FEATURE_BAR_MASK & (bar << 1)))
-#define EPC_FEATURE_GET_BAR(features) \
- ((features & EPC_FEATURE_BAR_MASK) >> 1)
-
#define to_pci_epc(device) container_of((device), struct pci_epc, dev)

#define pci_epc_create(dev, ops) \
--
2.17.1


[RFC PATCH 4.19.y-cip 14/50] PCI: designware-plat: Remove setting epc->features in Designware plat EP driver

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 92f2b028418c6f59f92703eed111136ca0d22c39 upstream.

Now that pci-epf-test uses get_features callback and
dw_plat_pcie_epc_features in Designware plat EP driver already indicates
it doesn't support linkup notification and is MSIX capable, remove setting
epc->features which is not used anymore by the endpoint function driver.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/dwc/pcie-designware-plat.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index bd0516afc86f..3be87126aef3 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -70,14 +70,10 @@ static const struct dw_pcie_ops dw_pcie_ops = {
static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- struct pci_epc *epc = ep->epc;
enum pci_barno bar;

for (bar = BAR_0; bar <= BAR_5; bar++)
dw_pcie_ep_reset_bar(pci, bar);
-
- epc->features |= EPC_FEATURE_NO_LINKUP_NOTIFIER;
- epc->features |= EPC_FEATURE_MSIX_AVAILABLE;
}

static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
--
2.17.1


[RFC PATCH 4.19.y-cip 13/50] PCI: rockchip: Remove pci_epf_linkup() from Rockchip EP driver

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit f1267978457e77ae7ddabe82ad48cf34f54e96fb upstream.

pci_epf_linkup() is intended to be invoked if the EPC supports linkup
notification. Now that pci-epf-test uses get_features callback, which
indicates Rockchip EP driver doesn't support linkup notification, remove
pci_epf_linkup() from Rockchip EP driver.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Acked-by: Shawn Lin <shawn.lin@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/pcie-rockchip-ep.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index ab6478334101..d743b0a48988 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -499,9 +499,6 @@ static int rockchip_pcie_ep_start(struct pci_epc *epc)

rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG);

- list_for_each_entry(epf, &epc->pci_epf, list)
- pci_epf_linkup(epf);
-
return 0;
}

--
2.17.1


[RFC PATCH 4.19.y-cip 12/50] PCI: cadence: Remove pci_epf_linkup() from Cadence EP driver

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit c274c9f4ea758bd6667a363f275e45275f2b5672 upstream.

pci_epf_linkup() is intended to be invoked if the EPC supports linkup
notification. Now that pci-epf-test uses the get_features() callback,
which indicates Cadence EP driver doesn't support the linkup notification,
remove pci_epf_linkup() from Cadence EP driver.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/pcie-cadence-ep.c | 12 ------------
1 file changed, 12 deletions(-)

diff --git a/drivers/pci/controller/pcie-cadence-ep.c b/drivers/pci/controller/pcie-cadence-ep.c
index 14c2545bb17e..def7820cb824 100644
--- a/drivers/pci/controller/pcie-cadence-ep.c
+++ b/drivers/pci/controller/pcie-cadence-ep.c
@@ -396,18 +396,6 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
cfg |= BIT(epf->func_no);
cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg);

- /*
- * The PCIe links are automatically established by the controller
- * once for all at powerup: the software can neither start nor stop
- * those links later at runtime.
- *
- * Then we only have to notify the EP core that our links are already
- * established. However we don't call directly pci_epc_linkup() because
- * we've already locked the epc->lock.
- */
- list_for_each_entry(epf, &epc->pci_epf, list)
- pci_epf_linkup(epf);
-
return 0;
}

--
2.17.1


[RFC PATCH 4.19.y-cip 11/50] PCI: pci-epf-test: Use pci_epc_get_features() to get EPC features

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 2c04c5b8eef797dca99699cfb55ff42dd3c12c23 upstream.

Use pci_epc_get_features() to get EPC features such as linkup
notifier support, MSI/MSIX capable, BAR configuration etc and use it
for configuring pci-epf-test. Since these features are now obtained
directly from EPC driver, remove pci_epf_test_data which was initially
added to have EPC features in endpoint function driver.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 87 ++++++++++++-------
1 file changed, 54 insertions(+), 33 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index a385927a9239..d0b91da49bf4 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -47,9 +47,8 @@ struct pci_epf_test {
void *reg[6];
struct pci_epf *epf;
enum pci_barno test_reg_bar;
- bool linkup_notifier;
- bool msix_available;
struct delayed_work cmd_handler;
+ const struct pci_epc_features *epc_features;
};

struct pci_epf_test_reg {
@@ -71,11 +70,6 @@ static struct pci_epf_header test_header = {
.interrupt_pin = PCI_INTERRUPT_INTA,
};

-struct pci_epf_test_data {
- enum pci_barno test_reg_bar;
- bool linkup_notifier;
-};
-
static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 };

static int pci_epf_test_copy(struct pci_epf_test *epf_test)
@@ -402,10 +396,16 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
struct device *dev = &epf->dev;
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+ const struct pci_epc_features *epc_features;
+
+ epc_features = epf_test->epc_features;

for (bar = BAR_0; bar <= BAR_5; bar++) {
epf_bar = &epf->bar[bar];

+ if (!!(epc_features->reserved_bar & (1 << bar)))
+ continue;
+
ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
if (ret) {
pci_epf_free_space(epf, epf_test->reg[bar], bar);
@@ -433,6 +433,9 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
void *base;
int bar;
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+ const struct pci_epc_features *epc_features;
+
+ epc_features = epf_test->epc_features;

base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
test_reg_bar);
@@ -446,6 +449,10 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
epf_bar = &epf->bar[bar];
if (bar == test_reg_bar)
continue;
+
+ if (!!(epc_features->reserved_bar & (1 << bar)))
+ continue;
+
base = pci_epf_alloc_space(epf, bar_size[bar], bar);
if (!base)
dev_err(dev, "Failed to allocate space for BAR%d\n",
@@ -458,25 +465,50 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
return 0;
}

+static void pci_epf_configure_bar(struct pci_epf *epf,
+ const struct pci_epc_features *epc_features)
+{
+ struct pci_epf_bar *epf_bar;
+ bool bar_fixed_64bit;
+ int i;
+
+ for (i = BAR_0; i <= BAR_5; i++) {
+ epf_bar = &epf->bar[i];
+ bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i));
+ if (bar_fixed_64bit)
+ epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+ if (epc_features->bar_fixed_size[i])
+ bar_size[i] = epc_features->bar_fixed_size[i];
+ }
+}
+
static int pci_epf_test_bind(struct pci_epf *epf)
{
int ret;
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
struct pci_epf_header *header = epf->header;
+ const struct pci_epc_features *epc_features;
+ enum pci_barno test_reg_bar = BAR_0;
struct pci_epc *epc = epf->epc;
struct device *dev = &epf->dev;
+ bool linkup_notifier = false;
+ bool msix_capable = false;
+ bool msi_capable = true;

if (WARN_ON_ONCE(!epc))
return -EINVAL;

- if (epc->features & EPC_FEATURE_NO_LINKUP_NOTIFIER)
- epf_test->linkup_notifier = false;
- else
- epf_test->linkup_notifier = true;
-
- epf_test->msix_available = epc->features & EPC_FEATURE_MSIX_AVAILABLE;
+ epc_features = pci_epc_get_features(epc, epf->func_no);
+ if (epc_features) {
+ linkup_notifier = epc_features->linkup_notifier;
+ msix_capable = epc_features->msix_capable;
+ msi_capable = epc_features->msi_capable;
+ test_reg_bar = pci_epc_get_first_free_bar(epc_features);
+ pci_epf_configure_bar(epf, epc_features);
+ }

- epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features);
+ epf_test->test_reg_bar = test_reg_bar;
+ epf_test->epc_features = epc_features;

ret = pci_epc_write_header(epc, epf->func_no, header);
if (ret) {
@@ -492,13 +524,15 @@ static int pci_epf_test_bind(struct pci_epf *epf)
if (ret)
return ret;

- ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
- if (ret) {
- dev_err(dev, "MSI configuration failed\n");
- return ret;
+ if (msi_capable) {
+ ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
+ if (ret) {
+ dev_err(dev, "MSI configuration failed\n");
+ return ret;
+ }
}

- if (epf_test->msix_available) {
+ if (msix_capable) {
ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts);
if (ret) {
dev_err(dev, "MSI-X configuration failed\n");
@@ -506,7 +540,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
}
}

- if (!epf_test->linkup_notifier)
+ if (!linkup_notifier)
queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);

return 0;
@@ -523,17 +557,6 @@ static int pci_epf_test_probe(struct pci_epf *epf)
{
struct pci_epf_test *epf_test;
struct device *dev = &epf->dev;
- const struct pci_epf_device_id *match;
- struct pci_epf_test_data *data;
- enum pci_barno test_reg_bar = BAR_0;
- bool linkup_notifier = true;
-
- match = pci_epf_match_device(pci_epf_test_ids, epf);
- data = (struct pci_epf_test_data *)match->driver_data;
- if (data) {
- test_reg_bar = data->test_reg_bar;
- linkup_notifier = data->linkup_notifier;
- }

epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL);
if (!epf_test)
@@ -541,8 +564,6 @@ static int pci_epf_test_probe(struct pci_epf *epf)

epf->header = &test_header;
epf_test->epf = epf;
- epf_test->test_reg_bar = test_reg_bar;
- epf_test->linkup_notifier = linkup_notifier;

INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler);

--
2.17.1


[RFC PATCH 4.19.y-cip 10/50] PCI: pci-epf-test: Do not allocate next BARs memory if current BAR is 64Bit

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit b866c56b66d88a632e2fa6b922c4ea051937acbd upstream.

It's useless to allocate memory for next BAR if the current BAR is a
64Bit BAR. Stop allocating memory for the next BAR, if the current
BARs flag indicates this is a 64Bit BAR.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index ad0efa4446ba..a385927a9239 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -429,6 +429,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
{
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
struct device *dev = &epf->dev;
+ struct pci_epf_bar *epf_bar;
void *base;
int bar;
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
@@ -442,6 +443,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
epf_test->reg[test_reg_bar] = base;

for (bar = BAR_0; bar <= BAR_5; bar++) {
+ epf_bar = &epf->bar[bar];
if (bar == test_reg_bar)
continue;
base = pci_epf_alloc_space(epf, bar_size[bar], bar);
@@ -449,6 +451,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
dev_err(dev, "Failed to allocate space for BAR%d\n",
bar);
epf_test->reg[bar] = base;
+ if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
+ bar++;
}

return 0;
--
2.17.1


[RFC PATCH 4.19.y-cip 09/50] PCI: pci-epf-test: Remove setting epf_bar flags in function driver

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 0342e9a797db42a7d4d083d10b5d3f38b0cfc193 upstream.

Now that pci_epf_alloc_space() sets BAR MEM TYPE flags as 64Bit or
32Bit based on size, remove setting it in function driver.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 4bbd26e8a9e2..ad0efa4446ba 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -406,10 +406,6 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
for (bar = BAR_0; bar <= BAR_5; bar++) {
epf_bar = &epf->bar[bar];

- epf_bar->flags |= upper_32_bits(epf_bar->size) ?
- PCI_BASE_ADDRESS_MEM_TYPE_64 :
- PCI_BASE_ADDRESS_MEM_TYPE_32;
-
ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
if (ret) {
pci_epf_free_space(epf, epf_test->reg[bar], bar);
--
2.17.1


[RFC PATCH 4.19.y-cip 08/50] PCI: endpoint: Fix pci_epf_alloc_space() to set correct MEM TYPE flags

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 5544d67ed11245ccb64099deb32831308297bf6b upstream.

pci_epf_alloc_space() sets the MEM TYPE flags to indicate a 32-bit
Base Address Register irrespective of the size. Fix it here to indicate
64-bit BAR if the size is > 2GB.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/pci-epf-core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 825fa24427a3..8bfdcd291196 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -131,7 +131,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
epf->bar[bar].phys_addr = phys_addr;
epf->bar[bar].size = size;
epf->bar[bar].barno = bar;
- epf->bar[bar].flags = PCI_BASE_ADDRESS_SPACE_MEMORY;
+ epf->bar[bar].flags |= upper_32_bits(size) ?
+ PCI_BASE_ADDRESS_MEM_TYPE_64 :
+ PCI_BASE_ADDRESS_MEM_TYPE_32;

return space;
}
--
2.17.1


[RFC PATCH 4.19.y-cip 07/50] PCI: endpoint: Add helper to get first unreserved BAR

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 1e9efe6c9976552e88c6e6feaca3a78b8cf5aaf6 upstream.

Add a helper function pci_epc_get_first_free_bar() to get the first
unreserved BAR that can be used for endpoint function.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/pci-epc-core.c | 23 +++++++++++++++++++++++
include/linux/pci-epc.h | 2 ++
2 files changed, 25 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 5a099479d9ab..e4712a0f249c 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -83,6 +83,29 @@ struct pci_epc *pci_epc_get(const char *epc_name)
}
EXPORT_SYMBOL_GPL(pci_epc_get);

+/**
+ * pci_epc_get_first_free_bar() - helper to get first unreserved BAR
+ * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
+ *
+ * Invoke to get the first unreserved BAR that can be used for endpoint
+ * function. For any incorrect value in reserved_bar return '0'.
+ */
+unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+ *epc_features)
+{
+ int free_bar;
+
+ if (!epc_features)
+ return 0;
+
+ free_bar = ffz(epc_features->reserved_bar);
+ if (free_bar > 5)
+ return 0;
+
+ return free_bar;
+}
+EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
+
/**
* pci_epc_get_features() - get the features supported by EPC
* @epc: the features supported by *this* EPC device will be returned
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index fcd5e5047546..dcaecf715b1c 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -183,6 +183,8 @@ int pci_epc_start(struct pci_epc *epc);
void pci_epc_stop(struct pci_epc *epc);
const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
u8 func_no);
+unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
+ *epc_features);
struct pci_epc *pci_epc_get(const char *epc_name);
void pci_epc_put(struct pci_epc *epc);

--
2.17.1


[RFC PATCH 4.19.y-cip 06/50] PCI: cadence: Populate ->get_features() cdns_pcie_epc_ops

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 67c777e6015d857a5e9662c68281d83d946d9b70 upstream.

Populate ->get_features() dw_pcie_ep_ops to return the EPC features
supported by Cadence PCIe endpoint controller.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/pcie-cadence-ep.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/pci/controller/pcie-cadence-ep.c b/drivers/pci/controller/pcie-cadence-ep.c
index c3a088910f48..14c2545bb17e 100644
--- a/drivers/pci/controller/pcie-cadence-ep.c
+++ b/drivers/pci/controller/pcie-cadence-ep.c
@@ -411,6 +411,18 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
return 0;
}

+static const struct pci_epc_features cdns_pcie_epc_features = {
+ .linkup_notifier = false,
+ .msi_capable = true,
+ .msix_capable = false,
+};
+
+static const struct pci_epc_features*
+cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+{
+ return &cdns_pcie_epc_features;
+}
+
static const struct pci_epc_ops cdns_pcie_epc_ops = {
.write_header = cdns_pcie_ep_write_header,
.set_bar = cdns_pcie_ep_set_bar,
@@ -421,6 +433,7 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = {
.get_msi = cdns_pcie_ep_get_msi,
.raise_irq = cdns_pcie_ep_raise_irq,
.start = cdns_pcie_ep_start,
+ .get_features = cdns_pcie_ep_get_features,
};

static const struct of_device_id cdns_pcie_ep_of_match[] = {
--
2.17.1


[RFC PATCH 4.19.y-cip 05/50] PCI: rockchip: Populate ->get_features() dw_pcie_ep_ops

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 146221768c74bbd969f968b61ec95a0254a6b311 upstream.

Populate ->get_features() dw_pcie_ep_ops to return the EPC features
supported by Rockchip PCIe endpoint controller.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/pcie-rockchip-ep.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index caf34661d38d..ab6478334101 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -505,6 +505,18 @@ static int rockchip_pcie_ep_start(struct pci_epc *epc)
return 0;
}

+static const struct pci_epc_features rockchip_pcie_epc_features = {
+ .linkup_notifier = false,
+ .msi_capable = true,
+ .msix_capable = false,
+};
+
+static const struct pci_epc_features*
+rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+{
+ return &rockchip_pcie_epc_features;
+}
+
static const struct pci_epc_ops rockchip_pcie_epc_ops = {
.write_header = rockchip_pcie_ep_write_header,
.set_bar = rockchip_pcie_ep_set_bar,
@@ -515,6 +527,7 @@ static const struct pci_epc_ops rockchip_pcie_epc_ops = {
.get_msi = rockchip_pcie_ep_get_msi,
.raise_irq = rockchip_pcie_ep_raise_irq,
.start = rockchip_pcie_ep_start,
+ .get_features = rockchip_pcie_ep_get_features,
};

static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,
--
2.17.1


[RFC PATCH 4.19.y-cip 04/50] PCI: pci-dra7xx: Populate ->get_features() dw_pcie_ep_ops

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 4894467e78619232a79e39c2f26ae8378c4500ed upstream.

Populate ->get_features() dw_pcie_ep_ops to return the EPC features
supported by DRA7xx PCIe endpoint controller.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/dwc/pci-dra7xx.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 412524aa1fde..49417092f5e3 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -390,9 +390,22 @@ static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
return 0;
}

+static const struct pci_epc_features dra7xx_pcie_epc_features = {
+ .linkup_notifier = true,
+ .msi_capable = true,
+ .msix_capable = false,
+};
+
+static const struct pci_epc_features*
+dra7xx_pcie_get_features(struct dw_pcie_ep *ep)
+{
+ return &dra7xx_pcie_epc_features;
+}
+
static struct dw_pcie_ep_ops pcie_ep_ops = {
.ep_init = dra7xx_pcie_ep_init,
.raise_irq = dra7xx_pcie_raise_irq,
+ .get_features = dra7xx_pcie_get_features,
};

static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
--
2.17.1


[RFC PATCH 4.19.y-cip 03/50] PCI: designware-plat: Populate ->get_features() dw_pcie_ep_ops

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 3b4322e589a630fe35944ced5852655fcc4a5d24 upstream.

Populate ->get_features() dw_pcie_ep_ops to return the EPC features
supported by Designware PCIe endpoint controller.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/dwc/pcie-designware-plat.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index c12bf794d69c..bd0516afc86f 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -100,9 +100,22 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
return 0;
}

+static const struct pci_epc_features dw_plat_pcie_epc_features = {
+ .linkup_notifier = false,
+ .msi_capable = true,
+ .msix_capable = true,
+};
+
+static const struct pci_epc_features*
+dw_plat_pcie_get_features(struct dw_pcie_ep *ep)
+{
+ return &dw_plat_pcie_epc_features;
+}
+
static struct dw_pcie_ep_ops pcie_ep_ops = {
.ep_init = dw_plat_pcie_ep_init,
.raise_irq = dw_plat_pcie_ep_raise_irq,
+ .get_features = dw_plat_pcie_get_features,
};

static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
--
2.17.1


[RFC PATCH 4.19.y-cip 02/50] PCI: dwc: Add ->get_features() callback function to dw_pcie_ep_ops

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit fee35cb76a54c87985410ea6aa12002e5d38b367 upstream.

Each platform using Designware PCIe core can support different set of
endpoint features. Add a new callback function ->get_features() in
dw_pcie_ep_ops so that each platform using Designware PCIe core can
advertise its supported features to the endpoint function driver.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 12 ++++++++++++
drivers/pci/controller/dwc/pcie-designware.h | 1 +
2 files changed, 13 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index a3d07d9c598b..d1bb4b852b6c 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -355,6 +355,17 @@ static int dw_pcie_ep_start(struct pci_epc *epc)
return pci->ops->start_link(pci);
}

+static const struct pci_epc_features*
+dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+{
+ struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+
+ if (!ep->ops->get_features)
+ return NULL;
+
+ return ep->ops->get_features(ep);
+}
+
static const struct pci_epc_ops epc_ops = {
.write_header = dw_pcie_ep_write_header,
.set_bar = dw_pcie_ep_set_bar,
@@ -368,6 +379,7 @@ static const struct pci_epc_ops epc_ops = {
.raise_irq = dw_pcie_ep_raise_irq,
.start = dw_pcie_ep_start,
.stop = dw_pcie_ep_stop,
+ .get_features = dw_pcie_ep_get_features,
};

int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 14dcf6646699..90f978f2d1b0 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -181,6 +181,7 @@ struct dw_pcie_ep_ops {
void (*ep_init)(struct dw_pcie_ep *ep);
int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
enum pci_epc_irq_type type, u16 interrupt_num);
+ const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep);
};

struct dw_pcie_ep {
--
2.17.1


[RFC PATCH 4.19.y-cip 01/50] PCI: endpoint: Add new pci_epc_ops to get EPC features

Lad Prabhakar
 

From: Kishon Vijay Abraham I <kishon@...>

commit 41cb8d189c9d4964df52a6f497cab7b301ae831b upstream.

Add a new pci_epc_ops ->get_features() to get the features
supported by the EPC. Since EPC can provide different features to
different functions, the ->get_features() ops takes _func_no_ as
an argument.

Tested-by: Gustavo Pimentel <gustavo.pimentel@...>
Signed-off-by: Kishon Vijay Abraham I <kishon@...>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/pci/endpoint/pci-epc-core.c | 30 +++++++++++++++++++++++++++++
include/linux/pci-epc.h | 22 +++++++++++++++++++++
2 files changed, 52 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 094dcc3203b8..5a099479d9ab 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -83,6 +83,36 @@ struct pci_epc *pci_epc_get(const char *epc_name)
}
EXPORT_SYMBOL_GPL(pci_epc_get);

+/**
+ * pci_epc_get_features() - get the features supported by EPC
+ * @epc: the features supported by *this* EPC device will be returned
+ * @func_no: the features supported by the EPC device specific to the
+ * endpoint function with func_no will be returned
+ *
+ * Invoke to get the features provided by the EPC which may be
+ * specific to an endpoint function. Returns pci_epc_features on success
+ * and NULL for any failures.
+ */
+const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
+ u8 func_no)
+{
+ const struct pci_epc_features *epc_features;
+ unsigned long flags;
+
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
+ return NULL;
+
+ if (!epc->ops->get_features)
+ return NULL;
+
+ spin_lock_irqsave(&epc->lock, flags);
+ epc_features = epc->ops->get_features(epc, func_no);
+ spin_unlock_irqrestore(&epc->lock, flags);
+
+ return epc_features;
+}
+EXPORT_SYMBOL_GPL(pci_epc_get_features);
+
/**
* pci_epc_stop() - stop the PCI link
* @epc: the link of the EPC device that has to be stopped
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 931fda3e5e0d..fcd5e5047546 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -59,6 +59,8 @@ struct pci_epc_ops {
enum pci_epc_irq_type type, u16 interrupt_num);
int (*start)(struct pci_epc *epc);
void (*stop)(struct pci_epc *epc);
+ const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
+ u8 func_no);
struct module *owner;
};

@@ -103,6 +105,24 @@ struct pci_epc {
unsigned int features;
};

+/**
+ * struct pci_epc_features - features supported by a EPC device per function
+ * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up
+ * @msi_capable: indicate if the endpoint function has MSI capability
+ * @msix_capable: indicate if the endpoint function has MSI-X capability
+ * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
+ * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs
+ * @bar_fixed_size: Array specifying the size supported by each BAR
+ */
+struct pci_epc_features {
+ unsigned int linkup_notifier : 1;
+ unsigned int msi_capable : 1;
+ unsigned int msix_capable : 1;
+ u8 reserved_bar;
+ u8 bar_fixed_64bit;
+ u64 bar_fixed_size[BAR_5 + 1];
+};
+
#define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0)
#define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3))
#define EPC_FEATURE_MSIX_AVAILABLE BIT(4)
@@ -161,6 +181,8 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
enum pci_epc_irq_type type, u16 interrupt_num);
int pci_epc_start(struct pci_epc *epc);
void pci_epc_stop(struct pci_epc *epc);
+const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
+ u8 func_no);
struct pci_epc *pci_epc_get(const char *epc_name);
void pci_epc_put(struct pci_epc *epc);

--
2.17.1


[RFC PATCH 4.19.y-cip 00/50] Add PCIe EP support for Renesas R-Car Gen3 and RZ/G2x

Lad Prabhakar
 

Hi All,

This patch series adds support for PCIe EP on Renesas R-Car Gen3 and
RZ/G2x platforms.

* Required EP framework changes and fixes are ported as well.
* All the patches have been cheery picked from upstream kernel.
* Patches [43, 44, 45, 46, 48]/50 are picked from linux-next.
* I was skeptic with patch 36/50 "Rename pcie-rcar.c to pcie-rcar-host.c"
this is required as patch 38/50 adds a new file named pcie-rcar.c. Open
for suggestions if this can be handled differently.
* In patch 37/48 I have dropped the changes for host driver as the patch
doesn't apply cleanly and manually applying it was resulting in a big diff.
* As the changes touches three other controller drivers I have build tested them
as done similarly while upstreaming R-Car Gen3 PCIe EP driver.
* Since the changes are huge I am sending the patches as RFC.

Cheers,
Prabhakar

Alan Mikhak (5):
PCI: endpoint: Set endpoint controller pointer to NULL
PCI: endpoint: Allocate enough space for fixed size BAR
PCI: endpoint: Skip odd BAR when skipping 64bit BAR
PCI: endpoint: Clear BAR before freeing its space
PCI: endpoint: Cast the page number to phys_addr_t

Hewenliang (1):
tools: PCI: Fix fd leakage

Jean-Jacques Hiblot (1):
tools: PCI: Exit with error code when test fails

Kangjie Lu (1):
PCI: endpoint: Fix a potential NULL pointer dereference

Kishon Vijay Abraham I (23):
PCI: endpoint: Add new pci_epc_ops to get EPC features
PCI: dwc: Add ->get_features() callback function to dw_pcie_ep_ops
PCI: designware-plat: Populate ->get_features() dw_pcie_ep_ops
PCI: pci-dra7xx: Populate ->get_features() dw_pcie_ep_ops
PCI: rockchip: Populate ->get_features() dw_pcie_ep_ops
PCI: cadence: Populate ->get_features() cdns_pcie_epc_ops
PCI: endpoint: Add helper to get first unreserved BAR
PCI: endpoint: Fix pci_epf_alloc_space() to set correct MEM TYPE flags
PCI: pci-epf-test: Remove setting epf_bar flags in function driver
PCI: pci-epf-test: Do not allocate next BARs memory if current BAR is
64Bit
PCI: pci-epf-test: Use pci_epc_get_features() to get EPC features
PCI: cadence: Remove pci_epf_linkup() from Cadence EP driver
PCI: rockchip: Remove pci_epf_linkup() from Rockchip EP driver
PCI: designware-plat: Remove setting epc->features in Designware plat
EP driver
PCI: endpoint: Remove features member in struct pci_epc
PCI: endpoint: Add support to specify alignment for buffers allocated
to BARs
PCI: endpoint: Use notification chain mechanism to notify EPC events
to EPF
PCI: endpoint: Replace spinlock with mutex
PCI: endpoint: Protect concurrent access to pci_epf_ops with mutex
PCI: endpoint: Assign function number for each PF in EPC core
PCI: endpoint: Fix ->set_msix() to take BIR and offset as arguments
PCI: dwc: Fix dw_pcie_ep_raise_msix_irq() to get correct MSI-X table
address
PCI: endpoint: functions/pci-epf-test: Print throughput information

Kunihiko Hayashi (1):
PCI: endpoint: Fix clearing start entry in configfs

Lad Prabhakar (15):
PCI: endpoint: Pass page size as argument to pci_epc_mem_init()
PCI: endpoint: Add support to handle multiple base for mapping
outbound memory
PCI: rcar: Rename pcie-rcar.c to pcie-rcar-host.c
arm64: defconfig: Enable CONFIG_PCIE_RCAR_HOST
PCI: rcar: Move shareable code to a common file
PCI: rcar: Fix calculating mask for PCIEPAMR register
dt-bindings: PCI: rcar: Add bindings for R-Car PCIe endpoint
controller
PCI: rcar: Add endpoint mode support
arm64: defconfig: Enable R-Car PCIe endpoint driver
dt-bindings: pci: rcar-pci-ep: Document r8a774a1 and r8a774b1
arm64: dts: renesas: r8a774c0: Add PCIe EP node
arm64: dts: renesas: r8a774a1: Add PCIe EP nodes
arm64: dts: renesas: r8a774b1: Add PCIe EP nodes
misc: pci_endpoint_test: Add Device ID for RZ/G2E PCIe controller
misc: pci_endpoint_test: Add Device ID for RZ/G2M and RZ/G2N PCIe
controllers

Vidya Sagar (3):
PCI: endpoint: Add core init notifying feature
PCI: endpoint: Add notification for core init completion
PCI: pci-epf-test: Add support to defer core initialization

.../devicetree/bindings/pci/rcar-pci-ep.yaml | 80 ++
arch/arm64/boot/dts/renesas/r8a774a1.dtsi | 38 +
arch/arm64/boot/dts/renesas/r8a774b1.dtsi | 38 +
arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 19 +
arch/arm64/configs/defconfig | 7 +-
drivers/misc/pci_endpoint_test.c | 7 +
drivers/pci/controller/Kconfig | 18 +
drivers/pci/controller/Makefile | 3 +-
drivers/pci/controller/dwc/pci-dra7xx.c | 13 +
.../pci/controller/dwc/pcie-designware-ep.c | 39 +-
.../pci/controller/dwc/pcie-designware-plat.c | 17 +-
drivers/pci/controller/dwc/pcie-designware.h | 1 +
drivers/pci/controller/pcie-cadence-ep.c | 27 +-
drivers/pci/controller/pcie-rcar-ep.c | 563 ++++++++
drivers/pci/controller/pcie-rcar-host.c | 1264 +++++++++++++++++
drivers/pci/controller/pcie-rcar.c | 1224 +---------------
drivers/pci/controller/pcie-rcar.h | 140 ++
drivers/pci/controller/pcie-rockchip-ep.c | 18 +-
drivers/pci/endpoint/functions/pci-epf-test.c | 295 +++-
drivers/pci/endpoint/pci-ep-cfs.c | 28 +-
drivers/pci/endpoint/pci-epc-core.c | 187 ++-
drivers/pci/endpoint/pci-epc-mem.c | 204 ++-
drivers/pci/endpoint/pci-epf-core.c | 49 +-
include/linux/pci-epc.h | 95 +-
include/linux/pci-epf.h | 32 +-
tools/pci/pcitest.c | 5 +-
26 files changed, 2919 insertions(+), 1492 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml
create mode 100644 drivers/pci/controller/pcie-rcar-ep.c
create mode 100644 drivers/pci/controller/pcie-rcar-host.c
create mode 100644 drivers/pci/controller/pcie-rcar.h

--
2.17.1


LAVA infrastructure: Planned maintenance

Chris Paterson
 

Hello all,

Just a heads up that the CIP LAVA infrastructure will be offline for a couple of hours (maybe less, maybe more) on Wednesday 14th from about 0700 UTC.

We're going to be upgrading to the latest version of lava-docker on the master and workers.

If the downtime at that time is going to cause any headaches please let me know, preferably before Wednesday...

Kind regards, Chris

4101 - 4120 of 9638