What modifications must be done to a Linux kernel driver to support (equal) multiple devices(myipcore) on a SoC (defined in the device tree) instead of only one?
In my application: only one process will open the appropriate /dev/myipcoreX file!
Device Tree:
amba: amba {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
axi_myipcore1: myipcore#A0001000 {
compatible = "xy,my-ip-core-1.00";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 89 1>;
reg = <0x0 0xA0001000 0x0 0x14>;
};
axi_myipcore2: myipcore#A0002000 {
compatible = "xy,my-ip-core-1.00";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 90 1>;
reg = <0x0 0xA0002000 0x0 0x14>;
};
....
}
For each device tree entry the _probe() function of the driver is called. How to get dynamically the next minor number for alloc_chrdev_region() and how to execute class_create() only once?
Or do I have to modify the device tree?
You see, I'm looking for the central theme....
Related
I have 3 instances of device sharing the same interrupt number. When I add these numbers in the interrupt property of the device node in dtsi file, I get build errors.
Any idea how to resolve this ?
rpc1: rpc#350a0000 {
compatible = "sat,rpc";
label = "IF0_RPC1";
reg = <0x190a0000 0x100>,
<0x19030420 0x4>;
reg-names = "sfr", "sysreg";
interrupts = <91 0>, <90 0>;
status = "disabled";
};
rpc2: rpc#150a0000 {
compatible = "sat,rpc";
label = "IF0_RPC2";
reg = <0x190f0000 0x100>,
<0x190b0420 0x4>;
reg-names = "sfr", "sysreg";
interrupts = <91 0>, <90 0>;
status = "disabled";
};
Error:
gen_isr_tables.py: error: multiple registrations at table_index 90 for irq 90 (0x5a)
Existing handler 0x7002aae7, new handler 0x7002aae7
The Linux kernel device tree can specify the address of an interrupt controller like this:
interrupt-controller {
compatible = "arm,cortex-a15-gic";
interrupt-parent = <0x38>;
#interrupt-cells = <0x3>;
interrupt-controller;
reg = <0x0 0x50041000 0x0 0x1000 0x0 0x50042000 0x0 0x100>;
status = "okay";
linux,phandle = <0x38>;
phandle = <0x38>;
};
https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt seems outdated, it doesn't mention what it means when #interrupt-cells = <0x3>;, so I don't know for example what 0x0 0x50041000 0x0 means.
Also, what does status, linux, phandle, phandle and interrupt-parent mean?
I want to add support for virtualization on a Jetson Nano board, and I must know which interrupts to add to the device tree, as well as how to translate them to the device three interrupt-controller node.
In my application I need RS485 interfaces. I am using some UARTs from am3352 but I need few more, so I'm trying to expand using SPI and max3109 chip.
I have successfully added max3109 to my device tree using module max310x - it shows two devices: /dev/ttyMAX0 and /dev/ttyMAX1. Here is the device tree fragment:
&spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
num_cs = <1>;
cs-gpios = <&gpio2 17 0>;
ti,pindir-d0-out-d1-in;
max310x_0: max0#0 {
compatible = "maxim,max3109";
reg = <0>;
spi-max-frequency = <24000000>;
clocks = <&clk1m8>;
clock-names = "xtal";
interrupt-parent = <&gpio2>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
clk1m8: clk1m8 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1843200>;
};
};
};
and the pins:
spi1_pins: pinmux_spi1_pins {
pinctrl-single,pins = <
0x108 (PIN_INPUT_PULLUP | MUX_MODE2) /* (H16) gmii1_col.spi1_sclk */
0x10c (PIN_INPUT_PULLUP | MUX_MODE2) /* (H17) gmii1_crs.spi1_d0 */
0x110 (PIN_INPUT_PULLUP | MUX_MODE2) /* (J15) gmii1_rxer.spi1_d1 */
>;
};
UARTs from max3109 are connected to rs232/rs485 converter with max3109's RTSn pins conected to both DE and RE pins.
The problem: UARTS on max3109 seems to work fine - both rs485 are transmitting data, but not reciving. Problem is that RTS is always at 0V level...
In UARTs from am3352 I am using in device tree the following property: "linux,rs485-enabled-at-boot-time". But adding it to main max310x_0 node is not giving any effect - this node is the expander node (containing 2 UARTs and gpio-controller), not the UART itself.
My idea is that I need to add a child-nodes for each UART and in it place the property "linux,rs485-enabled-at-boot-time". But I don't have a clue how to do it. I tried something like this:
&spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
num_cs = <1>;
cs-gpios = <&gpio2 17 0>;
ti,pindir-d0-out-d1-in;
max310x_0: max0#0 {
compatible = "maxim,max3109";
reg = <0>;
spi-max-frequency = <24000000>;
clocks = <&clk1m8>;
clock-names = "xtal";
interrupt-parent = <&gpio2>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
clk1m8: clk1m8 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1843200>;
};
ttyMAX0 {
linux,rs485-enabled-at-boot-time;
};
ttyMAX1 {
linux,rs485-enabled-at-boot-time;
};
};
};
but it didn't worked.
My question: How am I supposed to add those child-nodes (if that's the proper way) and what should I place in them to make RTS work?
EDIT:
after sawdust suggestion it seems it's impossible to add rs485 mode in device tree.
So I tried to add this functionality to device tree and I think I'm starting to understand how things work down in here. To start with something I'm printing port.flags value to dmesg and it seems my little insertion works (a bit) - it changes the value depending on presence of linux,rs485-enabled-at-boot-time parameter in device tree.
Here is the code I have inserted:
if (of_property_read_bool(dev->of_node, "linux,rs485-enabled-at-boot-time"))
s->p[i].port.flags |= SER_RS485_ENABLED;
printk("s->p[i].port.flags is: %d\n",s->p[i].port.flags);
The value of port.flags toggles from 134225920 to 134225921 depending on presence of linux,rs485-enabled-at-boot-time.
but the RTS pin still have constant 0V on my oscilloscope...
I'm trying to figure out if SER_RS485_RTS_ON_SEND and SER_RS485_RTS_AFTER_SEND have something to do with this, but I'm prete sure it's only for reverting RTS signal.
After few attempts IOCTL was the best and easiest solution. Here is some example code that helped me much. https://gist.github.com/amarburg/07564916d8d32e20e6ae375c1c83a995
It's basic example how to turn RS485 mode on and off using IOCTL and read it's current mode. Works with both CPUs internal UARTS and MAX3109.
First I must to tell you, I am not really from electronics background, I have very rough knowledge about Linux drivers, I2C, touch screens, etc.
Problem background
My Wandboard was previously working with Fusion 7 touch display worked with Prism touch screen driver, already provided by Wandboard.
As per my new requirement, I have got Ilitek touch screen which I am trying get it working with my Wandboard dual (i.MX6-Cortex-A9, Linux Kernel:3.0.35).
I got following Ilitek touch screen driver files under folder ilitek_limv3_0_9.
ilitek_lim.c
ilitek.h
ilitek_update.c
ilitek_i2c.idc
I compiled the driver into Linux kerenl as a built-in module, tried to run on the board but failed. The driver doesn't appear in /dev/input.
I debuged the kerenl code a bit, and found that the code doesn't reach to driver's probe function, instead it fails in device binding (i2c device registration). Just then I come to know about Device tree.
I looked into following dts files (which I believe my Wandboard is using), putting little i2c configuration present in the files here.
imx6qdl.dtsi
i2c1: i2c#021a0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a0000 0x4000>;
interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C1>;
status = "disabled";
};
i2c2: i2c#021a4000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a4000 0x4000>;
interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C2>;
status = "disabled";
};
i2c3: i2c#021a8000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a8000 0x4000>;
interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C3>;
status = "disabled";
};
imx6qdl-wandboard.dtsi
&hdmi {
ddc-i2c-bus = <&i2c1>;
status = "okay";
};
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
codec: sgtl5000#0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
clocks = <&clks 201>;
VDDA-supply = <®_2p5v>;
VDDIO-supply = <®_3p3v>;
};
};
I see dts note entry for sgtl5000 which is audio codec which then appears as /dev/input/event0. But I don't find any entry for 'prism' driver, which actually runs perfectly on the board. Neither dts files nor board-files have entry for 'prism' driver. But I am sure it's using 'device-tree' approach.
Questions
As my Wandboard works fine with 'prism' driver and touch device, why I don't see device node entry for 'prism' in dts files ?
Is there any other way for 'i2c device registration' other than 'device-tree' and 'earlier board-file' approach ?
How could I get past with ilitek touch driver not getting i2c-matched/registered problem ?
Thanks in advance.
I am using freescale powerpc 85xx processor with linux 2.6.32.
The i2c subsytem is mapped at address 0x03000 inside the ccsr registers. I want to add an RTC device,DS1338 (i2c addr: 0x68) connected to an I2c mux (address: 0x76) on channel 5 (selected by writing 0xfd on control register).
Without adding the device in the dts file, the rtc device won't bind to driver.
I have the following entry in my device tree right now:
i2c#3000 { /* I2C 1 */
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl-i2c";
reg = <0x3000 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
dfsrr;
};
What would it look like after adding the above information. Had it been a device directly on the i2c bus and not through mux, I would have added something like this:
i2c#3000 { /* I2C 1 */
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl-i2c";
reg = <0x3000 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
rtc:rtc#68 {
compatible = "dallas,ds1307";
reg = <0x68>;
};
dfsrr;
};
Now with the mux in the path, and having to select channel, I don't think I know how to make an entry.