Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

Link: https://lore.kernel.org/all/20231018061714.3553817-15-s.hauer@pengutronix.de/
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>

authored by

Sascha Hauer and committed by
Chanwoo Choi
d724f4a4 b82932fb

+40 -17
+40 -17
drivers/devfreq/event/rockchip-dfi.c
··· 68 68 void __iomem *regs; 69 69 struct regmap *regmap_pmu; 70 70 struct clk *clk; 71 + int usecount; 72 + struct mutex mutex; 71 73 u32 ddr_type; 72 74 unsigned int channel_mask; 73 75 unsigned int max_channels; 74 76 }; 75 77 76 - static void rockchip_dfi_start_hardware_counter(struct rockchip_dfi *dfi) 78 + static int rockchip_dfi_enable(struct rockchip_dfi *dfi) 77 79 { 78 80 void __iomem *dfi_regs = dfi->regs; 81 + int ret = 0; 82 + 83 + mutex_lock(&dfi->mutex); 84 + 85 + dfi->usecount++; 86 + if (dfi->usecount > 1) 87 + goto out; 88 + 89 + ret = clk_prepare_enable(dfi->clk); 90 + if (ret) { 91 + dev_err(&dfi->edev->dev, "failed to enable dfi clk: %d\n", ret); 92 + goto out; 93 + } 79 94 80 95 /* clear DDRMON_CTRL setting */ 81 96 writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN | DDRMON_CTRL_SOFTWARE_EN | ··· 115 100 /* enable count, use software mode */ 116 101 writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, DDRMON_CTRL_SOFTWARE_EN), 117 102 dfi_regs + DDRMON_CTRL); 103 + out: 104 + mutex_unlock(&dfi->mutex); 105 + 106 + return ret; 118 107 } 119 108 120 - static void rockchip_dfi_stop_hardware_counter(struct rockchip_dfi *dfi) 109 + static void rockchip_dfi_disable(struct rockchip_dfi *dfi) 121 110 { 122 111 void __iomem *dfi_regs = dfi->regs; 123 112 113 + mutex_lock(&dfi->mutex); 114 + 115 + dfi->usecount--; 116 + 117 + WARN_ON_ONCE(dfi->usecount < 0); 118 + 119 + if (dfi->usecount > 0) 120 + goto out; 121 + 124 122 writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN), 125 123 dfi_regs + DDRMON_CTRL); 124 + clk_disable_unprepare(dfi->clk); 125 + out: 126 + mutex_unlock(&dfi->mutex); 126 127 } 127 128 128 129 static void rockchip_dfi_read_counters(struct rockchip_dfi *dfi, struct dmc_count *count) ··· 156 125 } 157 126 } 158 127 159 - static int rockchip_dfi_disable(struct devfreq_event_dev *edev) 128 + static int rockchip_dfi_event_disable(struct devfreq_event_dev *edev) 160 129 { 161 130 struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev); 162 131 163 - rockchip_dfi_stop_hardware_counter(dfi); 164 - clk_disable_unprepare(dfi->clk); 132 + rockchip_dfi_disable(dfi); 165 133 166 134 return 0; 167 135 } 168 136 169 - static int rockchip_dfi_enable(struct devfreq_event_dev *edev) 137 + static int rockchip_dfi_event_enable(struct devfreq_event_dev *edev) 170 138 { 171 139 struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev); 172 - int ret; 173 140 174 - ret = clk_prepare_enable(dfi->clk); 175 - if (ret) { 176 - dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret); 177 - return ret; 178 - } 179 - 180 - rockchip_dfi_start_hardware_counter(dfi); 181 - return 0; 141 + return rockchip_dfi_enable(dfi); 182 142 } 183 143 184 144 static int rockchip_dfi_set_event(struct devfreq_event_dev *edev) ··· 213 191 } 214 192 215 193 static const struct devfreq_event_ops rockchip_dfi_ops = { 216 - .disable = rockchip_dfi_disable, 217 - .enable = rockchip_dfi_enable, 194 + .disable = rockchip_dfi_event_disable, 195 + .enable = rockchip_dfi_event_enable, 218 196 .get_event = rockchip_dfi_get_event, 219 197 .set_event = rockchip_dfi_set_event, 220 198 }; ··· 302 280 return PTR_ERR(dfi->regmap_pmu); 303 281 304 282 dfi->dev = dev; 283 + mutex_init(&dfi->mutex); 305 284 306 285 desc = &dfi->desc; 307 286 desc->ops = &rockchip_dfi_ops;