just moving things around. It's a lot easier
to handle a dynamically allocated structure
as it allows for multiple instances of the
same device.

Signed-off-by: Felipe Balbi <[email protected]>
---
 drivers/cbus/tahvo.c |  128 ++++++++++++++++++++++++++++++++------------------
 1 files changed, 82 insertions(+), 46 deletions(-)

diff --git a/drivers/cbus/tahvo.c b/drivers/cbus/tahvo.c
index 4b062de..3a77d12 100644
--- a/drivers/cbus/tahvo.c
+++ b/drivers/cbus/tahvo.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/device.h>
@@ -40,12 +41,16 @@
 #define TAHVO_ID               0x02
 #define PFX                    "tahvo: "
 
-static int tahvo_initialized;
-static int tahvo_is_betty;
+struct tahvo {
+       /* device lock */
+       struct mutex    mutex;
+       struct device   *dev;
 
-static struct mutex tahvo_lock;
+       unsigned int    is_betty;
+       unsigned int    wide_backlight;
+};
 
-static struct device *the_dev;
+static struct tahvo *the_tahvo;
 
 struct tahvo_irq_handler_desc {
        int (*func)(unsigned long);
@@ -57,7 +62,7 @@ static struct tahvo_irq_handler_desc 
tahvo_irq_handlers[MAX_TAHVO_IRQ_HANDLERS];
 
 int tahvo_get_status(void)
 {
-       return tahvo_initialized;
+       return the_tahvo != NULL;
 }
 EXPORT_SYMBOL(tahvo_get_status);
 
@@ -69,8 +74,9 @@ EXPORT_SYMBOL(tahvo_get_status);
  */
 int tahvo_read_reg(unsigned reg)
 {
-       BUG_ON(!tahvo_initialized);
-       return cbus_read_reg(the_dev, TAHVO_ID, reg);
+       struct tahvo            *tahvo = the_tahvo;
+
+       return cbus_read_reg(tahvo->dev, TAHVO_ID, reg);
 }
 EXPORT_SYMBOL(tahvo_read_reg);
 
@@ -83,8 +89,9 @@ EXPORT_SYMBOL(tahvo_read_reg);
  */
 void tahvo_write_reg(unsigned reg, u16 val)
 {
-       BUG_ON(!tahvo_initialized);
-       cbus_write_reg(the_dev, TAHVO_ID, reg, val);
+       struct tahvo            *tahvo = the_tahvo;
+
+       cbus_write_reg(tahvo->dev, TAHVO_ID, reg, val);
 }
 EXPORT_SYMBOL(tahvo_write_reg);
 
@@ -97,37 +104,40 @@ EXPORT_SYMBOL(tahvo_write_reg);
  */
 void tahvo_set_clear_reg_bits(unsigned reg, u16 set, u16 clear)
 {
-       u16 w;
+       struct tahvo            *tahvo = the_tahvo;
+       u16                     w;
 
-       mutex_lock(&tahvo_lock);
+       mutex_lock(&tahvo->mutex);
        w = tahvo_read_reg(reg);
        w &= ~clear;
        w |= set;
        tahvo_write_reg(reg, w);
-       mutex_unlock(&tahvo_lock);
+       mutex_unlock(&tahvo->mutex);
 }
 
 void tahvo_disable_irq(int id)
 {
-       u16 mask;
+       struct tahvo            *tahvo = the_tahvo;
+       u16                     mask;
 
-       mutex_lock(&tahvo_lock);
+       mutex_lock(&tahvo->mutex);
        mask = tahvo_read_reg(TAHVO_REG_IMR);
        mask |= 1 << id;
        tahvo_write_reg(TAHVO_REG_IMR, mask);
-       mutex_unlock(&tahvo_lock);
+       mutex_unlock(&tahvo->mutex);
 }
 EXPORT_SYMBOL(tahvo_disable_irq);
 
 void tahvo_enable_irq(int id)
 {
-       u16 mask;
+       struct tahvo            *tahvo = the_tahvo;
+       u16                     mask;
 
-       mutex_lock(&tahvo_lock);
+       mutex_lock(&tahvo->mutex);
        mask = tahvo_read_reg(TAHVO_REG_IMR);
        mask &= ~(1 << id);
        tahvo_write_reg(TAHVO_REG_IMR, mask);
-       mutex_unlock(&tahvo_lock);
+       mutex_unlock(&tahvo->mutex);
 }
 EXPORT_SYMBOL(tahvo_enable_irq);
 
@@ -137,13 +147,12 @@ void tahvo_ack_irq(int id)
 }
 EXPORT_SYMBOL(tahvo_ack_irq);
 
-static int tahvo_7bit_backlight;
-
 int tahvo_get_backlight_level(void)
 {
-       int mask;
+       struct tahvo            *tahvo = the_tahvo;
+       int                     mask;
 
-       if (tahvo_7bit_backlight)
+       if (tahvo->wide_backlight)
                mask = 0x7f;
        else
                mask = 0x0f;
@@ -153,7 +162,9 @@ EXPORT_SYMBOL(tahvo_get_backlight_level);
 
 int tahvo_get_max_backlight_level(void)
 {
-       if (tahvo_7bit_backlight)
+       struct tahvo            *tahvo = the_tahvo;
+
+       if (tahvo->wide_backlight)
                return 0x7f;
        else
                return 0x0f;
@@ -162,7 +173,7 @@ EXPORT_SYMBOL(tahvo_get_max_backlight_level);
 
 void tahvo_set_backlight_level(int level)
 {
-       int max_level;
+       int                     max_level;
 
        max_level = tahvo_get_max_backlight_level();
        if (level > max_level)
@@ -174,9 +185,11 @@ EXPORT_SYMBOL(tahvo_set_backlight_level);
 static irqreturn_t tahvo_irq_handler(int irq, void *dev_id)
 {
        struct tahvo_irq_handler_desc *hnd;
-       u16 id;
-       u16 im;
-       int i;
+
+       struct tahvo            *tahvo = the_tahvo;
+       u16                     id;
+       u16                     im;
+       int                     i;
 
        for (;;) {
                id = tahvo_read_reg(TAHVO_REG_IDR);
@@ -192,7 +205,7 @@ static irqreturn_t tahvo_irq_handler(int irq, void *dev_id)
                        hnd = &tahvo_irq_handlers[i];
                        if (hnd->func == NULL) {
                                /* Spurious tahvo interrupt - just ack it */
-                               printk(KERN_INFO "Spurious Tahvo interrupt "
+                               dev_err(tahvo->dev, "Spurious interrupt "
                                                 "(id %d)\n", i);
                                tahvo_disable_irq(i);
                                tahvo_ack_irq(i);
@@ -215,19 +228,20 @@ static irqreturn_t tahvo_irq_handler(int irq, void 
*dev_id)
 int tahvo_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
 {
        struct tahvo_irq_handler_desc *hnd;
+       struct tahvo            *tahvo = the_tahvo;
 
        if (irq_handler == NULL || id >= MAX_TAHVO_IRQ_HANDLERS ||
            name == NULL) {
-               printk(KERN_ERR PFX "Invalid arguments to %s\n",
+               dev_err(tahvo->dev, "Invalid arguments to %s\n",
                       __FUNCTION__);
                return -EINVAL;
        }
        hnd = &tahvo_irq_handlers[id];
        if (hnd->func != NULL) {
-               printk(KERN_ERR PFX "IRQ %d already reserved\n", id);
+               dev_err(tahvo->dev, "IRQ %d already reserved\n", id);
                return -EBUSY;
        }
-       printk(KERN_INFO PFX "Registering interrupt %d for device %s\n",
+       dev_dbg(tahvo->dev, "Registering interrupt %d for device %s\n",
               id, name);
        hnd->func = irq_handler;
        hnd->arg = arg;
@@ -246,15 +260,16 @@ EXPORT_SYMBOL(tahvo_request_irq);
 void tahvo_free_irq(int id)
 {
        struct tahvo_irq_handler_desc *hnd;
+       struct tahvo            *tahvo = the_tahvo;
 
        if (id >= MAX_TAHVO_IRQ_HANDLERS) {
-               printk(KERN_ERR PFX "Invalid argument to %s\n",
+               dev_err(tahvo->dev, "Invalid argument to %s\n",
                       __FUNCTION__);
                return;
        }
        hnd = &tahvo_irq_handlers[id];
        if (hnd->func == NULL) {
-               printk(KERN_ERR PFX "IRQ %d already freed\n", id);
+               dev_err(tahvo->dev, "IRQ %d already freed\n", id);
                return;
        }
 
@@ -265,13 +280,24 @@ EXPORT_SYMBOL(tahvo_free_irq);
 
 static int __devinit tahvo_probe(struct platform_device *pdev)
 {
-       int rev, id, ret;
-       int irq;
+       struct tahvo            *tahvo;
+       int                     rev;
+       int                     ret;
+       int                     irq;
+       int                     id;
+
+       tahvo = kzalloc(sizeof(*tahvo), GFP_KERNEL);
+       if (!tahvo) {
+               dev_err(&pdev->dev, "not enough memory\n");
+               ret = -ENOMEM;
+               goto err0;
+       }
 
-       mutex_init(&tahvo_lock);
-       the_dev = &pdev->dev;
+       the_tahvo = tahvo;
+       platform_set_drvdata(pdev, tahvo);
 
-       tahvo_initialized = 1;
+       mutex_init(&tahvo->mutex);
+       tahvo->dev = &pdev->dev;
 
        rev = tahvo_read_reg(TAHVO_REG_ASICR);
 
@@ -280,19 +306,20 @@ static int __devinit tahvo_probe(struct platform_device 
*pdev)
        switch (id) {
        case 0x03:
                if ((rev & 0xff) >= 0x50)
-                       tahvo_7bit_backlight = 1;
+                       tahvo->wide_backlight = true;
                break;
        case 0x0b:
-               tahvo_is_betty = 1;
-               tahvo_7bit_backlight = 1;
+               tahvo->is_betty = true;
+               tahvo->wide_backlight = true;
                break;
        default:
                dev_err(&pdev->dev, "Tahvo/Betty chip not found");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto err1;
        }
 
        dev_err(&pdev->dev, "%s v%d.%d found\n",
-                       tahvo_is_betty ? "Betty" : "Tahvo",
+                       tahvo->is_betty ? "Betty" : "Tahvo",
                        (rev >> 4) & 0x0f, rev & 0x0f);
 
        irq = platform_get_irq(pdev, 0);
@@ -305,21 +332,30 @@ static int __devinit tahvo_probe(struct platform_device 
*pdev)
                        "tahvo", 0);
        if (ret < 0) {
                dev_err(&pdev->dev, "Unable to register IRQ handler\n");
-               return ret;
+               goto err1;
        }
+
        return 0;
+
+err1:
+       kfree(tahvo);
+
+err0:
+       return ret;
 }
 
 static int __devexit tahvo_remove(struct platform_device *pdev)
 {
-       int irq;
+       struct tahvo            *tahvo = platform_get_drvdata(pdev);
+       int                     irq;
 
        irq = platform_get_irq(pdev, 0);
 
        /* Mask all TAHVO interrupts */
        tahvo_write_reg(TAHVO_REG_IMR, 0xffff);
        free_irq(irq, 0);
-       the_dev = NULL;
+       kfree(tahvo);
+       the_tahvo = NULL;
 
        return 0;
 }
-- 
1.7.6.396.ge0613

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to