Hi Kevin,

On Tue, Sep 27, 2011 at 1:53 AM, Kevin Hilman <khil...@ti.com> wrote:
> Benoit did just this in preparation for DT.
>
>       http://marc.info/?l=linux-omap&m=131672480111927&w=2
>
> Will that meet your needs?

It's almost there, but not entirely.

Benoit's alloc/delete functions focus on the omap_device part, leaving
the handling of the platform device (allocation and pdata setting) to
omap_device_build_ss(), which at the same time registers the pdev.

I'd need to split omap_device_build_ss() into two: an alloc() part
which does everything but registering the pdev, and a register() part.
Users will first call alloc(), manually set archdata members, and then
call the register() part.

Something like this (compile-tested only, based on Benoit's
for_3.2/4_omap4_dt_early_devices branch):

diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 0ae9e7f..9b8008c 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -671,7 +671,7 @@ struct platform_device *omap_device_build(const
char *pdev_name, int pdev_id,
 }

 /**
- * omap_device_build_ss - build and register an omap_device with
multiple hwmods
+ * omap_device_alloc_ss - build an omap_device with multiple hwmods
  * @pdev_name: name of the platform_device driver to use
  * @pdev_id: this platform_device's connection ID
  * @oh: ptr to the single omap_hwmod that backs this omap_device
@@ -679,19 +679,19 @@ struct platform_device *omap_device_build(const
char *pdev_name, int pdev_id,
  * @pdata_len: amount of memory pointed to by @pdata
  * @pm_lats: pointer to a omap_device_pm_latency array for this device
  * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
- * @is_early_device: should the device be registered as an early device or not
  *
- * Convenience function for building and registering an omap_device
+ * Convenience function for building (only) an omap_device
  * subsystem record.  Subsystem records consist of multiple
- * omap_hwmods.  This function in turn builds and registers a
- * platform_device record.  Returns an ERR_PTR() on error, or passes
- * along the return value of omap_device_register().
+ * omap_hwmods.  This function in turn builds (but doesn't register) a
+ * platform_device record, so callers can manipulate it (typically by
+ * setting one or more archdata members) before it's registered.
+ * Returns an ERR_PTR() on error, or the allocated pdev on success.
  */
-struct platform_device *omap_device_build_ss(const char *pdev_name,
int pdev_id,
+struct platform_device *omap_device_alloc_ss(const char *pdev_name,
int pdev_id,
                                         struct omap_hwmod **ohs, int oh_cnt,
                                         void *pdata, int pdata_len,
                                         struct omap_device_pm_latency *pm_lats,
-                                        int pm_lats_cnt, int is_early_device)
+                                        int pm_lats_cnt)
 {
        int ret = -ENOMEM;
        struct platform_device *pdev;
@@ -723,13 +723,6 @@ struct platform_device
*omap_device_build_ss(const char *pdev_name, int pdev_id,
        if (ret)
                goto odbs_exit2;

-       if (is_early_device)
-               ret = omap_early_device_register(pdev);
-       else
-               ret = omap_device_register(pdev);
-       if (ret)
-               goto odbs_exit2;
-
        return pdev;

 odbs_exit2:
@@ -744,6 +737,93 @@ odbs_exit:
 }

 /**
+ * omap_device_delete_ss - free an omap_device-based platform device
+ * @pdev: platform_device that represents this omap_device
+ *
+ * Convenience function for freeing a platform_device record, which
+ * is based on an omap_device subsystem record.
+ *
+ * Use this function only if @pdev was created using omap_device_alloc_ss(),
+ * most commonly because a subsequent call to omap_device_register_ss() failed.
+ */
+void omap_device_delete_ss(struct platform_device *pdev)
+{
+       struct omap_device *od = to_omap_device(pdev);
+
+       omap_device_delete(od);
+       platform_device_put(pdev);
+}
+
+/**
+ * omap_device_register_ss - register an omap_device-based platform device
+ * @pdev: platform_device that represents this omap_device
+ * @is_early_device: should the device be registered as an early device or not
+ *
+ * Convenience function for registering a platform_device record, which
+ * is based on an omap_device subsystem record, which was created using
+ * omap_device_alloc_ss().
+ *
+ * Returns 0 on success, or an appropriate error value otherwise (essentially
+ * by returning the value of platform_device_register())
+ */
+int omap_device_register_ss(struct platform_device *pdev, int is_early_device)
+{
+       int ret;
+
+       if (is_early_device)
+               ret = omap_early_device_register(pdev);
+       else
+               ret = omap_device_register(pdev);
+
+       return ret;
+}
+
+/**
+ * omap_device_build_ss - build and register an omap_device with
multiple hwmods
+ * @pdev_name: name of the platform_device driver to use
+ * @pdev_id: this platform_device's connection ID
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ * @is_early_device: should the device be registered as an early device or not
+ *
+ * Convenience function for building and registering an omap_device
+ * subsystem record.  Subsystem records consist of multiple
+ * omap_hwmods.  This function in turn builds and registers a
+ * platform_device record.  Returns an ERR_PTR() on error, or passes
+ * along the built pdev on success.
+ */
+struct platform_device *omap_device_build_ss(const char *pdev_name,
int pdev_id,
+                                        struct omap_hwmod **ohs, int oh_cnt,
+                                        void *pdata, int pdata_len,
+                                        struct omap_device_pm_latency *pm_lats,
+                                        int pm_lats_cnt, int is_early_device)
+{
+       struct platform_device *pdev;
+       int ret;
+
+       pdev = omap_device_alloc_ss(pdev_name, pdev_id, ohs, oh_cnt, pdata,
+                       pdata_len, pm_lats, pm_lats_cnt);
+
+       if (IS_ERR(pdev))
+               goto out;
+
+       ret = omap_device_register_ss(pdev, is_early_device);
+       if (ret) {
+               pdev = ERR_PTR(ret);
+               goto delete_od;
+       }
+
+       return pdev;
+delete_od:
+       omap_device_delete_ss(pdev);
+out:
+       return pdev;
+}
+
+/**
  * omap_early_device_register - register an omap_device as an early platform
  * device.
  * @od: struct omap_device * to register


That's the idea; please tell me how you'd like to see this go forward
(there are at least several personal-taste issues here, e.g., naming:
now we have two sets of alloc/delete functions which have different
semantics) and which branch would you like me to base this work off of
(not sure if Benoit's patches already went into your
for_3.2/omap_device branch) and I'll respin this patch properly.

Thanks a lot!
Ohad.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to