linux device tree node names and labels duplicated in include files - linux

In the linux kernel device tree documentation for pinctrl-single binding I find this syntax in the example:
/* SoC common file */
/* first controller instance for pins in core domain */
pmx_core: pinmux#4a100040 {
...
/* board specific .dts file */
&pmx_core {
...
The pmx_core label appears in the SoC common file (I assume this is an include file with .dtsi extension) and in the board specific .dts file.
What does the & in front of the pmx_core label mean?

This is usually used to "append" devices to a node defined in another file.
In your case, you will likely find nodes underneath your &pmx_core node which are attached ot the pmx_core defined in the SoC common file.

Related

device tree, change fixed link ethernet phy speed runtime

I'm working with a custom IMX8 board with a phy that is not supported by the Linux kernel (it's a clause 45 automotive oabr transceiver).
The phy is actually working, and its mdio bus and digital IO's are controlled with an userspace application.
To acheive this i had to bind it in the device tree with the fixed-link property as below.
...
port#0 {
reg = <0x00>;
label = "oabr";
phy-mode = "rgmii";
fixed-link {
speed = <1000>;
full-duplex;
pause;
asym-pause;
};
};
...
Now... the question is, i would like to change the speed of the phy from 1000 to 100, i'm able to do it if configure the phy AND change the device tree, but this implies a reboot of the device to load a new dts file.
Is there a way to get it working runtime?
Thanks a lot,
Marco
In order to add or load a device tree blob in runtime, the only way is to use Linux overlay.
But the problem is that NXP does not support it in its linux-imx kernel , you can see their post about it here.
If you don't make the change permanently to your main device tree file used for the image, I can advise you of doing this:
Create another dts (Ex: new-phy.dts) that includes the main dts and add your override node there
Add the new dtb name to your ${MACHINE}.conf KERNEL_DEVICETREE variable:
KERNEL_DEVICETREE += "freescale/new-phy.dtb"
Now you need to choose it once you boot from u-boot CLI, like:
u-boot> setenv fdt_file new-phy.dtb
u-boot> saveenv
u-boot> boot
Or, you can set it in your u-boot/configs/${MACHINE}_defconfig:
CONFIG_DEFAULT_FDT_FILE="new-phy.dtb"
Otherwise, you can try to add the overlay support for the kernel you are using.
Toradex has SOMs and EVKs based on IMX8M and they are working with overlays, you can take a look here and try to understand what they did to support it.

PWM without sysfs

I am pretty new to linux kernel.I am trying to generate PWM through linux. The API man talks about a sysfs interface. I want to implement a userspace program in C. But using PWM forces me to use a command line. Furthermore, using read, write is a problem in C as when I am using cd, it is changing path directory.
Thus the path is variable. Is there any way I can pass values to pwm_config() without using sysfs? Perhaps through ioctl? If yes, then what would be the procedure?
Application C code:
void main(){
int export = open("/sys/class/pwm/pmwchip0/export",O_WRONLY);
int period,duty_cycle,enable;
if(export == -1)
{
perror("Export:");
}
and so on for other files like period and duty cycle.
When I try to run my application I get the following error.
Export:: No such file or directory
Export_write: Bad file descriptor
Period_write:: Bad file descriptor
Duty_cycle_write:: Bad file descriptor
Enable_write:: Bad file descriptor
As far as I know, the sysfs is the only standard userspace interface to PWM. But anything you can do from the command line can be done in C (the shell is written in C, after all).
The problem you are having with cd is not actually a problem. Inside sysfs the directories in /sys/class/pwd/* are actually symbolic links to the proper devices. In your case /sys/class/pwm/pwmchip0 is a symlink to /sys/devices/soc0/amba/f8001000.timer/pwm/pwmchip0.
The funny thing is that some shells, when you cd a symbolic link will resolve to the real directory, but other shells will actually keep the symlink name as the current directory.
But that issue with the directory symlinks should not be an issue for you. A C program willing to manage PWM devices should not change the working directory. Instead open the files with the full path:
open("/sys/class/pwm/pwmchip0/npwm", O_RDONLY);
and so on.

How can I modify vmlinux.lds to break up a built-in.o?

So I'm working with ucLinux under the NXP LPC1788 processor (ARM-CortexM3, no MMU). The ucLinux port was orignally done by Emcraft Systems.
The 1788 has 512KiB of onboard flash (called eNVM) which is faster to access than the rest of memory connected via the external memory controller. Emcraft's linker script has a portion where you can relocate critical parts of the kernel to this eNVM area. I'm using 80K for the bootloader so I have 432K free to stuff with as much kernel as I can.
So the linker script, vmlinux.lds.S, has a portion that begins like this:
#ifdef CONFIG_KERNEL_IN_ENVM
_envm_loc = .;
.envm ENVM_PHYS_OFFSET + CONFIG_KERNEL_IN_ENVM_OFFSET * 1024 : {
_envm_start = .;
#if CONFIG_KERNEL_IN_ENVM_SIZE>0
__exception_text_start = .;
*(.exception.text*)
*(.exception.rodata*)
__exception_text_end = .;
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
usr/built-in.o(.text)
usr/built-in.o(.rodata*)
init/built-in.o(.text)
init/built-in.o(.rodata*)
mm/built-in.o(.text)
mm/built-in.o(.rodata*)
...and so on. As you can see, entire subdirectories are being pulled in via their built-in.o object file.
As I get closer and closer to the end of the flash space, I'd like to have a bit more control over what gets linked here. drivers/built-in.o, for example, won't fit in the free space but if I could get drivers/usb and drivers/input here, that would help a lot.
If I modify the linker script to have just those portions, like this:
drivers/usb/built-in.o(.text)
drivers/usb/built-in.o(.rodata*)
drivers/input/built-in.o(.text)
drivers/input/built-in.o(.rodata*)
then I get duplicate symbol errors when drivers/built-in.o gets linked. I can't see where that happens exactly, so that's part of the problem I think.
So the question: Is there a way to link individual built-in.o files to different regions without linking the master .o built at the top of the directory?
I've put the whole linker file at http://pastebin.com/qcj6rHme if anyone wants to take a look.
Thanks!
If you're going to link usb and input directly, drivers/built-in.o should not include them. Modifying Kbuild to build the subdirs but not include them is a bit tricky; those two elements will have to filtered out of obj-y where drivers/built-in.o is generated -- if they aren't included in obj-y they won't get built at all.

Linux device file is missing

I find the driver specific stuff in /sys/class/graphic/XM_403
But in /dev/ is no XM_403 file.
Here is the pertinent code.
graphic_class = class_create(THIS_MODULE,"graphic");
device_create(graphic_class,NULL,MKDEV(MAJOR_NR,minor),NULL,"XM_403");
device_create creates a file within the sysfs, exactly what you are seeing.
Usually it's udev that creates the device file.

Embedded linux driver load-up

I'm developing a device driver for embedded linux(ARM).
How can I compile the KO file generated as a part of the kernel,
in a way that the module will be loaded in boot ?
this is the first time I need to compile the driver into the kernel and not as a loadable module. so I'm not sure how to do it.
Thanks,
Ramon.
For your first question, I assume that you want to build your driver statically into the kernel image(not as a module). First, you select a directory in drivers directory where you want to put your driver files. Assume you want to put your files in drivers/char/. Copy your files into this directory. There will be a Kconfig file in the drivers/char/ directory, open it and add an entry like this in the before the endmenu.
config MYDRIVER
bool "This is a driver for something"
default n
help
This is a test driver.
Save the file and open Makefile in the same directory. Goto end of the file and add the following entry.
obj-$(CONFIG_MYDRIVER) += mydriver.o
That's it you have added the file to the kernel tree. Now, as usual, do make menuconfig and select MYDRIVER.
See this Kernel Compilation article for more info.
You need to build your device driver as a built-in. You can either edit your kernel .config file manually and change "=m" to "=y" for the CONFIG option that belongs to your module, or use make menuconfig to change <M> to <*> for your device driver.
before -> <M> Your Device Driver Name Here
after -> <*> Your Device Driver Name Here

Resources