From 48367c0c4996f48217e3768bf0fd8dd599434ec4 Mon Sep 17 00:00:00 2001
From: Manuel Traut <manut@linutronix.de>
Date: Thu, 12 Apr 2012 17:34:47 +0200
Subject: add new chapter about the struct device

- what is it
- how is it used
- should be extended to sth. like linux driver model overview

Signed-off-by: Manuel Traut <manut@linutronix.de>
---
 kernel-devel/linux-device/pres_linux-device_en.tex | 237 +++++++++++++++++++++
 1 file changed, 237 insertions(+)
 create mode 100644 kernel-devel/linux-device/pres_linux-device_en.tex

(limited to 'kernel-devel/linux-device/pres_linux-device_en.tex')

diff --git a/kernel-devel/linux-device/pres_linux-device_en.tex b/kernel-devel/linux-device/pres_linux-device_en.tex
new file mode 100644
index 0000000..1d49773
--- /dev/null
+++ b/kernel-devel/linux-device/pres_linux-device_en.tex
@@ -0,0 +1,237 @@
+\input{configpres}
+
+\title{struct device}
+%\maketitle
+
+\begin{frame}
+\maketitle{aim}
+\begin{itemize}
+\item lowest level representation of every device in a Linux system
+\item hosts information that the device model core needs to model the system
+\item most subsystems track additional information about the devices they host
+\item it is rare for devices to be represented by bare device structures
+\item this struct is usually embedded within higher-level representation of
+	the device
+\end{itemize}
+\end{frame}
+
+\subtitle{components of the struct}
+
+\begin{frame}
+\frametitle{name and type}
+for example a mouse device
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+include/linux/device.h:
+...
+struct device {
+	...
+	const char *init_name;
+	const struct device_type *type;
+	...
+\end{lstlisting}
+\end{tiny}
+\end{frame}
+
+\begin{frame}
+\frametitle{connection of multiple devices}
+for example usb-hostcontroller1/usb-device3/usb-endpoint4/mouse
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+include/linux/device.h:
+...
+struct device {
+	...
+	struct device *parent;
+	...
+\end{lstlisting}
+\end{tiny}
+\begin{itemize}
+\item 'parent' is a ptr to the device to which this device is attached
+\item normaly a parent device is some sort of bus or host controller
+\item If parent is NULL, the device, is a top-level device, which is not
+	usually what you want
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{private data}
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+drivers/base/base.h
+...
+struct device_private {
+  struct klist klist_children;    //containing all children of this device
+  struct klist_node knode_parent; //node in sibling list
+  struct klist_node knode_driver; //node in driver list
+  struct klist_node knode_bus;    //node in bus list
+  struct list_head deferred_probe;//entry in deferred_probe_list
+  void *driver_data;              //private pointer for driver specific info
+  struct device *device;          //pointer back to the device
+};
+...
+include/linux/device.h:
+...
+struct device {
+	...
+	struct device_private *p;
+	...
+\end{lstlisting}
+\end{tiny}
+\end{frame}
+
+\begin{frame}
+\frametitle{bus}
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+include/linux/device.h:
+...
+struct device {
+	...
+	struct bus_type *bus;
+	...
+\end{lstlisting}
+\end{tiny}
+\begin{itemize}
+\item used by driver core to link between bus - device
+\item hosts pointer for: probe, remove, suspend, \dots
+\item these functions are called by the driver core on bus state changes
+\item bus drivers need to implement these calls and normaly redirect them to
+				the associated devices
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{driver}
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+include/linux/device.h:
+...
+struct device {
+	...
+	struct device_driver *driver;
+	...
+\end{lstlisting}
+\end{tiny}
+\begin{itemize}
+\item used by driver core to link between driver - device
+\item hosts a table of device id, the driver is responsible for
+\item hosts pointer for: probe, remove, suspend, \dots
+\item these functions are called by the bus driver on bus state changes
+\item device drivers need to implement these calls
+\item e.g. after a succesful probe call a driver is responsible for a device
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{platform data}
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+include/linux/device.h:
+...
+struct device {
+	...
+	void *platform_data;
+	...
+\end{lstlisting}
+\end{tiny}
+\begin{itemize}
+\item structure is declared by the platform device driver
+\item structure is normally initialized by 'board support package'
+\item hosts for example how a specific device is connected (mem\_base, irq)
+\item can host informations about chip variants
+\item shrinks 'board support packages'
+\item reduces board specific #ifdefs in driver code
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{misc}
+\begin{itemize}
+\item structs for device power management
+\item ptr to NUMA node this device is close to
+\item structs for DMA handling (if device is DMA capable)
+\item information about associated device node(s) (/dev/huhu)
+\item unique device id
+\item lock to protect device resources
+\item pointer to release() function of the device
+\end{itemize}
+\end{frame}
+
+\subtitle{how is it used}
+
+\begin{frame}
+\frametitle{initialization}
+The bus driver that discovers the device uses this to register the device with
+the core:
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+int device_register(struct device * dev);
+\end{lstlisting}
+\end{tiny}
+these fields should be initialized before calling the register function:
+\begin{itemize}
+\item parent
+\item name
+\item bus\_id
+\item bus
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{use by a driver}
+A device is removed from the core when its reference count goes to 0.
+The reference count can be adjusted using:
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+struct device * get_device(struct device * dev);
+void put_device(struct device * dev);
+\end{lstlisting}
+\end{tiny}
+The device lock can be accessed by:
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+void lock_device(struct device * dev);
+void unlock_device(struct device * dev);
+\end{lstlisting}
+\end{tiny}
+\end{frame}
+
+\begin{frame}
+\frametitle{device attributes}
+Attributes can be exported to sysfs by the device driver.
+\begin{tiny}
+\begin{lstlisting}[frame=trBL]
+my.c:
+...
+static DEVICE_ATTR(ro, 0444, my_show_ro, NULL);
+static DEVICE_ATTR(rw, 0644, my_show_rw, my_store_rw);
+
+static struct attribute *my_dev_attrs[] = {
+  &dev_attr_ro.attr,
+  &dev_attr_rw.attr,
+  NULL,
+};
+
+static struct attribute_group my_dev_attr_group = {
+  .attrs = my_dev_attrs,
+};
+
+static const struct attribute_group *my_dev_attr_groups[] = {
+  &my_dev_attr_group,
+  NULL,
+};
+
+static int __init my_driver_init(struct device *my_dev)
+{
+	...
+	my_dev->groups = my_dev_attr_groups;
+	device_register(my_dev);
+	...
+}
+
+\end{lstlisting}
+\end{tiny}
+\end{frame}
+
+\input{tailpres}
-- 
cgit v1.2.3

