[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
<BY3PR18MB4673C5C5CA684C64B2C218AAA7FE2@BY3PR18MB4673.namprd18.prod.outlook.com>
Date: Fri, 14 Feb 2025 17:13:30 +0000
From: Wilson Ding <dingwei@...vell.com>
To: Philipp Zabel <p.zabel@...gutronix.de>,
"linux-kernel@...r.kernel.org"
<linux-kernel@...r.kernel.org>,
"devicetree@...r.kernel.org"
<devicetree@...r.kernel.org>,
"linux-arm-kernel@...ts.infradead.org"
<linux-arm-kernel@...ts.infradead.org>
CC: "andrew@...n.ch" <andrew@...n.ch>,
"gregory.clement@...tlin.com"
<gregory.clement@...tlin.com>,
"sebastian.hesselbarth@...il.com"
<sebastian.hesselbarth@...il.com>,
"robh@...nel.org" <robh@...nel.org>,
"krzk+dt@...nel.org" <krzk+dt@...nel.org>,
"conor+dt@...nel.org"
<conor+dt@...nel.org>,
Sanghoon Lee <salee@...vell.com>,
Geethasowjanya Akula
<gakula@...vell.com>
Subject: Re: [PATCH 1/4] [PATCH 1/4] reset: simple: Add syscon device
compatible
> -----Original Message-----
> From: Philipp Zabel <p.zabel@...gutronix.de>
> Sent: Friday, February 14, 2025 3:54 AM
> To: Wilson Ding <dingwei@...vell.com>; linux-kernel@...r.kernel.org;
> devicetree@...r.kernel.org; linux-arm-kernel@...ts.infradead.org
> Cc: andrew@...n.ch; gregory.clement@...tlin.com;
> sebastian.hesselbarth@...il.com; robh@...nel.org; krzk+dt@...nel.org;
> conor+dt@...nel.org; Sanghoon Lee <salee@...vell.com>; Geethasowjanya
> Akula <gakula@...vell.com>
> Subject: [EXTERNAL] Re: [PATCH 1/4] [PATCH 1/4] reset: simple: Add syscon
> device compatible
>
> On Do, 2025-02-13 at 22:58 -0800, Wilson Ding wrote:
> > Introduce the new ops for updating reset line and getting status.
> > Thus, the reset controller can be accessed through either direct I/O
> > or regmap interfaces.
>
> Please don't add a new layer of function pointer indirection, just add a new
> struct reset_control_ops for the regmap variant.
>
If just adding a new struct reset_control_ops for the regmap variant, almost
all the functions will be duplicated for regmap variant.
Besides reset_simple_regmap_assert/deassert(), we also need to have the
regmap version of reset_simple_update(). Since reset_simple_reset() invokes
reset_simple_regmap_assert/deassert(), it also needs to be duplicated.
In this case, there will be too many redundant codes in this file. I doubt if
it is worth to use the reset simple code. Maybe it's better to fork a new file
for the syscon device, such as 'reset-simple-syscon.c'. What do you say?
> > It enables the support of the syscon devices with the simple reset
> > code. To adapt the DT binding of the syscon device, the number of
> > reset lines must be specified in device data.
>
> If the DT node had a reg property, number of reset lines could be determined
> from its size, like for MMIO.
>
> > Signed-off-by: Wilson Ding <dingwei@...vell.com>
> > ---
> > drivers/reset/reset-simple.c | 117 +++++++++++++++++++++++------
> > include/linux/reset/reset-simple.h | 11 +++
> > 2 files changed, 107 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/reset/reset-simple.c
> > b/drivers/reset/reset-simple.c index 276067839830..e4e777d40a79
> 100644
> > --- a/drivers/reset/reset-simple.c
> > +++ b/drivers/reset/reset-simple.c
> > @@ -15,8 +15,10 @@
> > #include <linux/device.h>
> > #include <linux/err.h>
> > #include <linux/io.h>
> > +#include <linux/mfd/syscon.h>
> > #include <linux/of.h>
> > #include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > #include <linux/reset-controller.h>
> > #include <linux/reset/reset-simple.h> #include <linux/spinlock.h> @@
> > -27,10 +29,9 @@ to_reset_simple_data(struct reset_controller_dev *rcdev)
> > return container_of(rcdev, struct reset_simple_data, rcdev); }
> >
> > -static int reset_simple_update(struct reset_controller_dev *rcdev,
> > +static int reset_simple_update_mmio(struct reset_simple_data *data,
> > unsigned long id, bool assert)
>
> No need to rename or change the function prototype.
>
> > {
> > - struct reset_simple_data *data = to_reset_simple_data(rcdev);
> > int reg_width = sizeof(u32);
> > int bank = id / (reg_width * BITS_PER_BYTE);
> > int offset = id % (reg_width * BITS_PER_BYTE); @@ -51,16 +52,40
> @@
> > static int reset_simple_update(struct reset_controller_dev *rcdev,
> > return 0;
> > }
> >
> > +static int reset_simple_update_regmap(struct reset_simple_data *data,
> > + unsigned long id, bool assert)
>
> I'd call this reset_simple_regmap_update().
>
> > +{
> > + int reg_width = sizeof(u32);
> > + int bank = id / (reg_width * BITS_PER_BYTE);
> > + int offset = id % (reg_width * BITS_PER_BYTE);
> > + u32 mask, val;
> > +
> > + mask = BIT(offset);
> > +
> > + if (assert ^ data->active_low)
> > + val = mask;
> > + else
> > + val = 0;
> > +
> > + return regmap_write_bits(data->regmap,
> > + data->reg_offset + (bank * reg_width),
> > + mask, val);
> > +}
> > +
> > static int reset_simple_assert(struct reset_controller_dev *rcdev,
> > unsigned long id)
> > {
> > - return reset_simple_update(rcdev, id, true);
> > + struct reset_simple_data *data = to_reset_simple_data(rcdev);
> > +
> > + return data->ops.update(data, id, true);
> > }
> >
> > static int reset_simple_deassert(struct reset_controller_dev *rcdev,
> > unsigned long id)
> > {
> > - return reset_simple_update(rcdev, id, false);
> > + struct reset_simple_data *data = to_reset_simple_data(rcdev);
> > +
> > + return data->ops.update(data, id, false);
> > }
>
> No need for indirection. Better to just add separate
> reset_simple_regmap_assert/deassert() functions.
>
See my reply to the first comment.
> > static int reset_simple_reset(struct reset_controller_dev *rcdev, @@
> > -81,10 +106,9 @@ static int reset_simple_reset(struct reset_controller_dev
> *rcdev,
> > return reset_simple_deassert(rcdev, id); }
> >
> > -static int reset_simple_status(struct reset_controller_dev *rcdev,
> > - unsigned long id)
> > +static int reset_simple_status_mmio(struct reset_simple_data *data,
> > + unsigned long id)
> > {
> > - struct reset_simple_data *data = to_reset_simple_data(rcdev);
> > int reg_width = sizeof(u32);
> > int bank = id / (reg_width * BITS_PER_BYTE);
> > int offset = id % (reg_width * BITS_PER_BYTE); @@ -95,6 +119,31
> @@
> > static int reset_simple_status(struct reset_controller_dev *rcdev,
> > return !(reg & BIT(offset)) ^ !data->status_active_low; }
> >
> > +static int reset_simple_status_regmap(struct reset_simple_data *data,
> > + unsigned long id)
> > +{
> > + int reg_width = sizeof(u32);
> > + int bank = id / (reg_width * BITS_PER_BYTE);
> > + int offset = id % (reg_width * BITS_PER_BYTE);
> > + u32 reg;
> > + int ret;
> > +
> > + ret = regmap_read(data->regmap, data->reg_offset + (bank *
> reg_width),
> > + ®);
> > + if (ret)
> > + return ret;
> > +
> > + return !(reg & BIT(offset)) ^ !data->status_active_low; }
> > +
> > +static int reset_simple_status(struct reset_controller_dev *rcdev,
> > + unsigned long id)
> > +{
> > + struct reset_simple_data *data = to_reset_simple_data(rcdev);
> > +
> > + return data->ops.status(data, id);
> > +}
>
> Same as above, no need for indirection.
> Just add separate reset_simple_regmap_assert/deassert() functions ...
>
See my reply to the first comment.
> > +
> > const struct reset_control_ops reset_simple_ops = {
> > .assert = reset_simple_assert,
> > .deassert = reset_simple_deassert,
>
> ... and add a const struct reset_control_ops reset_simple_regmap_ops.
>
See my reply to the first comment.
> regards
> Philipp
- Wilson
Powered by blists - more mailing lists