Re: [RFC PATCH] x86/doc/boot_protocol: Correct the description of "reloc"

2019-09-26 Thread Cao jin
On 9/26/19 2:01 PM, Ingo Molnar wrote:
> * Cao jin  wrote:
> 
>> The fields marked with (reloc) actually are not dedicated for writing,
>> but communicating info for relocatable kernel with boot loaders. For
>> example:
>>
>> 
>> Field name: pref_address
>> Type:   read (reloc)
>> Offset/size:0x258/8
>> Protocol:   2.10+
>> 
>>
>> 
>> Field name: code32_start
>> Type:   modify (optional, reloc)
>> Offset/size:0x214/4
>> Protocol:   2.00+
>> 
>>
>> Signed-off-by: Cao jin 
>> ---
>> Unless I have incorrect non-native understanding for "fill in", I think
>> this is inaccurate.
>>
>>  Documentation/x86/boot.rst | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst
>> index 08a2f100c0e6..a611bf04492d 100644
>> --- a/Documentation/x86/boot.rst
>> +++ b/Documentation/x86/boot.rst
>> @@ -243,7 +243,7 @@ bootloader ("modify").
>>  
>>  All general purpose boot loaders should write the fields marked
>>  (obligatory).  Boot loaders who want to load the kernel at a
>> -nonstandard address should fill in the fields marked (reloc); other
>> +nonstandard address should consult with the fields marked (reloc); other
>>  boot loaders can ignore those fields.
>>  
>>  The byte order of all fields is littleendian (this is x86, after all.)
> 
> Well, this documentation is written from the point of view of a 
> *bootloader*, not the kernel. So the 'fill in' says that the bootloader 
> should write those fields - which is correct, right?
> 

Take pref_address or relocatable_kernel for example, they have type:
read (reloc), does boot loader need to write them? I don't see grub does
this at least.

-- 
Sincerely,
Cao jin




Re: [RFC PATCH] x86/doc/boot_protocol: Correct the description of "reloc"

2019-09-26 Thread hpa
On September 26, 2019 12:55:51 AM PDT, Cao jin  wrote:
>On 9/26/19 2:01 PM, Ingo Molnar wrote:
>> * Cao jin  wrote:
>> 
>>> The fields marked with (reloc) actually are not dedicated for
>writing,
>>> but communicating info for relocatable kernel with boot loaders. For
>>> example:
>>>
>>> 
>>> Field name: pref_address
>>> Type:   read (reloc)
>>> Offset/size:0x258/8
>>> Protocol:   2.10+
>>> 
>>>
>>> 
>>> Field name: code32_start
>>> Type:   modify (optional, reloc)
>>> Offset/size:0x214/4
>>> Protocol:   2.00+
>>> 
>>>
>>> Signed-off-by: Cao jin 
>>> ---
>>> Unless I have incorrect non-native understanding for "fill in", I
>think
>>> this is inaccurate.
>>>
>>>  Documentation/x86/boot.rst | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst
>>> index 08a2f100c0e6..a611bf04492d 100644
>>> --- a/Documentation/x86/boot.rst
>>> +++ b/Documentation/x86/boot.rst
>>> @@ -243,7 +243,7 @@ bootloader ("modify").
>>>  
>>>  All general purpose boot loaders should write the fields marked
>>>  (obligatory).  Boot loaders who want to load the kernel at a
>>> -nonstandard address should fill in the fields marked (reloc); other
>>> +nonstandard address should consult with the fields marked (reloc);
>other
>>>  boot loaders can ignore those fields.
>>>  
>>>  The byte order of all fields is littleendian (this is x86, after
>all.)
>> 
>> Well, this documentation is written from the point of view of a 
>> *bootloader*, not the kernel. So the 'fill in' says that the
>bootloader 
>> should write those fields - which is correct, right?
>> 
>
>Take pref_address or relocatable_kernel for example, they have type:
>read (reloc), does boot loader need to write them? I don't see grub
>does
>this at least.

Read means the boot later reads them.
-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


Re: [RFC PATCH] x86/doc/boot_protocol: Correct the description of "reloc"

2019-09-26 Thread Cao jin
On 9/26/19 3:58 PM, h...@zytor.com wrote:
> On September 26, 2019 12:55:51 AM PDT, Cao jin  
> wrote:
>> On 9/26/19 2:01 PM, Ingo Molnar wrote:
>>> * Cao jin  wrote:
>>>
 The fields marked with (reloc) actually are not dedicated for
>> writing,
 but communicating info for relocatable kernel with boot loaders. For
 example:

 
 Field name: pref_address
 Type:   read (reloc)
 Offset/size:0x258/8
 Protocol:   2.10+
 

 
 Field name: code32_start
 Type:   modify (optional, reloc)
 Offset/size:0x214/4
 Protocol:   2.00+
 

 Signed-off-by: Cao jin 
 ---
 Unless I have incorrect non-native understanding for "fill in", I
>> think
 this is inaccurate.

  Documentation/x86/boot.rst | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst
 index 08a2f100c0e6..a611bf04492d 100644
 --- a/Documentation/x86/boot.rst
 +++ b/Documentation/x86/boot.rst
 @@ -243,7 +243,7 @@ bootloader ("modify").
  
  All general purpose boot loaders should write the fields marked
  (obligatory).  Boot loaders who want to load the kernel at a
 -nonstandard address should fill in the fields marked (reloc); other
 +nonstandard address should consult with the fields marked (reloc);
>> other
  boot loaders can ignore those fields.
  
  The byte order of all fields is littleendian (this is x86, after
>> all.)
>>>
>>> Well, this documentation is written from the point of view of a 
>>> *bootloader*, not the kernel. So the 'fill in' says that the
>> bootloader 
>>> should write those fields - which is correct, right?
>>>
>>
>> Take pref_address or relocatable_kernel for example, they have type:
>> read (reloc), does boot loader need to write them? I don't see grub
>> does
>> this at least.
> 
> Read means the boot later reads them.
> 

Sorry I don't know what is going wrong in my mind. For me, if
pref_address has "read (reloc)", base on the current document, it means
boot loader will read it and also write it, which is conflicting. And
the purpose of pref_address should just inform boot loader that kernel
whats itself to be loaded at certain address, it don't want to be written.

-- 
Sincerely,
Cao jin




Re: [PATCH 0/3] LTC2947 support

2019-09-26 Thread Sa, Nuno
On Tue, 2019-09-24 at 14:49 +0200, Nuno Sá wrote:
> 
> This series adds support for the LTC2947 hwmon device. The device
> supports power[1-*]_min_alarm, so that it makes use of
> the HWMON_P_MIN_ALARM mask. This brings me to the first patch, which
> is a
> fix on the hwmon subsystem for the HWMON_P_MIN_ALARM mask. It was
> defining
> the same mask as HWMON_P_MAX_ALARM.
> The rest of the series is the usual for a new device.
> 
> Nuno Sá (3):
>   hwmon: Fix HWMON_P_MIN_ALARM mask
>   hwmon: Add support for  ltc2947
>   dt-bindings: iio: Add ltc2947 documentation

Ok, I will wait for further reviews, but the dt-bindings patch
definitely need to be renamed to *dt-bindings: hwmon* :(.
 
> 
>  .../bindings/hwmon/adi,ltc2947.yaml   |  101 ++
>  Documentation/hwmon/ltc2947.rst   |  110 ++
>  MAINTAINERS   |   11 +
>  drivers/hwmon/Kconfig |   27 +
>  drivers/hwmon/Makefile|3 +
>  drivers/hwmon/ltc2947-core.c  | 1421
> +
>  drivers/hwmon/ltc2947-i2c.c   |   49 +
>  drivers/hwmon/ltc2947-spi.c   |   50 +
>  drivers/hwmon/ltc2947.h   |   12 +
>  include/linux/hwmon.h |2 +-
>  10 files changed, 1785 insertions(+), 1 deletion(-)
>  create mode 100644
> Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml
>  create mode 100644 Documentation/hwmon/ltc2947.rst
>  create mode 100644 drivers/hwmon/ltc2947-core.c
>  create mode 100644 drivers/hwmon/ltc2947-i2c.c
>  create mode 100644 drivers/hwmon/ltc2947-spi.c
>  create mode 100644 drivers/hwmon/ltc2947.h
> 



[RFC PATCH 00/21] Implement NTB Controller using multiple PCI

2019-09-26 Thread Kishon Vijay Abraham I
This series is sent as RFC since this series is dependent on
[1] (cannot be merged before that series) and to get early review
comments.

I'll also split this series into smaller chunk when I post the
next revision.

This series is about implementing SW defined NTB using
multiple endpoint instances. This series has been tested using
2 endpoint instances in J7 connected to two DRA7 boards.

This was presented in Linux Plumbers Conference. The presentation
can be found @ [2]

This series:
  *) Add support to define endpoint function using device tree
  *) Add a specification for implementing NTB controller using
 multiple endpoint instances.
  *) Add a NTB endpoint function driver and a NTB host side PCI
 driver that follows the specification.
  *) Add support in PCIe endpoint core to support secondary
 interface.
  *) Add a device tree overlay file to configure J7 as NTB

The test setup is something like below
   +-+   +-+
   | |   | |
   |DRA72|   |DRA76|
   | |   | |
   +--^--+   +--^--+
  | |
  | |
+-|-|-+
|  +--v--+   +--v--+  |
|  | |   | |  |
|  | EP  |   | EP  |  |
|  | CONTROLLER1 |   | CONTROLLER2 |  |
|  | <---> |  |
|  | |   | |  |
|  | |   | |  |
|  | | J7| |  |
|  | |  (Configured using NTB Function)  | |  |
|  +-+   +-+  |
+-+

Here DRA72 and DRA76 could be replaced with *any* PCI host.

EP side (J7):
=

In the kernel:
cd /sys/kernel/config/pci_ep/
echo 1 > controllers/d80.pcie-ep/start
echo 1 > controllers/d00.pcie-ep/start

RC side (DRA7):
===
echo :01:00.0 > /sys/bus/pci/devices/\:01\:00.0/driver/unbind
echo :01:00.0 > /sys/bus/pci/drivers/ntb_hw_epf/bind
modprobe ntb_transport
modprobe ntb_netdev

On each of the hosts Ethernet Interface will be created.

Provide an IP address to each of the hosts:
HOST1 (dra72):
ifconfig eth2 192.168.1.2 up

HOST2 (dra76):
ifconfig eth2 192.168.1.1 up

Once this is done standard network utilities like ping or iperf can be
used.

root@dra7xx-evm:~# iperf -c 192.168.1.2

Client connecting to 192.168.1.2, TCP port 5001
TCP window size: 2.50 MByte (default)

[  3] local 192.168.1.1 port 60814 connected with 192.168.1.2 port 5001
[ ID] Interval   Transfer Bandwidth
[  3]  0.0-10.0 sec   705 MBytes   591 Mbits/sec

[1] -> http://lore.kernel.org/r/20190604131516.13596-1-kis...@ti.com
[2] -> 
https://www.linuxplumbersconf.org/event/4/contributions/395/attachments/284/481/Implementing_NTB_Controller_Using_PCIe_Endpoint_-_final.pdf

Kishon Vijay Abraham I (21):
  dt-bindings: PCI: Endpoint: Add DT bindings for PCI EPF Bus
  dt-bindings: PCI: Endpoint: Add DT bindings for PCI EPF Device
  dt-bindings: PCI: Endpoint: Add DT bindings for PCI EPF NTB Device
  Documentation: PCI: Add specification for the *PCI NTB* function
device
  PCI: endpoint: Add API to get reference to EPC from device-tree
  PCI: endpoint: Add API to create EPF device from device tree
  PCI: endpoint: Add "pci-epf-bus" driver
  PCI: endpoint: Make *_get_first_free_bar() take into account 64 bit
BAR
  PCI: endpoint: Add helper API to get the 'next' unreserved BAR
  PCI: endpoint: Make pci_epf_driver ops optional
  PCI: endpoint: Add helper API to populate header with values from DT
  PCI: endpoint: Add support to associate secondary EPC with EPF
  PCI: endpoint: Add pci_epc_ops to map MSI irq
  PCI: cadence: Implement ->msi_map_irq() ops
  PCI: endpoint: Remove unused pci_epf_match_device()
  PCI: endpoint: Fix missing mutex_unlock in error case
  PCI: endpoint: *_free_bar() to return error codes on failure
  PCI: endpoint: Add EP function driver to provide NTB functionality
  PCI: Add TI J721E device to pci ids
  NTB: Add support for EPF PCI-Express Non-Transparent Bridge
  NTB: tool: Enable the NTB/PCIe link on the local or remote side of
bridge

 Documentation/PCI/endpoint

[RFC PATCH 02/21] dt-bindings: PCI: Endpoint: Add DT bindings for PCI EPF Device

2019-09-26 Thread Kishon Vijay Abraham I
Add device tree bindings for PCI endpoint function device. The
nodes for PCI endpoint function device should be attached to
PCI endpoint function bus.

Signed-off-by: Kishon Vijay Abraham I 
---
 .../bindings/pci/endpoint/pci-epf.txt | 28 +++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/endpoint/pci-epf.txt

diff --git a/Documentation/devicetree/bindings/pci/endpoint/pci-epf.txt 
b/Documentation/devicetree/bindings/pci/endpoint/pci-epf.txt
new file mode 100644
index ..f006395fd526
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/endpoint/pci-epf.txt
@@ -0,0 +1,28 @@
+PCI Endpoint Function Device
+
+This describes the generic bindings to be used when a device has to be
+exposed to the remote host over PCIe. The device could be an actual
+peripheral in the platform or a virtual device created by the software.
+
+epcs : phandle to the endpoint controller device
+epc-names : the names of the endpoint controller device corresponding
+   to the EPCs present in the *epcs* phandle
+vendor-id: used to identify device manufacturer
+device-id: used to identify a particular device
+baseclass-code: used to classify the type of function the device performs
+subclass-code: used to identify more specifically the function of the device
+subsys-vendor-id: used to identify vendor of the add-in card or subsystem
+subsys-id: used to specify an id that is specific to a vendor
+
+Example:
+Following is an example of NTB device exposed to the remote host.
+
+ntb {
+   compatible = "pci-epf-ntb";
+   epcs = <&pcie0_ep>, <&pcie1_ep>;
+   epc-names = "primary", "secondary";
+   vendor-id = /bits/ 16 <0x104c>;
+   device-id = /bits/ 16 <0xb00d>;
+   num-mws = <4>;
+   mws-size = <0x10>, <0x10>, <0x10>, <0x10>;
+};
-- 
2.17.1



[RFC PATCH 05/21] PCI: endpoint: Add API to get reference to EPC from device-tree

2019-09-26 Thread Kishon Vijay Abraham I
Add of_pci_epc_get() and of_pci_epc_get_by_name() to get reference
to EPC from device-tree. This is added in preparation to define
an endpoint function from device tree.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epc-core.c | 61 +
 include/linux/pci-epc.h |  4 +-
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index 5bc094093a47..0c2fdd39090c 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -83,6 +83,66 @@ struct pci_epc *pci_epc_get(const char *epc_name)
 }
 EXPORT_SYMBOL_GPL(pci_epc_get);
 
+/**
+ * of_pci_epc_get() - get PCI endpoint controller from device node and index
+ * @node: device node which contains the phandle to endpoint controller
+ * @index: index of the endpoint controller in "epcs" property
+ *
+ * Returns the EPC corresponding to the _index_ entry in "epcs" property
+ * present in device node, after getting a refcount  to it or -ENODEV if
+ * there is no such EPC or -EPROBE_DEFER if there is a phandle to the phy,
+ * but the device is not yet loaded.
+ */
+struct pci_epc *of_pci_epc_get(struct device_node *node, int index)
+{
+   struct device_node *epc_node;
+   struct class_dev_iter iter;
+   struct pci_epc *epc;
+   struct device *dev;
+
+   epc_node = of_parse_phandle(node, "epcs", index);
+   if (!epc_node)
+   return ERR_PTR(-ENODEV);
+
+   class_dev_iter_init(&iter, pci_epc_class, NULL, NULL);
+   while ((dev = class_dev_iter_next(&iter))) {
+   epc = to_pci_epc(dev);
+   if (epc_node != epc->dev.of_node)
+   continue;
+
+   of_node_put(epc_node);
+   class_dev_iter_exit(&iter);
+   get_device(&epc->dev);
+   return epc;
+   }
+
+   of_node_put(node);
+   class_dev_iter_exit(&iter);
+   return ERR_PTR(-EPROBE_DEFER);
+}
+EXPORT_SYMBOL_GPL(of_pci_epc_get);
+
+/**
+ * of_pci_epc_get_by_name() - get PCI endpoint controller from device node
+ *and string
+ * @node: device node which contains the phandle to endpoint controller
+ * @epc_name: name of endpoint controller as present in "epc-names" property
+ *
+ * Returns the EPC corresponding to the epc_name in "epc-names" property
+ * present in device node.
+ */
+struct pci_epc *of_pci_epc_get_by_name(struct device_node *node,
+  const char *epc_name)
+{
+   int index = 0;
+
+   if (epc_name)
+   index = of_property_match_string(node, "epc-names", epc_name);
+
+   return of_pci_epc_get(node, index);
+}
+EXPORT_SYMBOL_GPL(of_pci_epc_get_by_name);
+
 /**
  * pci_epc_get_first_free_bar() - helper to get first unreserved BAR
  * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
@@ -661,6 +721,7 @@ __pci_epc_create(struct device *dev, const struct 
pci_epc_ops *ops,
device_initialize(&epc->dev);
epc->dev.class = pci_epc_class;
epc->dev.parent = dev;
+   epc->dev.of_node = dev->of_node;
epc->ops = ops;
 
ret = dev_set_name(&epc->dev, "%s", dev_name(dev));
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 0fff52675a6b..ef6531af6ed2 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -202,7 +202,9 @@ 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);
-
+struct pci_epc *of_pci_epc_get(struct device_node *node, int index);
+struct pci_epc *of_pci_epc_get_by_name(struct device_node *node,
+  const char *epc_name);
 int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size,
   size_t page_size);
 void pci_epc_mem_exit(struct pci_epc *epc);
-- 
2.17.1



[RFC PATCH 06/21] PCI: endpoint: Add API to create EPF device from device tree

2019-09-26 Thread Kishon Vijay Abraham I
Add API to create EPF device from device tree and the device managed
interface corresponding to it. This is added in order to define
an endpoint function completely from device tree.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epf-core.c | 68 +
 include/linux/pci-epf.h |  6 +++
 2 files changed, 74 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epf-core.c 
b/drivers/pci/endpoint/pci-epf-core.c
index 16feff8cad50..c74c7cc6d8bd 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -529,6 +529,73 @@ struct pci_epf *pci_epf_create(const char *name)
 }
 EXPORT_SYMBOL_GPL(pci_epf_create);
 
+/**
+ * pci_epf_of_create() - create a new PCI EPF device from device tree node
+ * @node: the device node of the PCI EPF device.
+ *
+ * Invoke to create a new PCI EPF device by providing a device tree node
+ * with compatible property.
+ */
+struct pci_epf *pci_epf_of_create(struct device_node *node)
+{
+   struct pci_epf *epf;
+   const char *compat;
+   int ret;
+
+   of_node_get(node);
+
+   ret = of_property_read_string(node, "compatible", &compat);
+   if (ret) {
+   of_node_put(node);
+   return ERR_PTR(ret);
+   }
+
+   epf = pci_epf_create(compat);
+   if (!IS_ERR(epf))
+   epf->node = node;
+
+   return epf;
+}
+EXPORT_SYMBOL_GPL(pci_epf_of_create);
+
+static void devm_epf_release(struct device *dev, void *res)
+{
+   struct pci_epf *epf = *(struct pci_epf **)res;
+
+   pci_epf_destroy(epf);
+}
+
+/**
+ * devm_pci_epf_of_create() - create a new PCI EPF device from device tree node
+ * @dev: device that is creating the new EPF
+ * @node: the device node of the PCI EPF device.
+ *
+ * Invoke to create a new PCI EPF device by providing a device tree node with
+ * compatible property. While at that, it also associates the device with the
+ * EPF using devres. On driver detach, release function is invoked on the 
devres
+ * data, where devres data is freed.
+ */
+struct pci_epf *devm_pci_epf_of_create(struct device *dev,
+  struct device_node *node)
+{
+   struct pci_epf **ptr, *epf;
+
+   ptr = devres_alloc(devm_epf_release, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   epf = pci_epf_of_create(node);
+   if (!IS_ERR(epf)) {
+   *ptr = epf;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return epf;
+}
+EXPORT_SYMBOL_GPL(devm_pci_epf_of_create);
+
 const struct pci_epf_device_id *
 pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf)
 {
@@ -549,6 +616,7 @@ static void pci_epf_dev_release(struct device *dev)
 {
struct pci_epf *epf = to_pci_epf(dev);
 
+   of_node_put(epf->node);
kfree(epf->name);
kfree(epf);
 }
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 02090eb41563..7e997fb656fb 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 struct pci_epf;
@@ -101,6 +102,7 @@ struct pci_epf_bar {
 /**
  * struct pci_epf - represents the PCI EPF device
  * @dev: the PCI EPF device
+ * @node: the device tree node of the PCI EPF device
  * @name: the name of the PCI EPF device
  * @header: represents standard configuration header
  * @bar: represents the BAR of EPF device
@@ -125,6 +127,7 @@ struct pci_epf_bar {
  */
 struct pci_epf {
struct device   dev;
+   struct device_node  *node;
const char  *name;
struct pci_epf_header   *header;
struct pci_epf_bar  bar[6];
@@ -167,6 +170,9 @@ static inline void *epf_get_drvdata(struct pci_epf *epf)
 const struct pci_epf_device_id *
 pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf);
 struct pci_epf *pci_epf_create(const char *name);
+struct pci_epf *pci_epf_of_create(struct device_node *node);
+struct pci_epf *devm_pci_epf_of_create(struct device *dev,
+  struct device_node *node);
 void pci_epf_destroy(struct pci_epf *epf);
 int __pci_epf_register_driver(struct pci_epf_driver *driver,
  struct module *owner);
-- 
2.17.1



[RFC PATCH 01/21] dt-bindings: PCI: Endpoint: Add DT bindings for PCI EPF Bus

2019-09-26 Thread Kishon Vijay Abraham I
Add device tree bindings for PCI endpoint function bus to which
endpoint function devices should be attached.

Signed-off-by: Kishon Vijay Abraham I 
---
 .../bindings/pci/endpoint/pci-epf-bus.txt | 27 +++
 1 file changed, 27 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.txt

diff --git a/Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.txt 
b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.txt
new file mode 100644
index ..16727ddf01f5
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.txt
@@ -0,0 +1,27 @@
+PCI Endpoint Function Bus
+
+This describes the bindings for endpoint function bus to which endpoint
+function devices should be attached.
+
+Required Properties:
+ - compatible: Should be "pci-epf-bus"
+
+One or more subnodes representing PCIe endpoint function device exposed
+to the remote host.
+
+Example:
+Following is an example of NTB device exposed to the remote host.
+
+epf_bus {
+   compatible = "pci-epf-bus";
+
+   ntb {
+   compatible = "pci-epf-ntb";
+   epcs = <&pcie0_ep>, <&pcie1_ep>;
+   epc-names = "primary", "secondary";
+   vendor-id = /bits/ 16 <0x104c>;
+   device-id = /bits/ 16 <0xb00d>;
+   num-mws = <4>;
+   mws-size = <0x10>, <0x10>, <0x10>, <0x10>;
+   };
+};
-- 
2.17.1



[RFC PATCH 10/21] PCI: endpoint: Make pci_epf_driver ops optional

2019-09-26 Thread Kishon Vijay Abraham I
pci_epf_driver had two ops for bind and unbind which will be invoked
when an endpoint controller is bound to an endpoint function (using
configfs). Now that endpoint core has support to define an endpoint
function using device tree alone, the bind and unbind ops can be
optional. Make pci_epf_driver ops optional here.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epf-core.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epf-core.c 
b/drivers/pci/endpoint/pci-epf-core.c
index c74c7cc6d8bd..67015c66d09f 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -446,11 +446,9 @@ int __pci_epf_register_driver(struct pci_epf_driver 
*driver,
 {
int ret;
 
-   if (!driver->ops)
-   return -EINVAL;
-
-   if (!driver->ops->bind || !driver->ops->unbind)
-   return -EINVAL;
+   if (!driver->ops || !driver->ops->bind || !driver->ops->unbind)
+   pr_debug("%s: Supports only pci_epf device created using DT\n",
+driver->driver.name);
 
driver->driver.bus = &pci_epf_bus_type;
driver->driver.owner = owner;
-- 
2.17.1



[RFC PATCH 03/21] dt-bindings: PCI: Endpoint: Add DT bindings for PCI EPF NTB Device

2019-09-26 Thread Kishon Vijay Abraham I
Add device tree bindings for PCI endpoint NTB function device.

Signed-off-by: Kishon Vijay Abraham I 
---
 .../bindings/pci/endpoint/pci-epf-ntb.txt | 31 +++
 1 file changed, 31 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.txt

diff --git a/Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.txt 
b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.txt
new file mode 100644
index ..e7896932423e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.txt
@@ -0,0 +1,31 @@
+PCI Endpoint NTB Function Device
+
+This describes the bindings to be used when a NTB device has to be
+exposed to the remote host over PCIe.
+
+Required Properties:
+ - compatible: Should be "pci-epf-ntb"
+ - epcs: As defined in generic pci-epf bindings defined in pci-epf.txt
+ - epc-names: As defined in generic pci-epf bindings defined in pci-epf.txt
+ - vendor-id: As defined in generic pci-epf bindings defined in pci-epf.txt
+ - device-id: As defined in generic pci-epf bindings defined in pci-epf.txt
+ - num-mws: Specify the number of memory windows. Should not be more than 4.
+ - mws-size: List of 'num-mws' entries containing size of each memory window.
+
+Optional Properties:
+ - spad-count: Specify the number of scratchpad registers to be supported
+ - db-count: Specify the number of doorbell interrupts to be supported. Must
+not be greater than 32.
+
+Example:
+Following is an example of NTB device exposed to the remote host.
+
+ntb {
+   compatible = "pci-epf-ntb";
+   epcs = <&pcie0_ep>, <&pcie1_ep>;
+   epc-names = "primary", "secondary";
+   vendor-id = /bits/ 16 <0x104c>;
+   device-id = /bits/ 16 <0xb00d>;
+   num-mws = <4>;
+   mws-size = <0x10>, <0x10>, <0x10>, <0x10>;
+};
-- 
2.17.1



[RFC PATCH 09/21] PCI: endpoint: Add helper API to get the 'next' unreserved BAR

2019-09-26 Thread Kishon Vijay Abraham I
Add an API to get the next unreserved BAR starting from a given BAR
number that can be used by the endpoint function.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epc-core.c | 26 ++
 include/linux/pci-epc.h |  2 ++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index 7eae7dcaebf9..49bdff21 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -147,17 +147,36 @@ EXPORT_SYMBOL_GPL(of_pci_epc_get_by_name);
  * 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
+ * Invoke to get the first unreserved BAR that can be used by the 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)
+{
+   return pci_epc_get_next_free_bar(epc_features, BAR_0);
+}
+EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
+
+/**
+ * pci_epc_get_next_free_bar() - helper to get unreserved BAR starting from 
@bar
+ * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
+ * @bar: the starting BAR number from where unreserved BAR should be searched
+ *
+ * Invoke to get the next unreserved BAR starting from @bar that can be used
+ * for endpoint function. For any incorrect value in reserved_bar return '0'.
+ */
+unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
+  *epc_features, enum pci_barno bar)
 {
unsigned long free_bar;
 
if (!epc_features)
return 0;
 
+   /* If 'bar - 1' is a 64-bit BAR, move to the next BAR */
+   if ((epc_features->bar_fixed_64bit << 1) & 1 << bar)
+   bar++;
+
/* Find if the reserved BAR is also a 64-bit BAR */
free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit;
 
@@ -165,14 +184,13 @@ unsigned int pci_epc_get_first_free_bar(const struct 
pci_epc_features
free_bar <<= 1;
free_bar |= epc_features->reserved_bar;
 
-   /* Now find the free BAR */
-   free_bar = ffz(free_bar);
+   free_bar = find_next_zero_bit(&free_bar, 6, bar);
if (free_bar > 5)
return 0;
 
return free_bar;
 }
-EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
+EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
 
 /**
  * pci_epc_get_features() - get the features supported by EPC
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index ef6531af6ed2..993b1a55a239 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -200,6 +200,8 @@ const struct pci_epc_features *pci_epc_get_features(struct 
pci_epc *epc,
u8 func_no, u8 vfunc_no);
 unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
*epc_features);
+unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
+  *epc_features, enum pci_barno bar);
 struct pci_epc *pci_epc_get(const char *epc_name);
 void pci_epc_put(struct pci_epc *epc);
 struct pci_epc *of_pci_epc_get(struct device_node *node, int index);
-- 
2.17.1



[RFC PATCH 11/21] PCI: endpoint: Add helper API to populate header with values from DT

2019-09-26 Thread Kishon Vijay Abraham I
Add helper API pci_epc_of_parse_header() to populate header with
values from device tree. These values will be written to the
configuration space header in the endpoint controller.

Signed-off-by: Kishon Vijay Abraham I 
---
 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 49bdff21..98acadbfc934 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -31,6 +31,29 @@ static int devm_pci_epc_match(struct device *dev, void *res, 
void *match_data)
return *epc == match_data;
 }
 
+/**
+ * pci_epc_of_parse_header() - parse the device tree to get PCI config space
+ * header
+ * @node: The device tree node (of endpoint function) which has the PCI config
+ *space header values
+ * @header: standard configuration space header fields that has to be populated
+ *
+ * Invoke to populate *header* with the PCI configuration space values 
populated
+ * in device tree.
+ */
+void pci_epc_of_parse_header(struct device_node *node,
+struct pci_epf_header *header)
+{
+   of_property_read_u16(node, "vendor-id", &header->vendorid);
+   of_property_read_u16(node, "device-id", &header->deviceid);
+   of_property_read_u8(node, "baseclass-code", &header->baseclass_code);
+   of_property_read_u8(node, "subclass-code", &header->subclass_code);
+   of_property_read_u16(node, "subsys-vendor-id",
+&header->subsys_vendor_id);
+   of_property_read_u16(node, "subsys-id", &header->subsys_id);
+}
+EXPORT_SYMBOL_GPL(pci_epc_of_parse_header);
+
 /**
  * pci_epc_put() - release the PCI endpoint controller
  * @epc: epc returned by pci_epc_get()
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 993b1a55a239..18fff589a881 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -196,6 +196,8 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 
vfunc_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);
+void pci_epc_of_parse_header(struct device_node *node,
+struct pci_epf_header *header);
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
u8 func_no, u8 vfunc_no);
 unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
-- 
2.17.1



[RFC PATCH 07/21] PCI: endpoint: Add "pci-epf-bus" driver

2019-09-26 Thread Kishon Vijay Abraham I
Add "pci-epf-bus" driver that helps to create EPF device from
device tree. This is added in order to define an endpoint function
completely from device tree.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/Makefile  |  3 +-
 drivers/pci/endpoint/pci-epf-bus.c | 54 ++
 2 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pci/endpoint/pci-epf-bus.c

diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
index 95b2fe47e3b0..36cf33cf975c 100644
--- a/drivers/pci/endpoint/Makefile
+++ b/drivers/pci/endpoint/Makefile
@@ -5,4 +5,5 @@
 
 obj-$(CONFIG_PCI_ENDPOINT_CONFIGFS)+= pci-ep-cfs.o
 obj-$(CONFIG_PCI_ENDPOINT) += pci-epc-core.o pci-epf-core.o\
-  pci-epc-mem.o functions/
+  pci-epc-mem.o pci-epf-bus.o \
+  functions/
diff --git a/drivers/pci/endpoint/pci-epf-bus.c 
b/drivers/pci/endpoint/pci-epf-bus.c
new file mode 100644
index ..c47eeae7fe7a
--- /dev/null
+++ b/drivers/pci/endpoint/pci-epf-bus.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * PCI Endpoint *Function* Bus Driver
+ *
+ * Copyright (C) 2019 Texas Instruments
+ * Author: Kishon Vijay Abraham I 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int pci_epf_bus_probe(struct platform_device *pdev)
+{
+   struct device *dev = &pdev->dev;
+   struct device_node *node = of_node_get(dev->of_node);
+   struct device_node *child;
+   struct pci_epf *epf;
+
+   for_each_child_of_node(node, child) {
+   epf = devm_pci_epf_of_create(dev, child);
+   if (IS_ERR(epf)) {
+   dev_err(dev, "Failed to create PCI EPF device %s\n",
+   node->full_name);
+   of_node_put(child);
+   break;
+   }
+   }
+   of_node_put(node);
+
+   return 0;
+}
+
+static const struct of_device_id pci_epf_bus_id_table[] = {
+   { .compatible = "pci-epf-bus" },
+   {}
+};
+MODULE_DEVICE_TABLE(of, pci_epf_bus_id_table);
+
+static struct platform_driver pci_epf_bus_driver = {
+   .probe  = pci_epf_bus_probe,
+   .driver = {
+   .name   = "pci-epf-bus",
+   .of_match_table = of_match_ptr(pci_epf_bus_id_table),
+   },
+};
+
+module_platform_driver(pci_epf_bus_driver);
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("PCI EPF Bus Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1



[RFC PATCH 04/21] Documentation: PCI: Add specification for the *PCI NTB* function device

2019-09-26 Thread Kishon Vijay Abraham I
Add specification for the *PCI NTB* function device. The endpoint function
driver and the host PCI driver should be created based on this
specification.

Signed-off-by: Kishon Vijay Abraham I 
---
 Documentation/PCI/endpoint/pci-test-ntb.txt | 315 
 1 file changed, 315 insertions(+)
 create mode 100644 Documentation/PCI/endpoint/pci-test-ntb.txt

diff --git a/Documentation/PCI/endpoint/pci-test-ntb.txt 
b/Documentation/PCI/endpoint/pci-test-ntb.txt
new file mode 100644
index ..c8bfe9dbfd8b
--- /dev/null
+++ b/Documentation/PCI/endpoint/pci-test-ntb.txt
@@ -0,0 +1,315 @@
+  PCI NTB FUNCTION
+   Kishon Vijay Abraham I 
+
+PCI NTB Function allows two different systems (or hosts) to communicate
+with each other by configurig the endpoint instances in such a way that
+transactions from one system is routed to the other system.
+
+In the below diagram, PCI NTB function configures the SoC with multiple
+PCIe Endpoint (EP) instances in such a way that transaction from one EP
+controller is routed to the other EP controller. Once PCI NTB function
+configures the SoC with multiple EP instances, HOST1 and HOST2 can
+communicate with each other using SoC as a bridge.
+
+   +-+   +-+
+   | |   | |
+   |HOST1|   |HOST2|
+   | |   | |
+   +--^--+   +--^--+
+  | |
+  | |
++-|-|-+
+|  +--v--+   +--v--+  |
+|  | |   | |  |
+|  | EP  |   | EP  |  |
+|  | CONTROLLER1 |   | CONTROLLER2 |  |
+|  | <---> |  |
+|  | |   | |  |
+|  | |   | |  |
+|  | |  SoC With Multiple EP Instances   | |  |
+|  | |  (Configured using NTB Function)  | |  |
+|  +-+   +-+  |
++-+
+
+Constructs used for Implementing NTB:
+
+   *) Config Region
+   *) Self Scratchpad Registers
+   *) Peer Scratchpad Registers
+   *) Doorbell Registers
+   *) Memory Window
+
+Modeling Constructs:
+
+  There are 5 or more distinct regions (config, self scratchpad, peer
+scratchpad, doorbell, one or more memory windows) to be modeled to achieve
+NTB functionality. Atleast one memory window is required while more than
+one is permitted. All these regions should be mapped to BAR for hosts to
+access these regions.
+
+If one 32-bit BAR is allocated for each of these regions, the scheme would
+look like
+   BAR0 -> Config Region
+   BAR1 -> Self Scratchpad
+   BAR2 -> Peer Scratchpad
+   BAR3 -> Doorbell
+   BAR4 -> Memory Window 1
+   BAR5 -> Memory Window 2
+
+However if we allocate a separate BAR for each of the region, there would not
+be enough BARs for all the regions in a platform that supports only 64-bit
+BAR.
+
+In order to be be supported by most of the platforms, the regions should be
+packed and mapped to BARs in a way that provides NTB functionality and
+also making sure the hosts doesn't access any region that it is not supposed
+to.
+
+The following scheme is used in EPF NTB Function
+
+   BAR0 -> Config Region + Self Scratchpad
+   BAR1 -> Peer Scratchpad
+   BAR2 -> Doorbell + Memory Window 1
+   BAR3 -> Memory Window 2
+   BAR4 -> Memory Window 3
+   BAR4 -> Memory Window 4
+
+With this scheme, for the basic NTB functionality 3 BARs should be sufficient.
+
+Modeling Config/Scratchpad Region:
+
++-+--->+--++-+
+|   BAR0  ||  CONFIG REGION   ||   BAR0  |
++-++   +--+<---+-+
+|   BAR1  ||   |SCRATCHPAD REGION ||   BAR1  |
++-++-->+--+<---+-+
+|   BAR2  |Local Memory|   BAR2  |
++-++-+
+|   BAR3  ||   BAR3  |
++-++-+
+|   BAR4  ||   BAR4  |
++-+  

[RFC PATCH 13/21] PCI: endpoint: Add pci_epc_ops to map MSI irq

2019-09-26 Thread Kishon Vijay Abraham I
Add pci_epc_ops to map physical address to MSI address and return MSI
data. The physical address is an address in the outbound region. This is
required to implement doorbell functionality of NTB (non transparent
bridge) wherein EPC on either side of the interface (primary and
secondary) can directly write to the physical address (in outbound
region) of the other interface to ring doorbell using MSI.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epc-core.c | 40 +
 include/linux/pci-epc.h |  7 +
 2 files changed, 47 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index 42085fcc746d..797e5d323998 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -363,6 +363,46 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 
vfunc_no,
 }
 EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
 
+/**
+ * pci_epc_map_msi_irq() - Map physical address to MSI address and return
+ * MSI data
+ * @epc: the EPC device which has the MSI capability
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
+ * @phys_addr: the physical address of the outbound region
+ * @interrupt_num: the MSI interrupt number
+ * @entry_size: Size of Outbound address region for each interrupt
+ * @msi_data: the data that should be written in order to raise MSI interrupt
+ *with interrupt number as 'interrupt num'
+ *
+ * Invoke to map physical address to MSI address and return MSI data. The
+ * physical address should be an address in the outbound region. This is
+ * required to implement doorbell functionality of NTB wherein EPC on either
+ * side of the interface (primary and secondary) can directly write to the
+ * physical address (in outbound region) of the other interface to ring
+ * doorbell.
+ */
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+   phys_addr_t phys_addr, u8 interrupt_num, u32 entry_size,
+   u32 *msi_data)
+{
+   int ret;
+
+   if (IS_ERR_OR_NULL(epc))
+   return -EINVAL;
+
+   if (!epc->ops->map_msi_irq)
+   return -EINVAL;
+
+   mutex_lock(&epc->lock);
+   ret = epc->ops->map_msi_irq(epc, func_no, vfunc_no, phys_addr,
+   interrupt_num, entry_size, msi_data);
+   mutex_unlock(&epc->lock);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epc_map_msi_irq);
+
 /**
  * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
  * @epc: the EPC device to which MSI interrupts was requested
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 91d5cbaabc8f..0632a4d4714d 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -57,6 +57,7 @@ pci_epc_interface_string(enum pci_epc_interface_type type)
  * @get_msix: ops to get the number of MSI-X interrupts allocated by the RC
  *  from the MSI-X capability register
  * @raise_irq: ops to raise a legacy, MSI or MSI-X interrupt
+ * @map_msi_irq: ops to map physical address to MSI address and return MSI data
  * @start: ops to start the PCI link
  * @stop: ops to stop the PCI link
  * @owner: the module owner containing the ops
@@ -85,6 +86,9 @@ struct pci_epc_ops {
int (*get_msix)(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
int (*raise_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 enum pci_epc_irq_type type, u16 interrupt_num);
+   int (*map_msi_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+  phys_addr_t phys_addr, u8 interrupt_num,
+  u32 entry_size, u32 *msi_data);
int (*start)(struct pci_epc *epc);
void(*stop)(struct pci_epc *epc);
const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
@@ -212,6 +216,9 @@ int pci_epc_get_msi(struct pci_epc *epc, u8 func_no, u8 
vfunc_no);
 int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 u16 interrupts);
 int pci_epc_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+   phys_addr_t phys_addr, u8 interrupt_num,
+   u32 entry_size, u32 *msi_data);
 int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
  enum pci_epc_irq_type type, u16 interrupt_num);
 int pci_epc_start(struct pci_epc *epc);
-- 
2.17.1



[RFC PATCH 14/21] PCI: cadence: Implement ->msi_map_irq() ops

2019-09-26 Thread Kishon Vijay Abraham I
Implement ->msi_map_irq() ops in order to map physical address to
MSI address and return MSI data.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/controller/pcie-cadence-ep.c | 59 
 1 file changed, 59 insertions(+)

diff --git a/drivers/pci/controller/pcie-cadence-ep.c 
b/drivers/pci/controller/pcie-cadence-ep.c
index ff4b4b8eb017..5d41c892177f 100644
--- a/drivers/pci/controller/pcie-cadence-ep.c
+++ b/drivers/pci/controller/pcie-cadence-ep.c
@@ -517,6 +517,64 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep 
*ep, u8 fn, u8 vfn,
return 0;
 }
 
+static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
+   phys_addr_t addr, u8 interrupt_num,
+   u32 entry_size, u32 *msi_data)
+{
+   u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
+   struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+   u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+   struct cdns_pcie *pcie = &ep->pcie;
+   u16 flags, mme, data, data_mask;
+   u32 first_vf_offset, stride;
+   u8 msi_count;
+   u64 pci_addr;
+   int ret;
+   int i;
+
+   if (vfn > 0) {
+   first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+   PCI_SRIOV_VF_OFFSET);
+   stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+  PCI_SRIOV_VF_STRIDE);
+   fn = fn + first_vf_offset + ((vfn - 1) * stride);
+   }
+
+   /* Check whether the MSI feature has been enabled by the PCI host. */
+   flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+   if (!(flags & PCI_MSI_FLAGS_ENABLE))
+   return -EINVAL;
+
+   /* Get the number of enabled MSIs */
+   mme = (flags & PCI_MSI_FLAGS_QSIZE) >> 4;
+   msi_count = 1 << mme;
+   if (!interrupt_num || interrupt_num > msi_count)
+   return -EINVAL;
+
+   /* Compute the data value to be written. */
+   data_mask = msi_count - 1;
+   data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
+   data = data & ~data_mask;
+
+   /* Get the PCI address where to write the data into. */
+   pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
+   pci_addr <<= 32;
+   pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
+   pci_addr &= GENMASK_ULL(63, 2);
+
+   for (i = 0; i < interrupt_num; i++) {
+   ret = cdns_pcie_ep_map_addr(epc, fn, vfn, addr, pci_addr,
+   entry_size);
+   if (ret)
+   return ret;
+   addr = addr + entry_size;
+   }
+
+   *msi_data = data;
+
+   return 0;
+}
+
 static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
  u16 interrupt_num)
 {
@@ -678,6 +736,7 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = {
.set_msix   = cdns_pcie_ep_set_msix,
.get_msix   = cdns_pcie_ep_get_msix,
.raise_irq  = cdns_pcie_ep_raise_irq,
+   .map_msi_irq= cdns_pcie_ep_map_msi_irq,
.start  = cdns_pcie_ep_start,
.get_features   = cdns_pcie_ep_get_features,
 };
-- 
2.17.1



[RFC PATCH 12/21] PCI: endpoint: Add support to associate secondary EPC with EPF

2019-09-26 Thread Kishon Vijay Abraham I
In the case of standard endpoint functions, only one endpoint
controller (EPC) will be associated with an endpoint function
(EPF). However for providing NTB (non transparent bridge)
functionality, two EPCs should be associated with a single EPF.
Add support to associate secondary EPC with EPF. This is in
preparation for adding NTB endpoint function driver.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 12 +++--
 drivers/pci/endpoint/pci-ep-cfs.c |  6 +--
 drivers/pci/endpoint/pci-epc-core.c   | 47 
 drivers/pci/endpoint/pci-epf-core.c   | 53 ++-
 include/linux/pci-epc.h   | 24 -
 include/linux/pci-epf.h   | 27 +-
 6 files changed, 135 insertions(+), 34 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c 
b/drivers/pci/endpoint/functions/pci-epf-test.c
index 608545aaf7c8..c7003c2dbbb2 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -484,7 +484,8 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
epf_bar = &epf->bar[bar];
 
if (epf_test->reg[bar]) {
-   pci_epf_free_space(epf, epf_test->reg[bar], bar);
+   pci_epf_free_space(epf, epf_test->reg[bar], bar,
+  PRIMARY_INTERFACE);
pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no,
  epf_bar);
}
@@ -514,7 +515,8 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
  epf_bar);
if (ret) {
-   pci_epf_free_space(epf, epf_test->reg[bar], bar);
+   pci_epf_free_space(epf, epf_test->reg[bar], bar,
+  PRIMARY_INTERFACE);
dev_err(dev, "Failed to set BAR%d\n", bar);
if (bar == test_reg_bar)
return ret;
@@ -544,7 +546,8 @@ 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, epc_features->align);
+  test_reg_bar, epc_features->align,
+  PRIMARY_INTERFACE);
if (!base) {
dev_err(dev, "Failed to allocated register space\n");
return -ENOMEM;
@@ -560,7 +563,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
continue;
 
base = pci_epf_alloc_space(epf, bar_size[bar], bar,
-  epc_features->align);
+  epc_features->align,
+  PRIMARY_INTERFACE);
if (!base)
dev_err(dev, "Failed to allocate space for BAR%d\n",
bar);
diff --git a/drivers/pci/endpoint/pci-ep-cfs.c 
b/drivers/pci/endpoint/pci-ep-cfs.c
index c18ef626ada5..f274a5b6ee10 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -93,13 +93,13 @@ static int pci_epc_epf_link(struct config_item *epc_item,
struct pci_epc *epc = epc_group->epc;
struct pci_epf *epf = epf_group->epf;
 
-   ret = pci_epc_add_epf(epc, epf);
+   ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
if (ret)
return ret;
 
ret = pci_epf_bind(epf);
if (ret) {
-   pci_epc_remove_epf(epc, epf);
+   pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
return ret;
}
 
@@ -119,7 +119,7 @@ static void pci_epc_epf_unlink(struct config_item *epc_item,
epc = epc_group->epc;
epf = epf_group->epf;
pci_epf_unbind(epf);
-   pci_epc_remove_epf(epc, epf);
+   pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
 }
 
 static struct configfs_item_operations pci_epc_item_ops = {
diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index 98acadbfc934..42085fcc746d 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -634,17 +634,21 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header);
  * pci_epc_add_epf() - bind PCI endpoint function to an endpoint controller
  * @epc: the EPC device to which the endpoint function should be added
  * @epf: the endpoint function to be added
+ * @type: Identifies if the EPC is connected to the primary or secondary
+ *interface of EPF
  *
  * A PCI endpoint device can have one or more functions. In the case of PCIe,
  * the specification allows up to 8 PCIe endpoint functions

[RFC PATCH 08/21] PCI: endpoint: Make *_get_first_free_bar() take into account 64 bit BAR

2019-09-26 Thread Kishon Vijay Abraham I
pci_epc_get_first_free_bar() uses only "reserved_bar" member in
epc_features to get the first unreserved BAR. However if the
reserved BAR is also a 64-bit BAR, then the next BAR shouldn't be
returned (since 64-bit BAR uses two BARs).

Make pci_epc_get_first_free_bar() take into account 64 bit BAR while
returning the first free unreserved BAR.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epc-core.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index 0c2fdd39090c..7eae7dcaebf9 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -153,12 +153,20 @@ EXPORT_SYMBOL_GPL(of_pci_epc_get_by_name);
 unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
*epc_features)
 {
-   int free_bar;
+   unsigned long free_bar;
 
if (!epc_features)
return 0;
 
-   free_bar = ffz(epc_features->reserved_bar);
+   /* Find if the reserved BAR is also a 64-bit BAR */
+   free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit;
+
+   /* Set the adjacent bit if the reserved BAR is also a 64-bit BAR */
+   free_bar <<= 1;
+   free_bar |= epc_features->reserved_bar;
+
+   /* Now find the free BAR */
+   free_bar = ffz(free_bar);
if (free_bar > 5)
return 0;
 
-- 
2.17.1



[RFC PATCH 20/21] NTB: Add support for EPF PCI-Express Non-Transparent Bridge

2019-09-26 Thread Kishon Vijay Abraham I
Add support for EPF PCI-Express Non-Transparent Bridge (NTB) device.
This driver is platform independent and could be used by any platform
which have multiple PCIe endpoint instances configured using the
pci-epf-ntb driver. The driver connnects to the standard NTB sub-system
interface. The EPF NTB device has configurable number of memory windows
(Max 4), configurable number of doorbell (Max 32), and configurable
number of scratch-pad registers.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/ntb/hw/Kconfig  |   1 +
 drivers/ntb/hw/Makefile |   1 +
 drivers/ntb/hw/epf/Kconfig  |   5 +
 drivers/ntb/hw/epf/Makefile |   1 +
 drivers/ntb/hw/epf/ntb_hw_epf.c | 648 
 5 files changed, 656 insertions(+)
 create mode 100644 drivers/ntb/hw/epf/Kconfig
 create mode 100644 drivers/ntb/hw/epf/Makefile
 create mode 100644 drivers/ntb/hw/epf/ntb_hw_epf.c

diff --git a/drivers/ntb/hw/Kconfig b/drivers/ntb/hw/Kconfig
index e51b581fd102..623d43a2bec0 100644
--- a/drivers/ntb/hw/Kconfig
+++ b/drivers/ntb/hw/Kconfig
@@ -1,4 +1,5 @@
 source "drivers/ntb/hw/amd/Kconfig"
 source "drivers/ntb/hw/idt/Kconfig"
 source "drivers/ntb/hw/intel/Kconfig"
+source "drivers/ntb/hw/epf/Kconfig"
 source "drivers/ntb/hw/mscc/Kconfig"
diff --git a/drivers/ntb/hw/Makefile b/drivers/ntb/hw/Makefile
index 923c442db750..48f672ca857a 100644
--- a/drivers/ntb/hw/Makefile
+++ b/drivers/ntb/hw/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_NTB_AMD)  += amd/
 obj-$(CONFIG_NTB_IDT)  += idt/
 obj-$(CONFIG_NTB_INTEL)+= intel/
+obj-$(CONFIG_NTB_EPF)  += epf/
 obj-$(CONFIG_NTB_SWITCHTEC) += mscc/
diff --git a/drivers/ntb/hw/epf/Kconfig b/drivers/ntb/hw/epf/Kconfig
new file mode 100644
index ..314485574bf8
--- /dev/null
+++ b/drivers/ntb/hw/epf/Kconfig
@@ -0,0 +1,5 @@
+config NTB_EPF
+   tristate "Generic EPF Non-Transparent Bridge support"
+   help
+ This driver supports EPF NTB on configurable endpoint.
+ If unsure, say N.
diff --git a/drivers/ntb/hw/epf/Makefile b/drivers/ntb/hw/epf/Makefile
new file mode 100644
index ..2f560a422bc6
--- /dev/null
+++ b/drivers/ntb/hw/epf/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_NTB_EPF) += ntb_hw_epf.o
diff --git a/drivers/ntb/hw/epf/ntb_hw_epf.c b/drivers/ntb/hw/epf/ntb_hw_epf.c
new file mode 100644
index ..fba3d6f2
--- /dev/null
+++ b/drivers/ntb/hw/epf/ntb_hw_epf.c
@@ -0,0 +1,648 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * Host side endpoint driver to implement Non-Transparent Bridge functionality
+ *
+ * Copyright (C) 2019 Texas Instruments
+ * Author: Kishon Vijay Abraham I 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NTB_EPF_COMMAND0x0
+#define CMD_CONFIGURE_DOORBELL 1
+#define CMD_CONFIGURE_MW   2
+#define CMD_LINK_UP3
+
+#define NTB_EPF_ARGUMENT   0x4
+
+#define NTB_EPF_STATUS 0x8
+#define COMMAND_STATUS_OK  BIT(0)
+#define LINK_STATUS_UP BIT(1)
+
+#define NTB_EPF_TOPOLOGY   0xc
+#define NTB_EPF_ADDR   0x10
+#define NTB_EPF_SIZE   0x18
+#define NTB_EPF_MW1_OFFSET 0x1c
+#define NTB_EPF_MW_COUNT   0x20
+#define NTB_EPF_SPAD_OFFSET0x24
+#define NTB_EPF_SPAD_COUNT 0x28
+#define NTB_EPF_DB_ENTRY_SIZE  0x2c
+#define NTB_EPF_DB_DATA(n) (0x30 + (n) * 4)
+
+#define NTB_MIN_DB_COUNT   2
+#define NTB_MAX_DB_COUNT   32
+#define NTB_MW_OFFSET  2
+
+enum pci_barno {
+   BAR_0,
+   BAR_1,
+   BAR_2,
+   BAR_3,
+   BAR_4,
+   BAR_5,
+};
+
+struct ntb_epf_dev {
+   struct ntb_dev ntb;
+
+   enum pci_barno ctrl_reg_bar;
+   enum pci_barno peer_spad_reg_bar;
+   enum pci_barno db_reg_bar;
+
+   unsigned int mw_count;
+   unsigned int spad_count;
+   unsigned int db_count;
+
+   void __iomem *ctrl_reg;
+   void __iomem *db_reg;
+   void __iomem *peer_spad_reg;
+
+   unsigned int self_spad;
+   unsigned int peer_spad;
+
+   int db_val;
+   u64 db_valid_mask;
+};
+
+#define ntb_ndev(__ntb) container_of(__ntb, struct ntb_epf_dev, ntb)
+
+struct ntb_epf_data {
+   /* BAR that contains both control region and self spad region */
+   enum pci_barno ctrl_reg_bar;
+   /* BAR that contains peer spad region */
+   enum pci_barno peer_spad_reg_bar;
+   /* BAR that contains Doorbell region and Memory window '1' */
+   enum pci_barno db_reg_bar;
+};
+
+static inline u32 ntb_epf_ctrl_readl(struct ntb_epf_dev *ndev, u32 offset)
+{
+   return readl(ndev->ctrl_reg + offset);
+}
+
+static inline void ntb_epf_ctrl_writel(struct ntb_epf_dev *ndev, u32 offset,
+  u32 val)
+{
+   return writel(val, ndev->ctrl_reg + offset);
+}
+
+static int ntb_epf_send_command(struct ntb_epf_dev *ndev, u32 command,
+   u32 argument)
+{
+   ktime_t timeout;
+   bool timedout;
+   u32 status;
+
+   ntb_epf_ctrl_writel(ndev, 

[RFC PATCH 21/21] NTB: tool: Enable the NTB/PCIe link on the local or remote side of bridge

2019-09-26 Thread Kishon Vijay Abraham I
Invoke ntb_link_enable() to enable the NTB/PCIe link on the local
or remote side of the bridge.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/ntb/test/ntb_tool.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/ntb/test/ntb_tool.c b/drivers/ntb/test/ntb_tool.c
index d592c0ffbd19..04138e6a371b 100644
--- a/drivers/ntb/test/ntb_tool.c
+++ b/drivers/ntb/test/ntb_tool.c
@@ -1638,6 +1638,7 @@ static int tool_probe(struct ntb_client *self, struct 
ntb_dev *ntb)
 
tool_setup_dbgfs(tc);
 
+   ntb_link_enable(ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO);
return 0;
 
 err_clear_mws:
-- 
2.17.1



[RFC PATCH 18/21] PCI: endpoint: Add EP function driver to provide NTB functionality

2019-09-26 Thread Kishon Vijay Abraham I
Add a new endpoint function driver to provide NTB functionality
using multiple PCIe endpoint instances.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/functions/Kconfig   |   12 +
 drivers/pci/endpoint/functions/Makefile  |1 +
 drivers/pci/endpoint/functions/pci-epf-ntb.c | 1143 ++
 3 files changed, 1156 insertions(+)
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-ntb.c

diff --git a/drivers/pci/endpoint/functions/Kconfig 
b/drivers/pci/endpoint/functions/Kconfig
index 8820d0f7ec77..55ac7bb2d469 100644
--- a/drivers/pci/endpoint/functions/Kconfig
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -12,3 +12,15 @@ config PCI_EPF_TEST
   for PCI Endpoint.
 
   If in doubt, say "N" to disable Endpoint test driver.
+
+config PCI_EPF_NTB
+   tristate "PCI Endpoint NTB driver"
+   depends on PCI_ENDPOINT
+   help
+  Select this configuration option to enable the NTB driver
+  for PCI Endpoint. NTB driver implements NTB controller
+  functionality using multiple PCIe endpoint instances. It
+  can support NTB endpoint function devices created using
+  device tree.
+
+  If in doubt, say "N" to disable Endpoint NTB driver.
diff --git a/drivers/pci/endpoint/functions/Makefile 
b/drivers/pci/endpoint/functions/Makefile
index d6fafff080e2..96ab932a537a 100644
--- a/drivers/pci/endpoint/functions/Makefile
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_PCI_EPF_TEST) += pci-epf-test.o
+obj-$(CONFIG_PCI_EPF_NTB)  += pci-epf-ntb.o
diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c 
b/drivers/pci/endpoint/functions/pci-epf-ntb.c
new file mode 100644
index ..14b3862fc780
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
@@ -0,0 +1,1143 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * Endpoint Function Driver to implement Non-Transparent Bridge functionality
+ *
+ * Copyright (C) 2019 Texas Instruments
+ * Author: Kishon Vijay Abraham I 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static struct workqueue_struct *kpcintb_workqueue;
+
+#define COMMAND_CONFIGURE_DOORBELL 1
+#define COMMAND_CONFIGURE_MW   2
+#define COMMAND_LINK_UP3
+
+#define COMMAND_STATUS_OK  BIT(0)
+#define LINK_STATUS_UP BIT(1)
+
+#define SPAD_COUNT 64
+#define DB_COUNT   4
+#define NTB_MW_OFFSET  2
+#define DB_COUNT_MASK  GENMASK(15, 0)
+#define MSIX_ENABLEBIT(16)
+#define MAX_DB_COUNT   32
+#define MAX_MW 4
+
+enum epf_ntb_bar {
+   BAR_CONFIG,
+   BAR_PEER_SPAD,
+   BAR_DB_MW1,
+   BAR_MW2,
+   BAR_MW3,
+   BAR_MW4,
+};
+
+struct epf_ntb {
+   u32 num_mws;
+   u32 *mws_size;
+   u32 db_count;
+   u32 spad_count;
+   struct pci_epf *epf;
+   struct epf_ntb_epc *epc[2];
+};
+
+struct epf_ntb_epc {
+   u8 func_no;
+   u8 vfunc_no;
+   bool linkup;
+   u32 spad_size;
+   struct pci_epc *epc;
+   struct epf_ntb *epf_ntb;
+   void __iomem *mw_addr[6];
+   struct epf_ntb_ctrl *reg;
+   struct pci_epf_bar *epf_bar;
+   enum pci_barno epf_ntb_bar[6];
+   struct delayed_work cmd_handler;
+   enum pci_epc_interface_type type;
+   const struct pci_epc_features *epc_features;
+};
+
+struct epf_ntb_ctrl {
+   u32 command;
+   u32 argument;
+   u32 status;
+   u32 topology;
+   u64 addr;
+   u32 size;
+   u32 mw1_offset;
+   u32 num_mws;
+   u32 spad_offset;
+   u32 spad_count;
+   u32 db_entry_size;
+   u32 db_data[MAX_DB_COUNT];
+} __packed;
+
+static struct pci_epf_header epf_ntb_header = {
+   .vendorid   = PCI_ANY_ID,
+   .deviceid   = PCI_ANY_ID,
+   .baseclass_code = PCI_BASE_CLASS_MEMORY,
+   .interrupt_pin  = PCI_INTERRUPT_INTA,
+};
+
+static void epf_ntb_link_up(struct epf_ntb *ntb)
+{
+   enum pci_epc_interface_type type;
+   struct epf_ntb_epc *ntb_epc;
+   struct epf_ntb_ctrl *ctrl;
+   u8 vfunc_no, func_no;
+
+   for (type = PRIMARY_INTERFACE; type <= SECONDARY_INTERFACE; type++) {
+   ntb_epc = ntb->epc[type];
+   func_no = ntb_epc->func_no;
+   vfunc_no = ntb_epc->vfunc_no;
+   ctrl = ntb_epc->reg;
+   ctrl->status |= LINK_STATUS_UP;
+   pci_epc_raise_irq(ntb_epc->epc, func_no, vfunc_no,
+ PCI_EPC_IRQ_MSI, 1);
+   }
+}
+
+static void
+epf_ntb_configure_mw(struct epf_ntb *ntb, enum pci_epc_interface_type type,
+u32 mw)
+{
+   struct epf_ntb_epc *peer_ntb_epc;
+   struct pci_epf_bar *peer_epf_bar;
+   struct epf_ntb_epc *ntb_epc;
+   en

[RFC PATCH 19/21] PCI: Add TI J721E device to pci ids

2019-09-26 Thread Kishon Vijay Abraham I
Add TI J721E device to the pci id database. Since this device has
a configurable PCIe endpoint, it could be used with different
drivers.

Signed-off-by: Kishon Vijay Abraham I 
---
 include/linux/pci_ids.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index d157983b84cf..b2820a834a5e 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -868,6 +868,7 @@
 #define PCI_DEVICE_ID_TI_X620  0xac8d
 #define PCI_DEVICE_ID_TI_X420  0xac8e
 #define PCI_DEVICE_ID_TI_XX20_FM   0xac8f
+#define PCI_DEVICE_ID_TI_J721E 0xb00d
 #define PCI_DEVICE_ID_TI_DRA74x0xb500
 #define PCI_DEVICE_ID_TI_DRA72x0xb501
 
-- 
2.17.1



[RFC PATCH 17/21] PCI: endpoint: *_free_bar() to return error codes on failure

2019-09-26 Thread Kishon Vijay Abraham I
Modify pci_epc_get_next_free_bar() and pci_epc_get_first_free_bar() to
return error values if there are no free BARs available.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epc-core.c | 9 -
 include/linux/pci-epc.h | 7 +++
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index 33c745546a42..a93c78488bca 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -173,8 +173,7 @@ EXPORT_SYMBOL_GPL(of_pci_epc_get_by_name);
  * Invoke to get the first unreserved BAR that can be used by the 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 pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features)
 {
return pci_epc_get_next_free_bar(epc_features, BAR_0);
 }
@@ -188,8 +187,8 @@ EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
  * Invoke to get the next unreserved BAR starting from @bar that can be used
  * for endpoint function. For any incorrect value in reserved_bar return '0'.
  */
-unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
-  *epc_features, enum pci_barno bar)
+int pci_epc_get_next_free_bar(const struct pci_epc_features
+ *epc_features, enum pci_barno bar)
 {
unsigned long free_bar;
 
@@ -209,7 +208,7 @@ unsigned int pci_epc_get_next_free_bar(const struct 
pci_epc_features
 
free_bar = find_next_zero_bit(&free_bar, 6, bar);
if (free_bar > 5)
-   return 0;
+   return -EINVAL;
 
return free_bar;
 }
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 0632a4d4714d..ad8021b0efb7 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -227,10 +227,9 @@ void pci_epc_of_parse_header(struct device_node *node,
 struct pci_epf_header *header);
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
u8 func_no, u8 vfunc_no);
-unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
-   *epc_features);
-unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features
-  *epc_features, enum pci_barno bar);
+int pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
+int pci_epc_get_next_free_bar(const struct pci_epc_features
+ *epc_features, enum pci_barno bar);
 struct pci_epc *pci_epc_get(const char *epc_name);
 void pci_epc_put(struct pci_epc *epc);
 struct pci_epc *of_pci_epc_get(struct device_node *node, int index);
-- 
2.17.1



[RFC PATCH 16/21] PCI: endpoint: Fix missing mutex_unlock in error case

2019-09-26 Thread Kishon Vijay Abraham I
There is a missing mutex_unlock() in pci_epc_add_epf() in one of the
error scenarios. Fix it here.

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epc-core.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index 797e5d323998..33c745546a42 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -686,6 +686,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf 
*epf,
 {
struct list_head *list;
u32 func_no = 0;
+   int ret = 0;
 
if (epf->is_vf)
return -EINVAL;
@@ -705,8 +706,10 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf 
*epf,
mutex_lock(&epc->lock);
func_no = find_first_zero_bit(&epc->function_num_map,
  BITS_PER_LONG);
-   if (func_no >= BITS_PER_LONG)
-   return -EINVAL;
+   if (func_no >= BITS_PER_LONG) {
+   ret = -EINVAL;
+   goto err;
+   }
 
set_bit(func_no, &epc->function_num_map);
if (type == PRIMARY_INTERFACE) {
@@ -720,9 +723,11 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf 
*epf,
}
 
list_add_tail(list, &epc->pci_epf);
+
+err:
mutex_unlock(&epc->lock);
 
-   return 0;
+   return ret;
 }
 EXPORT_SYMBOL_GPL(pci_epc_add_epf);
 
-- 
2.17.1



[RFC PATCH 15/21] PCI: endpoint: Remove unused pci_epf_match_device()

2019-09-26 Thread Kishon Vijay Abraham I
Remove unused pci_epf_match_device() function added in pci-epf-core.c

Signed-off-by: Kishon Vijay Abraham I 
---
 drivers/pci/endpoint/pci-epf-core.c | 16 
 include/linux/pci-epf.h |  2 --
 2 files changed, 18 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epf-core.c 
b/drivers/pci/endpoint/pci-epf-core.c
index 388966faf17a..9fa4d8d4d829 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -619,22 +619,6 @@ struct pci_epf *devm_pci_epf_of_create(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_pci_epf_of_create);
 
-const struct pci_epf_device_id *
-pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf)
-{
-   if (!id || !epf)
-   return NULL;
-
-   while (*id->name) {
-   if (strcmp(epf->name, id->name) == 0)
-   return id;
-   id++;
-   }
-
-   return NULL;
-}
-EXPORT_SYMBOL_GPL(pci_epf_match_device);
-
 static void pci_epf_dev_release(struct device *dev)
 {
struct pci_epf *epf = to_pci_epf(dev);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index b5075119f3ad..80505106c770 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -189,8 +189,6 @@ static inline void *epf_get_drvdata(struct pci_epf *epf)
return dev_get_drvdata(&epf->dev);
 }
 
-const struct pci_epf_device_id *
-pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf);
 struct pci_epf *pci_epf_create(const char *name);
 struct pci_epf *pci_epf_of_create(struct device_node *node);
 struct pci_epf *devm_pci_epf_of_create(struct device *dev,
-- 
2.17.1



Re: [RFC PATCH] x86/doc/boot_protocol: Correct the description of "reloc"

2019-09-26 Thread Randy Dunlap
On 9/26/19 12:58 AM, h...@zytor.com wrote:
> On September 26, 2019 12:55:51 AM PDT, Cao jin  
> wrote:
>> On 9/26/19 2:01 PM, Ingo Molnar wrote:
>>> * Cao jin  wrote:
>>>
 The fields marked with (reloc) actually are not dedicated for
>> writing,
 but communicating info for relocatable kernel with boot loaders. For
 example:

 
 Field name: pref_address
 Type:   read (reloc)
 Offset/size:0x258/8
 Protocol:   2.10+
 

 
 Field name: code32_start
 Type:   modify (optional, reloc)
 Offset/size:0x214/4
 Protocol:   2.00+
 

 Signed-off-by: Cao jin 
 ---
 Unless I have incorrect non-native understanding for "fill in", I
>> think
 this is inaccurate.

  Documentation/x86/boot.rst | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst
 index 08a2f100c0e6..a611bf04492d 100644
 --- a/Documentation/x86/boot.rst
 +++ b/Documentation/x86/boot.rst
 @@ -243,7 +243,7 @@ bootloader ("modify").
  
  All general purpose boot loaders should write the fields marked
  (obligatory).  Boot loaders who want to load the kernel at a
 -nonstandard address should fill in the fields marked (reloc); other
 +nonstandard address should consult with the fields marked (reloc);
>> other
  boot loaders can ignore those fields.
  
  The byte order of all fields is littleendian (this is x86, after
>> all.)
>>>
>>> Well, this documentation is written from the point of view of a 
>>> *bootloader*, not the kernel. So the 'fill in' says that the
>> bootloader 
>>> should write those fields - which is correct, right?
>>>
>>
>> Take pref_address or relocatable_kernel for example, they have type:
>> read (reloc), does boot loader need to write them? I don't see grub
>> does
>> this at least.
> 
> Read means the boot later reads them.

is that  boot loader ??


-- 
~Randy


Re: [PATCH 1/3] docs: fix some broken references

2019-09-26 Thread Shannon Nelson

On 9/24/19 6:01 AM, Mauro Carvalho Chehab wrote:

There are a number of documentation files that got moved or
renamed. update their references.

Signed-off-by: Mauro Carvalho Chehab 



  drivers/net/ethernet/pensando/ionic/ionic_if.h| 4 ++--


Acked-by: Shannon Nelson 



Re: [RFC PATCH] x86/doc/boot_protocol: Correct the description of "reloc"

2019-09-26 Thread hpa
On September 26, 2019 8:20:28 AM PDT, Randy Dunlap  
wrote:
>On 9/26/19 12:58 AM, h...@zytor.com wrote:
>> On September 26, 2019 12:55:51 AM PDT, Cao jin
> wrote:
>>> On 9/26/19 2:01 PM, Ingo Molnar wrote:
 * Cao jin  wrote:

> The fields marked with (reloc) actually are not dedicated for
>>> writing,
> but communicating info for relocatable kernel with boot loaders.
>For
> example:
>
> 
> Field name: pref_address
> Type:   read (reloc)
> Offset/size:0x258/8
> Protocol:   2.10+
> 
>
> 
> Field name: code32_start
> Type:   modify (optional, reloc)
> Offset/size:0x214/4
> Protocol:   2.00+
> 
>
> Signed-off-by: Cao jin 
> ---
> Unless I have incorrect non-native understanding for "fill in", I
>>> think
> this is inaccurate.
>
>  Documentation/x86/boot.rst | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/x86/boot.rst
>b/Documentation/x86/boot.rst
> index 08a2f100c0e6..a611bf04492d 100644
> --- a/Documentation/x86/boot.rst
> +++ b/Documentation/x86/boot.rst
> @@ -243,7 +243,7 @@ bootloader ("modify").
>  
>  All general purpose boot loaders should write the fields marked
>  (obligatory).  Boot loaders who want to load the kernel at a
> -nonstandard address should fill in the fields marked (reloc);
>other
> +nonstandard address should consult with the fields marked
>(reloc);
>>> other
>  boot loaders can ignore those fields.
>  
>  The byte order of all fields is littleendian (this is x86, after
>>> all.)

 Well, this documentation is written from the point of view of a 
 *bootloader*, not the kernel. So the 'fill in' says that the
>>> bootloader 
 should write those fields - which is correct, right?

>>>
>>> Take pref_address or relocatable_kernel for example, they have type:
>>> read (reloc), does boot loader need to write them? I don't see grub
>>> does
>>> this at least.
>> 
>> Read means the boot later reads them.
>
>is that  boot loader ??

Yes, stupid autocorrect.
-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


Re: [RFC PATCH] x86/doc/boot_protocol: Correct the description of "reloc"

2019-09-26 Thread hpa
On September 26, 2019 1:20:02 AM PDT, Cao jin  wrote:
>On 9/26/19 3:58 PM, h...@zytor.com wrote:
>> On September 26, 2019 12:55:51 AM PDT, Cao jin
> wrote:
>>> On 9/26/19 2:01 PM, Ingo Molnar wrote:
 * Cao jin  wrote:

> The fields marked with (reloc) actually are not dedicated for
>>> writing,
> but communicating info for relocatable kernel with boot loaders.
>For
> example:
>
> 
> Field name: pref_address
> Type:   read (reloc)
> Offset/size:0x258/8
> Protocol:   2.10+
> 
>
> 
> Field name: code32_start
> Type:   modify (optional, reloc)
> Offset/size:0x214/4
> Protocol:   2.00+
> 
>
> Signed-off-by: Cao jin 
> ---
> Unless I have incorrect non-native understanding for "fill in", I
>>> think
> this is inaccurate.
>
>  Documentation/x86/boot.rst | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/x86/boot.rst
>b/Documentation/x86/boot.rst
> index 08a2f100c0e6..a611bf04492d 100644
> --- a/Documentation/x86/boot.rst
> +++ b/Documentation/x86/boot.rst
> @@ -243,7 +243,7 @@ bootloader ("modify").
>  
>  All general purpose boot loaders should write the fields marked
>  (obligatory).  Boot loaders who want to load the kernel at a
> -nonstandard address should fill in the fields marked (reloc);
>other
> +nonstandard address should consult with the fields marked
>(reloc);
>>> other
>  boot loaders can ignore those fields.
>  
>  The byte order of all fields is littleendian (this is x86, after
>>> all.)

 Well, this documentation is written from the point of view of a 
 *bootloader*, not the kernel. So the 'fill in' says that the
>>> bootloader 
 should write those fields - which is correct, right?

>>>
>>> Take pref_address or relocatable_kernel for example, they have type:
>>> read (reloc), does boot loader need to write them? I don't see grub
>>> does
>>> this at least.
>> 
>> Read means the boot later reads them.
>> 
>
>Sorry I don't know what is going wrong in my mind. For me, if
>pref_address has "read (reloc)", base on the current document, it means
>boot loader will read it and also write it, which is conflicting. And
>the purpose of pref_address should just inform boot loader that kernel
>whats itself to be loaded at certain address, it don't want to be
>written.

read (reloc) means it is information for the boot loader to read, but that it 
can ignore it completely if it does not want to relocate the kernel.
-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


Re: [RFC PATCH] x86/doc/boot_protocol: Correct the description of "reloc"

2019-09-26 Thread Cao jin
On 9/27/19 3:18 AM, h...@zytor.com wrote:
> On September 26, 2019 1:20:02 AM PDT, Cao jin  
> wrote:
>> On 9/26/19 3:58 PM, h...@zytor.com wrote:
>>> On September 26, 2019 12:55:51 AM PDT, Cao jin
>>  wrote:
 On 9/26/19 2:01 PM, Ingo Molnar wrote:
> * Cao jin  wrote:
>
>> The fields marked with (reloc) actually are not dedicated for
 writing,
>> but communicating info for relocatable kernel with boot loaders.
>> For
>> example:
>>
>> 
>> Field name: pref_address
>> Type:   read (reloc)
>> Offset/size:0x258/8
>> Protocol:   2.10+
>> 
>>
>> 
>> Field name: code32_start
>> Type:   modify (optional, reloc)
>> Offset/size:0x214/4
>> Protocol:   2.00+
>> 
>>
>> Signed-off-by: Cao jin 
>> ---
>> Unless I have incorrect non-native understanding for "fill in", I
 think
>> this is inaccurate.
>>
>>  Documentation/x86/boot.rst | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/Documentation/x86/boot.rst
>> b/Documentation/x86/boot.rst
>> index 08a2f100c0e6..a611bf04492d 100644
>> --- a/Documentation/x86/boot.rst
>> +++ b/Documentation/x86/boot.rst
>> @@ -243,7 +243,7 @@ bootloader ("modify").
>>  
>>  All general purpose boot loaders should write the fields marked
>>  (obligatory).  Boot loaders who want to load the kernel at a
>> -nonstandard address should fill in the fields marked (reloc);
>> other
>> +nonstandard address should consult with the fields marked
>> (reloc);
 other
>>  boot loaders can ignore those fields.
>>  
>>  The byte order of all fields is littleendian (this is x86, after
 all.)
>
> Well, this documentation is written from the point of view of a 
> *bootloader*, not the kernel. So the 'fill in' says that the
 bootloader 
> should write those fields - which is correct, right?
>

 Take pref_address or relocatable_kernel for example, they have type:
 read (reloc), does boot loader need to write them? I don't see grub
 does
 this at least.
>>>
>>> Read means the boot later reads them.
>>>
>>
>> Sorry I don't know what is going wrong in my mind. For me, if
>> pref_address has "read (reloc)", base on the current document, it means
>> boot loader will read it and also write it, which is conflicting. And
>> the purpose of pref_address should just inform boot loader that kernel
>> whats itself to be loaded at certain address, it don't want to be
>> written.
> 
> read (reloc) means it is information for the boot loader to read, but that it 
> can ignore it completely if it does not want to relocate the kernel.
> 

so, "read (reloc)" also means boot loader can't write it, right?

Please bear my verbiage, see protocol explanation for "(reloc)":

"Boot loaders who want to load the kernel at a nonstandard address
should fill in the fields marked (reloc);"

Doesn't the explanation means: if boot loaders want to relocate the
kernel, they should write pref_address?

And while pref_address actually just provide a suggestion to boot
loader, loader could take it or not as you said, but won't write it.
That is why I choose the word "consult with" instead of "fill in".
-- 
Sincerely,
Cao jin