@@ -155,11 +155,6 @@ static struct platform_device tahvo_device = {
},
};
-static struct platform_device tahvo_usb_device = {
- .name = "tahvo-usb",
- .id = -1,
-};
-
static void __init nokia770_cbus_init(void)
{
int ret;
@@ -200,7 +195,6 @@ static void __init nokia770_cbus_init(void)
tahvo_resource[0].start = gpio_to_irq(40);
platform_device_register(&tahvo_device);
- platform_device_register(&tahvo_usb_device);
}
#else
@@ -251,11 +251,6 @@ static struct platform_device tahvo_device = {
},
};
-static struct platform_device tahvo_usb_device = {
- .name = "tahvo-usb",
- .id = -1,
-};
-
static void __init n8x0_cbus_init(void)
{
int ret;
@@ -297,7 +292,6 @@ static void __init n8x0_cbus_init(void)
tahvo_resource[0].start = gpio_to_irq(111);
platform_device_register(&tahvo_device);
- platform_device_register(&tahvo_usb_device);
}
#else
@@ -215,39 +215,26 @@ EXPORT_SYMBOL(tahvo_set_backlight_level);
static irqreturn_t tahvo_irq_handler(int irq, void *_tahvo)
{
- struct tahvo_irq_handler_desc *hnd;
-
struct tahvo *tahvo = _tahvo;
u16 id;
u16 im;
- int i;
-
- for (;;) {
- id = __tahvo_read_reg(tahvo, TAHVO_REG_IDR);
- im = ~__tahvo_read_reg(tahvo, TAHVO_REG_IMR);
- id &= im;
-
- if (!id)
- break;
-
- for (i = 0; id != 0; i++, id >>= 1) {
- if (!(id & 1))
- continue;
- hnd = &tahvo_irq_handlers[i];
- if (hnd->func == NULL) {
- /* Spurious tahvo interrupt - just ack it */
- dev_err(tahvo->dev, "Spurious interrupt "
- "(id %d)\n", i);
- tahvo_disable_irq(i);
- tahvo_ack_irq(i);
- continue;
- }
- hnd->func(hnd->arg);
- /*
- * Don't acknowledge the interrupt here
- * It must be done explicitly
- */
- }
+
+ id = __tahvo_read_reg(tahvo, TAHVO_REG_IDR);
+ im = __tahvo_read_reg(tahvo, TAHVO_REG_IMR);
+ id &= ~im;
+
+ if (!id) {
+ dev_vdbg(tahvo->dev, "No IRQ, spurious ?\n");
+ return IRQ_NONE;
+ }
+
+ while (id) {
+ unsigned long pending = __ffs(id);
+ unsigned int irq;
+
+ id &= ~BIT(pending);
+ irq = pending + tahvo->irq_base;
+ handle_nested_irq(irq);
}
return IRQ_HANDLED;
@@ -397,6 +384,63 @@ static void tahvo_irq_init(struct tahvo *tahvo)
/* -------------------------------------------------------------------------- */
+static struct resource generic_resources[] = {
+ {
+ .start = -EINVAL, /* fixed later */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct device *tahvo_allocate_child(const char *name,
+ struct device *parent, int irq)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ pdev = platform_device_alloc(name, -1);
+ if (!pdev) {
+ dev_dbg(parent, "can't allocate %s\n", name);
+ goto err0;
+ }
+
+ pdev->dev.parent = parent;
+
+ generic_resources[0].start = irq;
+
+ ret = platform_device_add_resources(pdev,
+ generic_resources, ARRAY_SIZE(generic_resources));
+ if (ret < 0) {
+ dev_dbg(parent, "can't add resources to %s\n", name);
+ goto err1;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret < 0) {
+ dev_dbg(parent, "can't add %s\n", name);
+ goto err1;
+ }
+
+ return &pdev->dev;
+
+err1:
+ platform_device_put(pdev);
+
+err0:
+ return NULL;
+}
+
+static int tahvo_allocate_children(struct device *parent, int irq_base)
+{
+ struct device *child;
+
+ child = tahvo_allocate_child("tahvo-usb", parent,
+ irq_base + TAHVO_INT_VBUSON);
+ if (!child)
+ return -ENOMEM;
+
+ return 0;
+}
+
static int __devinit tahvo_probe(struct platform_device *pdev)
{
struct tahvo *tahvo;
@@ -450,6 +494,12 @@ static int __devinit tahvo_probe(struct platform_device *pdev)
goto err2;
}
+ ret = tahvo_allocate_children(&pdev->dev, tahvo->irq_base);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to allocate children\n");
+ goto err2;
+ }
+
dev_err(&pdev->dev, "%s v%d.%d found\n",
tahvo->is_betty ? "Betty" : "Tahvo",
(rev >> 4) & 0x0f, rev & 0x0f);
in order to chieve that, we needed to allocate our children devices (currently only one) and fix up the irq handler. Signed-off-by: Felipe Balbi <balbi@ti.com> --- arch/arm/mach-omap1/board-nokia770.c | 6 -- arch/arm/mach-omap2/board-n8x0.c | 6 -- drivers/cbus/tahvo.c | 110 ++++++++++++++++++++++++--------- 3 files changed, 80 insertions(+), 42 deletions(-)