6, practical operation device tree

Section 01 _ using the device tree to the DM9000 card _ touchscreen specified interrupt

Modification method:
The node device compatible property,
configuration / registration platform_driver, the driver
gets interrupt resources in the probe function platform_driver

Methods:
The following is the edited Code:
Lesson 6 1 card _ _ touch screen driver \ 001th_dm9000 \ dm9dev9000c.c
Lesson 6 1 card _ _ touch screen driver \ 002th_touchscreen \ s3c_ts.c

Are uploaded to the directory kernel follows:
Drivers / NET / Ethernet / Davicom
Drivers / INPUT / Touchscreen

. a compiling the kernel
. b start using the new uImage
c test card:.
ifconfig eth0 192.168.1.101
the ping 192.168.1.1

d Touch Screen Test:.
hexdump / dev / evetn0 // then tap the touch screen


Section 02 _ simple to use clock in the device tree

文档:
内核 Documentation/devicetree/bindings/clock/clock-bindings.txt
内核 Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt

. a device tree defines the various clock, called "Clock providers" in a document, such as:
  Clocks: Clock Controller @ 4c000000 {-
    compatible = "Samsung, S3C2440-Clock";
    REG = <0x20 0x4c000000>;
    # clock-cells = <1>; to provide a specified u32 // when it wants to use the clocks, such as selecting the LCD clock clocks emitted, PWM clock
  };

. b When the device needs the clock, it is the "Clock consumers", which describes which of which a clock (id) "Clock providers" uses, such as:
FB0: FB @ 4d000000 {
  compatible = "jz2440, LCD";
  REG = <0x60 0x4D000000>;
  interrupts = <0. 3 0 16>;
  Clocks = <& Clocks HCLK_LCD>; // use HCLK_LCD i.e. the Controller @ 4c000000 Clocks-Clock
    };

. C obtained in the driving / enable clock:

  // determine the number of clock
  int = nr_pclks of_count_phandle_with_args (the dev-> of_node, "Clocks",
                          "# Clock-cells");
  // get a clock
  for (I = 0; I <nr_pclks; I ++) {
    struct CLK CLK * = of_clk_get (the dev-> of_node, I);
  }

  // Enable clock
  clk_prepare_enable (clk);

  // Disable clock
  clk_disable_unprepare (clk);

Section 03 _ simple to use pinctrl in the device tree

Documentation:
Kernel Documentation / devicetree / bindings / pinctrl / samsung-pinctrl.txt

Several concepts:

Bank: name according to the pin, these pins are divided into several groups, each group is called a Bank
  such s3c2440 there GPA, GPB, GPC Bank other,
  each of which has several pins Bank, such GPA0, GPA1, ..., GPC0, GPC1, ... etc. pin

Group: a functional basis, the pin having the same function is called a Group
  such s3c2440 in the TxD port 0, the RxD pins GPH2, GPH3, that these two pins can be classified as a group
  , such as the serial-0 s3c2440 flow control pins GPH0, GPH1, that the two pins can be set as a

State: state of some equipment, such as defined in the kernel's own "default", "init", "idel", "sleep" state;
  may also be defined by their other states, such as serial "flow_ctrl" state (flow control )

  when the device is in a certain state, which can use several pins Group

. a device tree node pinctrl:
A.1 It defines various pin bank, there is such s3c2440 GPA, GPB, GPC, ..., GPB various BANK, there are a plurality of pins each BANK:
  pinctrl_0: @ pinctrl {56 million
        REG = <0x56000000 0x1000>;

        GPA: GPA {
          GPIO-Controller;
          # = GPIO-cells <2>; / * When you want to use later gpa bank of pins required to specify the pin 2 u32 * /
        };

        gpb: gpb {
          gpio-controller;
          #gpio-cells = <2>;
        };

        gpc: gpc {
          gpio-controller;
          #gpio-cells = <2>;
        };

        gpd: gpd {
          gpio-controller;
          #gpio-cells = <2>;
        };
      };

a.2 It also defines various Group (combinations), some functionality involved Group called pin,
such as the serial port to use two pins 0: gph0, gph1:

  uart0_data: Data-UART0 {
      Samsung, pins = "gph0", "gph0";
      Samsung, PIN-function = <2>; / * in GPHCON register gph0, gph1 can set the following values:
                0 --- input function
                1 --- output
                2 --- serial function
                we want to use the serial port functions,
                  Samsung, PIN-function is set to 2
          * /
  };

  uart0_sleep: {uart0_sleep
      Samsung, pins = "gph0", "GPH1";
      Samsung, PIN-function = <0>; / * in GPHCON register gph0, gph1 can set the following values:
                    0 --- input function
                    output 1 ---
                    2 --- serial function
                    we want to use an input function,
                      Samsung, PIN-function is set to 0
          * /
  };


. b To use a device node in a Group PIN:
  Serial 50000000 @ {
    ......
        pinctrl-names = "default", "SLEEP"; / * both names, also referred to State (state) * /
        pinctrl- 0 = <& uart0_data>;
        pinctrl-. 1 = <& uart0_sleep>;
  };

  pinctrl-names defined in the two kinds of state: default and SLEEP,
  default pin may be: pinctrl-0, which specifies which pin group used: uart0_data
  corresponding to the sleep pin is: pinctrl-1, which specifies the use of pin group: uart0_sleep

. C platform_device, platform_driver match:

"Matching Lesson 3 of 06 _platform_device with platform_driver of" matching process is explained in platform_device and platform_driver, and
will eventually call to really_probe (drivers / base / dd.c)

really_probe:
    /* If using pinctrl, bind pins now before probing */
    ret = pinctrl_bind_pins(dev);
        dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
                PINCTRL_STATE_DEFAULT); /* 获得"default"状态的pinctrl */
        dev->pins->init_state = pinctrl_lookup_state(dev->pins->p,
                PINCTRL_STATE_INIT); /* 获得"init"状态的pinctrl */

        ret = pinctrl_select_state (dev-> pins-> p, dev-> pins-> init_state); / * Set the priority "init" state pin * /
        RET = pinctrl_select_state (the dev-> pins-> P, the dev-> pins -> default_state); / * init state if not, set the "default" state pin * /

    ......
    RET = Drv-> Probe (dev);

Therefore: if the device node is specified pinctrl, before the corresponding probe function is called, to "bind pins", i.e. to bind, setting pin

. d want to select the drive, setting a state of the pin:
devm_pinctrl_get_select_default (struct Device * dev); // Pins "default" state
pinctrl_get_select (struct device * dev, const char * name); // The name choose a status pin

pinctrl_put (struct pinctrl * p); // no longer in use, calling on exit


_ Section 04 to the LCD device tree used to specify various parameters

Reference article:
Let TQ2440 gained access to the device tree (1)
http://www.cnblogs.com/pengdonglin137/p/6241895.html

Reference Code: https://github.com/pengdonglin137/linux-4.9/blob/tq2440_dt/drivers/video/fbdev/s3c2410fb.c

Experimental method:
the files used in: doc_and_sources_for_device_tree \ source_and_images \ 5th and 6th class source code and image file (using the full version of the device tree) \ Lesson 6 Section 4 _LCD drive \ 02th_ I modified

. a replacement dts files:
the "jz2440_irq.dts" put / arm / boot / dts directory kernel arch,

. b Alternatively drivers:
the "s3c2410fb.c" into the kernel drivers / video / fbdev / directory,
modify the kernel drivers / video / fbdev / the Makefile:
obj - $ (CONFIG_FB_S3C2410) + = lcd_4.3.o
read:
obj - $ (CONFIG_FB_S3C2410) + = s3c2410fb.o

c. 编译驱动、编译dtbs:
export PATH=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/system/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin
cp config_ok .config
make uImage // 生成 arch/arm/boot/uImage
make dtbs // 生成 arch/arm/boot/dts/jz2440_irq.dtb

d. Using the above uImage, dtb start to see the kernel appears LCD Penguin

 

(1). 设备树中的描述:
fb0: fb@4d000000{
compatible = "jz2440,lcd";
reg = <0x4D000000 0x60>;
interrupts = <0 0 16 3>;
clocks = <&clocks HCLK_LCD>; /* a. 时钟 */
clock-names = "lcd";
pinctrl-names = "default"; /* b. pinctrl */
pinctrl-0 = <&lcd_pinctrl &lcd_backlight &gpb0_backlight>;
status = "okay";

/* c. 根据LCD引脚特性设置lcdcon5, 指定lcd时序参数 */
lcdcon5 = <0xb09>;
type = <0x60>;
width = /bits/ 16 <480>;
height = /bits/ 16 <272>;
pixclock = <100000>; /* 单位: ps, 10^-12 S, */
xres = /bits/ 16 <480>;
yres = /bits/ 16 <272>;
bpp = /bits/ 16 <16>;
left_margin = /bits/ 16 <2>;
right_margin =/bits/ 16 <2>;
hsync_len = /bits/ 16 <41>;
upper_margin = /bits/ 16 <2>;
lower_margin = /bits/ 16 <2>;
vsync_len = /bits/ 16 <10>;
};

&pinctrl_0 {
  gpb0_backlight: gpb0_backlight {
  samsung,pins = "gpb-0";
  samsung,pin-function = <1>;
  samsung,pin-val = <1>;
  };
};


Processing (2) code:
A Clock:.
Info-> = of_clk_get CLK (the dev-> of_node, 0);
clk_prepare_enable (info-> CLK);

b pinctrl:.
code without processing, it will set the "default" state corresponding pinctrl after platform_device / platform_driver match

. C The set pin characteristics LCD lcdcon5, lcd timing parameters specified:

Directly reading the attribute values ​​in the device tree node, it is used to set the driving parameters

of_property_read_u32(np, "lcdcon5", (u32 *)(&display->lcdcon5));
of_property_read_u32(np, "type", &display->type);
of_property_read_u16(np, "width", &display->width);
of_property_read_u16(np, "height", &display->height);
of_property_read_u32(np, "pixclock", &display->pixclock);
of_property_read_u16(np, "xres", &display->xres);
of_property_read_u16(np, "yres", &display->yres);
of_property_read_u16(np, "bpp", &display->bpp);
of_property_read_u16(np, "left_margin", &display->left_margin);
of_property_read_u16(np, "right_margin", &display->right_margin);
of_property_read_u16(np, "hsync_len", &display->hsync_len);
of_property_read_u16(np, "upper_margin", &display->upper_margin);
of_property_read_u16(np, "lower_margin", &display->lower_margin);
of_property_read_u16(np, "vsync_len", &display->vsync_len);


 

 


Temporary notes:

(1) The following information is the key to the virtual address, physical address of the kernel is determined, interested students can look up:
determining vmlinux virtual address:
kernel source:
.config:
CONFIG_PAGE_OFFSET = 0xC0000000

Arch / ARM / the include / asm / Memory. H
#define PAGE_OFFSET UL (CONFIG_PAGE_OFFSET)

arch/arm/Makefile
textofs-y := 0x00008000
TEXT_OFFSET := $(textofs-y)

Arch / ARM / Kernel / vmlinux.lds.S:
. = + PAGE_OFFSET TEXT_OFFSET; // // i.e. 0xC0000000 + 0x00008000 = 0xC0008000, vmlinux virtual address 0xc0008000

Arch / ARM / Kernel / the head.S
#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) // i.e. 0xC0000000 + 0x00008000 = 0xC0008000

determined vmlinux physical address:
kernel source:
Arch / ARM / Mach-S3C24xx / Makefile.boot:
zreladdr-Y + = 0x30008000 // get the self-extracting zImage vmlinux, vmlinux storage location
params_phys-y: = 0x30000100 // tag parameter storage location is no longer required when using the tag dtb

arch/arm/boot/Makefile:
ZRELADDR := $(zreladdr-y)

arch/arm/boot/Makefile:
UIMAGE_LOADADDR=$(ZRELADDR)

scripts/Makefile.lib:
UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)

// create the command uImage, uImage = 64 byte header + zImage, the entry address contained in the header information of the kernel (vmlinux is a physical address)
cmd_uimage = $ (CONFIG_SHELL) $ (MKIMAGE) -A $ (UIMAGE_ARCH) Linux -O \
-C $ (UIMAGE_COMPRESSION) $ (UIMAGE_OPTS-Y) \
-T $ (UIMAGE_TYPE) \
-a $ (UIMAGE_LOADADDR) -e $ (UIMAGE_ENTRYADDR) \
-n $ (UIMAGE_NAME) -d $ (UIMAGE_IN) $ (UIMAGE_OUT)

 

 

 

 

00-Linux device tree Series - Introduction - CSDN blog .html - fly de Hedgehog
https://blog.csdn.net/lhl_blog/article/details/82387486

Linux kernel interrupt subsystems (b): IRQ Domain Introduction _ _ Sohu Sohu technology .html
http://www.sohu.com/a/201793206_467784

(1) Based on TQ2440 interrupt the device tree
https://www.cnblogs.com/pengdonglin137/p/6847685.html

(2) Based on TQ2440 interrupt the device tree
https://www.cnblogs.com/pengdonglin137/p/6848851.html

Based on the Linux kernel porting tiny4412 examples of learning --- behind interrupt knowledge (1)
http://www.cnblogs.com/pengdonglin137/p/6349209.html

Linux kernel interrupt subsystem of (a): Summary
http://www.wowotech.net/irq_subsystem/interrupt_subsystem_architecture.html

Linux kernel interrupt subsystems (b): IRQ Domain Introduction

linux kernel interrupt subsystem, (c): IRQ number and an interrupt descriptor

linux kernel interrupt subsystems (D): High level irq event handler

Linux kernel interrupt subsystems (V): Drive API request a break

Linux kernel interrupt subsystems (VI): ARM interrupt processing

Interrupt subsystems (seven) linux kernel is: GIC code analysis

Guess you like

Origin www.cnblogs.com/liusiluandzhangkun/p/11925064.html