diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-18 12:43:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-18 12:43:09 -0400 |
commit | 515b696b282f856c3ad1679ccd658120faa387d0 (patch) | |
tree | d9d7c1185c396617f128ca23463062308d11393b /drivers/uio | |
parent | fa877c71e2136bd682b45022c96d5e073ced9f58 (diff) | |
parent | 064a16dc41be879d12bd5de5d2f9d38d890e0ee7 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (262 commits)
sh: mach-ecovec24: Add user debug switch support
sh: Kill off unused se_skipped in alignment trap notification code.
sh: Wire up HAVE_SYSCALL_TRACEPOINTS.
video: sh_mobile_lcdcfb: use both register sets for display panning
video: sh_mobile_lcdcfb: implement display panning
sh: Fix up sh7705 flush_dcache_page() build.
sh: kfr2r09: document the PLL/FLL <-> RF relationship.
sh: mach-ecovec24: need asm/clock.h.
sh: mach-ecovec24: deassert usb irq on boot.
sh: Add KEYSC support for EcoVec24
sh: add kycr2_delay for sh_keysc
sh: cpufreq: Include CPU id in info messages.
sh: multi-evt support for SH-X3 proto CPU.
sh: clkfwk: remove bogus set_bus_parent() from SH7709.
sh: Fix the indication point of the liquid crystal of AP-325RXA(AP3300)
sh: Add EcoVec24 romImage defconfig
sh: USB disable process is needed if romImage boot for EcoVec24
sh: EcoVec24: add HIZA setting for LED
sh: EcoVec24: write MAC address in boot
sh: Add romImage support for EcoVec24
...
Diffstat (limited to 'drivers/uio')
-rw-r--r-- | drivers/uio/uio_pdrv_genirq.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index 3f06818cf9f..02347c57357 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/stringify.h> | 22 | #include <linux/stringify.h> |
23 | #include <linux/pm_runtime.h> | ||
23 | 24 | ||
24 | #define DRIVER_NAME "uio_pdrv_genirq" | 25 | #define DRIVER_NAME "uio_pdrv_genirq" |
25 | 26 | ||
@@ -27,8 +28,27 @@ struct uio_pdrv_genirq_platdata { | |||
27 | struct uio_info *uioinfo; | 28 | struct uio_info *uioinfo; |
28 | spinlock_t lock; | 29 | spinlock_t lock; |
29 | unsigned long flags; | 30 | unsigned long flags; |
31 | struct platform_device *pdev; | ||
30 | }; | 32 | }; |
31 | 33 | ||
34 | static int uio_pdrv_genirq_open(struct uio_info *info, struct inode *inode) | ||
35 | { | ||
36 | struct uio_pdrv_genirq_platdata *priv = info->priv; | ||
37 | |||
38 | /* Wait until the Runtime PM code has woken up the device */ | ||
39 | pm_runtime_get_sync(&priv->pdev->dev); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int uio_pdrv_genirq_release(struct uio_info *info, struct inode *inode) | ||
44 | { | ||
45 | struct uio_pdrv_genirq_platdata *priv = info->priv; | ||
46 | |||
47 | /* Tell the Runtime PM code that the device has become idle */ | ||
48 | pm_runtime_put_sync(&priv->pdev->dev); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
32 | static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info) | 52 | static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info) |
33 | { | 53 | { |
34 | struct uio_pdrv_genirq_platdata *priv = dev_info->priv; | 54 | struct uio_pdrv_genirq_platdata *priv = dev_info->priv; |
@@ -97,6 +117,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) | |||
97 | priv->uioinfo = uioinfo; | 117 | priv->uioinfo = uioinfo; |
98 | spin_lock_init(&priv->lock); | 118 | spin_lock_init(&priv->lock); |
99 | priv->flags = 0; /* interrupt is enabled to begin with */ | 119 | priv->flags = 0; /* interrupt is enabled to begin with */ |
120 | priv->pdev = pdev; | ||
100 | 121 | ||
101 | uiomem = &uioinfo->mem[0]; | 122 | uiomem = &uioinfo->mem[0]; |
102 | 123 | ||
@@ -136,8 +157,17 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) | |||
136 | uioinfo->irq_flags |= IRQF_DISABLED; | 157 | uioinfo->irq_flags |= IRQF_DISABLED; |
137 | uioinfo->handler = uio_pdrv_genirq_handler; | 158 | uioinfo->handler = uio_pdrv_genirq_handler; |
138 | uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol; | 159 | uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol; |
160 | uioinfo->open = uio_pdrv_genirq_open; | ||
161 | uioinfo->release = uio_pdrv_genirq_release; | ||
139 | uioinfo->priv = priv; | 162 | uioinfo->priv = priv; |
140 | 163 | ||
164 | /* Enable Runtime PM for this device: | ||
165 | * The device starts in suspended state to allow the hardware to be | ||
166 | * turned off by default. The Runtime PM bus code should power on the | ||
167 | * hardware and enable clocks at open(). | ||
168 | */ | ||
169 | pm_runtime_enable(&pdev->dev); | ||
170 | |||
141 | ret = uio_register_device(&pdev->dev, priv->uioinfo); | 171 | ret = uio_register_device(&pdev->dev, priv->uioinfo); |
142 | if (ret) { | 172 | if (ret) { |
143 | dev_err(&pdev->dev, "unable to register uio device\n"); | 173 | dev_err(&pdev->dev, "unable to register uio device\n"); |
@@ -157,16 +187,40 @@ static int uio_pdrv_genirq_remove(struct platform_device *pdev) | |||
157 | struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev); | 187 | struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev); |
158 | 188 | ||
159 | uio_unregister_device(priv->uioinfo); | 189 | uio_unregister_device(priv->uioinfo); |
190 | pm_runtime_disable(&pdev->dev); | ||
160 | kfree(priv); | 191 | kfree(priv); |
161 | return 0; | 192 | return 0; |
162 | } | 193 | } |
163 | 194 | ||
195 | static int uio_pdrv_genirq_runtime_nop(struct device *dev) | ||
196 | { | ||
197 | /* Runtime PM callback shared between ->runtime_suspend() | ||
198 | * and ->runtime_resume(). Simply returns success. | ||
199 | * | ||
200 | * In this driver pm_runtime_get_sync() and pm_runtime_put_sync() | ||
201 | * are used at open() and release() time. This allows the | ||
202 | * Runtime PM code to turn off power to the device while the | ||
203 | * device is unused, ie before open() and after release(). | ||
204 | * | ||
205 | * This Runtime PM callback does not need to save or restore | ||
206 | * any registers since user space is responsbile for hardware | ||
207 | * register reinitialization after open(). | ||
208 | */ | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = { | ||
213 | .runtime_suspend = uio_pdrv_genirq_runtime_nop, | ||
214 | .runtime_resume = uio_pdrv_genirq_runtime_nop, | ||
215 | }; | ||
216 | |||
164 | static struct platform_driver uio_pdrv_genirq = { | 217 | static struct platform_driver uio_pdrv_genirq = { |
165 | .probe = uio_pdrv_genirq_probe, | 218 | .probe = uio_pdrv_genirq_probe, |
166 | .remove = uio_pdrv_genirq_remove, | 219 | .remove = uio_pdrv_genirq_remove, |
167 | .driver = { | 220 | .driver = { |
168 | .name = DRIVER_NAME, | 221 | .name = DRIVER_NAME, |
169 | .owner = THIS_MODULE, | 222 | .owner = THIS_MODULE, |
223 | .pm = &uio_pdrv_genirq_dev_pm_ops, | ||
170 | }, | 224 | }, |
171 | }; | 225 | }; |
172 | 226 | ||