No pwmchip2 in /sys/class/pwm after update to kernel 6.12
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.
- Is there a pwmchip0 or pwmchip1?
- What do you need pwmchip2 for?
- What changes have you made to config.txt?
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
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 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
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
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.
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
You did good - I'm just acknowledging that the way the kernel presents PWM chips to userspace could be better.