From: Felipe Balbi <balbi@ti.com>
To: Tony Lindgren <tony@atomide.com>
Cc: Linux OMAP Mailing List <linux-omap@vger.kernel.org>,
Felipe Balbi <balbi@ti.com>
Subject: [RFT/PATCH 01/10] cbus: retu: give it a context structure
Date: Mon, 3 Jan 2011 09:49:39 +0200 [thread overview]
Message-ID: <1294040988-21191-2-git-send-email-balbi@ti.com> (raw)
In-Reply-To: <1294040988-21191-1-git-send-email-balbi@ti.com>
This is pretty much a cleanup patch just
adding a context structure for Retu, to avoid
all the globals it had.
Note that this breaks retu-user.c due to moving
the lock around, but that retu-user.c has to
go anyway as it's completely non-standard way
of accessing Retu children.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/retu.c | 126 ++++++++++++++++++++++++++++++++++-----------------
drivers/cbus/retu.h | 2 -
2 files changed, 85 insertions(+), 43 deletions(-)
diff --git a/drivers/cbus/retu.c b/drivers/cbus/retu.c
index a2977c9..6e130bf 100644
--- a/drivers/cbus/retu.c
+++ b/drivers/cbus/retu.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>
@@ -49,11 +50,18 @@
#define RETU_ID 0x01
#define PFX "retu: "
-static int retu_initialized;
-static int retu_is_vilma;
+struct retu {
+ /* Device lock */
+ spinlock_t lock;
+ struct tasklet_struct tasklet;
+ struct device *dev;
-static struct tasklet_struct retu_tasklet;
-spinlock_t retu_lock = SPIN_LOCK_UNLOCKED;
+ int irq;
+
+ bool is_vilma;
+};
+
+static struct retu *the_retu;
struct retu_irq_handler_desc {
int (*func)(unsigned long);
@@ -65,7 +73,7 @@ static struct retu_irq_handler_desc retu_irq_handlers[MAX_RETU_IRQ_HANDLERS];
int retu_get_status(void)
{
- return retu_initialized;
+ return the_retu ? 1 : 0;
}
EXPORT_SYMBOL(retu_get_status);
@@ -77,7 +85,7 @@ EXPORT_SYMBOL(retu_get_status);
*/
int retu_read_reg(unsigned reg)
{
- BUG_ON(!retu_initialized);
+ BUG_ON(!the_retu);
return cbus_read_reg(RETU_ID, reg);
}
EXPORT_SYMBOL(retu_read_reg);
@@ -91,22 +99,23 @@ EXPORT_SYMBOL(retu_read_reg);
*/
void retu_write_reg(unsigned reg, u16 val)
{
- BUG_ON(!retu_initialized);
+ BUG_ON(!the_retu);
cbus_write_reg(RETU_ID, reg, val);
}
EXPORT_SYMBOL(retu_write_reg);
void retu_set_clear_reg_bits(unsigned reg, u16 set, u16 clear)
{
- unsigned long flags;
- u16 w;
+ struct retu *retu = the_retu;
+ unsigned long flags;
+ u16 w;
- spin_lock_irqsave(&retu_lock, flags);
+ spin_lock_irqsave(&retu->lock, flags);
w = retu_read_reg(reg);
w &= ~clear;
w |= set;
retu_write_reg(reg, w);
- spin_unlock_irqrestore(&retu_lock, flags);
+ spin_unlock_irqrestore(&retu->lock, flags);
}
EXPORT_SYMBOL_GPL(retu_set_clear_reg_bits);
@@ -114,15 +123,19 @@ EXPORT_SYMBOL_GPL(retu_set_clear_reg_bits);
int retu_read_adc(int channel)
{
- unsigned long flags;
- int res;
+ struct retu *retu = the_retu;
+ unsigned long flags;
+ int res;
+
+ if (!retu)
+ return -ENODEV;
if (channel < 0 || channel > ADC_MAX_CHAN_NUMBER)
return -EINVAL;
- spin_lock_irqsave(&retu_lock, flags);
+ spin_lock_irqsave(&retu->lock, flags);
- if ((channel == 8) && retu_is_vilma) {
+ if ((channel == 8) && retu->is_vilma) {
int scr = retu_read_reg(RETU_REG_ADCSCR);
int ch = (retu_read_reg(RETU_REG_ADCR) >> 10) & 0xf;
if (((scr & 0xff) != 0) && (ch != 8))
@@ -133,11 +146,11 @@ int retu_read_adc(int channel)
retu_write_reg(RETU_REG_ADCR, channel << 10);
res = retu_read_reg(RETU_REG_ADCR) & 0x3ff;
- if (retu_is_vilma)
+ if (retu->is_vilma)
retu_write_reg(RETU_REG_ADCR, (1 << 13));
/* Unlock retu */
- spin_unlock_irqrestore(&retu_lock, flags);
+ spin_unlock_irqrestore(&retu->lock, flags);
return res;
}
@@ -164,15 +177,16 @@ static u16 retu_disable_bogus_irqs(u16 mask)
*/
void retu_disable_irq(int id)
{
- unsigned long flags;
- u16 mask;
+ struct retu *retu = the_retu;
+ unsigned long flags;
+ u16 mask;
- spin_lock_irqsave(&retu_lock, flags);
+ spin_lock_irqsave(&retu->lock, flags);
mask = retu_read_reg(RETU_REG_IMR);
mask |= 1 << id;
mask = retu_disable_bogus_irqs(mask);
retu_write_reg(RETU_REG_IMR, mask);
- spin_unlock_irqrestore(&retu_lock, flags);
+ spin_unlock_irqrestore(&retu->lock, flags);
}
EXPORT_SYMBOL(retu_disable_irq);
@@ -181,19 +195,21 @@ EXPORT_SYMBOL(retu_disable_irq);
*/
void retu_enable_irq(int id)
{
- unsigned long flags;
- u16 mask;
+ struct retu *retu = the_retu;
+ unsigned long flags;
+ u16 mask;
if (id == 3) {
printk("Enabling Retu IRQ %d\n", id);
dump_stack();
}
- spin_lock_irqsave(&retu_lock, flags);
+
+ spin_lock_irqsave(&retu->lock, flags);
mask = retu_read_reg(RETU_REG_IMR);
mask &= ~(1 << id);
mask = retu_disable_bogus_irqs(mask);
retu_write_reg(RETU_REG_IMR, mask);
- spin_unlock_irqrestore(&retu_lock, flags);
+ spin_unlock_irqrestore(&retu->lock, flags);
}
EXPORT_SYMBOL(retu_enable_irq);
@@ -209,9 +225,12 @@ EXPORT_SYMBOL(retu_ack_irq);
/*
* RETU interrupt handler. Only schedules the tasklet.
*/
-static irqreturn_t retu_irq_handler(int irq, void *dev_id)
+static irqreturn_t retu_irq_handler(int irq, void *_retu)
{
- tasklet_schedule(&retu_tasklet);
+ struct retu *retu = _retu;
+
+ tasklet_schedule(&retu->tasklet);
+
return IRQ_HANDLED;
}
@@ -259,9 +278,10 @@ static void retu_tasklet_handler(unsigned long data)
*/
int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
{
- struct retu_irq_handler_desc *hnd;
+ struct retu *retu = the_retu;
+ struct retu_irq_handler_desc *hnd;
- if (!retu_initialized)
+ if (!retu)
return -ENODEV;
if (irq_handler == NULL || id >= MAX_RETU_IRQ_HANDLERS ||
@@ -396,30 +416,46 @@ static int retu_allocate_children(struct device *parent)
*/
static int __init retu_probe(struct platform_device *pdev)
{
- int rev, ret;
- int irq;
+ struct retu *retu;
+ int rev;
+ int ret;
+ int irq;
+
+ retu = kzalloc(sizeof(*retu), GFP_KERNEL);
+ if (!retu) {
+ dev_err(&pdev->dev, "not enough memory\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, retu);
+ the_retu = retu;
/* Prepare tasklet */
- tasklet_init(&retu_tasklet, retu_tasklet_handler, 0);
+ tasklet_init(&retu->tasklet, retu_tasklet_handler, 0);
+ spin_lock_init(&retu->lock);
irq = platform_get_irq(pdev, 0);
- retu_initialized = 1;
+ retu->irq = irq;
rev = retu_read_reg(RETU_REG_ASICR) & 0xff;
if (rev & (1 << 7))
- retu_is_vilma = 1;
+ retu->is_vilma = true;
- dev_info(&pdev->dev, "%s v%d.%d found\n", retu_is_vilma ? "Vilma" : "Retu",
- (rev >> 4) & 0x07, rev & 0x0f);
+ dev_info(&pdev->dev, "%s v%d.%d found\n",
+ retu->is_vilma ? "Vilma" : "Retu",
+ (rev >> 4) & 0x07, rev & 0x0f);
/* Mask all RETU interrupts */
retu_write_reg(RETU_REG_IMR, 0xffff);
ret = request_irq(irq, retu_irq_handler, 0,
- "retu", 0);
+ "retu", retu);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to register IRQ handler\n");
+ tasklet_kill(&retu->tasklet);
+ kfree(retu);
+ the_retu = NULL;
return ret;
}
@@ -432,7 +468,10 @@ static int __init retu_probe(struct platform_device *pdev)
/* Initialize user-space interface */
if (retu_user_init() < 0) {
dev_err(&pdev->dev, "Unable to initialize driver\n");
+ tasklet_kill(&retu->tasklet);
free_irq(irq, 0);
+ kfree(retu);
+ the_retu = NULL;
return ret;
}
#endif
@@ -445,7 +484,9 @@ static int __init retu_probe(struct platform_device *pdev)
#endif
retu_write_reg(RETU_REG_IMR, 0xffff);
free_irq(irq, 0);
- tasklet_kill(&retu_tasklet);
+ tasklet_kill(&retu->tasklet);
+ kfree(retu);
+ the_retu = NULL;
return ret;
}
@@ -454,7 +495,8 @@ static int __init retu_probe(struct platform_device *pdev)
static int __exit retu_remove(struct platform_device *pdev)
{
- int irq;
+ struct retu *retu = platform_get_drvdata(pdev);
+ int irq;
irq = platform_get_irq(pdev, 0);
@@ -463,8 +505,10 @@ static int __exit retu_remove(struct platform_device *pdev)
#endif
/* Mask all RETU interrupts */
retu_write_reg(RETU_REG_IMR, 0xffff);
- free_irq(irq, 0);
- tasklet_kill(&retu_tasklet);
+ free_irq(irq, retu);
+ tasklet_kill(&retu->tasklet);
+ kfree(retu);
+ the_retu = NULL;
return 0;
}
diff --git a/drivers/cbus/retu.h b/drivers/cbus/retu.h
index cf3cf20..1cc486e 100644
--- a/drivers/cbus/retu.h
+++ b/drivers/cbus/retu.h
@@ -73,6 +73,4 @@ int retu_user_init(void);
void retu_user_cleanup(void);
#endif
-extern spinlock_t retu_lock;
-
#endif /* __DRIVERS_CBUS_RETU_H */
--
1.7.3.4.598.g85356
next prev parent reply other threads:[~2011-01-03 7:50 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-03 7:49 [RFT/PATCH 00/10] move retu to threaded IRQ Felipe Balbi
2011-01-03 7:49 ` Felipe Balbi [this message]
2011-01-04 1:40 ` [RFT/PATCH 01/10] cbus: retu: give it a context structure Tony Lindgren
2011-01-04 6:51 ` Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 02/10] cbus: retu: get rid of retu-user.c Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 03/10] cbus: retu: move module_* close to the matching symbol Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 04/10] cbus: retu: cleanup error path Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 05/10] cbus: retu: move to threaded IRQ and GENIRQ Felipe Balbi
2011-01-04 1:40 ` Tony Lindgren
2011-01-04 6:52 ` Felipe Balbi
2011-01-04 7:46 ` Felipe Balbi
2011-01-04 7:47 ` Felipe Balbi
2011-01-04 19:14 ` Tony Lindgren
2011-01-05 6:37 ` Felipe Balbi
2011-01-07 3:04 ` Tony Lindgren
2011-01-07 7:48 ` Felipe Balbi
2011-01-07 17:04 ` Tony Lindgren
2011-01-07 19:15 ` Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 06/10] cbus: retu: headset: convert to threaded_irq Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 07/10] cbus: retu-pwrbutton: convert to threaded irq Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 08/10] cbus: retu-rtc: move " Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 09/10] cbus: retu-rtc: drop the reset_occurred flag Felipe Balbi
2011-01-03 7:49 ` [RFT/PATCH 10/10] cbus: Makefile: re-enable retu-wdt Felipe Balbi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1294040988-21191-2-git-send-email-balbi@ti.com \
--to=balbi@ti.com \
--cc=linux-omap@vger.kernel.org \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox