Commit 27760f868663310ff9e701f47aec33da3b906f34
Committed by
Greg Kroah-Hartman
1 parent
1e4de81653
Exists in
master
and in
6 other branches
uio: uio_pdrv_genirq: Add OF support
Adding OF binding to genirq. Version string is setup to the "devicetree". Compatible string is not setup for now but you can add your custom compatible string to uio_of_genirq_match structure. For example with "vendor,device" compatible string: static const struct of_device_id __devinitconst uio_of_genirq_match[] = { { .compatible = "vendor,device", }, { /* empty for now */ }, }; Signed-off-by: Michal Simek <monstr@monstr.eu> Signed-off-by: Hans J. Koch <hjk@hansjkoch.de> Reviewed-by: Wolfram Sang <w.sang@pengutronix.de> CC: Hans J. Koch <hjk@hansjkoch.de> CC: Arnd Bergmann <arnd@arndb.de> CC: John Williams <john.williams@petalogix.com> CC: Grant Likely <grant.likely@secretlab.ca> CC: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 1 changed file with 43 additions and 0 deletions Side-by-side Diff
drivers/uio/uio_pdrv_genirq.c
... | ... | @@ -23,6 +23,10 @@ |
23 | 23 | #include <linux/pm_runtime.h> |
24 | 24 | #include <linux/slab.h> |
25 | 25 | |
26 | +#include <linux/of.h> | |
27 | +#include <linux/of_platform.h> | |
28 | +#include <linux/of_address.h> | |
29 | + | |
26 | 30 | #define DRIVER_NAME "uio_pdrv_genirq" |
27 | 31 | |
28 | 32 | struct uio_pdrv_genirq_platdata { |
... | ... | @@ -97,6 +101,27 @@ |
97 | 101 | int ret = -EINVAL; |
98 | 102 | int i; |
99 | 103 | |
104 | + if (!uioinfo) { | |
105 | + int irq; | |
106 | + | |
107 | + /* alloc uioinfo for one device */ | |
108 | + uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL); | |
109 | + if (!uioinfo) { | |
110 | + ret = -ENOMEM; | |
111 | + dev_err(&pdev->dev, "unable to kmalloc\n"); | |
112 | + goto bad2; | |
113 | + } | |
114 | + uioinfo->name = pdev->dev.of_node->name; | |
115 | + uioinfo->version = "devicetree"; | |
116 | + | |
117 | + /* Multiple IRQs are not supported */ | |
118 | + irq = platform_get_irq(pdev, 0); | |
119 | + if (irq == -ENXIO) | |
120 | + uioinfo->irq = UIO_IRQ_NONE; | |
121 | + else | |
122 | + uioinfo->irq = irq; | |
123 | + } | |
124 | + | |
100 | 125 | if (!uioinfo || !uioinfo->name || !uioinfo->version) { |
101 | 126 | dev_err(&pdev->dev, "missing platform_data\n"); |
102 | 127 | goto bad0; |
... | ... | @@ -180,6 +205,10 @@ |
180 | 205 | kfree(priv); |
181 | 206 | pm_runtime_disable(&pdev->dev); |
182 | 207 | bad0: |
208 | + /* kfree uioinfo for OF */ | |
209 | + if (pdev->dev.of_node) | |
210 | + kfree(uioinfo); | |
211 | + bad2: | |
183 | 212 | return ret; |
184 | 213 | } |
185 | 214 | |
... | ... | @@ -193,6 +222,10 @@ |
193 | 222 | priv->uioinfo->handler = NULL; |
194 | 223 | priv->uioinfo->irqcontrol = NULL; |
195 | 224 | |
225 | + /* kfree uioinfo for OF */ | |
226 | + if (pdev->dev.of_node) | |
227 | + kfree(priv->uioinfo); | |
228 | + | |
196 | 229 | kfree(priv); |
197 | 230 | return 0; |
198 | 231 | } |
... | ... | @@ -219,6 +252,15 @@ |
219 | 252 | .runtime_resume = uio_pdrv_genirq_runtime_nop, |
220 | 253 | }; |
221 | 254 | |
255 | +#ifdef CONFIG_OF | |
256 | +static const struct of_device_id __devinitconst uio_of_genirq_match[] = { | |
257 | + { /* empty for now */ }, | |
258 | +}; | |
259 | +MODULE_DEVICE_TABLE(of, uio_of_genirq_match); | |
260 | +#else | |
261 | +# define uio_of_genirq_match NULL | |
262 | +#endif | |
263 | + | |
222 | 264 | static struct platform_driver uio_pdrv_genirq = { |
223 | 265 | .probe = uio_pdrv_genirq_probe, |
224 | 266 | .remove = uio_pdrv_genirq_remove, |
... | ... | @@ -226,6 +268,7 @@ |
226 | 268 | .name = DRIVER_NAME, |
227 | 269 | .owner = THIS_MODULE, |
228 | 270 | .pm = &uio_pdrv_genirq_dev_pm_ops, |
271 | + .of_match_table = uio_of_genirq_match, | |
229 | 272 | }, |
230 | 273 | }; |
231 | 274 |