PCI: endpoint: Add pci_epf_ops to expose function-specific attrs
authorKishon Vijay Abraham I <kishon@ti.com>
Mon, 1 Feb 2021 19:58:01 +0000 (01:28 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 23 Feb 2021 20:11:31 +0000 (14:11 -0600)
In addition to the attributes that are generic across function drivers
documented in Documentation/PCI/endpoint/pci-endpoint-cfs.rst, there could
be function-specific attributes that has to be exposed by the function
driver to be configured by the user. Add ->add_cfs() in pci_epf_ops to be
populated by the function driver if it has to expose any function-specific
attributes and pci_epf_type_add_cfs() to be invoked by pci-ep-cfs.c when
sub-directory to main function directory is created.

Link: https://lore.kernel.org/r/20210201195809.7342-10-kishon@ti.com
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/endpoint/pci-epf-core.c
include/linux/pci-epf.h

index 79329ec..7646c86 100644 (file)
@@ -21,6 +21,38 @@ static struct bus_type pci_epf_bus_type;
 static const struct device_type pci_epf_type;
 
 /**
+ * pci_epf_type_add_cfs() - Help function drivers to expose function specific
+ *                          attributes in configfs
+ * @epf: the EPF device that has to be configured using configfs
+ * @group: the parent configfs group (corresponding to entries in
+ *         pci_epf_device_id)
+ *
+ * Invoke to expose function specific attributes in configfs. If the function
+ * driver does not have anything to expose (attributes configured by user),
+ * return NULL.
+ */
+struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
+                                         struct config_group *group)
+{
+       struct config_group *epf_type_group;
+
+       if (!epf->driver) {
+               dev_err(&epf->dev, "epf device not bound to driver\n");
+               return NULL;
+       }
+
+       if (!epf->driver->ops->add_cfs)
+               return NULL;
+
+       mutex_lock(&epf->lock);
+       epf_type_group = epf->driver->ops->add_cfs(epf, group);
+       mutex_unlock(&epf->lock);
+
+       return epf_type_group;
+}
+EXPORT_SYMBOL_GPL(pci_epf_type_add_cfs);
+
+/**
  * pci_epf_unbind() - Notify the function driver that the binding between the
  *                   EPF device and EPC device has been lost
  * @epf: the EPF device which has lost the binding with the EPC device
index 1dc6682..b241e7d 100644 (file)
@@ -62,10 +62,13 @@ struct pci_epf_header {
  * @bind: ops to perform when a EPC device has been bound to EPF device
  * @unbind: ops to perform when a binding has been lost between a EPC device
  *         and EPF device
+ * @add_cfs: ops to initialize function specific configfs attributes
  */
 struct pci_epf_ops {
        int     (*bind)(struct pci_epf *epf);
        void    (*unbind)(struct pci_epf *epf);
+       struct config_group *(*add_cfs)(struct pci_epf *epf,
+                                       struct config_group *group);
 };
 
 /**
@@ -188,4 +191,6 @@ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
                        enum pci_epc_interface_type type);
 int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
+struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
+                                         struct config_group *group);
 #endif /* __LINUX_PCI_EPF_H */