Re: [U-Boot] [PATCH u-boot] reset: Add get/assert/deassert/release for bulk of reset signals

2018-03-31 Thread Simon Glass
Hi Neil,

On 30 March 2018 at 16:54, Neil Armstrong  wrote:
>
> This patch adds a "bulk" API to the reset API in order to get/deassert/
> assert/release a group of reset signals associated with a device.
>
> This bulk API will avoid adding a copy of the same code to manage
> a group of reset signals in drivers.
>
> Signed-off-by: Neil Armstrong 
> ---
> This serie and the "clk bulk" serie is necessary and suggested by Marek Vasut
> for the "Add USB Support for Amlogic Meson GXL SoCs" to avoid adding the same
> code to manage a bulk of clocks and resets in another driver.
> I will push a RFC code to update the other drivers having a similar
> code pattern when these patches are merged.
>
>  drivers/reset/reset-uclass.c | 60 +++
>  include/reset.h  | 99 
> 
>  2 files changed, 159 insertions(+)
>

This looks good. Please can you add a sandbox test?

Regards,
Simon
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH u-boot] reset: Add get/assert/deassert/release for bulk of reset signals

2018-03-30 Thread Neil Armstrong
This patch adds a "bulk" API to the reset API in order to get/deassert/
assert/release a group of reset signals associated with a device.

This bulk API will avoid adding a copy of the same code to manage
a group of reset signals in drivers.

Signed-off-by: Neil Armstrong 
---
This serie and the "clk bulk" serie is necessary and suggested by Marek Vasut
for the "Add USB Support for Amlogic Meson GXL SoCs" to avoid adding the same
code to manage a bulk of clocks and resets in another driver.
I will push a RFC code to update the other drivers having a similar
code pattern when these patches are merged.

 drivers/reset/reset-uclass.c | 60 +++
 include/reset.h  | 99 
 2 files changed, 159 insertions(+)

diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index 307a297..9a5c9c9 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -81,6 +81,40 @@ int reset_get_by_index(struct udevice *dev, int index,
return 0;
 }
 
+int reset_get_bulk(struct udevice *dev, struct reset_ctl_bulk *bulk)
+{
+   int i, ret, err, count;
+   
+   bulk->count = 0;
+
+   count = dev_count_phandle_with_args(dev, "resets", "#reset-cells");
+   if (!count)
+   return 0;
+
+   bulk->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
+   GFP_KERNEL);
+   if (!bulk->resets)
+   return -ENOMEM;
+
+   for (i = 0; i < count; i++) {
+   ret = reset_get_by_index(dev, i, >resets[i]);
+   if (ret < 0)
+   goto bulk_get_err;
+
+   ++bulk->count;
+   }
+
+   return 0;
+
+bulk_get_err:
+   err = reset_release_all(bulk->resets, bulk->count);
+   if (err)
+   debug("%s: could release all resets for %p\n",
+ __func__, dev);
+
+   return ret;
+}
+
 int reset_get_by_name(struct udevice *dev, const char *name,
 struct reset_ctl *reset_ctl)
 {
@@ -126,6 +160,19 @@ int reset_assert(struct reset_ctl *reset_ctl)
return ops->rst_assert(reset_ctl);
 }
 
+int reset_assert_bulk(struct reset_ctl_bulk *bulk)
+{
+   int i, ret;
+
+   for (i = 0; i < bulk->count; i++) {
+   ret = reset_assert(>resets[i]);
+   if (ret < 0)
+   return ret;
+   }
+
+   return 0;
+}
+
 int reset_deassert(struct reset_ctl *reset_ctl)
 {
struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
@@ -135,6 +182,19 @@ int reset_deassert(struct reset_ctl *reset_ctl)
return ops->rst_deassert(reset_ctl);
 }
 
+int reset_deassert_bulk(struct reset_ctl_bulk *bulk)
+{
+   int i, ret;
+
+   for (i = 0; i < bulk->count; i++) {
+   ret = reset_deassert(>resets[i]);
+   if (ret < 0)
+   return ret;
+   }
+
+   return 0;
+}
+
 int reset_release_all(struct reset_ctl *reset_ctl, int count)
 {
int i, ret;
diff --git a/include/reset.h b/include/reset.h
index 7185ade..d38f176 100644
--- a/include/reset.h
+++ b/include/reset.h
@@ -60,6 +60,24 @@ struct reset_ctl {
unsigned long id;
 };
 
+/**
+ * struct reset_ctl_bulk - A handle to (allowing control of) a bulk of reset
+ * signals.
+ *
+ * Clients provide storage for the reset control bulk. The content of the
+ * structure is managed solely by the reset API. A reset control bulk struct is
+ * initialized by "get"ing the reset control bulk struct.
+ * The reset control bulk struct is passed to all other bulk reset APIs to 
apply
+ * the API to all the reset signals in the bulk struct.
+ *
+ * @resets: An array of reset signal handles handles.
+ * @count: The number of reset signal handles in the reset array.
+ */
+struct reset_ctl_bulk {
+   struct reset_ctl *resets;
+   unsigned int count;
+};
+
 #ifdef CONFIG_DM_RESET
 /**
  * reset_get_by_index - Get/request a reset signal by integer index.
@@ -81,6 +99,22 @@ int reset_get_by_index(struct udevice *dev, int index,
   struct reset_ctl *reset_ctl);
 
 /**
+ * reset_get_bulk - Get/request all reset signals of a device.
+ *
+ * This looks up and requests all reset signals of the client device; each
+ * device is assumed to have n reset signals associated with it somehow,
+ * and this function finds and requests all of them in a separate structure.
+ * The mapping of client device reset signals indices to provider reset signals
+ * may be via device-tree properties, board-provided mapping tables, or some
+ * other mechanism.
+ *
+ * @dev:   The client device.
+ * @bulk   A pointer to a reset control bulk struct to initialize.
+ * @return 0 if OK, or a negative error code.
+ */
+int reset_get_bulk(struct udevice *dev, struct reset_ctl_bulk *bulk);
+
+/**
  * reset_get_by_name - Get/request a reset signal by name.
  *
  * This looks up and requests a