-
Notifications
You must be signed in to change notification settings - Fork 0
/
linux-reset-controller.tex
191 lines (169 loc) · 10.4 KB
/
linux-reset-controller.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
\documentclass{beamer}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{listings}
\usetheme{Warsaw}
\title{Reset controller framework: how to use it}
\author{Romain Perier}
\institute{Embedded linux engineer and foss developer\newline [email protected]}
\date{December 3th 2015}
\begin{document}
\begin{frame}
\titlepage{}
\end{frame}
\begin{frame}{Romain Perier}
\begin{itemize}
\item Embedded linux engineer since 2011
\item Mainline linux kernel and yocto contributor (Rockchip, Meson)
\item Maintainer of meta-rockchip in the yocto project
\item Living in Toulouse, France
\end{itemize}
\end{frame}
\begin{frame}{Overview}
\begin{itemize}
\item Hardware reset controller
\item What is the reset controller framework
\item How to add your own reset controller driver
\item How to interface it with the devicetree
\item Use reset lines from device drivers
\item Questions?
\end{itemize}
\end{frame}
\begin{frame}{Hardware reset controller}
\begin{itemize}
\item A system reset controller includes resets: generated by hardware, watchdog, or software
\item On most SoCs, devices include a reset line that is driven by a reset system
\item Some IP blocks have the ability to reset their internal logics or do internal initializations when its reset line is asserted/deasserted
\item It is strongly platform-dependent, but you might have to generate software resets for power up peripherals
\item you might have to generate software resets to power down peripherals or restart their internal logic
\item Example: cpu cores, ethernet controller, Nand flash controller, etc...
\end{itemize}
\end{frame}
\begin{frame}{What is the reset controller framework}
\begin{itemize}
\item Started by Philipp Zabel in 2013
\item That is a framework to abstract reset signals handling inside the kernel
\item All the platform-dependent parts about how to assert or deassert a specific reset line is handled internally on the provider side
\item Allow to declare reset lines and to provide these lines to the device driver throught the Device Tree
\item Retrieve a reset line from the Device Tree and bind the corresponding reset controller driver to it
\item Like many other frameworks it is based on the consumer/provider software architecture
\end{itemize}
\end{frame}
\begin{frame}{Diagram overview of the reset subsystem architecture}
\centering
\includegraphics[scale=0.4]{reset_framework_architecture.png}
\end{frame}
\begin{frame}{Interface of the reset framework}
There are different types of interfaces:
\begin{itemize}
\item The one used by the reset controller driver, in \textcolor{gray}{include/linux/reset-controller.h}:
\begin{itemize}
\item \textit{\textcolor{blue}{struct} reset\_controller\_dev}: data structure of the reset system driver that is going to be registered to the kernel
\item \textit{reset\_controller\_register}: register your reset system to the kernel
\item \textit{\textcolor{blue}{struct} reset\_control\_ops}: operations invoked by the RCF, containing callbacks implemented by your driver
\end{itemize}
\end{itemize}
\begin{itemize}
\item The one used by devices drivers, in \textcolor{gray}{include/linux/reset.h}:
\begin{itemize}
\item \textit{\textcolor{blue}{struct} reset\_control}: data structure corresponding to the reset line being used by the consumer
\item \textit{reset\_control\_reset}: does all required things to reset the device connected to this signal (self-asserting/deasserting)
\item \textit{reset\_control\_assert}: manually asserts the reset line
\item \textit{reset\_control\_status}: get the status of the reset line
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}{Implementation of the reset controller framework core}
Everything is in \textcolor{gray}{drivers/reset/core.c}, it does the following:
\begin{itemize}
\item Maintain a list of reset controller drivers
\item Forward all reset lines operations to the right reset controller driver
\item Also, pass the identifier of the corresponding line to the driver, including remapping if needed
\item Provides allocation functions to retrieve a \textit{\textcolor{blue}{struct} reset\_control} from the devicetree
\item However, you need to take care about concurrency prevention yourself, in your driver
\end{itemize}
\end{frame}
\begin{frame}{How to add your own reset controller driver}
You need to define reset controller operations implemented in \textcolor{gray}{include/linux/reset-controller.h}
\lstinputlisting[language=C,basicstyle=\footnotesize\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{reset-control-ops.h}
\end{frame}
\begin{frame}{Registering the reset controller driver}
\begin{itemize}
\item Allocate a \textit{\textcolor{blue}{struct} reset\_controller\_dev}, then populate the following fields:
\lstinputlisting[language=C,basicstyle=\scriptsize\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{reset-controller-dev.h}
%\begin{itemize}
% \item \textit{.ops}: a pointer to the previous data structure defining your drivers operations
% \item \textit{.owner}: usually \textit{THIS\_MODULE}
% \item \textit{.of\_node}: a pointer to \textit{\textcolor{blue}{struct} device\_node}
% \item \textit{.nr\_resets}: number of reset lines
% \item \textit{.of\_reset\_n\_cells}: Number of cells in a reset controller specifier, it should match \textit{reset-cells} from the devicetree
%\end{itemize}
%\item \textit{.of\_xlate}: you can also define a mapping function to translate logicals to physicals identifiers, for a reset line (optional)
\item Then call the function \textit{reset\_controller\_register}
\item Usually implemented in \textcolor{gray}{drivers/reset}, but there are few exceptions. Sometimes you might find reset controller drivers in \textcolor{gray}{drivers/clk}, when it has to do with the CRU
\end{itemize}
\end{frame}
\begin{frame}{Example of reset controller driver}
\lstinputlisting[language=C,basicstyle=\scriptsize\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{reset-controller-driver-probe.c}
\end{frame}
\begin{frame}{Operations for a reset controller driver}
\lstinputlisting[language=C,basicstyle=\scriptsize\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{reset-controller-driver-functions.c}
\end{frame}
\begin{frame}{How to interface your driver with the devicetree}
It's pretty simple:
\begin{itemize}
\item For the provider:
\begin{itemize}
\item Define a basic \textit{device\_node} in your devicetree, matching your compatility identifiers
\item Make sure that \textit{\textcolor{gray}{\#reset-cells}} is equal to \textit{.of\_reset\_n\_cells}
\end{itemize}
\item For the consumer:
\begin{itemize}
\item Use the property \textit{\textcolor{gray}{resets}} for devices that will use your rstc
\item This property contains one or more phandle with argument corresponding to the reset line identifier passed to the specifier
\item When there are more than one phandle, use the property \textit{\textcolor{gray}{resets-names}} to retrieve them easily from your device driver
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}{Example: How to interface your driver with the devicetree}
For the provider:
\lstinputlisting[language=xml, keywordstyle=\color{gray},basicstyle=\scriptsize\ttfamily,stringstyle=\color{red},commentstyle=\color{gray},otherkeywords={\#reset-cells}]{reset-controller.dts}
For the consumer:
\lstinputlisting[language=xml, keywordstyle=\color{gray},basicstyle=\scriptsize\ttfamily,stringstyle=\color{red},commentstyle=\color{gray},otherkeywords={\#reset-cells}]{reset-consumer.dts}
The identifier passed to \textit{rst} will be also be passed to the function \newline\textit{\textcolor{blue}{int} meson\_reset\_assert(\textcolor{blue}{struct} reset\_controller\_dev *, \textcolor{blue}{unsigned long})},\newline when the RCF will invoke your driver operations
\end{frame}
\begin{frame}{Use reset lines from device drivers}
\lstinputlisting[language=C,basicstyle=\small\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{of_reset_control.c}
\begin{itemize}
\item To do so you need to instantiate a \textit{\textcolor{blue}{struct} reset\_control} from the \textit{\textcolor{gray}{resets}} property by using the above function
\item Pass the name of one reset line listed in \textit{\textcolor{gray}{reset-names}} as second argument or \textit{\textcolor{cyan}{NULL}} if the \textit{\textcolor{gray}{resets}} property contains a single phandle
\item Use functions from consumer API in order to change the state of your reset line, \textit{reset\_control\_assert} typically
\item Each time you call a function on a reset line, the reset framework will delegate the corresponding operation to the reset controller driver
\end{itemize}
\end{frame}
\begin{frame}{Example of device driver that uses a reset line}
\lstinputlisting[language=C,basicstyle=\scriptsize\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{reset-consumer.c}
\end{frame}
\begin{frame}{reset: API}
You have also these functions:
\begin{itemize}
\lstinputlisting[language=C,basicstyle=\scriptsize\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{reset.h}
\item \textit{reset\_control\_get}: retrieve the reset line described by \textit{\textcolor{gray}{id}} from the devicetree for the corresponding device
\item \textit{devm\_reset\_control\_get}: same thing but with managed resources (no need to call \textit{reset\_control\_put})
\item \textit{device\_reset\_optional}: retrieve the unique reset line associated to this device, call the \textit{\textcolor{gray}{reset}} operation, then release the object
\end{itemize}
\end{frame}
\begin{frame}{Thank you!}
\centering{\includegraphics[scale=0.3]{tuxquestion.png}}
\vfill
\vfill
\centering{Slides under CC-BY-SA 3.0}
\url{https://github.com/rperier/confs}
\end{frame}
\begin{frame}{Just in case...}
\lstinputlisting[language=C,basicstyle=\scriptsize\ttfamily,keywordstyle=\bfseries\color{blue},breaklines=true,commentstyle=\color{gray}\ttfamily]{xlate.c}
\end{frame}
\begin{frame}{Just in case...}
\lstinputlisting[language=xml, keywordstyle=\color{gray},basicstyle=\scriptsize\ttfamily,stringstyle=\color{red},commentstyle=\color{gray},otherkeywords={\#reset-cells}]{xlate.dts}
\end{frame}
\end{document}