> -----Original Message----- > From: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> > Sent: Wednesday, October 18, 2023 3:17 PM > To: linux-rockchip@xxxxxxxxxxxxxxxxxxx > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; > linux-pm@xxxxxxxxxxxxxxx; Heiko Stuebner <heiko@xxxxxxxxx>; Chanwoo Choi > <chanwoo@xxxxxxxxxx>; Kyungmin Park <kyungmin.park@xxxxxxxxxxx>; MyungJoo > Ham <myungjoo.ham@xxxxxxxxxxx>; Will Deacon <will@xxxxxxxxxx>; Mark > Rutland <mark.rutland@xxxxxxx>; kernel@xxxxxxxxxxxxxx; Michael Riesch > <michael.riesch@xxxxxxxxxxxxxx>; Robin Murphy <robin.murphy@xxxxxxx>; > Vincent Legoll <vincent.legoll@xxxxxxxxx>; Rob Herring > <robh+dt@xxxxxxxxxx>; Krzysztof Kozlowski > <krzysztof.kozlowski+dt@xxxxxxxxxx>; Conor Dooley <conor+dt@xxxxxxxxxx>; > devicetree@xxxxxxxxxxxxxxx; Sebastian Reichel > <sebastian.reichel@xxxxxxxxxxxxx>; Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>; > Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>; Chanwoo Choi > <cw00.choi@xxxxxxxxxxx> > Subject: [PATCH v8 14/26] PM / devfreq: rockchip-dfi: Prepare for multiple > users > > When adding perf support later the DFI must be enabled when either of > devfreq-event or perf is active. Prepare for that by adding a usage > counter for the DFI. Also move enabling and disabling of the clock away > from the devfreq-event specific functions to which the perf specific part > won't have access. > > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > Reviewed-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx> > Acked-by: Chanwoo Choi <cw00.choi@xxxxxxxxxxx> > Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> > --- > drivers/devfreq/event/rockchip-dfi.c | 57 +++++++++++++++++++--------- > 1 file changed, 40 insertions(+), 17 deletions(-) > > diff --git a/drivers/devfreq/event/rockchip-dfi.c > b/drivers/devfreq/event/rockchip-dfi.c > index d56a33d03db4c..7a4f1901314d4 100644 > --- a/drivers/devfreq/event/rockchip-dfi.c > +++ b/drivers/devfreq/event/rockchip-dfi.c > @@ -68,14 +68,29 @@ struct rockchip_dfi { > void __iomem *regs; > struct regmap *regmap_pmu; > struct clk *clk; > + int usecount; > + struct mutex mutex; > u32 ddr_type; > unsigned int channel_mask; > unsigned int max_channels; > }; > > -static void rockchip_dfi_start_hardware_counter(struct rockchip_dfi *dfi) > +static int rockchip_dfi_enable(struct rockchip_dfi *dfi) > { > void __iomem *dfi_regs = dfi->regs; > + int ret = 0; > + > + mutex_lock(&dfi->mutex); > + > + dfi->usecount++; > + if (dfi->usecount > 1) > + goto out; > + > + ret = clk_prepare_enable(dfi->clk); > + if (ret) { > + dev_err(&dfi->edev->dev, "failed to enable dfi clk: %d\n", > ret); > + goto out; > + } > > /* clear DDRMON_CTRL setting */ > writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN | > DDRMON_CTRL_SOFTWARE_EN | @@ -100,14 +115,30 @@ static void > rockchip_dfi_start_hardware_counter(struct rockchip_dfi *dfi) > /* enable count, use software mode */ > writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, > DDRMON_CTRL_SOFTWARE_EN), > dfi_regs + DDRMON_CTRL); > +out: > + mutex_unlock(&dfi->mutex); > + > + return ret; > } > > -static void rockchip_dfi_stop_hardware_counter(struct rockchip_dfi *dfi) > +static void rockchip_dfi_disable(struct rockchip_dfi *dfi) > { > void __iomem *dfi_regs = dfi->regs; > > + mutex_lock(&dfi->mutex); > + > + dfi->usecount--; > + > + WARN_ON_ONCE(dfi->usecount < 0); > + > + if (dfi->usecount > 0) > + goto out; > + > writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN), > dfi_regs + DDRMON_CTRL); > + clk_disable_unprepare(dfi->clk); > +out: > + mutex_unlock(&dfi->mutex); > } > > static void rockchip_dfi_read_counters(struct rockchip_dfi *dfi, struct > dmc_count *count) @@ -125,29 +156,20 @@ static void > rockchip_dfi_read_counters(struct rockchip_dfi *dfi, struct dmc_coun > } > } > > -static int rockchip_dfi_disable(struct devfreq_event_dev *edev) > +static int rockchip_dfi_event_disable(struct devfreq_event_dev *edev) > { > struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev); > > - rockchip_dfi_stop_hardware_counter(dfi); > - clk_disable_unprepare(dfi->clk); > + rockchip_dfi_disable(dfi); > > return 0; > } > > -static int rockchip_dfi_enable(struct devfreq_event_dev *edev) > +static int rockchip_dfi_event_enable(struct devfreq_event_dev *edev) > { > struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev); > - int ret; > - > - ret = clk_prepare_enable(dfi->clk); > - if (ret) { > - dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret); > - return ret; > - } > > - rockchip_dfi_start_hardware_counter(dfi); > - return 0; > + return rockchip_dfi_enable(dfi); > } > > static int rockchip_dfi_set_event(struct devfreq_event_dev *edev) @@ - > 191,8 +213,8 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev > *edev, } > > static const struct devfreq_event_ops rockchip_dfi_ops = { > - .disable = rockchip_dfi_disable, > - .enable = rockchip_dfi_enable, > + .disable = rockchip_dfi_event_disable, > + .enable = rockchip_dfi_event_enable, > .get_event = rockchip_dfi_get_event, > .set_event = rockchip_dfi_set_event, > }; > @@ -280,6 +302,7 @@ static int rockchip_dfi_probe(struct platform_device > *pdev) > return PTR_ERR(dfi->regmap_pmu); > > dfi->dev = dev; > + mutex_init(&dfi->mutex); > > desc = &dfi->desc; > desc->ops = &rockchip_dfi_ops; > -- > 2.39.2 Applied it. Thanks Best Regards, Chanwoo Choi