Hello,

On 04/08/2015 03:47 PM, Simon Glass wrote:
Hi Przemyslaw,

On 8 April 2015 at 07:01, Przemyslaw Marczak <p.marc...@samsung.com> wrote:
This commit adds 'uclass_platdata' field to 'struct udevice', which
can be automatically allocated at bind. The allocation size is defined
in 'struct uclass_driver' as 'per_device_platdata_auto_alloc_size'.

New device's flag is added: DM_FLAG_ALLOC_UCLASS_PDATA, which is used
for memory freeing at device unbind method.

As for other udevice's fields, a complementary function is added:
- dev_get_uclass_platdata()

Signed-off-by: Przemyslaw Marczak <p.marc...@samsung.com>
Cc: Simon Glass <s...@chromium.org>
---
  drivers/core/device-remove.c |  4 ++++
  drivers/core/device.c        | 33 +++++++++++++++++++++++++++++----
  include/dm/device.h          | 17 ++++++++++++++++-
  include/dm/uclass.h          |  4 ++++
  4 files changed, 53 insertions(+), 5 deletions(-)

Acked-by: Simon Glass <s...@chromium.org>

(one nit below)


diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index 7fee1c0..6a16b4f 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -92,6 +92,10 @@ int device_unbind(struct udevice *dev)
                 free(dev->platdata);
                 dev->platdata = NULL;
         }
+       if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
+               free(dev->uclass_platdata);
+               dev->uclass_platdata = NULL;
+       }
         if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
                 free(dev->parent_platdata);
                 dev->parent_platdata = NULL;
diff --git a/drivers/core/device.c b/drivers/core/device.c
index ccaa99c..c93141b 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -30,7 +30,7 @@ int device_bind(struct udevice *parent, const struct driver 
*drv,
  {
         struct udevice *dev;
         struct uclass *uc;
-       int ret = 0;
+       int size = 0, ret = 0;

nit: I don't think you need = 0 on size.


Ok, will fix.


         *devp = NULL;
         if (!name)
@@ -79,9 +79,19 @@ int device_bind(struct udevice *parent, const struct driver 
*drv,
                         goto fail_alloc1;
                 }
         }
-       if (parent) {
-               int size = parent->driver->per_child_platdata_auto_alloc_size;

+       size = uc->uc_drv->per_device_platdata_auto_alloc_size;
+       if (size) {
+               dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA;
+               dev->uclass_platdata = calloc(1, size);
+               if (!dev->uclass_platdata) {
+                       ret = -ENOMEM;
+                       goto fail_alloc2;
+               }
+       }
+
+       if (parent) {
+               size = parent->driver->per_child_platdata_auto_alloc_size;
                 if (!size) {
                         size = parent->uclass->uc_drv->
                                         per_child_platdata_auto_alloc_size;
@@ -91,7 +101,7 @@ int device_bind(struct udevice *parent, const struct driver 
*drv,
                         dev->parent_platdata = calloc(1, size);
                         if (!dev->parent_platdata) {
                                 ret = -ENOMEM;
-                               goto fail_alloc2;
+                               goto fail_alloc3;
                         }
                 }
         }
@@ -139,6 +149,11 @@ fail_uclass_bind:
                 free(dev->parent_platdata);
                 dev->parent_platdata = NULL;
         }
+fail_alloc3:
+       if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
+               free(dev->uclass_platdata);
+               dev->uclass_platdata = NULL;
+       }
  fail_alloc2:
         if (dev->flags & DM_FLAG_ALLOC_PDATA) {
                 free(dev->platdata);
@@ -314,6 +329,16 @@ void *dev_get_parent_platdata(struct udevice *dev)
         return dev->parent_platdata;
  }

+void *dev_get_uclass_platdata(struct udevice *dev)
+{
+       if (!dev) {
+               dm_warn("%s: null device", __func__);
+               return NULL;
+       }
+
+       return dev->uclass_platdata;
+}
+
  void *dev_get_priv(struct udevice *dev)
  {
         if (!dev) {
diff --git a/include/dm/device.h b/include/dm/device.h
index c11342c..ad002fe 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -30,8 +30,11 @@ struct driver_info;
  /* DM is responsible for allocating and freeing parent_platdata */
  #define DM_FLAG_ALLOC_PARENT_PDATA     (1 << 3)

+/* DM is responsible for allocating and freeing uclass_platdata */
+#define DM_FLAG_ALLOC_UCLASS_PDATA     (1 << 4)
+
  /* Allocate driver private data on a DMA boundary */
-#define DM_FLAG_ALLOC_PRIV_DMA (1 << 4)
+#define DM_FLAG_ALLOC_PRIV_DMA (1 << 5)

  /**
   * struct udevice - An instance of a driver
@@ -54,6 +57,7 @@ struct driver_info;
   * @name: Name of device, typically the FDT node name
   * @platdata: Configuration data for this device
   * @parent_platdata: The parent bus's configuration data for this device
+ * @uclass_platdata: The uclass's configuration data for this device
   * @of_offset: Device tree node offset for this device (- for none)
   * @driver_data: Driver data word for the entry that matched this device with
   *             its driver
@@ -75,6 +79,7 @@ struct udevice {
         const char *name;
         void *platdata;
         void *parent_platdata;
+       void *uclass_platdata;
         int of_offset;
         ulong driver_data;
         struct udevice *parent;
@@ -210,6 +215,16 @@ void *dev_get_platdata(struct udevice *dev);
  void *dev_get_parent_platdata(struct udevice *dev);

  /**
+ * dev_get_uclass_platdata() - Get the uclass platform data for a device
+ *
+ * This checks that dev is not NULL, but no other checks for now
+ *
+ * @dev                Device to check
+ * @return uclass's platform data, or NULL if none
+ */
+void *dev_get_uclass_platdata(struct udevice *dev);
+
+/**
   * dev_get_parentdata() - Get the parent data for a device
   *
   * The parent data is data stored in the device but owned by the parent.
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index d57d804..b271472 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -65,6 +65,9 @@ struct udevice;
   * @per_device_auto_alloc_size: Each device can hold private data owned
   * by the uclass. If required this will be automatically allocated if this
   * value is non-zero.
+ * @per_device_platdata_auto_alloc_size: Each device can hold platform data
+ * owned by the uclass as 'dev->uclass_platdata'. If the value is non-zero,
+ * then this will be automatically allocated.
   * @per_child_auto_alloc_size: Each child device (of a parent in this
   * uclass) can hold parent data for the device/uclass. This value is only
   * used as a falback if this member is 0 in the driver.
@@ -90,6 +93,7 @@ struct uclass_driver {
         int (*destroy)(struct uclass *class);
         int priv_auto_alloc_size;
         int per_device_auto_alloc_size;
+       int per_device_platdata_auto_alloc_size;
         int per_child_auto_alloc_size;
         int per_child_platdata_auto_alloc_size;
         const void *ops;
--
1.9.1


Regards,
Simon


Thanks,
--
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marc...@samsung.com
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to