No userspace chardev available when using pwm-ir-tx module - linux

I'm attempted to use a pwm output pin as a IR transmitter using a RAMIPS SoC and the PWM IR TX kernel module. I'm running linux 4.14.37 and have added the following entry to the dts file:
pwm_ir_tx1: pwm-ir-transmitter1 {
compatible = "pwm-ir-tx";
pwms = <&pwm 1 100>;
};
I'm loading the rc-core and pwm-ir-tx kernel modules:
lsmod | grep pwm
pwm_ir_tx 2032 0
pwm_mediatek_ramips 1744 1
rc_core 19348 2 pwm_ir_tx
When the pwm-ir-tx module loads, the kernel logs:
[ 3754.108259] rc rc0: PWM IR Transmitter as /devices/platform/pwm-ir-transmitter1/rc/rc0
The sysfs nodes appear to be loaded correctly:
ls -la /sys/class/rc/
drwxr-xr-x 2 root root 0 May 29 00:18 .
drwxr-xr-x 23 root root 0 Jan 1 1970 ..
lrwxrwxrwx 1 root root 0 May 29 01:16 rc0 -> ../../devices/platform/pwm-ir-transmitter1/rc/rc0
But there is no userspace (chardev) lirc device listed in /dev so I'm not sure how I'm supposed to interact with the device. Ideally I'd like to use the Remote Controller API but this requires a chardev to be present in /dev.
ls /dev
autofs mtd2ro network_throughput
console mtd3 null
cpu_dma_latency mtd3ro port
full mtd4 ptmx
gpiochip0 mtd4ro pts
gpiochip1 mtd5 random
gpiochip2 mtd5ro shm
gpiochip3 mtd6 tty
i2c-0 mtd6ro ttyS0
kmsg mtdblock0 ttyS1
log mtdblock1 ttyS2
memory_bandwidth mtdblock2 urandom
mtd0 mtdblock3 watchdog
mtd0ro mtdblock4 watchdog0
mtd1 mtdblock5 zero
mtd1ro mtdblock6
mtd2 network_latency
I've tried loading the lirc_dev module before and after the pwm-ir-tx module, but nothing appears in /dev still, the following output appears when I load the lirc_dev module:
[ 4775.367966] lirc_dev: IR Remote Control driver registered, major 251
But still no lirc userspace device in /dev... I'm thinking the lirc_dev module is required since it provides the lirc userspace api but there doesn't appear to be any connection between it and the pwm-ir-tx module, and it's not creating any lirc chardevs in /dev.

The pwm_ir_tx module seems to be more or less a piggy-back to the pwm driver. And the pwm driver seems to be available at /sys/class/pwm/. See https://www.kernel.org/doc/Documentation/pwm.txt.
BTW, not having a lirc link in rc0/ is not uncommon - not all drivers implements this.

After reading some of rc source files in the kernel, it became obvious the ir-lirc-codec module was also required.
Basically, the pwm-ir-tx driver is defined as a type of RC_DRIVER_IR_RAW_TX. When the rc-core module registers a driver with a type of RC_DRIVER_IR_RAW or RC_DRIVER_IR_RAW_TX it calls the ir_raw_event_prepare function which in turn tries to load the ir-lirc-codec module. Once this module was available the following kernel logs appear:
[ 10.004460] lirc_dev: IR Remote Control driver registered, major 251
[ 10.131011] IR LIRC bridge handler initialized
[ 10.471561] rc rc0: PWM IR Transmitter as /devices/platform/pwm-ir-transmitter1/rc/rc0
[ 10.487456] rc rc0: lirc_dev: driver ir-lirc-codec (pwm-ir-tx) registered at minor = 0
And in /dev there is a lirc chardev device available:
ls /dev/li*
/dev/lirc0

Related

Issue with binding platform driver to the platform device

I want to make work mt7622 soc's ethernet controller and faced with this issue. I've compiled mtk_soc_eth driver as mkt_eth module and I have an entry in mt7622-bananapi-bpi-r64.dts device tree for device, compatible with driver.
During boot this module is loaded into system automatically (I think after mounting rootfs):
[root#nixos:~]# lsmod | grep mtk_eth
mtk_eth 69632 0
dsa_core 98304 1 mtk_eth
And it seems registered as platform driver:
[root#nixos:~]# ls /sys/bus/platform/drivers/mtk_soc_eth
bind module uevent unbind
Also after boot I have an platform device:
[root#nixos:~]# ls /sys/bus/platform/devices/1b100000.ethernet
driver_override
modalias
of_node
power
subsystem
supplier:platform:10006000.power-controller
supplier:platform:10209000.apmixedsys
supplier:platform:10210000.topckgen
supplier:platform:10211000.pinctrl
supplier:platform:1b000000.syscon
supplier:platform:1b128000.sgmiisys
uevent
waiting_for_supplier
However they are not binded for some reason. Moreover, when I try to bind them manually, I get an error:
[root#nixos:~]# echo '1b100000.ethernet' > /sys/bus/platform/drivers/mtk_soc_eth/bind
-bash: echo: write error: Resource temporarily unavailable
How can I understand why ethernet device doesn't bind with driver?
Well, it seems that I figured out where is the problem. It seems that linux kernel have rich debug options) I've enabled dynamic debug to track which happens inside __driver_probe_device https://github.com/torvalds/linux/blob/master/drivers/base/dd.c#L730 function:
[root#nixos:~]# echo 'file dd.c +p'>/sys/kernel/debug/dynamic_debug/control
[root#nixos:~]# echo 'file core.c +p'>/sys/kernel/debug/dynamic_debug/control
And then tried to bind device driver and device:
[root#nixos:~]# echo '1b100000.ethernet' >/sys/bus/platform/drivers/mtk_soc_eth/bind
-bash: echo: write error: Resource temporarily unavailable
[root#nixos:~]# dmesg -T | tail
...
[Sat Jan 1 00:03:27 2000] bus: 'platform': __driver_probe_device: matched device 1b100000.ethernet with driver mtk_soc_eth
[Sat Jan 1 00:03:27 2000] platform 1b100000.ethernet: error -EPROBE_DEFER: supplier 1b000000.syscon not ready
It seems that one of the dependent devices (1b000000.syscon) is not ready (at the same time /sys/bus/platform/devices/1b100000.ethernet/waiting_for_supplier was still 0 for some reason). I need to load clk-mt7622-eth driver as well.

Error running qemu-system-riscv using root.bin and vmlinux

I am following riscv.org guides for toolchain building. When emulate using qemu running local built rootfilesystem (with busybox) and Linux Kernel, encounter the error below:
Running Qemu using local-built root.bin and kernel image
danny#danny:~/test/riscv/work$ qemu-system-riscv -hda root-local.bin -kernel vmlinux-local -nographic
unassigned address was called?
with addr: 102000735F80006E
not implemented for riscv
Running Qemu using riscv.org stocked root.bin and kernel image
danny#danny:~/test/riscv/work$ qemu-system-riscv -hda root.bin -kernel vmlinux -nographic
[ 0.150000] io scheduler cfq registered (default)
[ 0.160000] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 0.160000] serial8250: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[ 0.160000] TCP: cubic registered
[ 0.160000] htifbd: detected disk with ID 1
[ 0.160000] htifbd: adding htifbd0
[ 0.160000] VFS: Mounted root (ext2 filesystem) readonly on device 254:0.
[ 0.160000] devtmpfs: mounted
[ 0.160000] Freeing unused kernel memory: 64K (ffffffff80002000 - ffffffff80012000)
[ 0.200000] EXT2-fs (htifbd0): warning: mounting unchecked fs, running e2fsck is recommended
#uname -a
Linux ucbvax 3.14.15-g4073e84-dirty #4 Sun Jan 11 07:17:06 PST 2015 riscv GNU/Linux
If qemu testing using the downloaded root.bin and vmlinux from riscv.org, seem ok but cant see the busybox starting message and the terminal cant Halt :
Have tested qemu using various combination and result as below:
**root.bin vmlinux RESULT**
local-built local-built Unassigned address was called ....
Downloaded Downloaded Seem OK but without busybox starting bar
local-built Downloaded Kernelpanic-not syncing:No working init found
Downloaded local-built Unassigned address was called ....
We are starting a project to build and fabricate a RISCV silicon chip for Makers around the world and testing the toolchain now in order to port Ubuntu Core & Android to RISCV. Any idea what might probably went wrong ?
Thanks.
QEMU hasn't been fully updated to support the new RISC-V privileged spec (github issue). The update is currently underway.
For an ISA simulator, spike is a good alternative. It may not have all of the platform features of QEMU, but it could serve as a starting point while the QEMU update completes.

Init process not found when booting with ramdisk as rootfs

I'm trying to setup a ramdisk for a setup I have with AT91SAM9261 and 2.6.30 kernel.
I know you would say why don't I use initramfs? I will use also that one, as of now I would like to check if I can boot with a ramdisk as rootfs.
I have already a root fs running fine on this system in jffs2 format.
I used below tutorial:
http://www.ibm.com/developerworks/library/l-initrd/
So I created the ramdisk directly on the embedded target, with 4MB size.
I used "dd" and "mkefs" and the ramdisk image works fine if I mount it as loop when rootfs is my jffs2.
I can browse mount_point and do stuff inside.
The content was created according to the section "Manually building initial RAM disk" in the above link.
In /dev I placed null and console, in /bin I copied busybox and created the links.
I set the execute attribute to init script as well, which works fine when I run it here (as loop device with jffs2 as rootfs)
In my kernel config I enabled ramdisk support as follows:
CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_GZIP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
Using tftp I download the ramdisk image to 0x21100000.
At 0x20008000 I have the kernel uncompressed and at 0x22000000 the zImage copied.
However, I'm not able to boot successfully the system as it hangs when checking init process.
As I mentioned, I checked several times that my init can be executed,
I also used in the bootargs init=/bin/busybox or other scripts/binaries to check if any can be used as init.
Command line I use now:
bootargs=64M console=ttyS0,115200 root=/dev/ram0 rw
initrd=0x21100000,4194304 init=/init
For some I set ownership to "nobody" just to check if it makes any difference.
As it can be seen in the log output the ramdisk is mounted, but init fails.
It gives a warning to check the ext2 image, which I did before copying it and I have no error reported.
The tftp server is on Windows7. I though I might have some incompatibility if I copy the ramdisk image from linux to Windows then do tftp from Windows server.
So I copied the image again from Windows to linux, mounted it and checked if the FS reports any error and scripts can be executed - everything looks normal.
So I do have all files in place, attributes set, ramdisk is reported as being mounted ok as rootfs, but init cannot be found.
Uncompressing Linux......................................................................................................... done, booting the kernel.
Linux version 2.6.30-olimex (mishu#KubuntuVM) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #1 Mon Dec 29 13:53:54 CET 2014
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: Olimex SAM9-L9261
Ignoring unrecognised tag 0x54410008
Memory policy: ECC disabled, Data cache writeback
Clocks: CPU 198 MHz, master 99 MHz, main 18.432 MHz
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: 64M console=ttyS0,115200 root=/dev/ram0 rw initrd=0x21100000,4194304 init=/init
NR_IRQS:192
AT91: 96 gpio irqs in 3 banks
PID hash table entries: 256 (order: 8, 1024 bytes)
Console: colour dummy device 80x30
console [ttyS0] enabled
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 57384KB available (2924K code, 246K data, 132K init, 0K highmem)
Calibrating delay loop... 99.12 BogoMIPS (lpj=495616)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 716 bytes
NET: Registered protocol family 16
AT91: Power Management
AT91: Starting after user reset
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
Trying to unpack rootfs image as initramfs...
rootfs image is not initramfs (junk in compressed archive); looks like an initrd
Freeing initrd memory: 4096K
NetWinder Floating Point Emulator V0.97 (double precision)
JFFS2 version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc.
msgmni has been set to 120
io scheduler noop registered
io scheduler anticipatory registered (default)
atmel_lcdfb atmel_lcdfb.0: backlight control is not available
atmel_lcdfb atmel_lcdfb.0: 225KiB frame buffer at 23140000 (mapped at ffc00000)
Console: switching to colour frame buffer device 40x30
atmel_lcdfb atmel_lcdfb.0: fb0: Atmel LCDC at 0x00600000 (mapped at c4866000), irq 21
atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
atmel_usart.1: ttyS1 at MMIO 0xfffb0000 (irq = 6) is a ATMEL_SERIAL
brd: module loaded
loop: module loaded
ssc ssc.1: Atmel SSC device at 0xc4878000 (irq 15)
Driver 'sd' needs updating - please use bus_type methods
dm9000 Ethernet Driver, V1.31
eth0 (dm9000): not using net_device_ops yet
eth0: dm9000e at c486a000,c486e044 IRQ 107 MAC: 3a:1f:34:08:54:64 (chip)
NAND device: Manufacturer ID: 0xec, Chip ID: 0xdc (Samsung NAND 512MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 1478 at 0x00000b8c0000
Creating 2 MTD partitions on "atmel_nand":
0x000000000000-0x000000040000 : "Partition 1"
0x000000040000-0x000020000000 : "Partition 2"
atmel_spi atmel_spi.0: Atmel SPI Controller at 0xfffc8000 (irq 12)
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
at91_ohci at91_ohci: AT91 OHCI
at91_ohci at91_ohci: new USB bus registered, assigned bus number 1
at91_ohci at91_ohci: irq 20, io mem 0x00500000
usb usb1: New USB device found, idVendor=1d6b, idProduct=0001
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: AT91 OHCI
usb usb1: Manufacturer: Linux 2.6.30-olimex ohci_hcd
usb usb1: SerialNumber: at91
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
udc: at91_udc version 3 May 2006
g_serial gadget: Gadget Serial v2.4
g_serial gadget: g_serial ready
mice: PS/2 mouse device common for all mice
input: gpio-keys as /class/input/input0
ads7846 spi0.2: touchscreen, irq 29
input: ADS784x Touchscreen as /class/input/input1
rtc-at91sam9 at91_rtt.0: rtc core: registered at91_rtt as rtc0
IRQ 1/rtc0: IRQF_DISABLED is not guaranteed on shared IRQs
rtc-at91sam9 at91_rtt.0: rtc0: SET TIME!
i2c /dev entries driver
i2c-gpio: probe of i2c-gpio failed with error -16
Registered led device: led1
Registered led device: led2
Registered led device: led3
Advanced Linux Sound Architecture Driver Version 1.0.20.
at73c213 spi0.3: at73c213: supported bitrate is 48500 (64 divider)
usb 1-1: new full speed USB device using at91_ohci and address 2
usb 1-1: New USB device found, idVendor=0457, idProduct=0151
usb 1-1: New USB device strings: Mfr=0, Product=2, SerialNumber=3
usb 1-1: Product: USB Mass Storage Device
usb 1-1: SerialNumber: 8d54bd8186b42c
usb 1-1: configuration #1 chosen from 1 choice
scsi0 : SCSI emulation for USB Mass Storage devices
ALSA device list:
#0: SAM9-L9261 external DAC on irq 15
TCP cubic registered
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
rtc-at91sam9 at91_rtt.0: hctosys: unable to read the hardware clock
RAMDISK: ext2 filesystem found at block 0
RAMDISK: Loading 4096KiB [1 disk] into ram disk... done.
EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended
VFS: Mounted root (ext2 filesystem) on device 1:0.
Freeing init memory: 132K
Failed to execute /init. Attempting defaults...
Kernel panic - not syncing: No init found. Try passing init= option to kernel.
[<c002f414>] (unwind_backtrace+0x0/0xdc) from [<c025bd34>] (panic+0x40/0x110)
[<c025bd34>] (panic+0x40/0x110) from [<c0029500>] (init_post+0xd0/0xf8)
[<c0029500>] (init_post+0xd0/0xf8) from [<c00085a0>] (kernel_init+0xbc/0xe4)
[<c00085a0>] (kernel_init+0xbc/0xe4) from [<c0041998>] (do_exit+0x0/0x5ac)
[<c0041998>] (do_exit+0x0/0x5ac) from [<00000001>] (0x1)
I plan to rebuild busybox and try again, but as my current ramdisk image works when I mount it as loop I don't have too much confidence it will change something.
I'm out of ideas. I've been trying the whole day to get this working.
Help is much appreciated.
Thanks.
Missing libraries were the root cause for the non-executable init placed on the ramdisk.
Using chroot turned out to be extremely useful. With this issue I learned how to use chroot and simulate a jail.
Another trick was to use user_debug=31 in the command line so that the kernel will output a message saying that the file is not found.
It looks like the "file not found" does not really point to a missing file, but to a failure to read the file system due to busybox not executing properly (missing libraries).
In parallel I have compiled dynamically the busybox 1.20.02 for my arm architecture and the ramdisk worked properly (without libs).
This user_debug=31 turned out to be again useful when I compiled and ran busybox, as it was also failing after mounting the ramdisk, but it thrown out an "undefined exception" which led me to a wrong "arch" value used for compiling busybox. After changing it everything was fine.

Debugging cdc-acm kernel module

I am trying to fix a problem I am having on Ubuntu (tried different versions including the latest 13.10) with a USB device talking CDC/ACM on one of its interfaces. The kernel module handling this kind of devices only reports
cdc_acm 6-2:1.1: This device cannot do calls on its own. It is not a modem.
cdc_acm: probe of 6-2:1.1 failed with error -22
in dmesg and that is it. Nothing about "Zero length descriptor references" or similar stuff that other people report on the web. So I wanted to find out what the problem might be. I followed the description in http://www.silly-science.co.uk/2012/06/23/lenovo-usb-modem-in-linux-ubuntu-10-04 to compile and load a custom cdc-acm module. First, I changed the two #undefs for debug to #defines in cdc-acm.c, but I am still not getting any additional output in dmesg.
Changing the version string in cdc-acm.c's DRIVER_VERSION define to something else, I can verify that my modified module is indeed loaded. Am I looking for the debug output in the wrong place?
I managed to get debug info from cdc_acm in dmesg, and even though I don't have something special to share, these were my steps, using latest kernel as of today 4.2-rc5:
Change DEBUG and VERBOSE_DEBUG #undefs to #defines in cdc-acm.c.
make -C /lib/modules/$(uname -r)/build M=$(pwd)/drivers/usb/class modules
modprobe -r cdc_acm; insmod $(pwd)/drivers/usb/class/cdc-acm.ko
dmesg after plugging a compatible device
[...]
[14035.355036] cdc_acm 2-2:1.1: acm_tty_write - write 1
[14035.368040] cdc_acm 2-2:1.1: acm_softint
[14038.156445] cdc_acm 2-2:1.0: acm_tty_close
[14038.173054] cdc_acm 2-2:1.0: acm_ctrl_msg - rq 0x22, val 0x0, len 0x0, result 0
[14038.173059] cdc_acm 2-2:1.0: acm_port_shutdown
[14038.173640] cdc_acm 2-2:1.0: acm_ctrl_irq - urb shutting down with status: -2
[14038.174636] cdc_acm 2-2:1.1: acm_read_bulk_callback - urb 0, len 0
[...]

ttyS1/uart1 initialised but not accessible through /dev/ttyS1

Apologies if this is the wrong place for this question, I'm not currently sure which level the problem is at so I'm hedging my bets a tad.
System is a LeopardBoard DM368 running TI's own SDK / LSP / BusyBox kernel.
By default the system has one UART enabled, UART0, mounted as /dev/ttyS0 which is also used/invoked via the bootargs console=ttyS0,115200n8 earlyprintk.
We want to enable UART1 as /dev/ttyS1, so have gone through the low-level board initialisation code which sets up the pinmux, clocks, etc.
On booting, the low-level init reports (via printk's I added in) that it's enabled the UART1, and the driver code reports happiness too:
[ 0.547812] serial8250.0: ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A
[ 0.569849] serial8250.0: ttyS1 at MMIO 0x1d06000 (irq = 41) is a 16550A
However, the port does not (reliably) appear in /dev/, and there are discrepancies with its status (flow control bits) which I suspect may be causing it to hang / never transmit:
cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:97998 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:0 rx:0 DSR
If I try to modify it from the command line I get an error:
>: stty -F /dev/ttyS1
stty: /dev/ttyS1: Inappropriate ioctl for device
Bizarrely, if I change the bootargs to console=ttyS1,115200n8 earlyprintk the port works perfectly, and ttyS0 is initialised correctly and works too:
cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:0 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:11563 rx:0 RTS|DTR|DSR
Now, that would be fine, but our bootloader must use UART0 so it would be nice to keep all the console stuff on ttyS0 and have ttyS1 for our secondary comms.
Edit to add: I inserted a couple of printk's into serial_core.c and it seems like uart_open() is never being called for ttyS1, I'm assuming it's something in the Linux init/startup sequence that needs modifying?
I'll state now that I'm not a hardy Linux hacker so it's entirely possible I've missed some obvious/dumb thing in either the kernel code, initialisation sequence, etc.
Any thoughts greatly appreciated!
Well a nice chap over on the Linux board solved it, I need to insert a mknod /dev/ttyS1 c 4 65 somewhere.
Quite why this (apparently) happens for ttyS0 or whichever port is console I don't know, but right now all that matters is it works!
Comments / further info on the reasons why would be welcome for my own knowledge / future generations.

Resources