F. 添加ti_reset.c文件:
drivers/reset/core.c文件声明了一个结构体struct reset_control,它的定义则由函数of_reset_control_get返回,并且在返回之前给其成员变量struct reset_controller_dev *rcdev赋值。
of_reset_control_get函数被reset_control_get函数调用;reset_control_get函数被SGX的PVRSRVDriverProbe函数调用。
在继续调试之前,先来理解list_for_each:
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next) \
pos = list_next_entry(pos, member))
pos是循环变量,相当于for循环里面的i;head是链表list的表头;list_next_entry展开得到:
container_of((pos)->member.next, typeof(*(pos)), member);
container_of的原型是container_of(ptr, type, member) ,它是一个非常常见的宏定义,含义是,返回type类型的地址,type类型包含了member类型,而ptr是实际的member类型指针。所以list_next_entry的含义是,返回一个typeof(*(pos))的地址,它包含有member这个类型,且(pos)->member.next指向这个member。
再来理解 list_for_each_entry:
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
&pos->member != (head); \
pos = list_next_entry(pos, member))
pos是循环变量,相当于for循环里面的i;head是链表list的表头;member是被包含的类型定义;
首先,pos初始化为typeof(*pos)类型的指针,它包含有member类型,且member的地址为head->next;
然后,如果没有循环返回到head,则pos会指向包含有(pos)->member.next的pos类型地址。
所以,of_reset_control_get函数中的list_for_each_entry(r, &reset_controller_list, list)含义是:
r相当与for循环里面的i,指向下一个被操作的struct reset_controller_dev;reset_controller_list是链表的表头;
首先,r初始化为struct reset_controller_dev类型的指针,它包含有list类型,且list的地址为(&reset_controller_list)->next;
但是已知 reset_controller_list在此文件头被初始化了,它是一个空链表:
static LIST_HEAD(reset_controller_list);
因此为了让list_for_each_entry得到有效的执行,即得到可用的rcdev,需要执行reset_controller_register函数。
So,将TI公司提供的内核中的ti_reset.c拷贝到driver/reset目录下,它包含有关键的注册操作,即reset_controller_register函数。
另外,不要忘记修改Makefile和Kconfig。
另外,不要忘记把ti_reset.c中的.compatible值改为和am33xx.dtsi文件中相同的"ti,am3-prcm"。
文章评论(0条评论)
登录后参与讨论