[PATCH 07/27] cbus: tahvo: git it a context structure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <balbi@xxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux