首页 > 系统相关 >linux reset模块

linux reset模块

时间:2023-06-13 20:24:08浏览次数:50  
标签:reset control struct int provider controller 模块 linux

前言

大家都知道,复杂IC内部有很多具有独立功能的硬件模块,例如CPU cores、GPU cores、USB控制器、MMC控制器、等等,出于功耗、稳定性等方面的考虑,有些IC在内部为这些硬件模块设计了复位信号(reset signals),软件可通过寄存器(一般1个bit控制1个硬件)控制这些硬件模块的复位状态。

Linux kernel为了方便设备驱动的编写,抽象出一个简单的软件框架----reset framework,为reset的provider提供统一的reset资源管理手段,并为reset的consumer(各个硬件模块)提供便捷、统一的复位控制API。

reset framework的思路、实现和使用都非常简单、易懂(参考kernel有关的API--include/linux/reset-controller.h、include/linux/reset.h可知),不过麻雀虽小,五脏俱全,通过它可以加深对Linux kernel的设备模型、驱动框架、分层设计、provider/consumer等设计思想的理解,因此本文将对其进行一个简单的罗列和总结。

reset框架

模块驱动程序调用reset统一封装的接口,实现模块的复位,reset封装屏蔽了寄存器的具体细节。

flowchart TD subgraph crg CRG end subgraph consumer I2C EMMC IPC ... end subgraph provider reset("reset framework") end consumer --> provider provider --> crg

从consumer的角度看

从某一个硬件模块的驱动设计者来看,他的要求很简单:我只是想复位我的硬件,而不想知道到底用什么手段才能复位(例如控制哪个寄存器的哪个bit位,等等)。

这个要求其实体现了软件设计(甚至是任何设计)中的一个最最质朴的设计理念:封装和抽象。对设备驱动来说,它期望看到是“reset”这个通用概念,用这个通用概念去发号施令的话,这个驱动就具备了通用性和可移植性(无论在周围的环境如何变化,“reset”本身不会变化)。而至于怎么reset,是通过寄存器A的bit m,还是寄存器B的bit n,则是平台维护者需要关心的事情(就是本文的reset provider)。

看到这样的要求,Linux kernel说:OK,于是reset framework出场,提供了如下的机制(基于device tree):

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

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

device {
        resets = <&rst 20>;
        reset-names = "reset";
};
  1. 最后,consumer driver在需要的时候,可以调用下面的API复位自己(具体可参考“include/linux/reset.h“):
  • 只有一个reset信号的话,可以使用最简单的device_reset API

int 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);
void reset_control_put(struct reset_control *rstc);
struct reset_control *devm_reset_control_get(struct device *dev, const char *id);

/* 通过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);

从provider的角度看

kernel为reset provider提供的API位于“include/linux/reset-controller.h”中,很简单,无非就是:创建并填充reset controller设备(struct reset_controller_dev),并调用相应的接口(reset_controller_register/reset_controller_unregister)注册或者注销之。

reset controller的抽象也很简单:

struct reset_controller_dev {
        struct reset_control_ops *ops;
        struct module *owner;
        struct list_head list;
        struct device_node *of_node;
        int of_reset_n_cells;
        int (*of_xlate)(struct reset_controller_dev *rcdev,
                        const struct of_phandle_args *reset_spec);
        unsigned int nr_resets;
};

ops提供reset操作的实现,基本上是reset provider的所有工作量。
of_xlate和of_reset_n_cells用于解析consumer device dts node中的“resets = ; ”节点,如果reset controller比较简单(仅仅是线性的索引),可以不实现,使用reset framework提供的简单版本----of_reset_simple_xlate即可。
nr_resets,该reset controller所控制的reset信号的个数。
其它字段内部使用,provider不需要关心。

struct reset_control_ops也比较单纯,如下:

struct reset_control_ops {
        int (*reset)(struct reset_controller_dev *rcdev, unsigned long id);
        int (*assert)(struct reset_controller_dev *rcdev, unsigned long id);
        int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id);
};

reset可控制设备完成一次完整的复位过程。
assert和deassert分别控制设备reset状态的生效和失效。

文件

文件 作用
include/linux/reset.h consumer使用的头文件
drivers/reset/core.c reset 主逻辑以及API实现

Ref

  1. http://www.wowotech.net/pm_subsystem/clock_provider.html
  2. https://docs.kernel.org/driver-api/reset.html

标签:reset,control,struct,int,provider,controller,模块,linux
From: https://www.cnblogs.com/lvzh/p/17478644.html

相关文章

  • Linux hwrng以及ARM TRNG记录
    关键词:hwrng,/dev/random,/dev/urandom,rngd,rngtest等。  Linuxhwrng驱动比较简单,hwrngcore注册设备提供应用层设备。hwrnddriver提供具体硬件接口,然后注册到hwrngcore中,以及往内核熵池提供随机数。1.Linuxhwrng框架1.1hwrng框架对外接口 hwrng对外提供的API接口包括......
  • 实验七 面向对象编程与内置模块
    实验任务1task1.pyclassAccount:def__init__(self,name,account_number,initial_amount=10):self._name=nameself._card_no=account_numberself._balance=initial_amountdefdeposit(self,amount):self._balance+=amoun......
  • 学无止境--linux 代码中获取pid的方法
    #include<linux/resource.h>#include<unistd.h>#include<signal.h>pid_twd_pid;charline[8];FILE*cmd;intpri;/*创建管道并创建shell子进程,执行pidofbspInit0命令:‘bspInit0’是进程名*/cmd=popen("pidofbspInit0","r");/*从文件流......
  • 10分钟让你掌握Linux常用命令(+3万+++收藏)
    1、常用Linux命令2、Linux下脚本编写3、windows下CMD常用命令文章目录一、目录操作1、批量操作二、文件操作三、文件内容操作(查看日志,更改配置文件)1、grep(检索文件内容)2、awk(数据统计)3、sed(替换文件内容)4、管道操作符`|`5、cut(数据裁剪)四、系统日志位置五、创建与删除软连......
  • Python基础之subprocess模块、hashlib模块、日志模块
    subprocess模块tasklist:列举出来文件进程命令"""1.以后我们可以用自己的电脑连接上别人的电脑(socket)2.通过subprocess可以在别人的计算机上执行我们想要执行的命令3.把在别人计算机上执行的结果给返回过来"""importsubprocessimportsubprocessres=subprocess.P......
  • python 之logging 模块
    一、日志的简单使用1、什么是日志记录你的代码在执行过程中的一些变化(记录的是一些有意义的变化)2、日志的5个等级importlogginglogging.debug('debugmessage')#10logging.info('infomessage')#20logging.warning('warningmessage')#30logging.error('errorm......
  • Linux系统下如果在编译时指定程序运行时动态链接库相对目录,及为程序收集默认不安装动
    1、在编译中指定编译的程序去查找的动态链接库目录qmake是这样指定运行时动态库目录的:  QMAKE_LFLAGS+=-Wl,-rpath=/usr/local/ultrasec/policyfilter/lib/ 2、用lddPROG  查看程序的动态链接库,如果没有的动态链接库,就从其它计算机或者网络上找这个库,然后拷贝到指......
  • RDIFramework.NET V3.3 Web版角色授权管理新增角色对操作权限项、模块起止生效日期的
    在实际应用在我们可能会有这样的需求,某个操作权限项(按钮)或菜单在某个时间范围内可以让指定角色访问。此时通过我们的角色权限扩展设置就可以办到。在我们框架V3.3Web版本全新增加了角色权限扩展设置的功能。主要是针对角色对操作权限项、角色对模块在指定时间范围内有效的设置。功......
  • RDIFramework.NET V3.3 WinForm版角色授权管理新增角色对操作权限项、模块起止生效日
    在实际应用在我们可能会有这样的需求,某个操作权限项(按钮)或菜单在某个时间范围内可以让指定角色访问。此时通过我们的角色权限扩展设置就可以办到。在我们框架V3.3WinForm版全新增加了角色权限扩展设置的功能。主要是针对角色对操作权限项、角色对模块在指定时间范围内有效的设置。......
  • 宝塔Linux安装
    首先找到宝塔的安装地址:https://www.bt.cn/new/index.html第一步:安装宝塔SSH终端安装成功之后的界面是这样的:  第二步:Liunx宝塔面板的安装地址:https://www.bt.cn/btcode.html 这里我安装的是第一个 ......