2015년 2월 28일 토요일

[Linux Kernel] 92주차(2015.2.28)

ARM10C 92주차 후기

일시 : 2015.02.28 (92주차)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 3명

92주차 진도

  • start_kernel()->time_init()
    • ->of_clk_init()
      • ->clk_init_cb()
        • ->exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
          • ->samsung_clk_register_mux()
    1 1 time_init 741 init/main.c 2 1 of_clk_init 154 ~/kernel/iamroot/linux-stable/arch/arm/kernel/time.c 3 1 exynos5420_clk_init 3243 // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소) 4 1 samsung_clk_register_mux 1194 ~/kernel/iamroot/linux-stable/drivers/clk/samsung/clk-exynos5420.c 5 1 clk_register_mux 391 ~/kernel/iamroot/linux-stable/drivers/clk/samsung/clk.c 6 1 clk_register_mux_table 378 ~/kernel/iamroot/linux-stable/drivers/clk/clk-mux.c 7 1 clk_register 299 ~/kernel/iamroot/linux-stable/drivers/clk/clk-mux.c 8 1 _clk_register 2729 ret = _clk_register(dev, hw, clk); 9 1 __clk_init 2597 ret = __clk_init(dev, clk);

start_kernel()->time_init()

  • time_init()
asmlinkage void __init start_kernel(void)
{
...
    early_irq_init();
    // irq_desc 0 ~ 15 까지의 object을 할당 받고 초기화를 수행
    // allocated_irqs에 bit를 1로 세팅하고 radix tree에 각 irq_desc를 노트로 추가

    init_IRQ();
    // gic, combiner이 사용할 메모리 할당과 자료 구조 설정,
    // gic irq (0~15), combiner irq (32~63) interrupt 를 enable 시킴

    tick_init();
    // tick 관련 mask 변수를 0으로 초기화 수행

    init_timers();
    // boot_tvec_bases의 맴버 값을 초기화하고 timers_nb를 cpu_notifier 에 등록,
    // softirq_vec[1] 에 run_timer_softirq 등록하여 초기화 수행

    hrtimers_init();
    // hrtimer_bases의 맴버 값을 초기화하고 hrtimers_nb를 cpu_notifier 에 등록,
    // softirq_vec[8] 에 run_hrtimer_softirq 등록하여 초기화 수행

    softirq_init();
    // tasklet_vec, tasklet_hi_vec 맴버 값을 초기화하고,
    // softirq_vec[6]에 tasklet_action, softirq_vec[0]에 tasklet_hi_action 등록하여 초기화 수행

    timekeeping_init();
    // ntp 관련 전역변수 초기화, timekeeper, shadow_timekeeper의 맴버값 초기화 수행

    time_init();

time_init()->of_clk_init(NULL)

  • time_init()
// ARM10C 20150103
void __init time_init(void)
{
    // machine_desc->init_time: __mach_desc_EXYNOS5_DT.init_time: NULL
    if (machine_desc->init_time) {
        machine_desc->init_time();
    } else {
#ifdef CONFIG_COMMON_CLK // CONFIG_COMMON_CLK=y
        of_clk_init(NULL);
#endif

of_clk_init()->clk_init_cb(np)

  • clk_init_ch()
// ARM10C 20150103
// NULL
void __init of_clk_init(const struct of_device_id *matches)
{
    const struct of_device_id *match;
    struct device_node *np;

    // matches: NULL
    if (!matches)
        // __clk_of_table:
        // __clk_of_table_fixed_factor_clk
        // __clk_of_table_fixed_clk
        // __clk_of_table_exynos4210_audss_clk
        // __clk_of_table_exynos5250_audss_clk
        // __clk_of_table_exynos5420_clk
        matches = __clk_of_table;
        // matches:
        // __clk_of_table_fixed_factor_clk
        // __clk_of_table_fixed_clk
        // __clk_of_table_exynos4210_audss_clk
        // __clk_of_table_exynos5250_audss_clk
        // __clk_of_table_exynos5420_clk

    for_each_matching_node_and_match(np, matches, &match) {
    // for (np = of_find_matching_node_and_match(NULL, matches, &match);
    //      np; np = of_find_matching_node_and_match(np, matches, &match))

        // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, match: __clk_of_table_exynos5420_clk

        // match->data: __clk_of_table_exynos5420_clk.data: exynos5420_clk_init
        of_clk_init_cb_t clk_init_cb = match->data;
        // clk_init_cb: exynos5420_clk_init

        // clk_init_cb: exynos5420_clk_init,
        // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
        // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
        clk_init_cb(np);
    }
}
#endif
  • call: exynos5420_clk_init()
    • // clk_init_cb: exynos5420_clk_init,
    • // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
    • // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
    • clk_init_cb(np);

exynos5420_clk_init()

  • called: clk_init_cb(np)
    • start_kernel()->time_init()->of_clk_init()->clk_init_cb(np)
/* register exynos5420 clocks */
// ARM10C 20150103
// devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
static void __init exynos5420_clk_init(struct device_node *np)
{
    void __iomem *reg_base;

// 2015/01/03 종료
// 2015/01/10 시작

    // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
    if (np) {
        // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
        // of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
        reg_base = of_iomap(np, 0);
        // reg_base: 0xf0040000

        // of_iomap에서 한일:
        // device tree 있는 clock node에서 node의 resource 값을 가져옴
        // of_address_to_resource에서 한일(index: 0):
        // (&res)->start: 0x10010000
        // (&res)->end: 0x1003ffff
        // (&res)->flags: IORESOURCE_MEM: 0x00000200
        // (&res)->name: "/clock-controller@10010000"
        /*
        // alloc area (CLK) 를 만들고 rb tree에 alloc area 를 추가
        // 가상주소 va_start 기준으로 CLK 를 RB Tree 추가한 결과
        //
        //                                  CHID-b
        //                               (0xF8000000)
        //                              /            \
        //                         TMR-b               PMU-b
        //                    (0xF6300000)             (0xF8180000)
        //                      /      \               /           \
        //                GIC#1-r      WDT-b         CMU-b         SRAM-b
        //            (0xF0002000)   (0xF6400000)  (0xF8100000)   (0xF8400000)
        //             /       \                                          \
        //        GIC#0-b     CLK-b                                        ROMC-r
        //    (0xF0000000)   (0xF0040000)                                 (0xF84C0000)
        //                   /      \
        //               COMB-r     SYSC-r
        //          (0xF0004000)   (0xF6100000)
        //
        // vmap_area_list에 GIC#0 - GIC#1 - COMB - CLK - SYSC -TMR - WDT - CHID - CMU - PMU - SRAM - ROMC
        // 순서로 리스트에 연결이 됨
        //
        // (kmem_cache#30-oX (vm_struct))->flags: GFP_KERNEL: 0xD0
        // (kmem_cache#30-oX (vm_struct))->addr: 0xf0040000
        // (kmem_cache#30-oX (vm_struct))->size: 0x31000
        // (kmem_cache#30-oX (vm_struct))->caller: __builtin_return_address(0)
        //
        // (kmem_cache#30-oX (vmap_area CLK))->vm: kmem_cache#30-oX (vm_struct)
        // (kmem_cache#30-oX (vmap_area CLK))->flags: 0x04
        */
        // device tree 있는  clock node에서 node의 resource 값을 pgtable에 매핑함
        // 0xc0004780이 가리키는 pte의 시작주소에 0x10010653 값을 갱신
        // (linux pgtable과 hardware pgtable의 값 같이 갱신)
        //
        //  pgd                   pte
        // |              |
        // +--------------+
        // |              |       +--------------+ +0
        // |              |       |  0xXXXXXXXX  | ---> 0x10010653 에 매칭되는 linux pgtable 값
        // +- - - - - - - +       |  Linux pt 0  |
        // |              |       +--------------+ +1024
        // |              |       |              |
        // +--------------+ +0    |  Linux pt 1  |
        // | *(c0004780)  |-----> +--------------+ +2048
        // |              |       |  0x10010653  | ---> 2308
        // +- - - - - - - + +4    |   h/w pt 0   |
        // | *(c0004784)  |-----> +--------------+ +3072
        // |              |       +              +
        // +--------------+ +8    |   h/w pt 1   |
        // |              |       +--------------+ +4096
        //
        // cache의 값을 전부 메모리에 반영

        // reg_base: 0xf0040000
        if (!reg_base)
            panic("%s: failed to map registers\n", __func__);
    } else {
        panic("%s: unable to determine soc\n", __func__);
    }

    // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
    // ARRAY_SIZE(exynos5420_clk_regs): 59
    samsung_clk_init(np, reg_base, nr_clks,
            exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
            NULL, 0);

    // samsung_clk_init 에서 한일:
    // struct samsung_clk_reg_dump를 59개 만큼 메모리를 할당 받아
    // exynos5420_clk_regs의 값으로 맴버값 세팅
    // (kmem_cache#26-oX)[0...58].offset: exynos5420_clk_regs[0...58]
    //
    // syscore_ops_list의 tail에 (&samsung_clk_syscore_ops)->node 를 추가
    //
    // struct clk * 를 769개 만큼 메모리를 clk_table에 할당 받음
    // clk_table: kmem_cache#23-o0
    //
    // clk_data.clks: kmem_cache#23-o0 (clk_table)
    // clk_data.clk_num: 769
    //
    // struct of_clk_provider 의 메모리(kmem_cache#30-oX)를 할당 받고 맴버값 초기화 수행
    //
    // (kmem_cache#30-oX)->node: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
    // (kmem_cache#30-oX)->data: &clk_data
    // (kmem_cache#30-oX)->get: of_clk_src_onecell_get
    //
    // list인 of_clk_providers의 head에 (kmem_cache#30-oX)->link를 추가

    // ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
    samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
            ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
            ext_clk_match);

    // samsung_clk_of_register_fixed_ext 에서 한일:
    //
    // devtree에서 allnext로 순회 하면서 찾은 fixed-rate-clocks node 에서
    // fixed-rate-clocks node에서 "clock-frequency" property값을 freq에 읽어옴
    // freq: 24000000
    // exynos5420_fixed_rate_ext_clks[0].fixed_rate: 24000000
    //
    // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#30-oX)->fixed_rate: 24000000
    // (kmem_cache#30-oX)->hw.init: &init
    // (&(kmem_cache#30-oX)->hw)->clk: kmem_cache#29-oX
    //
    // struct clk 만큼 메모리를 kmem_cache#29-oX 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#29-oX)->name: kmem_cache#30-oX ("fin_pll")
    // (kmem_cache#29-oX)->ops: &clk_fixed_rate_ops
    // (kmem_cache#29-oX)->hw: &(kmem_cache#30-oX)->hw
    // (kmem_cache#29-oX)->flags: 0x30
    // (kmem_cache#29-oX)->num_parents: 0
    // (kmem_cache#29-oX)->parent_names: ((void *)16)
    // (kmem_cache#29-oX)->parent: NULL
    // (kmem_cache#29-oX)->rate: 24000000
    //
    // (&(kmem_cache#29-oX)->child_node)->next: NULL
    // (&(kmem_cache#29-oX)->child_node)->pprev: &(&(kmem_cache#29-oX)->child_node)
    //
    // (&clk_root_list)->first: &(kmem_cache#29-oX)->child_node
    //
    // clk_table[1]: (kmem_cache#23-o0)[1]: kmem_cache#29-oX
    //
    // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX 할당 받고
    // struct clk_lookup_alloc 맴버값 초기화 수행
    //
    // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX
    // (kmem_cache#30-oX)->con_id: "fin_pll"
    // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fin_pll"
    //
    // list clocks에 &(&(kmem_cache#30-oX)->cl)->nade를 tail로 추가

    // ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
    samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
                    reg_base);

    // samsung_clk_register_pll에서 한일:
    // exynos5420_plls에 정의되어 있는 PLL 값들을 초기화 수행
    //
    // [apll] 의 초기화 값 수행 결과:
    // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX (apll) 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
    // pll: kmem_cache#30-oX (apll)
    //
    // (kmem_cache#30-oX (apll))->hw.init: &init
    // (kmem_cache#30-oX (apll))->type: pll_2550: 2
    // (kmem_cache#30-oX (apll))->lock_reg: 0xf0040000
    // (kmem_cache#30-oX (apll))->con_reg: 0xf0040100
    //
    // struct clk 만큼 메모리를 kmem_cache#29-oX (apll) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#29-oX (apll))->name: kmem_cache#30-oX ("fout_apll")
    // (kmem_cache#29-oX (apll))->ops: &samsung_pll35xx_clk_min_ops
    // (kmem_cache#29-oX (apll))->hw: &(kmem_cache#30-oX (apll))->hw
    // (kmem_cache#29-oX (apll))->flags: 0x40
    // (kmem_cache#29-oX (apll))->num_parents: 1
    // (kmem_cache#29-oX (apll))->parent_names: kmem_cache#30-oX
    // (kmem_cache#29-oX (apll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
    // (kmem_cache#29-oX (apll))->parent: kmem_cache#29-oX (fin_pll)
    // (kmem_cache#29-oX (apll))->rate: 1000000000 (1 Ghz)
    //
    // (&(kmem_cache#29-oX (apll))->child_node)->next: NULL
    // (&(kmem_cache#29-oX (apll))->child_node)->pprev: &(&(kmem_cache#29-oX (apll))->child_node)
    //
    // (&(kmem_cache#29-oX (fin_pll))->children)->first: &(kmem_cache#29-oX (apll))->child_node
    //
    // (&(kmem_cache#30-oX (apll))->hw)->clk: kmem_cache#29-oX (apll)
    //
    // clk_table[2]: (kmem_cache#23-o0)[2]: kmem_cache#29-oX (apll)
    //
    // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX (apll) 할당 받고
    // struct clk_lookup_alloc 맴버값 초기화 수행
    //
    // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX (apll)
    // (kmem_cache#30-oX)->con_id: "fout_apll"
    // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fout_apll"
    //
    // list clocks에 &(&(kmem_cache#30-oX (apll))->cl)->nade를 tail로 추가
    //
    // cpll, dpll, epll, rpll, ipll, spll, vpll, mpll, bpll, kpll 초기화 수행 결과는 생략.

    // ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
    samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
            ARRAY_SIZE(exynos5420_fixed_rate_clks));

    // samsung_clk_register_fixed_rate에서 한일:
    // exynos5420_fixed_rate_clks에 정의되어 있는 fixed rate 값들을 초기화 수행
    //
    // sclk_hdmiphy 의 초기화 값 수행 결과
    // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#30-oX)->fixed_rate: 24000000
    // (kmem_cache#30-oX)->hw.init: &init
    // (&(kmem_cache#30-oX)->hw)->clk: kmem_cache#29-oX
    //
    // struct clk 만큼 메모리를 kmem_cache#29-oX 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#29-oX)->name: kmem_cache#30-oX ("sclk_hdmiphy")
    // (kmem_cache#29-oX)->ops: &clk_fixed_rate_ops
    // (kmem_cache#29-oX)->hw: &(kmem_cache#30-oX)->hw
    // (kmem_cache#29-oX)->flags: 0x30
    // (kmem_cache#29-oX)->num_parents: 0
    // (kmem_cache#29-oX)->parent_names: ((void *)16)
    // (kmem_cache#29-oX)->parent: NULL
    // (kmem_cache#29-oX)->rate: 24000000
    //
    // (&(kmem_cache#29-oX)->child_node)->next: NULL
    // (&(kmem_cache#29-oX)->child_node)->pprev: &(&(kmem_cache#29-oX)->child_node)
    //
    // (&clk_root_list)->first: &(kmem_cache#29-oX)->child_node
    //
    // clk_table[158]: (kmem_cache#23-o0)[158]: kmem_cache#29-oX
    //
    // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX 할당 받고
    // struct clk_lookup_alloc 맴버값 초기화 수행
    //
    // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX
    // (kmem_cache#30-oX)->con_id: "fin_pll"
    // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fin_pll"
    //
    // list clocks에 &(&(kmem_cache#30-oX)->cl)->nade를 tail로 추가
    //
    // "sclk_pwi", "sclk_usbh20", "mphy_refclk_ixtal24", "sclk_usbh20_scan_clk" 초기화 수행 결과는 생략.

    // ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
    samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
            ARRAY_SIZE(exynos5420_fixed_factor_clks));

    // samsung_clk_register_fixed_factor에서 한일:
    // struct clk_fixed_factor 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_factor 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#30-oX)->mult: 1
    // (kmem_cache#30-oX)->div: 2
    // (kmem_cache#30-oX)->hw.init: &init
    //
    // struct clk 만큼 메모리를 kmem_cache#29-oX (sclk_hsic_12m) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#29-oX (sclk_hsic_12m))->name: kmem_cache#30-oX ("sclk_hsic_12m")
    // (kmem_cache#29-oX (sclk_hsic_12m))->ops: &clk_fixed_factor_ops
    // (kmem_cache#29-oX (sclk_hsic_12m))->hw: &(kmem_cache#30-oX (sclk_hsic_12m))->hw
    // (kmem_cache#29-oX (sclk_hsic_12m))->flags: 0x20
    // (kmem_cache#29-oX (sclk_hsic_12m))->num_parents: 1
    // (kmem_cache#29-oX (sclk_hsic_12m))->parent_names: kmem_cache#30-oX
    // (kmem_cache#29-oX (sclk_hsic_12m))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
    // (kmem_cache#29-oX (sclk_hsic_12m))->parent: kmem_cache#29-oX (fin_pll)
    // (kmem_cache#29-oX (sclk_hsic_12m))->rate: 12000000
    //
    // (&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)->next: NULL
    // (&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)
    //
    // (&(kmem_cache#29-oX (fin_pll))->children)->first: &(kmem_cache#29-oX (sclk_hsic_12m))->child_node
    //
    // (&(kmem_cache#30-oX (sclk_hsic_12m))->hw)->clk: kmem_cache#29-oX (sclk_hsic_12m)
    //
    // clk_table[0]: (kmem_cache#23-o0)[0]: kmem_cache#29-oX (sclk_hsic_12m)

// 2015/01/24 종료
// 2015/01/31 시작

    // ARRAY_SIZE(exynos5420_mux_clks): 85
    samsung_clk_register_mux(exynos5420_mux_clks,
            ARRAY_SIZE(exynos5420_mux_clks));

    // samsung_clk_register_mux 에서 한일:
    // exynos5420_mux_clks에 등록 되어 있는 clock mux 들의 초기화를 수행
    //
    // mout_mspll_kfc, sclk_dpll를 수행한 결과:
    //
    // (mout_mspll_kfc) 에서 한일:
    // struct clk_mux 만큼 메모리를 kmem_cache#30-oX (mout_mspll_kfc) 할당 받고 struct clk_mux 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#30-oX)->reg: 0xf005021c
    // (kmem_cache#30-oX)->shift: 8
    // (kmem_cache#30-oX)->mask: 0x3
    // (kmem_cache#30-oX)->flags: 0
    // (kmem_cache#30-oX)->lock: &lock
    // (kmem_cache#30-oX)->table: NULL
    // (kmem_cache#30-oX)->hw.init: &init
    //
    // struct clk 만큼 메모리를 kmem_cache#29-oX (mout_mspll_kfc) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#29-oX (mout_mspll_kfc))->name: kmem_cache#30-oX ("mout_mspll_kfc")
    // (kmem_cache#29-oX (mout_mspll_kfc))->ops: &clk_mux_ops
    // (kmem_cache#29-oX (mout_mspll_kfc))->hw: &(kmem_cache#30-oX (mout_mspll_kfc))->hw
    // (kmem_cache#29-oX (mout_mspll_kfc))->flags: 0xa0
    // (kmem_cache#29-oX (mout_mspll_kfc))->num_parents 4
    // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names: kmem_cache#30-oX
    // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "sclk_cpll"
    // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[1]: (kmem_cache#30-oX)[1]: kmem_cache#30-oX: "sclk_dpll"
    // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[2]: (kmem_cache#30-oX)[2]: kmem_cache#30-oX: "sclk_mpll"
    // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[3]: (kmem_cache#30-oX)[3]: kmem_cache#30-oX: "sclk_spll"
    // (kmem_cache#29-oX (mout_mspll_kfc))->parent: NULL
    // (kmem_cache#29-oX (mout_mspll_kfc))->rate: 0
    //
    // (kmem_cache#29-oX (mout_mspll_kfc))->parents: kmem_cache#30-oX
    // (kmem_cache#29-oX (mout_mspll_kfc))->parents[0...3]: (kmem_cache#30-oX)[0...3]: NULL
    //
    // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next: NULL
    // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
    //
    // (&clk_orphan_list)->first: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
    //
    // (&(kmem_cache#30-oX (mout_mspll_kfc))->hw)->clk: kmem_cache#29-oX (mout_mspll_kfc)
    //
    // (sclk_dpll) 에서 한일:
    // struct clk_mux 만큼 메모리를 kmem_cache#30-oX (sclk_dpll) 할당 받고 struct clk_mux 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#30-oX)->reg: 0xf0050218
    // (kmem_cache#30-oX)->shift: 24
    // (kmem_cache#30-oX)->mask: 0x3
    // (kmem_cache#30-oX)->flags: 0
    // (kmem_cache#30-oX)->lock: &lock
    // (kmem_cache#30-oX)->table: NULL
    // (kmem_cache#30-oX)->hw.init: &init
    //
    // struct clk 만큼 메모리를 kmem_cache#29-oX (sclk_dpll) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
    //
    // (kmem_cache#29-oX (sclk_dpll))->name: kmem_cache#30-oX ("sclk_dpll")
    // (kmem_cache#29-oX (sclk_dpll))->ops: &clk_mux_ops
    // (kmem_cache#29-oX (sclk_dpll))->hw: &(kmem_cache#30-oX (sclk_dpll))->hw
    // (kmem_cache#29-oX (sclk_dpll))->flags: 0xa0
    // (kmem_cache#29-oX (sclk_dpll))->num_parents 2
    // (kmem_cache#29-oX (sclk_dpll))->parent_names: kmem_cache#30-oX
    // (kmem_cache#29-oX (sclk_dpll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
    // (kmem_cache#29-oX (sclk_dpll))->parent_names[1]: (kmem_cache#30-oX)[1]: kmem_cache#30-oX: "fout_dpll"
    // (kmem_cache#29-oX (sclk_dpll))->parent: NULL
    // (kmem_cache#29-oX (sclk_dpll))->rate: 600000000
    //
    // (kmem_cache#29-oX (sclk_dpll))->parents: kmem_cache#30-oX
    // (kmem_cache#29-oX (sclk_dpll))->parents[0]: (kmem_cache#30-oX)[0]: kmem_cache#29-oX (fin_pll)
    // (kmem_cache#29-oX (sclk_dpll))->parents[1]: (kmem_cache#30-oX)[1]: kmem_cache#29-oX (fout_dpll)
    //
    // parents 인 "fin_pll", "fout_dpll" 값들 중에
    // register CLK_SRC_TOP6 의 값을 읽어서 mux 할 parent clock 을 선택함
    // return된 값이 선택된 parent clock의 index 값임
    // parent clock 중에 선택된 parent clock의 이름으로 등록된 clk struct를 반환함
    //
    // (&(kmem_cache#29-oX (sclk_dpll))->child_node)->next: NULL
    // (&(kmem_cache#29-oX (sclk_dpll))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_dpll))->child_node)
    //
    // (&(kmem_cache#29-oX (fout_dpll))->children)->first: &(kmem_cache#29-oX (sclk_dpll))->child_node
    //
    // (&(kmem_cache#30-oX (sclk_dpll))->hw)->clk: kmem_cache#29-oX (sclk_dpll)
    //
    // orphan 으로 등록된 mout_mspll_kfc의 값을 갱신
    // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next: NULL
    // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
    //
    // (&(kmem_cache#29-oX (sclk_dpll))->children)->first: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
    //
    // (kmem_cache#29-oX (mout_mspll_kfc))->parent: kmem_cache#29-oX (sclk_dpll)
    //
    // parent가 있는지 확인후 parent의 clock rate 값으로 clock rate 값을 세팅
    // (kmem_cache#29-oX (mout_mspll_kfc))->rate: 600000000

    // ARRAY_SIZE(exynos5420_div_clks): 53
    samsung_clk_register_div(exynos5420_div_clks,
            ARRAY_SIZE(exynos5420_div_clks));
    samsung_clk_register_gate(exynos5420_gate_clks,
            ARRAY_SIZE(exynos5420_gate_clks));
}

samsung_clk_register_mux()

  • 매개변수
    • // idx: 44, list->name: exynos5420_mux_clks[44].name: "sclk_dpll",
    • // list->parent_names: exynos5420_mux_clks[44].parent_names: dpll_p,
    • // list->num_parents: exynos5420_mux_clks[44].num_parents: 2,
    • // list->flags: exynos5420_mux_clks[44].flags: 0x80, reg_base: 0xf0040000,
    • // list->offset: exynos5420_mux_clks[44].offset: 0x10218,
    • // list->shift: exynos5420_mux_clks[44].shift: 24,
    • // list->width: exynos5420_mux_clks[44].width: 1,
    • // list->mux_flags: exynos5420_mux_clks[44].mux_flags: 0
    • // clk_register_mux(NULL, "sclk_dpll", dpll_p, 2, 0x80, 0xf0050218, 24, 1, 0, &lock): kmem_cache#29-oX (sclk_dpll)
    • clk = clk_register_mux(NULL, list->name, list->parent_names,list->num_parents, list->flags, reg_base + list->offset,list->shift, list->width, list->mux_flags, &lock);
  • log

  • 1st log
   6d6e4ca..367c531  master     -> origin/master
Updating 6d6e4ca..367c531
Fast-forward
drivers/clk/clk-divider.c            |  99 ++++++++++++++++++++
drivers/clk/clk-mux.c                |  99 +++++++++++++++++++-
drivers/clk/clk.c                    | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
drivers/clk/samsung/clk-exynos5420.c | 128 ++++++++++++++++++++++++++
drivers/clk/samsung/clk.c            |  84 +++++++++++++++--
drivers/clk/samsung/clk.h            |  45 ++++++++++
include/linux/bitops.h               |   1 +
include/linux/clk-private.h          |   1 +
include/linux/clk-provider.h         |  10 +++
include/linux/clk.h                  |   2 +
include/linux/gfp.h                  |   1 +
include/linux/list.h                 |  10 ++-
include/linux/mm_types.h             |   2 +-
include/linux/slab.h                 |   2 +
14 files changed, 775 insertions(+), 16 deletions(-)

2015년 2월 21일 토요일

[Linux Kernel] 91주차(2015.2.21)

ARM10C 91주차 후기

일시 : 2015.02.21 (91주차)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 5명

91주차 진도

  • start_kernel()->mm_init()
  • 조성진님을 위해서 mm_init()을 buddy할당까지 복습했습니다.
  • Iamroot 운영관련해서 백창우님과 다른 분들을 모시고 이야기 나누었습니다.

2015년 2월 7일 토요일

[Linux Kernel] 90주차(2015.2.07)

ARM10C 90주차 후기

일시 : 2015.02.07 (90주차)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 3명

90주차 진도

  • time_init()을 해야만 하나,
  • 1년만에 돌아오신 조성진님이 복귀하셔서.
  • start_kernel()을 처음부터 그동안 진행했던 것을 복습했습니다.