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

counter: rz-mtu3-cnt: do not use struct rz_mtu3_channel's dev member

The counter driver can use HW channels 1 and 2, while the PWM driver can
use HW channels 0, 1, 2, 3, 4, 6, 7.

The dev member is assigned both by the counter driver and the PWM driver
for channels 1 and 2, to their own struct device instance, overwriting
the previous value.

The sub-drivers race to assign their own struct device pointer to the
same struct rz_mtu3_channel's dev member.

The dev member of struct rz_mtu3_channel is used by the counter
sub-driver for runtime PM.

Depending on the probe order of the counter and PWM sub-drivers, the
dev member may point to the wrong struct device instance, causing the
counter sub-driver to do runtime PM actions on the wrong device.

To fix this, use the parent pointer of the counter, which is assigned
during probe to the correct struct device, not the struct device pointer
inside the shared struct rz_mtu3_channel.

Cc: stable@vger.kernel.org
Fixes: 0be8907359df ("counter: Add Renesas RZ/G2L MTU3a counter driver")
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://lore.kernel.org/r/20260130122353.2263273-6-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: William Breathitt Gray <wbg@kernel.org>

authored by

Cosmin Tanislav and committed by
William Breathitt Gray
2932095c 67c3f99b

+27 -28
+27 -28
drivers/counter/rz-mtu3-cnt.c
··· 107 107 struct rz_mtu3_cnt *const priv = counter_priv(counter); 108 108 unsigned long tmdr; 109 109 110 - pm_runtime_get_sync(priv->ch->dev); 110 + pm_runtime_get_sync(counter->parent); 111 111 tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3); 112 - pm_runtime_put(priv->ch->dev); 112 + pm_runtime_put(counter->parent); 113 113 114 114 if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr)) 115 115 return false; ··· 165 165 if (ret) 166 166 return ret; 167 167 168 - pm_runtime_get_sync(ch->dev); 168 + pm_runtime_get_sync(counter->parent); 169 169 if (count->id == RZ_MTU3_32_BIT_CH) 170 170 *val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW); 171 171 else 172 172 *val = rz_mtu3_16bit_ch_read(ch, RZ_MTU3_TCNT); 173 - pm_runtime_put(ch->dev); 173 + pm_runtime_put(counter->parent); 174 174 mutex_unlock(&priv->lock); 175 175 176 176 return 0; ··· 187 187 if (ret) 188 188 return ret; 189 189 190 - pm_runtime_get_sync(ch->dev); 190 + pm_runtime_get_sync(counter->parent); 191 191 if (count->id == RZ_MTU3_32_BIT_CH) 192 192 rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val); 193 193 else 194 194 rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TCNT, val); 195 - pm_runtime_put(ch->dev); 195 + pm_runtime_put(counter->parent); 196 196 mutex_unlock(&priv->lock); 197 197 198 198 return 0; 199 199 } 200 200 201 201 static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch, 202 - struct rz_mtu3_cnt *const priv, 202 + struct counter_device *const counter, 203 203 enum counter_function *function) 204 204 { 205 205 u8 timer_mode; 206 206 207 - pm_runtime_get_sync(ch->dev); 207 + pm_runtime_get_sync(counter->parent); 208 208 timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1); 209 - pm_runtime_put(ch->dev); 209 + pm_runtime_put(counter->parent); 210 210 211 211 switch (timer_mode & RZ_MTU3_TMDR1_PH_CNT_MODE_MASK) { 212 212 case RZ_MTU3_TMDR1_PH_CNT_MODE_1: ··· 240 240 if (ret) 241 241 return ret; 242 242 243 - ret = rz_mtu3_count_function_read_helper(ch, priv, function); 243 + ret = rz_mtu3_count_function_read_helper(ch, counter, function); 244 244 mutex_unlock(&priv->lock); 245 245 246 246 return ret; ··· 279 279 return -EINVAL; 280 280 } 281 281 282 - pm_runtime_get_sync(ch->dev); 282 + pm_runtime_get_sync(counter->parent); 283 283 rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode); 284 - pm_runtime_put(ch->dev); 284 + pm_runtime_put(counter->parent); 285 285 mutex_unlock(&priv->lock); 286 286 287 287 return 0; ··· 300 300 if (ret) 301 301 return ret; 302 302 303 - pm_runtime_get_sync(ch->dev); 303 + pm_runtime_get_sync(counter->parent); 304 304 tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR); 305 - pm_runtime_put(ch->dev); 305 + pm_runtime_put(counter->parent); 306 306 307 307 *direction = (tsr & RZ_MTU3_TSR_TCFD) ? 308 308 COUNTER_COUNT_DIRECTION_FORWARD : COUNTER_COUNT_DIRECTION_BACKWARD; ··· 377 377 return -EINVAL; 378 378 } 379 379 380 - pm_runtime_get_sync(ch->dev); 380 + pm_runtime_get_sync(counter->parent); 381 381 if (count->id == RZ_MTU3_32_BIT_CH) 382 382 rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling); 383 383 else 384 384 rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TGRA, ceiling); 385 385 386 386 rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA); 387 - pm_runtime_put(ch->dev); 387 + pm_runtime_put(counter->parent); 388 388 mutex_unlock(&priv->lock); 389 389 390 390 return 0; ··· 495 495 static int rz_mtu3_count_enable_write(struct counter_device *counter, 496 496 struct counter_count *count, u8 enable) 497 497 { 498 - struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id); 499 498 struct rz_mtu3_cnt *const priv = counter_priv(counter); 500 499 int ret = 0; 501 500 ··· 504 505 goto exit; 505 506 506 507 if (enable) { 507 - pm_runtime_get_sync(ch->dev); 508 + pm_runtime_get_sync(counter->parent); 508 509 ret = rz_mtu3_initialize_counter(counter, count->id); 509 510 if (ret == 0) 510 511 priv->count_is_enabled[count->id] = true; 511 512 } else { 512 513 rz_mtu3_terminate_counter(counter, count->id); 513 514 priv->count_is_enabled[count->id] = false; 514 - pm_runtime_put(ch->dev); 515 + pm_runtime_put(counter->parent); 515 516 } 516 517 517 518 exit: ··· 543 544 if (ret) 544 545 return ret; 545 546 546 - pm_runtime_get_sync(priv->ch->dev); 547 + pm_runtime_get_sync(counter->parent); 547 548 tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3); 548 - pm_runtime_put(priv->ch->dev); 549 + pm_runtime_put(counter->parent); 549 550 *cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr); 550 551 mutex_unlock(&priv->lock); 551 552 ··· 562 563 if (ret) 563 564 return ret; 564 565 565 - pm_runtime_get_sync(priv->ch->dev); 566 + pm_runtime_get_sync(counter->parent); 566 567 rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3, 567 568 RZ_MTU3_TMDR3_LWA, cascade_enable); 568 - pm_runtime_put(priv->ch->dev); 569 + pm_runtime_put(counter->parent); 569 570 mutex_unlock(&priv->lock); 570 571 571 572 return 0; ··· 582 583 if (ret) 583 584 return ret; 584 585 585 - pm_runtime_get_sync(priv->ch->dev); 586 + pm_runtime_get_sync(counter->parent); 586 587 tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3); 587 - pm_runtime_put(priv->ch->dev); 588 + pm_runtime_put(counter->parent); 588 589 *ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr); 589 590 mutex_unlock(&priv->lock); 590 591 ··· 601 602 if (ret) 602 603 return ret; 603 604 604 - pm_runtime_get_sync(priv->ch->dev); 605 + pm_runtime_get_sync(counter->parent); 605 606 rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3, 606 607 RZ_MTU3_TMDR3_PHCKSEL, 607 608 ext_input_phase_clock_select); 608 - pm_runtime_put(priv->ch->dev); 609 + pm_runtime_put(counter->parent); 609 610 mutex_unlock(&priv->lock); 610 611 611 612 return 0; ··· 643 644 if (ret) 644 645 return ret; 645 646 646 - ret = rz_mtu3_count_function_read_helper(ch, priv, &function); 647 + ret = rz_mtu3_count_function_read_helper(ch, counter, &function); 647 648 if (ret) { 648 649 mutex_unlock(&priv->lock); 649 650 return ret;