diff options
| author | Benedikt Spranger <b.spranger@linutronix.de> | 2009-11-24 10:52:22 +0100 |
|---|---|---|
| committer | Benedikt Spranger <b.spranger@linutronix.de> | 2009-11-24 10:54:35 +0100 |
| commit | e28a6bf75de1d098df46f46d710ebb0aefb21db7 (patch) | |
| tree | e9b5bdef8c28d2ce43e5ecc6219aa0777fb7cff5 /kernel-devel | |
| parent | c5b55712e06551da232fd77eb545e9b7f0409006 (diff) | |
Platform device added
Diffstat (limited to 'kernel-devel')
| -rw-r--r-- | kernel-devel/module-basics/images/plat_driver.dia | bin | 0 -> 2572 bytes | |||
| -rw-r--r-- | kernel-devel/module-basics/images/plat_driver.png | bin | 0 -> 23546 bytes | |||
| -rw-r--r-- | kernel-devel/module-basics/pres_module-basics_de.tex | 197 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/Makefile | 13 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/vain_plat.c | 6 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/vain_plat_1.c | 12 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/vain_plat_2.c | 25 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/vain_plat_3.c | 18 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/vain_plat_4.c | 23 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/vain_plat_5.c | 24 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_plat/vain_plat_orig.c | 105 |
11 files changed, 417 insertions, 6 deletions
diff --git a/kernel-devel/module-basics/images/plat_driver.dia b/kernel-devel/module-basics/images/plat_driver.dia Binary files differnew file mode 100644 index 0000000..ef9c404 --- /dev/null +++ b/kernel-devel/module-basics/images/plat_driver.dia diff --git a/kernel-devel/module-basics/images/plat_driver.png b/kernel-devel/module-basics/images/plat_driver.png Binary files differnew file mode 100644 index 0000000..691e948 --- /dev/null +++ b/kernel-devel/module-basics/images/plat_driver.png diff --git a/kernel-devel/module-basics/pres_module-basics_de.tex b/kernel-devel/module-basics/pres_module-basics_de.tex index a62397c..533a668 100644 --- a/kernel-devel/module-basics/pres_module-basics_de.tex +++ b/kernel-devel/module-basics/pres_module-basics_de.tex @@ -134,22 +134,22 @@ vain_exit: done % ----- Slide Komplexere Module ------------------ \begin{frame} -\frametitle{Komplexere Modul} +\frametitle{Komplexere Module} \pause \begin{itemize} \item Teil eines Bussystems \pause \begin{itemize} -\item USB -\pause \item PCI \pause \item Platform \pause +\item USB +\pause \item \dots \pause \end{itemize} -\item Teil eines Subsystems +\item Teil eines Subsystems\footnote{nicht Teil des Vortrages} \pause \begin{itemize} \item Character-Devices @@ -182,7 +182,7 @@ vain_exit: done \pause \begin{tiny} \begin{lstlisting}[frame=trBL] -static int vain_pci_init(void) +static int __init vain_pci_init(void) { int err; @@ -207,7 +207,7 @@ module_init(vain_pci_init); \pause \begin{tiny} \begin{lstlisting}[frame=trBL] -static void vain_pci_exit(void) +static void __exit vain_pci_exit(void) { |pci_unregister_driver(&vain_pci_driver);| printk(KERN_INFO ``vain_pci_exit: done\n''); @@ -368,4 +368,189 @@ module_exit(vain_pci_exit); \end{tiny} \end{frame} +% ----- Slide Platform Treiber ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines Platform Treiber Moduls} +\pause +\begin{itemize} +\item Header +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +#include <linux/init.h> +#include <linux/module.h> +|#include <linux/platform_device.h> + +#include <asm/io.h>| +\end{lstlisting} +\end{tiny} +\pause +\item Init +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +static int __init vain_plat_init(void) +{ + int err; + + |err = platform_driver_register(&vain_plat_driver);| + + if (!err) + printk(KERN_INFO ``vain_plat_init: done\n''); + return err; +} +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide Platform Treiber ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines Platform Treiber Moduls (fort.)} +\pause +\begin{itemize} +\item Exit +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +static void __exit vain_plat_exit(void) +{ + |platform_driver_unregister(&vain_plat_driver);| + printk(KERN_INFO ``vain_plat_exit: done\n''); +} +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide Platform Treiber ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines Platform Treiber Moduls (fort.)} +\pause +\begin{itemize} +\item struct platform\_driver +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +|static struct platform_driver vain_plat_driver = { + .driver = { + .name = "vain_plat", + .owner = THIS_MODULE, + }, + .probe = vain_plat_probe, + .remove = __devexit_p(vain_plat_remove), +};| +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide Platform Treiber ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines Platform Treiber Moduls (fort.)} +\pause +\begin{itemize} +\item probe +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +|static int __devinit vain_plat_probe(struct platform_device *pdev) +{ + struct resource *res; + int err; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) + goto err_free; + + mem = request_mem_region(res->start, resource_size(res), pdev->name); + if (!mem) + goto err_free; + + info->base = ioremap(res->start, resource_size(res)); + if (!info->base) + goto err_ioremap; + + platform_set_drvdata(pdev, info); + + return 0;| +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide Platform Treiber ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines Platform Treiber Moduls (fort.)} +\pause +\begin{itemize} +\item remove +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +|static int __devexit vain_plat_remove(struct platform_device *pdev) +{ + struct vain_plat_info *info = platform_get_drvdata(pdev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + iounmap(info->base); + release_mem_region(res->start, resource_size(res)); + platform_set_drvdata(pdev, NULL); + + kfree (info); + + return 0; +}| +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber Hintergrund ------------------ +\begin{frame} +\frametitle{Platform Treiber Hintergrund} +\includegraphics[width=7cm]{images/plat_driver.png} +\end{frame} + +% ----- Slide Platform Rumpf Treiber ------------------ +\begin{frame}[fragile] +\frametitle{Platform Rumpf Treiber} +\begin{tiny} +\lstinputlisting{vain_plat/vain_plat_1.c} +\end{tiny} +\end{frame} + +% ----- Slide Platform Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Platform Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_plat/vain_plat_2.c} +\end{tiny} +\end{frame} + +% ----- Slide Platform Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Platform Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_plat/vain_plat_3.c} +\end{tiny} +\end{frame} + +% ----- Slide Platform Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Platform Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_plat/vain_plat_4.c} +\end{tiny} +\end{frame} + +% ----- Slide Platform Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Platform Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_plat/vain_plat_5.c} +\end{tiny} +\end{frame} + \end{document} diff --git a/kernel-devel/module-basics/vain_plat/Makefile b/kernel-devel/module-basics/vain_plat/Makefile new file mode 100644 index 0000000..f9610ca --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/Makefile @@ -0,0 +1,13 @@ +# If KERNELRELEASE is defined, we've been invoked from the +# kernel build system and can use its language. +ifneq ($(KERNELRELEASE),) + obj-m := vain_plat.o + +# Otherwise we were called directly from the command +# line; invoke the kernel build system. +else + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +endif diff --git a/kernel-devel/module-basics/vain_plat/vain_plat.c b/kernel-devel/module-basics/vain_plat/vain_plat.c new file mode 100644 index 0000000..de07040 --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/vain_plat.c @@ -0,0 +1,6 @@ +#include "vain_plat_1.c" +#include "vain_plat_2.c" +#include "vain_plat_3.c" +#include "vain_plat_4.c" +#include "vain_plat_5.c" +#include "vain_plat_6.c" diff --git a/kernel-devel/module-basics/vain_plat/vain_plat_1.c b/kernel-devel/module-basics/vain_plat/vain_plat_1.c new file mode 100644 index 0000000..302fa7d --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/vain_plat_1.c @@ -0,0 +1,12 @@ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <asm/io.h> + +struct vain_plat_info { + void __iomem *base; + struct platform_device *pdev; + spinlock_t lock; +}; + diff --git a/kernel-devel/module-basics/vain_plat/vain_plat_2.c b/kernel-devel/module-basics/vain_plat/vain_plat_2.c new file mode 100644 index 0000000..9c5a980 --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/vain_plat_2.c @@ -0,0 +1,25 @@ +static int __devinit vain_plat_probe(struct platform_device *pdev) +{ + struct vain_plat_info *info; + struct resource *res, *mem; + int err; + + info = kzalloc(sizeof(struct vain_plat_info), GFP_KERNEL); + if (unlikely(!info)) { + dev_err(&pdev->dev, "Could not allocate memory\n"); + err = -ENOMEM; + goto out; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + dev_err(&pdev->dev, "I/O address already in use\n"); + err = -ENOENT; + goto err_free; + } + + mem = request_mem_region(res->start, resource_size(res), pdev->name); + if (!mem) { + err = -EBUSY; + goto err_free; + } diff --git a/kernel-devel/module-basics/vain_plat/vain_plat_3.c b/kernel-devel/module-basics/vain_plat/vain_plat_3.c new file mode 100644 index 0000000..8ec839c --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/vain_plat_3.c @@ -0,0 +1,18 @@ + info->base = ioremap(res->start, resource_size(res)); + if (!info->base) { + dev_err(&pdev->dev, "Unable to map card MMIO\n"); + err = -ENODEV; + goto err_ioremap; + } + + platform_set_drvdata(pdev, info); + + return 0; + +err_ioremap: + release_mem_region(res->start, resource_size(res)); +err_free: + kfree(info); +out: + return err; +} diff --git a/kernel-devel/module-basics/vain_plat/vain_plat_4.c b/kernel-devel/module-basics/vain_plat/vain_plat_4.c new file mode 100644 index 0000000..93a480a --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/vain_plat_4.c @@ -0,0 +1,23 @@ +static int __devexit vain_plat_remove(struct platform_device *pdev) +{ + struct vain_plat_info *info = platform_get_drvdata(pdev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + iounmap(info->base); + release_mem_region(res->start, resource_size(res)); + platform_set_drvdata(pdev, NULL); + + kfree (info); + + return 0; +} + +static struct platform_driver vain_plat_driver = { + .driver = { + .name = "vain_plat", + .owner = THIS_MODULE, + }, + .probe = vain_plat_probe, + .remove = __devexit_p(vain_plat_remove), +}; diff --git a/kernel-devel/module-basics/vain_plat/vain_plat_5.c b/kernel-devel/module-basics/vain_plat/vain_plat_5.c new file mode 100644 index 0000000..3ba3d84 --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/vain_plat_5.c @@ -0,0 +1,24 @@ +static int __init vain_plat_init(void) +{ + int err; + + err = platform_driver_register(&vain_plat_driver); + + if (!err) + printk(KERN_INFO "vain_plat_init: done\n"); + return err; +} + +static void __exit vain_plat_exit(void) +{ + platform_driver_unregister(&vain_plat_driver); + printk(KERN_INFO "vain_plat_exit: done\n"); +} + +module_init(vain_plat_init); +module_exit(vain_plat_exit); + +MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>"); +MODULE_DESCRIPTION("a more or less useless platform module"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0815"); diff --git a/kernel-devel/module-basics/vain_plat/vain_plat_orig.c b/kernel-devel/module-basics/vain_plat/vain_plat_orig.c new file mode 100644 index 0000000..530407e --- /dev/null +++ b/kernel-devel/module-basics/vain_plat/vain_plat_orig.c @@ -0,0 +1,105 @@ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <asm/io.h> + +struct vain_plat_info { + void __iomem *base; + struct platform_device *pdev; + spinlock_t lock; +}; + +static int __devinit vain_plat_probe(struct platform_device *pdev) +{ + struct vain_plat_info *info; + struct resource *res, *mem; + int err; + + info = kzalloc(sizeof(struct vain_plat_info), GFP_KERNEL); + if (unlikely(!info)) { + dev_err(&pdev->dev, "Could not allocate memory\n"); + err = -ENOMEM; + goto out; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + dev_err(&pdev->dev, "I/O address already in use\n"); + err = -ENOENT; + goto err_free; + } + + mem = request_mem_region(res->start, resource_size(res), pdev->name); + if (!mem) { + err = -EBUSY; + goto err_free; + } + + info->base = ioremap(res->start, resource_size(res)); + if (!info->base) { + dev_err(&pdev->dev, "Unable to map card MMIO\n"); + err = -ENODEV; + goto err_ioremap; + } + + platform_set_drvdata(pdev, info); + + return 0; + +err_ioremap: + release_mem_region(res->start, resource_size(res)); +err_free: + kfree(info); +out: + return err; +} + +static int __devexit vain_plat_remove(struct platform_device *pdev) +{ + struct vain_plat_info *info = platform_get_drvdata(pdev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + iounmap(info->base); + release_mem_region(res->start, resource_size(res)); + platform_set_drvdata(pdev, NULL); + + kfree (info); + + return 0; +} + +static struct platform_driver vain_plat_driver = { + .driver = { + .name = "vain_plat", + .owner = THIS_MODULE, + }, + .probe = vain_plat_probe, + .remove = __devexit_p(vain_plat_remove), +}; + +static int __init vain_plat_init(void) +{ + int err; + + err = platform_driver_register(&vain_plat_driver); + + if (!err) + printk(KERN_INFO "vain_plat_init: done\n"); + return err; +} + +static void __exit vain_plat_exit(void) +{ + platform_driver_unregister(&vain_plat_driver); + printk(KERN_INFO "vain_plat_exit: done\n"); +} + +module_init(vain_plat_init); +module_exit(vain_plat_exit); + +MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>"); +MODULE_DESCRIPTION("a more or less useless platform module"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0815"); |
