基于 “arch/arm/mach-imx/src.c”
参考这篇
reset-framework涉及的文件:
include/linux/reset-controller.h
drivers/reset/core.c
总之感觉就是封装了一个设备的复位操作,并可以通过设备树去灵活配置复位操作
静态定义:
static struct reset_controller_dev imx_reset_controller = {
.ops = &imx_src_ops,
.nr_resets = ARRAY_SIZE(sw_reset_bits),
};
static const int sw_reset_bits[5] = {
BP_SRC_SCR_SW_GPU_RST,
BP_SRC_SCR_SW_VPU_RST,
BP_SRC_SCR_SW_IPU1_RST,
BP_SRC_SCR_SW_OPEN_VG_RST,
BP_SRC_SCR_SW_IPU2_RST
};
关于ARRAY_SIZE这个宏,参考这篇blog
结构体类型定义
struct reset_controller_dev 类型
/**
* 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
* @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
* @nr_resets: number of reset controls in this reset controller device
*/
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;
};
struct reset_control定义:
/**
* struct reset_control - a reset control
* @rcdev: a pointer to the reset controller device
* this reset control belongs to
* @id: ID of the reset controller in the reset
* controller device
*/
struct reset_control {
struct reset_controller_dev *rcdev;
struct device *dev;
unsigned int id;
};
struct reset_control_ops定义
/**
* struct reset_control_ops
*
* @reset: for self-deasserting resets, does all necessary
* things to reset the device
* @assert: manually assert the reset line, if supported
* @deassert: manually deassert the reset line, if supported
* @status: return the status of the reset line, if supported
*/
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);
int (*status)(struct reset_controller_dev *rcdev, unsigned long id);
};
在函数 imx_src_init中
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,imx51-src");
...
imx_reset_controller.of_node = np;
if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
reset_controller_register(&imx_reset_controller);
...
np对应的结点为:
src: src@020d8000 {
compatible = "fsl,imx6ul-src", "fsl,imx51-src";
reg = <0x020d8000 0x4000>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
#reset-cells = <1>;
};
看reset_controller_register
/**
* reset_controller_register - register a reset controller device
* @rcdev: a pointer to the initialized reset controller device
*/
int reset_controller_register(struct reset_controller_dev *rcdev)
{
if (!rcdev->of_xlate) {
rcdev->of_reset_n_cells = 1;
rcdev->of_xlate = of_reset_simple_xlate;
}
mutex_lock(&reset_controller_list_mutex);
list_add(&rcdev->list, &reset_controller_list);
mutex_unlock(&reset_controller_list_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(reset_controller_register);