Linux Userspace GPIO Interrupts using sysfs - linux

I would like to use interrupts with GPIO on userspace using sysfs.
I use these commands :
[root#at91]:gpio109 > echo 109 > export
[root#at91]:gpio109 > cd gpio109/
[root#at91]:gpio109 > ll
-rw-r--r-- 1 root 0 4096 Jan 1 00:17 direction
drwxr-xr-x 2 root 0 0 Jan 1 00:17 power
lrwxrwxrwx 1 root 0 0 Jan 1 00:17 subsystem -> ../../gpio
-rw-r--r-- 1 root 0 4096 Jan 1 00:17 uevent
-rw-r--r-- 1 root 0 4096 Jan 1 00:17 value
The gpio works well but I can't use interrupts.
I read everywhere i must have an edge file to poll this file. But on my system this file doesn't exist.
I made a lot of tries to find a solution but remain unsuccessfull.
My target is an AT91SAM9263 on linux kernel 2.6.30.
At the boot of my board I got this message on interrupts :
AT91: 160 gpio irqs in 5 banks
which show that the function at91_gpio_irq_setup() is well executed.
Have you any idea ?

The "edge" file only exists if that GPIO pin can be configured as a an interrupt generting pin. See: http://www.mjmwired.net/kernel/Documentation/gpio.txt#634.
Since you don't see it, it means the driver and possibly the hardware do not support using that GPIO pin for interrupt source.

Related

linux kernel: regulator consumer usage from userspace

I have some kind of driver in user space:
program talk via some interface(rs232) with device.
Also I have pin(gpio) to switch on/off this device.
I do not code in my program concrete gpio, to make it more portable,
so I modify device tree description of my board,
and describe regulator-fixed, after that I thought to use
userspace-consumer driver to control power on/off,
but looks like that not kernel developers expected
(link to discussion of similar problem, not my):
http://patchwork.ozlabs.org/patch/374912/
So how should I control switch on/off
of my device from user space without adding to my program
information about what conrete gpio used to switch on/off device?
More details:
In my board dts I described my pin like this:
regulator-deviceX {
status = "okay";
compatible = "regulator-fixed";
regulator-name = "DEV_X_ON#";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio5 4 GPIO_ACTIVE_LOW>;
};
And of course, after boot "gpio = <&gpio5 4 GPIO_ACTIVE_LOW>" was
locked by the kernel, and it is impossible to use it via /sys/class/gpio interface.
Bad think about such approach, that is impossible (or I don't see how) to
change regulator state from user space, as you can see "state" is read only file.
root#board:/sys/class/regulator/regulator.1# ls -l
lrwxrwxrwx 1 root root 0 May 3 03:32 device -> ../../../regulator-deviceX
-r--r--r-- 1 root root 4096 May 3 03:32 microvolts
-r--r--r-- 1 root root 4096 May 3 03:32 name
-r--r--r-- 1 root root 4096 May 3 03:32 num_users
drwxr-xr-x 2 root root 0 May 3 03:32 power
-r--r--r-- 1 root root 4096 May 3 03:32 state
lrwxrwxrwx 1 root root 0 May 3 03:25 subsystem -> ../../../../class/regulator
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_disk_state
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_mem_state
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_standby_state
-r--r--r-- 1 root root 4096 May 3 03:32 type
-rw-r--r-- 1 root root 4096 May 3 03:25 uevent
So, the final solution looks like this:
Step 1
Describe device in device tree, though you no need
kernel for handling it, but looks right to describe it here
gps-reciever {
compatible = "my_company_name,gps_recv_name";
vcc-supply = <&ext_gps_recv_reg>;
comment = "connected via usb<->rs232, port0";
};
where ext_gps_recv_reg of any normal regulator.
Step 2
I wrote a simple platform device driver for linux kernel,
that compatible with device above, and in probe function of this
driver I call platform_device_register_full that setup arguments for
userspace_consumer driver.
After that I can find suitable file via name:
cat /sys/bus/platform/devices/reg-userspace-consumer*/name,
and then disable/enable regulator via:
echo "disabled" > /sys/bus/platform/devices/reg-userspace-consumer*/state
So I separate device description from linux kernel implementation.

MTD start and config at runtime

Got a embedded system that i have root shell access to.
I can not enter the U-boot boot menu. (boot delay=0)
The device boots from a nor flash and loads the filesystem on emmc.
It does not set /dev/mtd devices.
I want to access the nor flash.
There are MTD drivers on the system, so that seems the best option.
(no experiance with this at all, so please correct me if i'm wrong)
drwxrwxr-x 2 1000 root 1024 Jul 29 2013 chips
drwxrwxr-x 2 1000 root 1024 Jul 29 2013 maps
-rw-rw-r-- 1 1000 1000 21544 Jul 29 2013 mtd.ko
-rw-rw-r-- 1 1000 1000 8560 Jul 29 2013 mtd_blkdevs.ko
-rw-rw-r-- 1 1000 1000 6132 Jul 29 2013 mtdblock.ko
-rw-rw-r-- 1 1000 1000 9648 Jul 29 2013 mtdchar.ko
If start MTD with modprobe, /proc/mtd is created.
Nothing in dmesg.
root:/proc# cat /proc/mtd
dev: size erasesize name
So no partition.
How can i configure mtd to be able to access the nor flash.
( physical addresses are known )
Thanks
You need to describe your NOR partitions in a board-specific file in the kernel. In u-boot, you should be able to see them with smeminfo.
In your linux kernel, you'll need to populate an array of mtd_partitions.
Find more here: http://free-electrons.com/blog/managing-flash-storage-with-linux/

Device node at /dev/tty* not getting created for uart serial driver

I have written a simple UART serial driver in embedded Linux running busybox with mdev rules. I have provided .dev_name as "ttyC2C" in my driver code.
static struct uart_driver serial_omap_reg = {
.owner = THIS_MODULE,
.driver_name = "Omap-C2C-Serial",
.dev_name = "ttyC2C",
.nr = OMAP_MAX_HSUART_PORTS,
.cons = NULL,
};
However the node is getting created in
./sys/devices/platform/omap_c2c_uart.0/tty/ttyC2C0
./sys/class/tty/ttyC2C0
/ # ls -l ./sys/class/tty/ttyC2C0
lrwxrwxrwx 1 root 0 0 Jan 1 00:14 ./sys/class/tty/ttyC2C0 -> ../../devices/platform/omap_c2c_uart.0/tty/ttyC2C0
/ # ls -l ./sys/devices/platform/omap_c2c_uart.0/tty/ttyC2C0
-r--r--r-- 1 root 0 4096 Jan 1 00:14 dev
lrwxrwxrwx 1 root 0 0 Jan 1 00:14 device -> ../../../omap_c2c_uart.0
drwxr-xr-x 2 root 0 0 Jan 1 00:14 power
lrwxrwxrwx 1 root 0 0 Jan 1 00:14 subsystem -> ../../../../../class/tty
-rw-r--r-- 1 root 0 4096 Jan 1 00:14 uevent
/ #
The mdev rules for tty are:
tty 0:5 0666
tty.* 0:0 0620
How to get device node as /dev/ttyC2C ?
You are confusing two things. The sysfs nodes you are seeing are indeed maintained by the kernel based on the kobject hierarchy. However device nodes are entirely a user space problem and can exist anywhere (although by convention are under /dev).
So by hand you would first find the major:minor numbers:
cat /sys/class/tty/ttyC2C0/dev
And then:
mknod /dev/ttyC2C0 c ${MAJOR} ${MINOR}
However as you have already indicated you are using the fork of udev, mdev to handle the user space creation of device nodes. However the matching rules look odd to me. I assume mdev has the equivalent of udevadm which should help you write the matching rules. For example my USB tty driver can be queried like this:
udevadm info -a -p /sys/class/tty/ttyUSB0
And looking at the tree produced I can see a list of udev attributes which I could use to match. So in my case:
KERNEL=="ttyUSB0", DRIVERS=="ftdi_sio", NAME="ttyUSB0"
Would be enough to match (although my distro has a lot more complex matching rules to deal with dynamic setups).
I'm guessing but I suspect the mapping rule you want would look more like:
KERNEL=="ttyC2C", NAME="ttyC2C"
Although you might need a bit more to ensure you get device nodes created for each port (minor number?).
Does adding a specific mdev rule to your /etc/mdev.conf for ttyC2C resolve your problem ?
Something like one of the following ?
ttyC2C[0-9]+ root:tty 620
or
ttyC2C[0-9]+ root:tty 620 #/bin/ln -sf $MDEV ttyC2C

Linux: how do i know the module that exports a device node?

If a have a /dev device node and its major/minor numbers how do i know the kernel module name that exported this node?
Short answer :
cd /sys/dev/char/major:minor/device/driver/
ls -al | grep module
Each device is generally associated with a driver, and this is all what the "device model" is about. The sysfs filesystem contains a representation of this devices and their associated driver. Unfortuantely, it seems not all sysfs have a representation of the device nodes, so this applyd only if your /sys directory contains a /dev directory.
Let's take an example, with /dev/video0
On my board, ls -al /dev/video0 output is
crw------- 1 root root 81, 0 Jan 1 00:00 video0
So major number is 81 and minor number is 0.
Let's dive into sysfs :
# cd /sys
# ls
block class devices fs module
bus dev firmware kernel
The sys/dev directory contains entry for the char and block devices of the system :
# cd dev
# cd char
# ls
10:61 13:64 1:3 1:8 249:0 252:0 29:0 4:65 81:0 89:1
10:62 1:1 1:5 1:9 250:0 253:0 29:1 5:0 81:2
10:63 1:11 1:7 248:0 251:0 254:0 4:64 5:1 81:3
What the hell are this links with strange names ?
Remember the major and minor number, 81 and 0 ?
Let's follow this link :
#cd major:minor (ie 81:0)
#ls -al
drwxr-xr-x 2 root root 0 Jan 1 01:56 .
drwxr-xr-x 3 root root 0 Jan 1 01:56 ..
-r--r--r-- 1 root root 4096 Jan 1 01:56 dev
lrwxrwxrwx 1 root root 0 Jan 1 01:56 device -> ../../../vpfe-capture
-r--r--r-- 1 root root 4096 Jan 1 01:56 index
-r--r--r-- 1 root root 4096 Jan 1 01:56 name
lrwxrwxrwx 1 root root 0 Jan 1 01:56 subsystem -> ../../../../../class/video4linux
-rw-r--r-- 1 root root 4096 Jan 1 01:56 uevent
Now we can see that this device nod, which is how the device is presented to userspace, is associated with a kernel device. This association is made through a link. If we follow this link, we end up in a directory, with a driver link. The name of the driver is usually the name of the module :
# ls -al
drwxr-xr-x 3 root root 0 Jan 1 01:56 .
drwxr-xr-x 25 root root 0 Jan 1 00:00 ..
lrwxrwxrwx 1 root root 0 Jan 1 01:56 driver -> ../../../bus/platform/drivers/vpfe-capture
-r--r--r-- 1 root root 4096 Jan 1 01:56 modalias
lrwxrwxrwx 1 root root 0 Jan 1 01:56 subsystem -> ../../../bus/platform
-rw-r--r-- 1 root root 4096 Jan 1 01:56 uevent
drwxr-xr-x 3 root root 0 Jan 1 01:56 video4linux
So here the name of the module is vpfe_capture
The answer to this question is most likely different based on a number of factors. For example, if you're running udev, devfs, pre-devfs, etc.
If you're using Ubuntu (or another equally modern distro) the udevadm command might be what you want.
% udevadm info -q path -n /dev/cdrom
/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0/block/sr0
So, my /dev/cdrom is provided by the sr driver, which resides in the sr_mod kernel module. I don't know of a command that takes /dev/cdrom as an argument and prints sr_mod as output.

Can someone illustrate what's linux device number's minor number exactly for?

The minor number is used by the kernel
to determine exactly which device is
being referred to.
The above explanation is just two abstract, can someone illustrate?
The major number identifies the device driver to use, the minor number indicates which device. If you have multiple partitions, for instance, each gets its own minor:
brw-rw---- 1 root disk 8, 0 Jun 3 20:48 /dev/sda
brw-rw---- 1 root disk 8, 1 Jun 3 20:48 /dev/sda1
brw-rw---- 1 root disk 8, 2 Jun 3 20:48 /dev/sda2
Minor 0 in this case is the raw drive, minor 1 is partition 1, minor 2 is partition 2, etc. Not all devices use 0 as a special case, however. The serial devices start their numbering at 0, where /dev/tty0 is just the first (virtual) terminal device on the system:
crw--w---- 1 root tty 4, 0 Jun 3 20:48 /dev/tty0
crw------- 1 root root 4, 1 Jun 3 20:50 /dev/tty1
crw------- 1 root root 4, 2 Jun 3 20:50 /dev/tty2
crw------- 1 root root 4, 3 Jun 3 20:50 /dev/tty3
In either event, when the device file is opened the kernel will use the major number to determine which module will handle the file and passes the minor to the open() method of the struct file_operations structure that was registered with register_chrdev().
as in the language C ,counting starts from 0 ...it could be a sort of convention followed by driver writers ...after all everything in Linux is based upon C or to some extent C++.Its just a numbering scheme ..You can also start naming your devices from any number between 0 and 255,but please be carefull do not cross the 255 mark for minor numbers else you may overwrite the next available major number..hope this answer helps

Resources