iJoe's Blog
Published on

linux驱动学习-设备树04-reset系统

Authors

Reset

复位并不是将某一个模块的状态重置为0,而是将其置为初始状态。

很多模块都不能自己reset,也可能是要操作其他模块,所以一般是通过控制器,来为需要复位的模块进行发送信号。

Reset Controller

复位也和其他gpio,clock等一样有自己的控制器,也是用来发送signal的模块,使用assert或deassert来操作,其中assert是复位,deassert是取消复位。

一般有两种情况,一个是设备使用时候需要先复位一次,希望对应寄存器是原始状态以防出错。所以就有assert->sleep->deassert。另一个情况是设备需要使用时,不关注它是否复位,但是可能存在它现在现在处于复位,就需要先dessert->使用->assert

DTS

usb_drd0_dwc3: usb@23000000 {
    compatible = "rockchip,rk3576-dwc3", "snps,dwc3";
    reg = <0x0 0x23000000 0x0 0x400000>;

    clocks = <&cru CLK_REF_USB3OTG0>,
             <&cru CLK_SUSPEND_USB3OTG0>,
             <&cru ACLK_USB3OTG0>;
    clock-names = "ref_clk", "suspend_clk", "bus_clk";

    interrupts = <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;

    power-domains = <&power RK3576_PD_USB>;

    resets = <&cru SRST_A_USB3OTG0>;

    status = "disabled";
};

可以看到,USB 节点声明/引用了 clock 和 reset 资源。

Reset 流程

从 DTS 看,cru 是 reset provider, usb_drd0_dwc3 是 reset consumer。

使用流程

USB DTS 节点
resets = <&cru SRST_A_USB3OTG0>
        ↓
USB driver 获取 reset_control
        ↓
Reset Framework / Reset Core
        ↓
根据 &cru + reset ID 找到对应 provider
        ↓
调用 provider 的 assert / deassert
        ↓
Rockchip CRU/reset driver
        ↓
写对应 reset 寄存器 bit
        ↓
Reset Controller 硬件
        ↓
reset signal
        ↓
USB Controller 进入 / 退出 reset

Provider 注册

CRU/reset driver 会先把 reset controller 和对应 ops 注册到 Reset Framework 中,供后续 consumer 查找和使用。

参考文档

[1] rk3576.dtsi
[2] linux reset模块 [3] 复位控制器 API