Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 163511
b: refs/heads/master
c: af76756
h: refs/heads/master
i:
  163509: dd5e30f
  163507: ad420b1
  163503: a80e81e
v: v3
  • Loading branch information
Magnus Damm authored and Paul Mundt committed Aug 23, 2009
1 parent a40bef5 commit 3c9dfe3
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d1386c6b8db54ac8d94c01194e0c27cd538532b
refs/heads/master: af76756e6e8c268c684865d29b897a470de1f097
54 changes: 54 additions & 0 deletions trunk/drivers/uio/uio_pdrv_genirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,35 @@
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/stringify.h>
#include <linux/pm_runtime.h>

#define DRIVER_NAME "uio_pdrv_genirq"

struct uio_pdrv_genirq_platdata {
struct uio_info *uioinfo;
spinlock_t lock;
unsigned long flags;
struct platform_device *pdev;
};

static int uio_pdrv_genirq_open(struct uio_info *info, struct inode *inode)
{
struct uio_pdrv_genirq_platdata *priv = info->priv;

/* Wait until the Runtime PM code has woken up the device */
pm_runtime_get_sync(&priv->pdev->dev);
return 0;
}

static int uio_pdrv_genirq_release(struct uio_info *info, struct inode *inode)
{
struct uio_pdrv_genirq_platdata *priv = info->priv;

/* Tell the Runtime PM code that the device has become idle */
pm_runtime_put_sync(&priv->pdev->dev);
return 0;
}

static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info)
{
struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
Expand Down Expand Up @@ -97,6 +117,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
priv->uioinfo = uioinfo;
spin_lock_init(&priv->lock);
priv->flags = 0; /* interrupt is enabled to begin with */
priv->pdev = pdev;

uiomem = &uioinfo->mem[0];

Expand Down Expand Up @@ -136,8 +157,17 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
uioinfo->irq_flags |= IRQF_DISABLED;
uioinfo->handler = uio_pdrv_genirq_handler;
uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
uioinfo->open = uio_pdrv_genirq_open;
uioinfo->release = uio_pdrv_genirq_release;
uioinfo->priv = priv;

/* Enable Runtime PM for this device:
* The device starts in suspended state to allow the hardware to be
* turned off by default. The Runtime PM bus code should power on the
* hardware and enable clocks at open().
*/
pm_runtime_enable(&pdev->dev);

ret = uio_register_device(&pdev->dev, priv->uioinfo);
if (ret) {
dev_err(&pdev->dev, "unable to register uio device\n");
Expand All @@ -157,16 +187,40 @@ static int uio_pdrv_genirq_remove(struct platform_device *pdev)
struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev);

uio_unregister_device(priv->uioinfo);
pm_runtime_disable(&pdev->dev);
kfree(priv);
return 0;
}

static int uio_pdrv_genirq_runtime_nop(struct device *dev)
{
/* Runtime PM callback shared between ->runtime_suspend()
* and ->runtime_resume(). Simply returns success.
*
* In this driver pm_runtime_get_sync() and pm_runtime_put_sync()
* are used at open() and release() time. This allows the
* Runtime PM code to turn off power to the device while the
* device is unused, ie before open() and after release().
*
* This Runtime PM callback does not need to save or restore
* any registers since user space is responsbile for hardware
* register reinitialization after open().
*/
return 0;
}

static struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = {
.runtime_suspend = uio_pdrv_genirq_runtime_nop,
.runtime_resume = uio_pdrv_genirq_runtime_nop,
};

static struct platform_driver uio_pdrv_genirq = {
.probe = uio_pdrv_genirq_probe,
.remove = uio_pdrv_genirq_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.pm = &uio_pdrv_genirq_dev_pm_ops,
},
};

Expand Down

0 comments on commit 3c9dfe3

Please sign in to comment.