0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/platform_device.h>
0015 #include <linux/uio_driver.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/bitops.h>
0018 #include <linux/module.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/stringify.h>
0021 #include <linux/pm_runtime.h>
0022 #include <linux/slab.h>
0023 #include <linux/irq.h>
0024
0025 #include <linux/of.h>
0026 #include <linux/of_platform.h>
0027 #include <linux/of_address.h>
0028
0029 #define DRIVER_NAME "uio_pdrv_genirq"
0030
0031 struct uio_pdrv_genirq_platdata {
0032 struct uio_info *uioinfo;
0033 spinlock_t lock;
0034 unsigned long flags;
0035 struct platform_device *pdev;
0036 };
0037
0038
0039 enum {
0040 UIO_IRQ_DISABLED = 0,
0041 };
0042
0043 static int uio_pdrv_genirq_open(struct uio_info *info, struct inode *inode)
0044 {
0045 struct uio_pdrv_genirq_platdata *priv = info->priv;
0046
0047
0048 pm_runtime_get_sync(&priv->pdev->dev);
0049 return 0;
0050 }
0051
0052 static int uio_pdrv_genirq_release(struct uio_info *info, struct inode *inode)
0053 {
0054 struct uio_pdrv_genirq_platdata *priv = info->priv;
0055
0056
0057 pm_runtime_put_sync(&priv->pdev->dev);
0058 return 0;
0059 }
0060
0061 static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info)
0062 {
0063 struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
0064
0065
0066
0067
0068
0069 spin_lock(&priv->lock);
0070 if (!__test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags))
0071 disable_irq_nosync(irq);
0072 spin_unlock(&priv->lock);
0073
0074 return IRQ_HANDLED;
0075 }
0076
0077 static int uio_pdrv_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
0078 {
0079 struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
0080 unsigned long flags;
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 spin_lock_irqsave(&priv->lock, flags);
0091 if (irq_on) {
0092 if (__test_and_clear_bit(UIO_IRQ_DISABLED, &priv->flags))
0093 enable_irq(dev_info->irq);
0094 } else {
0095 if (!__test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags))
0096 disable_irq_nosync(dev_info->irq);
0097 }
0098 spin_unlock_irqrestore(&priv->lock, flags);
0099
0100 return 0;
0101 }
0102
0103 static void uio_pdrv_genirq_cleanup(void *data)
0104 {
0105 struct device *dev = data;
0106
0107 pm_runtime_disable(dev);
0108 }
0109
0110 static int uio_pdrv_genirq_probe(struct platform_device *pdev)
0111 {
0112 struct uio_info *uioinfo = dev_get_platdata(&pdev->dev);
0113 struct device_node *node = pdev->dev.of_node;
0114 struct uio_pdrv_genirq_platdata *priv;
0115 struct uio_mem *uiomem;
0116 int ret = -EINVAL;
0117 int i;
0118
0119 if (node) {
0120 const char *name;
0121
0122
0123 uioinfo = devm_kzalloc(&pdev->dev, sizeof(*uioinfo),
0124 GFP_KERNEL);
0125 if (!uioinfo) {
0126 dev_err(&pdev->dev, "unable to kmalloc\n");
0127 return -ENOMEM;
0128 }
0129
0130 if (!of_property_read_string(node, "linux,uio-name", &name))
0131 uioinfo->name = devm_kstrdup(&pdev->dev, name, GFP_KERNEL);
0132 else
0133 uioinfo->name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
0134 "%pOFn", node);
0135
0136 uioinfo->version = "devicetree";
0137
0138 }
0139
0140 if (!uioinfo || !uioinfo->name || !uioinfo->version) {
0141 dev_err(&pdev->dev, "missing platform_data\n");
0142 return ret;
0143 }
0144
0145 if (uioinfo->handler || uioinfo->irqcontrol ||
0146 uioinfo->irq_flags & IRQF_SHARED) {
0147 dev_err(&pdev->dev, "interrupt configuration error\n");
0148 return ret;
0149 }
0150
0151 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0152 if (!priv) {
0153 dev_err(&pdev->dev, "unable to kmalloc\n");
0154 return -ENOMEM;
0155 }
0156
0157 priv->uioinfo = uioinfo;
0158 spin_lock_init(&priv->lock);
0159 priv->flags = 0;
0160 priv->pdev = pdev;
0161
0162 if (!uioinfo->irq) {
0163 ret = platform_get_irq_optional(pdev, 0);
0164 uioinfo->irq = ret;
0165 if (ret == -ENXIO)
0166 uioinfo->irq = UIO_IRQ_NONE;
0167 else if (ret == -EPROBE_DEFER)
0168 return ret;
0169 else if (ret < 0) {
0170 dev_err(&pdev->dev, "failed to get IRQ\n");
0171 return ret;
0172 }
0173 }
0174
0175 if (uioinfo->irq) {
0176 struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq);
0177
0178
0179
0180
0181
0182
0183
0184
0185 if (irq_data &&
0186 irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) {
0187 dev_dbg(&pdev->dev, "disable lazy unmask\n");
0188 irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY);
0189 }
0190 }
0191
0192 uiomem = &uioinfo->mem[0];
0193
0194 for (i = 0; i < pdev->num_resources; ++i) {
0195 struct resource *r = &pdev->resource[i];
0196
0197 if (r->flags != IORESOURCE_MEM)
0198 continue;
0199
0200 if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
0201 dev_warn(&pdev->dev, "device has more than "
0202 __stringify(MAX_UIO_MAPS)
0203 " I/O memory resources.\n");
0204 break;
0205 }
0206
0207 uiomem->memtype = UIO_MEM_PHYS;
0208 uiomem->addr = r->start & PAGE_MASK;
0209 uiomem->offs = r->start & ~PAGE_MASK;
0210 uiomem->size = (uiomem->offs + resource_size(r)
0211 + PAGE_SIZE - 1) & PAGE_MASK;
0212 uiomem->name = r->name;
0213 ++uiomem;
0214 }
0215
0216 while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
0217 uiomem->size = 0;
0218 ++uiomem;
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 uioinfo->handler = uio_pdrv_genirq_handler;
0231 uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
0232 uioinfo->open = uio_pdrv_genirq_open;
0233 uioinfo->release = uio_pdrv_genirq_release;
0234 uioinfo->priv = priv;
0235
0236
0237
0238
0239
0240
0241 pm_runtime_enable(&pdev->dev);
0242
0243 ret = devm_add_action_or_reset(&pdev->dev, uio_pdrv_genirq_cleanup,
0244 &pdev->dev);
0245 if (ret)
0246 return ret;
0247
0248 ret = devm_uio_register_device(&pdev->dev, priv->uioinfo);
0249 if (ret)
0250 dev_err(&pdev->dev, "unable to register uio device\n");
0251
0252 return ret;
0253 }
0254
0255 static int uio_pdrv_genirq_runtime_nop(struct device *dev)
0256 {
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 return 0;
0270 }
0271
0272 static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = {
0273 .runtime_suspend = uio_pdrv_genirq_runtime_nop,
0274 .runtime_resume = uio_pdrv_genirq_runtime_nop,
0275 };
0276
0277 #ifdef CONFIG_OF
0278 static struct of_device_id uio_of_genirq_match[] = {
0279 { },
0280 { },
0281 };
0282 MODULE_DEVICE_TABLE(of, uio_of_genirq_match);
0283 module_param_string(of_id, uio_of_genirq_match[0].compatible, 128, 0);
0284 MODULE_PARM_DESC(of_id, "Openfirmware id of the device to be handled by uio");
0285 #endif
0286
0287 static struct platform_driver uio_pdrv_genirq = {
0288 .probe = uio_pdrv_genirq_probe,
0289 .driver = {
0290 .name = DRIVER_NAME,
0291 .pm = &uio_pdrv_genirq_dev_pm_ops,
0292 .of_match_table = of_match_ptr(uio_of_genirq_match),
0293 },
0294 };
0295
0296 module_platform_driver(uio_pdrv_genirq);
0297
0298 MODULE_AUTHOR("Magnus Damm");
0299 MODULE_DESCRIPTION("Userspace I/O platform driver with generic IRQ handling");
0300 MODULE_LICENSE("GPL v2");
0301 MODULE_ALIAS("platform:" DRIVER_NAME);