Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
uio_pdrv.c
Go to the documentation of this file.
1 /*
2  * drivers/uio/uio_pdrv.c
3  *
4  * Copyright (C) 2008 by Digi International Inc.
5  * All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 as published by
9  * the Free Software Foundation.
10  */
11 #include <linux/platform_device.h>
12 #include <linux/uio_driver.h>
13 #include <linux/stringify.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 
17 #define DRIVER_NAME "uio_pdrv"
18 
19 struct uio_platdata {
20  struct uio_info *uioinfo;
21 };
22 
23 static int uio_pdrv_probe(struct platform_device *pdev)
24 {
25  struct uio_info *uioinfo = pdev->dev.platform_data;
26  struct uio_platdata *pdata;
27  struct uio_mem *uiomem;
28  int ret = -ENODEV;
29  int i;
30 
31  if (!uioinfo || !uioinfo->name || !uioinfo->version) {
32  dev_dbg(&pdev->dev, "%s: err_uioinfo\n", __func__);
33  goto err_uioinfo;
34  }
35 
36  pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
37  if (!pdata) {
38  ret = -ENOMEM;
39  dev_dbg(&pdev->dev, "%s: err_alloc_pdata\n", __func__);
40  goto err_alloc_pdata;
41  }
42 
43  pdata->uioinfo = uioinfo;
44 
45  uiomem = &uioinfo->mem[0];
46 
47  for (i = 0; i < pdev->num_resources; ++i) {
48  struct resource *r = &pdev->resource[i];
49 
50  if (r->flags != IORESOURCE_MEM)
51  continue;
52 
53  if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
54  dev_warn(&pdev->dev, "device has more than "
56  " I/O memory resources.\n");
57  break;
58  }
59 
60  uiomem->memtype = UIO_MEM_PHYS;
61  uiomem->addr = r->start;
62  uiomem->size = resource_size(r);
63  ++uiomem;
64  }
65 
66  while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
67  uiomem->size = 0;
68  ++uiomem;
69  }
70 
71  pdata->uioinfo->priv = pdata;
72 
73  ret = uio_register_device(&pdev->dev, pdata->uioinfo);
74 
75  if (ret) {
76  kfree(pdata);
77 err_alloc_pdata:
78 err_uioinfo:
79  return ret;
80  }
81 
82  platform_set_drvdata(pdev, pdata);
83 
84  return 0;
85 }
86 
87 static int uio_pdrv_remove(struct platform_device *pdev)
88 {
89  struct uio_platdata *pdata = platform_get_drvdata(pdev);
90 
92 
93  kfree(pdata);
94 
95  return 0;
96 }
97 
98 static struct platform_driver uio_pdrv = {
99  .probe = uio_pdrv_probe,
100  .remove = uio_pdrv_remove,
101  .driver = {
102  .name = DRIVER_NAME,
103  .owner = THIS_MODULE,
104  },
105 };
106 
107 module_platform_driver(uio_pdrv);
108 
109 MODULE_AUTHOR("Uwe Kleine-Koenig");
110 MODULE_DESCRIPTION("Userspace I/O platform driver");
111 MODULE_LICENSE("GPL v2");
112 MODULE_ALIAS("platform:" DRIVER_NAME);