[커널 18차] 63주차
2022.08.06 22:21
clk 진행
git : https://github.com/iamroot18/5.10/commit/eaf80cdc1d36b00779646f5e193e71ef08ed6d23
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index eebbc8d7123e..2132fda934f6 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -51,6 +51,10 @@ unsigned long profile_pc(struct pt_regs *regs)
}
EXPORT_SYMBOL(profile_pc);
+/*
+ * IAMROOT, 2022.08.06:
+ * - 진행시작.
+ */
void __init time_init(void)
{
u32 arch_timer_rate;
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
index 2ef819606c41..13b0121de1b5 100644
--- a/drivers/clk/clk-conf.c
+++ b/drivers/clk/clk-conf.c
@@ -11,19 +11,58 @@
#include <linux/of.h>
#include <linux/printk.h>
+/*
+ * IAMROOT, 2022.08.06:
+ * - default parent를 지정한다.
+ * - ex)
+ *
+ * &uart1 {
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&pinctrl_uart1>;
+ * assigned-clocks = <&clk IMX8MM_CLK_UART1>;
+ * assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ * uart-has-rtscts;
+ * status = "okay";
+ * ..
+ * }
+ */
static int __set_clk_parents(struct device_node *node, bool clk_supplier)
{
struct of_phandle_args clkspec;
int index, rc, num_parents;
struct clk *clk, *pclk;
+/*
+ * IAMROOT, 2022.08.06:
+ * - assigned-clock-parents
+ * clk parents
+ * - #clock-cells
+ * 자신을 지정할때 사용해야되는 인자개수.
+ * - ex)
+ * #clock-cells = <1>; <-- 인자개수 1개를 의미
+ * assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>, <&clk IMX8MM_ARM_PLL_OUT>
+ * ^인자 1개 있음. ^인자 1개 있음
+ * num_parents의 개수는 2개.
+ */
num_parents = of_count_phandle_with_args(node, "assigned-clock-parents",
"#clock-cells");
if (num_parents == -EINVAL)
pr_err("clk: invalid value of clock-parents property at %pOF\n",
node);
+/*
+ * IAMROOT, 2022.08.06:
+ * - 위에서 구해온 clk parents을 iteration.
+ */
for (index = 0; index < num_parents; index++) {
+/*
+ * IAMROOT, 2022.08.06:
+ * - iterator를 돌며 index에 해당하는
+ * assigned-clock-parents, assigned-clocks를 가져오고 각각 provider로 등록되있는지
+ * 확인한다.
+ * 둘다 등록되있다면 assigned-clock-parent를 provider로, assigned-clocks를 consumer로
+ * 하여 parent등록을한다.
+ */
rc = of_parse_phandle_with_args(node, "assigned-clock-parents",
"#clock-cells", index, &clkspec);
if (rc < 0) {
@@ -128,6 +167,16 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
* If @clk_supplier is false the function exits returning 0 as soon as it
* determines the @node is also a supplier of any of the clocks.
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - papago
+ * 이 함수는 'assigned-{clocks/clock-parents/clock-rates}' 속성을 구문 분석하고
+ * 지정된 클록 부모 및 속도를 설정합니다. @node가 'assigned-clocks' 또는
+ * 'assigned-clock-parents' 속성에 나열된 clok의 clock 공급자일 수도 있는 경우
+ * @clk_supplier 인수는 true로 설정되어야 합니다. @clk_supplier가 false이면 함수는
+ * @node가 시계 공급자이기도 하다고 결정하자마자 0을 반환하며 종료됩니다.
+ */
int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
{
int rc;
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 45501637705c..41a41945763b 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -137,6 +137,11 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw)
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate);
#ifdef CONFIG_OF
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - 아래와 같은 속성값들을 읽어 of_clk_providers에 등록해준다.
+ */
static struct clk_hw *_of_fixed_clk_setup(struct device_node *node)
{
struct clk_hw *hw;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 65508eb89ec9..985ff1101bd7 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -442,6 +442,10 @@ static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
entry->core = parent;
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - parent가 없으면 NULL.
+ */
static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
u8 index)
{
@@ -1664,6 +1668,15 @@ unsigned long clk_get_rate(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_get_rate);
+/*
+ * IAMROOT, 2022.08.06:
+ * - @core의 parent중에서 @parent가 있는지 확인한다.
+ * 1. core->parent[i].core와 parent가 같거나.
+ * core->parent[i].core가 없는 것들 중에서.
+ * 1. hw가 같거나.
+ * 2. clk_core_get(core, i)와 core가 같거나
+ * 3. core->parents의 이름과 parent의 이름이 같은경우.
+ */
static int clk_fetch_parent_index(struct clk_core *core,
struct clk_core *parent)
{
@@ -2446,6 +2459,10 @@ static struct clk_core *__clk_init_parent(struct clk_core *core)
{
u8 index = 0;
+/*
+ * IAMROOT, 2022.08.06:
+ * - num_parents가 0이면 안구해온다.
+ */
if (core->num_parents > 1 && core->ops->get_parent)
index = core->ops->get_parent(core->hw);
@@ -2502,6 +2519,11 @@ bool clk_has_parent(struct clk *clk, struct clk *parent)
}
EXPORT_SYMBOL_GPL(clk_has_parent);
+/*
+ * IAMROOT, 2022.08.06:
+ * - @core의 parent를 @parent로 지정한다.
+ * 즉 mux clk의 입력소스로 @parent를 선택한다.
+ */
static int clk_core_set_parent_nolock(struct clk_core *core,
struct clk_core *parent)
{
@@ -2528,6 +2550,10 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
if (clk_core_rate_is_protected(core))
return -EBUSY;
+/*
+ * IAMROOT, 2022.08.06:
+ * - core에 parent가 fetch되있는지 확인한다.
+ */
/* try finding the new parent index */
if (parent) {
p_index = clk_fetch_parent_index(core, parent);
@@ -2590,6 +2616,21 @@ EXPORT_SYMBOL_GPL(clk_hw_set_parent);
*
* Returns 0 on success, -EERROR otherwise.
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - papgo
+ * 부모를 새 입력 소스로 사용하려면 다시 부모로 지정합니다. clk가 준비 상태에
+ * 있으면 이 호출 기간 동안 clk가 활성화됩니다. 특정 clk에 허용되지 않는 경우
+ * (예: 소비자가 이를 처리할 수 없고 하드웨어에서 부모 재지정이 결함이 있는 경우 등)
+ * CLK_SET_PARENT_GATE 플래그를 사용하여 clk가 준비되지 않은 경우에만 부모
+ * 재지정을 허용합니다.
+ *
+ * clk의 부모를 성공적으로 변경한 후 clk_set_parent는 clk 토폴로지, sysfs
+ * 토폴로지를 업데이트하고 __clk_recalc_rates를 통해 속도 재계산을 전파합니다.
+ *
+ * 성공하면 0을 반환하고 그렇지 않으면 -EERROR를 반환합니다
+ */
int clk_set_parent(struct clk *clk, struct clk *parent)
{
int ret;
@@ -2687,6 +2728,10 @@ int clk_set_phase(struct clk *clk, int degrees)
}
EXPORT_SYMBOL_GPL(clk_set_phase);
+/*
+ * IAMROOT, 2022.08.06:
+ * - get_phase ops가 있다면 함수를 수행해 위상을 알아온다.
+ */
static int clk_core_get_phase(struct clk_core *core)
{
int ret;
@@ -2725,6 +2770,10 @@ int clk_get_phase(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_get_phase);
+/*
+ * IAMROOT, 2022.08.06:
+ * - 50%를 default로 설정한다.
+ */
static void clk_core_reset_duty_cycle_nolock(struct clk_core *core)
{
/* Assume a default value of 50% */
@@ -2734,11 +2783,21 @@ static void clk_core_reset_duty_cycle_nolock(struct clk_core *core)
static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core);
+/*
+ * IAMROOT, 2022.08.06:
+ * - parent가 있고 parent것을 사용하라고하면 parent로 타고 올라가고, 아니면
+ * 자기것을 사용한다.
+ * - 아무대도 없을 경우 default로 50%를 사용한다.
+ */
static int clk_core_update_duty_cycle_nolock(struct clk_core *core)
{
struct clk_duty *duty = &core->duty;
int ret = 0;
+/*
+ * IAMROOT, 2022.08.06:
+ * - ops가 없으면 parent에서
+ */
if (!core->ops->get_duty_cycle)
return clk_core_update_duty_cycle_parent_nolock(core);
@@ -2759,6 +2818,12 @@ static int clk_core_update_duty_cycle_nolock(struct clk_core *core)
return ret;
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - parent가 존재하고 flag가 parent꺼를 사용하라고 되있으면 parent사용한다.
+ * 아니라면 default로 50%를 사용한다.
+ * - 재귀함수로 되있다.
+ */
static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core)
{
int ret = 0;
@@ -3368,6 +3433,11 @@ static inline void clk_debug_unregister(struct clk_core *core)
}
#endif
+/*
+ * IAMROOT, 2022.08.06:
+ * - clk_orphan_list를 순회하며 orphans이 였던 것들중에 parent가 생긴것이
+ * 있는 확인하여 작업을 해준다.
+ */
static void clk_core_reparent_orphans_nolock(void)
{
struct clk_core *orphan;
@@ -3479,6 +3549,13 @@ static int __clk_core_init(struct clk_core *core)
goto out;
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - num_parents를 사용하여 parent가 있는지 판단해본다.
+ * clk_hw_register_fixed_rate_with_accuracy()를 통해서 이 루틴 까지 왔을때
+ * clk_hw_register_fixed_rate_with_accuracy()에서 parent 관련 인자들이
+ * NULL값이였으면 num_parents가 0이 되어 parent를 안구한다.
+ */
parent = core->parent = __clk_init_parent(core);
/*
@@ -3491,6 +3568,11 @@ static int __clk_core_init(struct clk_core *core)
* clocks and re-parent any that are children of the clock currently
* being clk_init'd.
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - parent가 없는데, num_parents가 0이라는것은 root라는 것이고 num_parents가
+ * 존재하면 일단 orphan상태로 한다.
+ */
if (parent) {
hlist_add_head(&core->child_node, &parent->children);
core->orphan = parent->orphan;
@@ -3509,6 +3591,10 @@ static int __clk_core_init(struct clk_core *core)
* parent (or is orphaned) then accuracy is set to zero (perfect
* clock).
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - ex) clk_fixed_rate_recalc_accuracy,
+ */
if (core->ops->recalc_accuracy)
core->accuracy = core->ops->recalc_accuracy(core->hw,
clk_core_get_accuracy_no_lock(parent));
@@ -3595,6 +3681,10 @@ static int __clk_core_init(struct clk_core *core)
* @core: clk to add consumer to
* @clk: consumer to link to a clk
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - core(provider)에 clk(consumer) 등록.
+ */
static void clk_core_link_consumer(struct clk_core *core, struct clk *clk)
{
clk_prepare_lock();
@@ -3620,6 +3710,10 @@ static void clk_core_unlink_consumer(struct clk *clk)
*
* Returns: clk consumer left unlinked from the consumer list
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - struct clk 할당 및 초기화.
+ */
static struct clk *alloc_clk(struct clk_core *core, const char *dev_id,
const char *con_id)
{
@@ -3662,12 +3756,21 @@ static void free_clk(struct clk *clk)
* consumers. It connects a consumer to the clk_core and clk_hw structures
* used by the framework and clk provider respectively.
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - @hw가 error 라면 error return.
+ * - clk core에 clk을 할당하여 추가한다.
+ */
struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
const char *dev_id, const char *con_id)
{
struct clk *clk;
struct clk_core *core;
+/*
+ * IAMROOT, 2022.08.06:
+ * - @hw가 error라면 error 변환 return.
+ */
/* This is to allow this function to be chained to others */
if (IS_ERR_OR_NULL(hw))
return ERR_CAST(hw);
@@ -3683,7 +3786,16 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
return ERR_PTR(-ENOENT);
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - clk core ref up
+ */
kref_get(&core->ref);
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - core(provider)에 clk(consumer)를 등록한다.
+ */
clk_core_link_consumer(core, clk);
return clk;
@@ -3801,6 +3913,10 @@ static void clk_core_free_parent_map(struct clk_core *core)
kfree(core->parents);
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - @hw로 받은 data로 core와 clk를 생성한다.
+ */
static struct clk *
__clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
{
@@ -3862,12 +3978,23 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
goto fail_create_clk;
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - 자기자신으로 등록한다.
+ * +-- hw --+
+ * v v
+ * core <--- clk
+ */
clk_core_link_consumer(hw->core, hw->clk);
ret = __clk_core_init(core);
if (!ret)
return hw->clk;
+/*
+ * IAMROOT, 2022.08.06:
+ * - 실패시 unlink후 free.
+ */
clk_prepare_lock();
clk_core_unlink_consumer(hw->clk);
clk_prepare_unlock();
@@ -4449,6 +4576,11 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk,
EXPORT_SYMBOL_GPL(devm_clk_notifier_register);
#ifdef CONFIG_OF
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - orphans에 대해서 reparent를 수행한다.
+ */
static void clk_core_reparent_orphans(void)
{
clk_prepare_lock();
@@ -4475,6 +4607,12 @@ struct of_clk_provider {
void *data;
};
+/*
+ * IAMROOT, 2022.08.06:
+ * - CLK_OF_DECLARE(..) 을 통해서 정의된 of_table들은
+ * __clk_of_table section에 struct of_device_id 형태로 compile time에 넣어진다.
+ * __clk_of_table은 해당 시작주소를 가리킨다.
+ */
extern struct of_device_id __clk_of_table;
static const struct of_device_id __clk_of_table_sentinel
__used __section("__clk_of_table_end");
@@ -4574,6 +4712,10 @@ EXPORT_SYMBOL_GPL(of_clk_add_provider);
* @get: callback for decoding clk_hw
* @data: context pointer for @get callback.
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - of_clk_providers에 clk provider로 등록한다.
+ */
int of_clk_add_hw_provider(struct device_node *np,
struct clk_hw *(*get)(struct of_phandle_args *clkspec,
void *data),
@@ -4763,6 +4905,26 @@ EXPORT_SYMBOL(devm_of_clk_del_provider);
* if @name is NULL or -EINVAL if @name is non-NULL and it can't be found in
* the "clock-names" property of @np.
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - ex) imx8-ss-audio.dtsi 참고
+ * dsp라는 np를 예제로 가져온다;
+ * dsp: dsp@596e8000 {
+ * compatible = "fsl,imx8qxp-dsp";
+ * reg = <0x596e8000 0x88000>;
+ * clocks = <&dsp_lpcg IMX_LPCG_CLK_5>,
+ * <&dsp_ram_lpcg IMX_LPCG_CLK_4>,
+ * <&dsp_lpcg IMX_LPCG_CLK_7>;
+ * clock-names = "ipg", "ocram", "core";
+ * };
+ * clocks : 0번 index dsp_lpcg으로 사용하고 IMX_LPCG_CLK_5라는 속성을 사용한단것.
+ * 1번 index dsp_ram_lpcg, 2번 index는 dsp_lpcg가 된다.
+ * clock-names : cloks의 index에 대응하는 각각의 이름
+ *
+ * - @name이나 @index로 clkspec을 찾는다. 만약 해당 np에서 못찾았고, parent np에
+ * clock-ranges;가 있다면 부모에서 @name, @index로 찾아본다.(for arm lagacy)
+ */
static int of_parse_clkspec(const struct device_node *np, int index,
const char *name, struct of_phandle_args *out_args)
{
@@ -4776,12 +4938,30 @@ static int of_parse_clkspec(const struct device_node *np, int index,
* will be an error code and of_parse_phandle_with_args() will
* return -EINVAL.
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - name이 주어지면 name으로 index를 구해온다.
+ * cloks = <&dsp_lpcg ..>, <&dsp_ram_lpcg ..>, <&dsp_lpcg ..>
+ * clock-names = "ipg", "ocram", "core";
+ * 라고 했을대 "ocram"로 인자가오면 <&dsp_ram_lpcg ..>을 찾아주는 개념.
+ * - <&dsp_ram_lpcg IMX_LPCG_CLK_4>가 검색했다고 됬을대 out_args에 cnt는 1,
+ * arg[] = {IMX_LPCG_CLK_4} 가 얻어진다.
+ */
if (name)
index = of_property_match_string(np, "clock-names", name);
ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
index, out_args);
+/*
+ * IAMROOT, 2022.08.06:
+ * - 찾아지면 종료.
+ */
if (!ret)
break;
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - 못찾았는데 name이 주어지고, name에 해당하는 index까지 찾아진 경우 종료(error)
+ */
if (name && index >= 0)
break;
@@ -4790,6 +4970,11 @@ static int of_parse_clkspec(const struct device_node *np, int index,
* has a "clock-ranges" property, then we can try one of its
* clocks.
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - 부모가 존재하고 부모가 clock-ranges를 찾는다. 없으면 break.(error)
+ * 부모에 clock-ranges;가 있으면 부모까지 확장해서 name이나 index로 해보라는의미.
+ */
np = np->parent;
if (np && !of_get_property(np, "clock-ranges", NULL))
break;
@@ -4805,6 +4990,10 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
{
struct clk *clk;
+/*
+ * IAMROOT, 2022.08.06:
+ * - ex) of_clk_hw_simple_get
+ */
if (provider->get_hw)
return provider->get_hw(clkspec, provider->data);
@@ -4814,6 +5003,11 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
return __clk_get_hw(clk);
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - of_clk_providers에서 @clkspec이 존재하는 찾아본다
+ * - 못찾으면 -EPROBE_DEFER
+ */
static struct clk_hw *
of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
{
@@ -4844,6 +5038,13 @@ of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
* providers, an input is a clock specifier data structure as returned
* from the of_parse_phandle_with_args() function call.
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - papago
+ * 이 함수는 등록된 클럭 제공자 목록에서 구조체 clk를 조회하며, 입력은
+ * of_parse_phandle_with_args() 함수 호출에서 반환된 클럭 지정자 데이터 구조입니다.
+ */
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
{
struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
@@ -4852,6 +5053,11 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
}
EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
+/*
+ * IAMROOT, 2022.08.06:
+ * - @np에서 @index, @name에 해당하는 clock을 찾은후 of_clk_providers에서 일치하는게
+ * 있는지 확인한다.
+ */
struct clk_hw *of_clk_get_hw(struct device_node *np, int index,
const char *con_id)
{
@@ -4859,20 +5065,40 @@ struct clk_hw *of_clk_get_hw(struct device_node *np, int index,
struct clk_hw *hw;
struct of_phandle_args clkspec;
+/*
+ * IAMROOT, 2022.08.06:
+ * - @index or @name에 해당하는 clock을 phandle argu를 가져온다.
+ */
ret = of_parse_clkspec(np, index, con_id, &clkspec);
if (ret)
return ERR_PTR(ret);
+/*
+ * IAMROOT, 2022.08.06:
+ * - of_clk_provider에서 일치하는 걸 찾는다. 못찾았다면 -EPROBE_DEFER
+ */
hw = of_clk_get_hw_from_clkspec(&clkspec);
of_node_put(clkspec.np);
return hw;
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - @con_id or @index에 해당하는 clk을 찾고 struct clk를 초기화하여
+ * clk core에 consumer로 등록한다.
+ */
static struct clk *__of_clk_get(struct device_node *np,
int index, const char *dev_id,
const char *con_id)
{
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - @index or @con_idx에 해당하는 phandle에 대응하는 clk_hw를 찾고 of_clk_provider
+ * 에서 검색을 한다.
+ * - of_clk_provider에 없으면 -EPROBE_DEFER.
+ */
struct clk_hw *hw = of_clk_get_hw(np, index, con_id);
return clk_hw_create_clk(NULL, hw, dev_id, con_id);
@@ -5012,11 +5238,27 @@ struct clock_provider {
* checks that the provider for this parent clock was initialized, in
* this case the parent clock will be ready.
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * -papgo
+ * 이 함수는 부모 clock를 찾습니다. 있는 경우 이 상위 clock의 공급자가
+ * 초기화되었는지 확인합니다. 이 경우 상위 clock가 준비됩니다.
+ *
+ * - @np의 index 0부터 parent clock을 순회하며 clk을 가져온다.
+ *
+ * - 만약 -EPROBE_DEFER가 났다면 상위 부모를 못찾았다(부모가 아직 준비가 안됬다)
+ * 는 의미가 되고 return 0.
+ */
static int parent_ready(struct device_node *np)
{
int i = 0;
while (true) {
+/*
+ * IAMROOT, 2022.08.06:
+ * -
+ */
struct clk *clk = of_clk_get(np, i);
/* this parent is ready we can check the next one */
@@ -5038,6 +5280,14 @@ static int parent_ready(struct device_node *np)
* parent, no need to wait for them, then we can
* consider their absence as being ready
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - papago
+ * 여기서 우리는 장치 트리가 올바르게 작성되었다고 가정합니다. 따라서 오류는
+ * 더 이상 부모가 없음을 의미합니다. 아직 종료하지 않았으므로 이전 부모가
+ * 준비되었습니다. clock 부모가 없으면 기다릴 필요가 없다면 그들의 부재는 준비된
+ * 것으로 간주할 수 있습니다.*
+ */
return 1;
}
}
@@ -5094,6 +5344,16 @@ void __init of_clk_init(const struct of_device_id *matches)
bool force = false;
LIST_HEAD(clk_provider_list);
+/*
+ * IAMROOT, 2022.08.06:
+ * - matches == NULL일 경우 kernel image(CLK_OF_DECLARE(..))에 있는 구조체
+ * 시작주소를 가져온다.
+ * ex) CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
+ * device tree에서 compatible = "fixed-clock"인 것들을 of_device_id로 가져온다.
+ *
+ * - kernel image에서 1, 2, 3, 4, 5 라는 of_device_id가 있고, dts에서 3, 4, 6라는
+ * device_node가 있다고 했을때, 매치되는 3, 4를 찾는 과정.
+ */
if (!matches)
matches = &__clk_of_table;
@@ -5101,11 +5361,19 @@ void __init of_clk_init(const struct of_device_id *matches)
for_each_matching_node_and_match(np, matches, &match) {
struct clock_provider *parent;
+/*
+ * IAMROOT, 2022.08.06:
+ * - status ok가 아닌것들을 skip한다.
+ */
if (!of_device_is_available(np))
continue;
parent = kzalloc(sizeof(*parent), GFP_KERNEL);
if (!parent) {
+/*
+ * IAMROOT, 2022.08.06:
+ * - 할당 실패했을 경우 여지껏 만든것을 모두 해제하고 return.
+ */
list_for_each_entry_safe(clk_provider, next,
&clk_provider_list, node) {
list_del(&clk_provider->node);
@@ -5121,6 +5389,10 @@ void __init of_clk_init(const struct of_device_id *matches)
list_add_tail(&parent->node, &clk_provider_list);
}
+/*
+ * IAMROOT, 2022.08.06:
+ * - parent_ready가 되는 것들은 먼저 처리하고, 그 다음 루틴에서 나머지를 처리한다.
+ */
while (!list_empty(&clk_provider_list)) {
is_init_done = false;
list_for_each_entry_safe(clk_provider, next,
@@ -5131,6 +5403,11 @@ void __init of_clk_init(const struct of_device_id *matches)
of_node_set_flag(clk_provider->np,
OF_POPULATED);
+/*
+ * IAMROOT, 2022.08.06:
+ * - of_fixed_clk_setup 참고. of_clk_providers에 등록된다.
+ * - of_clk_add_hw_provider이나 of_clk_add_provider를 통해서 등록될것이다.
+ */
clk_provider->clk_init_cb(clk_provider->np);
of_clk_set_defaults(clk_provider->np, true);
@@ -5147,6 +5424,10 @@ void __init of_clk_init(const struct of_device_id *matches)
* initialize all the remaining ones unconditionally
* in case the clock parent was not mandatory
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - 한번에 안되면 한번더 돈다. 한번더 돌때는 parent_ready를 안따른다.
+ */
if (!is_init_done)
force = true;
}
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 4b8bd528c3bc..b2965b772b49 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -243,6 +243,10 @@ struct property *of_find_property(const struct device_node *np,
}
EXPORT_SYMBOL(of_find_property);
+/*
+ * IAMROOT, 2022.08.06:
+ * - tree 순회.
+ */
struct device_node *__of_find_all_nodes(struct device_node *prev)
{
struct device_node *np;
@@ -502,6 +506,11 @@ EXPORT_SYMBOL(of_get_cpu_state_node);
* 10. type
* 11. name
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - compatible을 주석에 내용에 따라 찾는다.
+ */
static int __of_device_is_compatible(const struct device_node *device,
const char *compat, const char *type, const char *name)
{
@@ -607,6 +616,11 @@ EXPORT_SYMBOL(of_machine_is_compatible);
* Return: True if the status property is absent or set to "okay" or "ok",
* false otherwise
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - dts에서 status=ok or okay인 것을 찾는다. dts에서의 on/off 기능.
+ */
static bool __of_device_is_available(const struct device_node *device)
{
const char *status;
@@ -635,6 +649,10 @@ static bool __of_device_is_available(const struct device_node *device)
* Return: True if the status property is absent or set to "okay" or "ok",
* false otherwise
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - dts에서 status=ok or okay인 것을 찾는다. dts에서의 on/off 기능.
+ */
bool of_device_is_available(const struct device_node *device)
{
unsigned long flags;
@@ -1101,6 +1119,10 @@ struct device_node *of_find_node_with_property(struct device_node *from,
}
EXPORT_SYMBOL(of_find_node_with_property);
+/*
+ * IAMROOT, 2022.08.06:
+ * - "compatible" 에 best한 of_device_id를 찾는다.
+ */
static
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
const struct device_node *node)
@@ -1156,6 +1178,11 @@ EXPORT_SYMBOL(of_match_node);
* Return: A node pointer with refcount incremented, use
* of_node_put() on it when done.
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - @from부터 모든 of_device_node를 순회한다.
+ */
struct device_node *of_find_matching_node_and_match(struct device_node *from,
const struct of_device_id *matches,
const struct of_device_id **match)
@@ -1500,6 +1527,20 @@ EXPORT_SYMBOL(of_parse_phandle);
* To get a device_node of the ``node2`` node you may call this:
* of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - 주석예제를 참고하면 phandle1은 인자2개, phandle2는 인자1개가 필요한 상황이고
+ * node3 {
+ * list = <&phandle1 1 2 &phandle2 3>;
+ * };
+ * 에서 phandle1에 인자2개를 1,2, phandle2에 인자1개를 3으로 설정해주는게 보인다.
+ *
+ * @index가 0이면 phandle1, @index가1이면 phandle2가 선택될것이고,
+ * phandle1은 out_args에서 args_count = 2, args[] = {1, 2},
+ * phandle2은 out_args에서 args_count = 1, args[] = {3}
+ * 로 될것이다.
+ */
int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
const char *cells_name, int index,
struct of_phandle_args *out_args)
@@ -1758,6 +1799,11 @@ EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
* determined by the #gpio-cells property in the node pointed to by the
* phandle.
*/
+
+/*
+ * IAMROOT, 2022.08.06:
+ * - papgo
+ */
int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
const char *cells_name)
{
diff --git a/iamroot18/cma/hello.c b/iamroot18/cma/hello.c
index 136ed776ffe9..15b1cab06963 100644
--- a/iamroot18/cma/hello.c
+++ b/iamroot18/cma/hello.c
@@ -34,35 +34,16 @@ static int iamroot_probe(struct platform_device *pdev)
{
int err;
- printk(KERN_INFO "%s %d %px\n", __func__, __LINE__, pdev->dev.dma_mem);
-
-#if 0
- struct device_node *mem_node;
- struct reserved_mem *rmem;
- mem_node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
- if (!mem_node) {
- dev_err(&pdev->dev, "No memory-region found for index %d\n", 0);
- return -ENODEV;
- }
-
- rmem = of_reserved_mem_lookup(mem_node);
- if (!rmem) {
- dev_err(&pdev->dev, "of_reserved_mem_lookup() returned NULL\n");
- return -ENODEV;
- }
+ err = of_reserved_mem_device_init_by_idx(&pdev->dev, pdev->dev.of_node, 0);
- pdev->dev.dma_mem = rmem->priv;
-
- printk(KERN_INFO "%s %d %px %x %x %s\n", __func__, __LINE__, pdev->dev.dma_mem,
- rmem->base, (uint32_t)rmem->size, rmem->name);
-#endif
-
- err = of_reserved_mem_device_init_by_name(&pdev->dev, pdev->dev.of_node, "iamroot_buffer2");
if (err < 0) {
dev_err(&pdev->dev, "failed to get nominal EMC table: %d\n", err);
return err;
}
+
+ printk(KERN_INFO "%s %d %px\n", __func__, __LINE__, pdev->dev.dma_mem);
g_dma = dma_alloc_coherent(&pdev->dev, ALLOC_SIZE, &g_dma_addr, GFP_KERNEL);
+ printk(KERN_INFO "%s %d %px %llx\n", __func__, __LINE__, g_dma, g_dma_addr);
return 0;
}
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index f59c875271a0..8cd3e47dd0b9 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -1241,6 +1241,12 @@ struct clk_hw_onecell_data {
struct clk_hw *hws[];
};
+/*
+ * IAMROOT, 2022.08.06:
+ * - static const struct of_device_id __of_table##name
+ * ex) CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
+ * -> __of_table_fixed_clk의 구조체로 __clk_of_table section에 정의된다
+ */
#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
/*
diff --git a/include/linux/kref.h b/include/linux/kref.h
index d32e21a2538c..bac26a36212a 100644
--- a/include/linux/kref.h
+++ b/include/linux/kref.h
@@ -40,6 +40,10 @@ static inline unsigned int kref_read(const struct kref *kref)
* kref_get - increment refcount for object.
* @kref: object.
*/
+/*
+ * IAMROOT, 2022.08.06:
+ * - kref up
+ */
static inline void kref_get(struct kref *kref)
{
refcount_inc(&kref->refcount);
diff --git a/include/linux/of.h b/include/linux/of.h
index 19feaddf3074..248038057536 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -115,6 +115,10 @@ struct device_node {
#if defined(CONFIG_OF_KOBJ)
struct kobject kobj;
#endif
+/*
+ * IAMROOT, 2022.08.06:
+ * - OF_POPULATED 와 같은 bit flag가 set된다.
+ */
unsigned long _flags;
void *data;
#if defined(CONFIG_SPARC)
@@ -1350,6 +1354,10 @@ static inline int of_property_read_s32(const struct device_node *np,
#define for_each_matching_node(dn, matches) \
for (dn = of_find_matching_node(NULL, matches); dn; \
dn = of_find_matching_node(dn, matches))
+/*
+ * IAMROOT, 2022.08.06:
+ * - matches되는 모든 device_node를 순회한다.
+ */
#define for_each_matching_node_and_match(dn, matches, match) \
for (dn = of_find_matching_node_and_match(NULL, matches, match); \
dn; dn = of_find_matching_node_and_match(dn, matches, match))
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index ef1bf2d5a9f8..7ff1be24435f 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -249,7 +249,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
/*
* IAMROOT, 2022.07.23:
- * 4) atomice 요청 시 dma coherent pool에서 할당한다.
+ * 4) atomic 요청 시 dma coherent pool에서 할당한다.
*/
if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
!gfpflags_allow_blocking(gfp) &&
diff --git a/kernel/module.c b/kernel/module.c
index 5c26a76e800b..3ef11c588f70 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1066,6 +1066,10 @@ void __module_get(struct module *module)
}
EXPORT_SYMBOL(__module_get);
+/*
+ * IAMROOT, 2022.08.06:
+ * - module ref up
+ */
bool try_module_get(struct module *module)
{
bool ret = true;
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
공지 | [공지] 스터디 정리 노트 공간입니다. | woos | 2016.05.14 | 626 |
148 | [커널 17차] 103주차 | ㅇㅇㅇ | 2022.08.28 | 35 |
147 | [커널 18차] 66주차 | kkr | 2022.08.27 | 76 |
146 | [커널 17차] 101~102주차 | ㅇㅇㅇ | 2022.08.21 | 47 |
145 | [커널 18차] 65주차 | kkr | 2022.08.20 | 28 |
144 | [커널 18차] 64주차 | kkr | 2022.08.13 | 75 |
143 | [커널 17차] 100주차 [1] | ㅇㅇㅇ | 2022.08.06 | 100 |
» | [커널 18차] 63주차 | kkr | 2022.08.06 | 102 |
141 | [커널 17차] 99주차 | ㅇㅇㅇ | 2022.07.31 | 35 |
140 | [커널 18차] 62주차 | kkr | 2022.07.30 | 26 |
139 | [커널 17차] 97~98주차 | ㅇㅇㅇ | 2022.07.24 | 52 |
138 | [커널 18차] 61주차 | kkr | 2022.07.23 | 113 |
137 | [커널 18차] 60주차 | kkr | 2022.07.16 | 129 |
136 | [커널 17차] 95~96주차 | ㅇㅇㅇ | 2022.07.10 | 105 |
135 | [커널 18차] 59주차 | kkr | 2022.07.09 | 126 |
134 | [커널 19차] 8주차 | kanlee | 2022.07.02 | 160 |
133 | [커널 19차] 7주차 | kanlee | 2022.07.02 | 95 |
132 | [커널 19차] 6주차 | kanlee | 2022.07.02 | 42 |
131 | [커널 19차] 5주차 | kanlee | 2022.07.02 | 38 |
130 | [커널 19차] 4주차 | kanlee | 2022.07.02 | 106 |
129 | [커널 18차] 57주차 | kkr | 2022.06.25 | 129 |
.