Skip to content

No pwmchip2 in /sys/class/pwm after update to kernel 6.12 #6818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Deepthought73 opened this issue Apr 15, 2025 · 7 comments
Open

No pwmchip2 in /sys/class/pwm after update to kernel 6.12 #6818

Deepthought73 opened this issue Apr 15, 2025 · 7 comments

Comments

@Deepthought73
Copy link

After updating from kernel 6.6. to 6.12, pwmchip2 disappeared from /sys/class/pwm. I did all possible updates, but the issue still persists.

I'm using a Raspberry Pi 5B 2GB, Raspberry Pi OS 64bit.

@pelwell pelwell transferred this issue from raspberrypi/bookworm-feedback Apr 28, 2025
@raspberrypi raspberrypi deleted a comment from lurch Apr 28, 2025
@pelwell
Copy link
Contributor

pelwell commented Apr 28, 2025

  1. Is there a pwmchip0 or pwmchip1?
  2. What do you need pwmchip2 for?
  3. What changes have you made to config.txt?

@coulombhunter
Copy link

I have the same issue on a pi5 8gb. Downgrading to 6.6 fixes it.

On 6.12 /sys/class/pwm/ has a pwmchip0; on 6.6 it has pwmchip0 and pwmchip2.

As I understand it pwmchip0 is used for fan control, and the user accessible pwm channels are on pwmchip2; at least that's how it works on 6.6

config.txt has this added to the end:
dtoverlay=pwm,pin=12,func=4

@pelwell
Copy link
Contributor

pelwell commented May 2, 2025

You've lost nothing useful, but the device numbers may have changed (the kernel doesn't make any attempt to use systematic numbering).

With the same config.txt pwm dtoverlay line as you, on 6.6:

pi@raspberrypi:~$ ls -l /sys/class/pwm/pwmchip*/device
lrwxrwxrwx 1 root gpio 0 May  2 10:41 /sys/class/pwm/pwmchip0/device -> ../../../107d517a80.pwm
lrwxrwxrwx 1 root gpio 0 May  2 10:41 /sys/class/pwm/pwmchip2/device -> ../../../1f00098000.pwm
lrwxrwxrwx 1 root gpio 0 May  2 10:41 /sys/class/pwm/pwmchip6/device -> ../../../1f0009c000.pwm

And on 6.12:

pi@raspberrypi:~$ ls -l /sys/class/pwm/pwmchip*/device
lrwxrwxrwx 1 root gpio 0 May  2 10:54 /sys/class/pwm/pwmchip0/device -> ../../../1f00098000.pwm
lrwxrwxrwx 1 root gpio 0 May  2 10:54 /sys/class/pwm/pwmchip1/device -> ../../../1f0009c000.pwm

Although the PWM interface that appeared as pwmchip0 on 6.6 is no longer available, that's because it's not available on user-accessible pins so it now remains disabled.

The header pins available for PWM are as follows:

pi@raspberrypi:~$ pinctrl -p -c rp1 funcs | grep PWM
8, GPIO14, PWM0_CHAN2, DPI_D10, CTS4, SDA3, TXD0, SYS_RIO014, PROC_RIO014, PIO14, SPI5_SIO0
10, GPIO15, PWM0_CHAN3, DPI_D11, RTS4, SCL3, RXD0, SYS_RIO015, PROC_RIO015, PIO15, SPI5_SCLK
12, GPIO18, SPI1_CE0, DPI_D14, I2S0_SCLK, PWM0_CHAN2, I2S1_SCLK, SYS_RIO018, PROC_RIO018, PIO18, GPCLK1
32, GPIO12, PWM0_CHAN0, DPI_D8, TXD4, SDA2, AAUD_LEFT, SYS_RIO012, PROC_RIO012, PIO12, SPI5_CE0
33, GPIO13, PWM0_CHAN1, DPI_D9, RXD4, SCL2, AAUD_RIGHT, SYS_RIO013, PROC_RIO013, PIO13, SPI5_SIO1
35, GPIO19, SPI1_MISO, DPI_D15, I2S0_WS, PWM0_CHAN3, I2S1_WS, SYS_RIO019, PROC_RIO019, PIO19, -

As an example showing how to interpret this information, header pin 32 carries GPIO12, on which channel 0 of PWM0 can appear as function a0 ("pinctrl -p 32 a0" or "pinctrl 12 a0"). Similarly, header pin 35 -> GPIO19, "pinctrl -p 35 a3" or "pinctrl 19 a3".

Of the two RP1 PWM interfaces, only PWM0 (at address 0x1f00098000) appears on the 40-pin header, but PWM1 (at address 0x1f0009c000) is used for fan control.

If you've been following along, you would may have figured out that the PWM block that used to appear as pwmchip2 on 6.6 is now pwmchip0 on 6.12. However, if other PWM interfaces are created (using the pwm-gpio or pwm-pio overlays, for example) then the numbering could change, since the numbering is determined by the enumeration order and the kernel doesn't guarantee that. However, when I added a pwm-gpio instance on GPIO 7 it appeared as pwmchip2, so it may be safe to assume for now that the interface you want (PWM0) is pwmchip0:

pi@raspberrypi:~$ ls -l /sys/class/pwm/pwmchip*/device
lrwxrwxrwx 1 root gpio 0 May  2 11:09 /sys/class/pwm/pwmchip0/device -> ../../../1f00098000.pwm
lrwxrwxrwx 1 root gpio 0 May  2 11:09 /sys/class/pwm/pwmchip1/device -> ../../../1f0009c000.pwm
lrwxrwxrwx 1 root gpio 0 May  2 11:09 /sys/class/pwm/pwmchip2/device -> ../../../pwm_gpio@7

@coulombhunter
Copy link

coulombhunter commented May 2, 2025

Thank you,

I switched to using pwmchip0 now and it works as intended. I'll add a check of the device name to be robust against possible future renumbering

@pelwell
Copy link
Contributor

pelwell commented May 2, 2025

I'm open to the possibility of deriving device numbers from Device Tree aliases, as is done with other subsystems, but it would be yet another downstream patch, in this case to some code which has so far been unaltered.

@coulombhunter
Copy link

I just did something like

pwmchip=unknown
for x in /sys/class/pwm/pwmchip*; do
    if [[ "$(basename -- "$(readlink "$x/device")")" == 1f00098000.pwm ]]; then
	pwmchip="$x"
	break
    fi
done
if [[ unknown == "$pwmchip" ]]; then
    echo "pwm chip not found" 1>&2
    exit 1
fi

which solved my problems and works on both 6.6 and 6.12

@pelwell
Copy link
Contributor

pelwell commented May 2, 2025

You did good - I'm just acknowledging that the way the kernel presents PWM chips to userspace could be better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants