diff mbox series

[RFC,4/7] dm: uclass: add functions to get device by platdata

Message ID 20200330033158.26751-5-walter.lozano@collabora.com
State New
Headers show
Series mx6cuboxi: enable OF_PLATDATA with MMC support | expand

Commit Message

Walter Lozano March 30, 2020, 3:31 a.m. UTC
When OF_PLATDATA is enabled DT information is parsed and platdata
structures are populated. In this context the links between DT nodes are
represented as pointers to platdata structures, and there is no clear way
to access to the device which owns the structure.

This patch implements a set of functions:

- device_find_by_platdata
- uclass_find_device_by_platdata

to access to the device.

Signed-off-by: Walter Lozano <walter.lozano at collabora.com>
---
 drivers/core/device.c        | 19 +++++++++++++++++++
 drivers/core/uclass.c        | 34 ++++++++++++++++++++++++++++++++++
 include/dm/device.h          | 11 +++++++++++
 include/dm/uclass-internal.h | 15 +++++++++++++++
 include/dm/uclass.h          | 15 +++++++++++++++
 5 files changed, 94 insertions(+)
diff mbox series

Patch

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 89ea820d48..54a3a8d870 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -591,6 +591,25 @@  static int device_find_by_ofnode(ofnode node, struct udevice **devp)
 }
 #endif
 
+
+int device_find_by_platdata(void *platdata, struct udevice **devp)
+{
+	struct uclass *uc;
+	struct udevice *dev;
+	int ret;
+
+	list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+		ret = uclass_find_device_by_platdata(uc->uc_drv->id, platdata,
+						   &dev);
+		if (!ret || dev) {
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
 int device_get_child(const struct udevice *parent, int index,
 		     struct udevice **devp)
 {
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 58b19a4210..7b0ae5b122 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -271,6 +271,29 @@  int uclass_find_device_by_name(enum uclass_id id, const char *name,
 	return -ENODEV;
 }
 
+int uclass_find_device_by_platdata(enum uclass_id id, void * platdata, struct udevice **devp)
+{
+	struct uclass *uc;
+	struct udevice *dev;
+	int ret;
+
+	*devp = NULL;
+	ret = uclass_get(id, &uc);
+	if (ret)
+		return ret;
+	if (list_empty(&uc->dev_head))
+		return -ENODEV;
+
+	uclass_foreach_dev(dev, uc) {
+		if (dev->platdata == platdata) {
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
 int uclass_find_next_free_req_seq(enum uclass_id id)
 {
 	struct uclass *uc;
@@ -466,6 +489,17 @@  int uclass_get_device_by_name(enum uclass_id id, const char *name,
 	return uclass_get_device_tail(dev, ret, devp);
 }
 
+int uclass_get_device_by_platdata(enum uclass_id id, void * platdata,
+			      struct udevice **devp)
+{
+	struct udevice *dev;
+	int ret;
+
+	*devp = NULL;
+	ret = uclass_find_device_by_platdata(id, platdata, &dev);
+	return uclass_get_device_tail(dev, ret, devp);
+}
+
 int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp)
 {
 	struct udevice *dev;
diff --git a/include/dm/device.h b/include/dm/device.h
index ab806d0b7e..6282376789 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -396,6 +396,17 @@  enum uclass_id device_get_uclass_id(const struct udevice *dev);
  */
 const char *dev_get_uclass_name(const struct udevice *dev);
 
+/**
+ * device_find_by_platdata() - return the device by its platdata
+ *
+ * Returns the device which onws the platdata structure pointed.
+ *
+ * @platdata:	Struct platdata to use for search
+ * @devp:	Returns pointer to device
+ * @return  error code
+ */
+int device_find_by_platdata(void *platdata, struct udevice **devp);
+
 /**
  * device_get_child() - Get the child of a device by index
  *
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index 6e3f15c2b0..aeff1ec127 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -100,6 +100,21 @@  int uclass_find_next_device(struct udevice **devp);
 int uclass_find_device_by_name(enum uclass_id id, const char *name,
 			       struct udevice **devp);
 
+/**
+ * uclass_find_device_by_platdata() - Find uclass device based on ID and platdata
+ *
+ * This searches for a device with the exactly given platada.
+ *
+ * The device is NOT probed, it is merely returned.
+ *
+ * @id: ID to look up
+ * @platdata: pointer to struct platdata of a device to find
+ * @devp: Returns pointer to device
+ * @return 0 if OK, -ve on error
+ */
+int uclass_find_device_by_platdata(enum uclass_id id, void *platdata,
+			       struct udevice **devp);
+
 /**
  * uclass_find_device_by_seq() - Find uclass device based on ID and sequence
  *
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index 70fca79b44..8429b28289 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -167,6 +167,21 @@  int uclass_get_device(enum uclass_id id, int index, struct udevice **devp);
 int uclass_get_device_by_name(enum uclass_id id, const char *name,
 			      struct udevice **devp);
 
+/**
+ * uclass_get_device_by_platdata() - Get a uclass device by its platdata
+ *
+ * This searches the devices in the uclass for one with the exactly given platdata.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @id: ID to look up
+ * @platdata: pointer to struct platdata of a device to get
+ * @devp: Returns pointer to device (the first one with the name)
+ * @return 0 if OK, -ve on error
+ */
+int uclass_get_device_by_platdata(enum uclass_id id, void *platdata,
+			      struct udevice **devp);
+
 /**
  * uclass_get_device_by_seq() - Get a uclass device based on an ID and sequence
  *