设为首页 加入收藏

TOP

Linux reset子系统(一)
2023-07-23 13:24:54 】 浏览:61
Tags:Linux reset
文章代码分析基于linux-5.19.13,架构基于aarch64(ARM64)。

1. 前言

复杂IC内部有很多具有独立功能的硬件模块,例如CPU cores、GPU cores、USB控制器、MMC控制器、等等,出于功耗、稳定性等方面的考虑,有些IC在内部为这些硬件模块设计了复位信号(reset signals),软件可通过寄存器(一般1个bit控制1个硬件)控制这些硬件模块的复位状态。
Linux kernel为了方便设备驱动的编写,抽象出一个简单的软件框架----reset framework,为reset的provider提供统一的reset资源管理手段,并为reset的consumer(各个硬件模块)提供便捷、统一的复位控制API。

2. 前言

reset子系统也分为了consumer和provider,结构体关系如下:

3. consumer

对于一个具体的硬件模块,它的要求很简单:复位我的硬件模块,而不必关注具体复位的手段(例如控制哪个寄存器的哪个bit位,等等)。

Linux kernel基于device tree提供了对应的reset framework:

  1. 首先,提供描述系统中reset资源的方法(参考provider的介绍),这样consumer可以基于这种描述,在自己的dts node中引用所需的reset信号。

  2. 然后,consumer设备在自己的dts node中使用“resets”、“reset-names”等关键字声明所需的reset的资源,例如("resets"字段的具体格式由reset provider决定):

device {
  resets = <&rst 20>;
  reset-names = "reset"; 
};
This represents a device with a single reset signal named "reset".

bus { 
  resets = <&rst 10> <&rst 11> <&rst 12> <&rst 11>;
  reset-names = "i2s1", "i2s2", "dma", "mixer"; 
};
This represents a bus that controls the reset signal of each of four sub- ordinate devices. Consider for example a bus that fails to operate unless no child device has reset asserted. 
  1. 最后,consumer driver在需要的时候,可以调用下面的API复位自己(具体可参考"include\linux\reset.h"):
  • 只有一个reset信号的话,可以使用最简单的device_reset API
static inline int __must_check device_reset(struct device *dev)
  • 如果需要更为复杂的控制(例如有多个reset信号、需要控制处于reset状态的长度的等),可以使用稍微复杂的API
/* 通过reset_control_get或者devm_reset_control_get获得reset句柄 */
struct reset_control *reset_control_get(struct device *dev, const char *id);                             
struct reset_control *devm_reset_control_get(struct device *dev, const char *id);

/* 通过reset_control_put释放reset句柄 */
void reset_control_put(struct reset_control *rstc);  

/* 通过reset_control_reset进行复位,或者通过reset_control_assert使设备处于复位生效状态,通过reset_control_deassert使复位失效 */
int reset_control_reset(struct reset_control *rstc);   /先复位,延迟一会,然后解复位                        
int reset_control_assert(struct reset_control *rstc);  //复位                       
int reset_control_deassert(struct reset_control *rstc);//解复位

4. provider

kernel为reset provider提供的API位于"include/linux/reset-controller.h"中,很简单,无非就是:创建并填充reset controller设备(struct reset_controller_dev),并调用相应的接口:

  • reset_controller_register //注册reset_controller
  • reset_controller_unregister //注销reset_controller

reset controller的抽象也很简单:

/**
 * struct reset_controller_dev - reset controller entity that might
 *                               provide multiple reset controls
 * @ops: a pointer to device specific struct reset_control_ops
 * @owner: kernel module of the reset controller driver
 * @list: internal list of reset controller devices
 * @reset_control_head: head of internal list of requested reset controls
 * @dev: corresponding driver model device struct
 * @of_node: corresponding device tree node as phandle target
 * @of_reset_n_cells: number of cells in reset line specifiers
 * @of_xlate: translation function to translate from specifier as found in the
 *            device tree to id as given to the reset control ops, defaults
 *            to :c:func:`of_reset_simple_xlate`.
 * @nr_resets: number of reset controls in this reset controller device
 */
struct reset_controller_dev {
	const struct reset_control_ops *ops;//ops提供reset操作的实现,基本上是reset provider的所有工作量。
	s
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇痞子衡嵌入式:恩智浦i.MX RT1xxx.. 下一篇Zephyr入门教程 2 线程

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目