hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/uio/uio_pdrv_genirq.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * drivers/uio/uio_pdrv_genirq.c
34 *
....@@ -8,10 +9,6 @@
89 * Based on uio_pdrv.c by Uwe Kleine-Koenig,
910 * Copyright (C) 2008 by Digi International Inc.
1011 * All rights reserved.
11
- *
12
- * This program is free software; you can redistribute it and/or modify it
13
- * under the terms of the GNU General Public License version 2 as published by
14
- * the Free Software Foundation.
1512 */
1613
1714 #include <linux/platform_device.h>
....@@ -23,6 +20,7 @@
2320 #include <linux/stringify.h>
2421 #include <linux/pm_runtime.h>
2522 #include <linux/slab.h>
23
+#include <linux/irq.h>
2624
2725 #include <linux/of.h>
2826 #include <linux/of_platform.h>
....@@ -102,15 +100,25 @@
102100 return 0;
103101 }
104102
103
+static void uio_pdrv_genirq_cleanup(void *data)
104
+{
105
+ struct device *dev = data;
106
+
107
+ pm_runtime_disable(dev);
108
+}
109
+
105110 static int uio_pdrv_genirq_probe(struct platform_device *pdev)
106111 {
107112 struct uio_info *uioinfo = dev_get_platdata(&pdev->dev);
113
+ struct device_node *node = pdev->dev.of_node;
108114 struct uio_pdrv_genirq_platdata *priv;
109115 struct uio_mem *uiomem;
110116 int ret = -EINVAL;
111117 int i;
112118
113
- if (pdev->dev.of_node) {
119
+ if (node) {
120
+ const char *name;
121
+
114122 /* alloc uioinfo for one device */
115123 uioinfo = devm_kzalloc(&pdev->dev, sizeof(*uioinfo),
116124 GFP_KERNEL);
....@@ -118,7 +126,13 @@
118126 dev_err(&pdev->dev, "unable to kmalloc\n");
119127 return -ENOMEM;
120128 }
121
- uioinfo->name = pdev->dev.of_node->name;
129
+
130
+ if (!of_property_read_string(node, "linux,uio-name", &name))
131
+ uioinfo->name = devm_kstrdup(&pdev->dev, name, GFP_KERNEL);
132
+ else
133
+ uioinfo->name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
134
+ "%pOFn", node);
135
+
122136 uioinfo->version = "devicetree";
123137 /* Multiple IRQs are not supported */
124138 }
....@@ -146,13 +160,32 @@
146160 priv->pdev = pdev;
147161
148162 if (!uioinfo->irq) {
149
- ret = platform_get_irq(pdev, 0);
163
+ ret = platform_get_irq_optional(pdev, 0);
150164 uioinfo->irq = ret;
151165 if (ret == -ENXIO)
152166 uioinfo->irq = UIO_IRQ_NONE;
167
+ else if (ret == -EPROBE_DEFER)
168
+ return ret;
153169 else if (ret < 0) {
154170 dev_err(&pdev->dev, "failed to get IRQ\n");
155171 return ret;
172
+ }
173
+ }
174
+
175
+ if (uioinfo->irq) {
176
+ struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq);
177
+
178
+ /*
179
+ * If a level interrupt, dont do lazy disable. Otherwise the
180
+ * irq will fire again since clearing of the actual cause, on
181
+ * device level, is done in userspace
182
+ * irqd_is_level_type() isn't used since isn't valid until
183
+ * irq is configured.
184
+ */
185
+ if (irq_data &&
186
+ irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) {
187
+ dev_dbg(&pdev->dev, "disable lazy unmask\n");
188
+ irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY);
156189 }
157190 }
158191
....@@ -172,8 +205,10 @@
172205 }
173206
174207 uiomem->memtype = UIO_MEM_PHYS;
175
- uiomem->addr = r->start;
176
- uiomem->size = resource_size(r);
208
+ uiomem->addr = r->start & PAGE_MASK;
209
+ uiomem->offs = r->start & ~PAGE_MASK;
210
+ uiomem->size = (uiomem->offs + resource_size(r)
211
+ + PAGE_SIZE - 1) & PAGE_MASK;
177212 uiomem->name = r->name;
178213 ++uiomem;
179214 }
....@@ -205,28 +240,16 @@
205240 */
206241 pm_runtime_enable(&pdev->dev);
207242
208
- ret = uio_register_device(&pdev->dev, priv->uioinfo);
209
- if (ret) {
210
- dev_err(&pdev->dev, "unable to register uio device\n");
211
- pm_runtime_disable(&pdev->dev);
243
+ ret = devm_add_action_or_reset(&pdev->dev, uio_pdrv_genirq_cleanup,
244
+ &pdev->dev);
245
+ if (ret)
212246 return ret;
213
- }
214247
215
- platform_set_drvdata(pdev, priv);
216
- return 0;
217
-}
248
+ ret = devm_uio_register_device(&pdev->dev, priv->uioinfo);
249
+ if (ret)
250
+ dev_err(&pdev->dev, "unable to register uio device\n");
218251
219
-static int uio_pdrv_genirq_remove(struct platform_device *pdev)
220
-{
221
- struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev);
222
-
223
- uio_unregister_device(priv->uioinfo);
224
- pm_runtime_disable(&pdev->dev);
225
-
226
- priv->uioinfo->handler = NULL;
227
- priv->uioinfo->irqcontrol = NULL;
228
-
229
- return 0;
252
+ return ret;
230253 }
231254
232255 static int uio_pdrv_genirq_runtime_nop(struct device *dev)
....@@ -263,7 +286,6 @@
263286
264287 static struct platform_driver uio_pdrv_genirq = {
265288 .probe = uio_pdrv_genirq_probe,
266
- .remove = uio_pdrv_genirq_remove,
267289 .driver = {
268290 .name = DRIVER_NAME,
269291 .pm = &uio_pdrv_genirq_dev_pm_ops,