#include <linux/stringify.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
+#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_platform.h>
}
}
+ if (uioinfo->irq) {
+ struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq);
+
+ /*
+ * If a level interrupt, dont do lazy disable. Otherwise the
+ * irq will fire again since clearing of the actual cause, on
+ * device level, is done in userspace
+ * irqd_is_level_type() isn't used since isn't valid until
+ * irq is configured.
+ */
+ if (irq_data &&
+ irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) {
+ dev_dbg(&pdev->dev, "disable lazy unmask\n");
+ irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY);
+ }
+ }
+
uiomem = &uioinfo->mem[0];
for (i = 0; i < pdev->num_resources; ++i) {
}
uiomem->memtype = UIO_MEM_PHYS;
- uiomem->addr = r->start;
- uiomem->size = resource_size(r);
+ uiomem->addr = r->start & PAGE_MASK;
+ uiomem->offs = r->start & ~PAGE_MASK;
+ uiomem->size = (uiomem->offs + resource_size(r)
+ + PAGE_SIZE - 1) & PAGE_MASK;
uiomem->name = r->name;
++uiomem;
}