* [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ
@ 2011-02-03 10:20 Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 01/13] cbus: retu: get rid of retu-user.c Felipe Balbi
` (13 more replies)
0 siblings, 14 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Hi Tony,
When you have some extra time, could you run these on N810
to check whether I'm on the right path ? After these patches
all CBUS drivers are using standard request_threaded_irq()
calls. It's one step closer into getting those in mainline.
Felipe Balbi (13):
cbus: retu: get rid of retu-user.c
cbus: retu: give it a context structure
cbus: retu: move module_* close to the matching symbol
cbus: retu: cleanup error path
arm: omap: irqs: add CBUS_RETU_IRQ_BASE and CBUS_RETU_IRQ_END
arm: omap: cbus: pass irq_base and irq_end via platform_data
cbus: retu: move to threaded IRQ and GENIRQ
cbus: retu: headset: convert to threaded_irq
cbus: retu-pwrbutton: convert to threaded irq
cbus: retu-rtc: move to threaded irq
cbus: retu-rtc: drop the reset_occurred flag
cbus: Makefile: re-enable retu-wdt
cbus: tahvo: drop tahvo-user
arch/arm/mach-omap1/board-nokia770.c | 8 +
arch/arm/mach-omap2/board-n8x0.c | 8 +
arch/arm/plat-omap/include/plat/cbus.h | 5 +
arch/arm/plat-omap/include/plat/irqs.h | 10 +-
drivers/cbus/Kconfig | 14 -
drivers/cbus/Makefile | 3 +-
drivers/cbus/retu-headset.c | 22 +-
drivers/cbus/retu-pwrbutton.c | 37 +--
drivers/cbus/retu-rtc.c | 130 ++---------
drivers/cbus/retu-user.c | 424 --------------------------------
drivers/cbus/retu.c | 394 ++++++++++++++----------------
drivers/cbus/retu.h | 12 -
drivers/cbus/tahvo-user.c | 406 ------------------------------
drivers/cbus/tahvo.c | 11 -
drivers/cbus/tahvo.h | 5 -
15 files changed, 258 insertions(+), 1231 deletions(-)
delete mode 100644 drivers/cbus/retu-user.c
delete mode 100644 drivers/cbus/tahvo-user.c
--
1.7.4.rc2
^ permalink raw reply [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 01/13] cbus: retu: get rid of retu-user.c
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 02/13] cbus: retu: give it a context structure Felipe Balbi
` (12 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Drop that non-standard of accessing Retu
as it's bypassing all the correct layers.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/Kconfig | 7 -
drivers/cbus/Makefile | 1 -
drivers/cbus/retu-user.c | 424 ----------------------------------------------
drivers/cbus/retu.c | 19 --
drivers/cbus/retu.h | 5 -
5 files changed, 0 insertions(+), 456 deletions(-)
delete mode 100644 drivers/cbus/retu-user.c
diff --git a/drivers/cbus/Kconfig b/drivers/cbus/Kconfig
index c6b39fb..9a827a2 100644
--- a/drivers/cbus/Kconfig
+++ b/drivers/cbus/Kconfig
@@ -49,13 +49,6 @@ config CBUS_RETU
If you want Retu support, you should say Y here.
-config CBUS_RETU_USER
- depends on CBUS_RETU
- bool "Support for Retu user space functions"
- ---help---
- If you want support for Retu's user space read/write etc. functions,
- you should say Y here.
-
config CBUS_RETU_POWERBUTTON
depends on CBUS_RETU
bool "Support for Retu power button"
diff --git a/drivers/cbus/Makefile b/drivers/cbus/Makefile
index 347c2a4..0ad112f 100644
--- a/drivers/cbus/Makefile
+++ b/drivers/cbus/Makefile
@@ -10,5 +10,4 @@ obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o
-obj-$(CONFIG_CBUS_RETU_USER) += retu-user.o
obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
diff --git a/drivers/cbus/retu-user.c b/drivers/cbus/retu-user.c
deleted file mode 100644
index c36f356..0000000
--- a/drivers/cbus/retu-user.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/**
- * drivers/cbus/retu-user.c
- *
- * Retu user space interface functions
- *
- * Copyright (C) 2004, 2005 Nokia Corporation
- *
- * Written by Mikko Ylinen <mikko.k.ylinen@nokia.com>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file "COPYING" in the main directory of this
- * archive for more details.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/poll.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-
-#include "retu.h"
-
-#include "user_retu_tahvo.h"
-
-/* Maximum size of IRQ node buffer/pool */
-#define RETU_MAX_IRQ_BUF_LEN 16
-
-#define PFX "retu-user: "
-
-/* Bitmap for marking the interrupt sources as having the handlers */
-static u32 retu_irq_bits;
-
-/* For allowing only one user process to subscribe to the retu interrupts */
-static struct file *retu_irq_subscr = NULL;
-
-/* For poll and IRQ passing */
-struct retu_irq {
- u32 id;
- struct list_head node;
-};
-
-static spinlock_t retu_irqs_lock;
-static struct retu_irq *retu_irq_block;
-static LIST_HEAD(retu_irqs);
-static LIST_HEAD(retu_irqs_reserve);
-
-/* Wait queue - used when user wants to read the device */
-DECLARE_WAIT_QUEUE_HEAD(retu_user_waitqueue);
-
-/* Semaphore to protect irq subscription sequence */
-static struct mutex retu_mutex;
-
-/* This array specifies RETU register types (read/write/toggle) */
-static const u8 retu_access_bits[] = {
- 1,
- 4,
- 3,
- 3,
- 1,
- 3,
- 3,
- 0,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 4,
- 4,
- 3,
- 0,
- 0,
- 0,
- 0,
- 1,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3
-};
-
-/*
- * The handler for all RETU interrupts.
- *
- * arg is the interrupt source in RETU.
- */
-static void retu_user_irq_handler(unsigned long arg)
-{
- struct retu_irq *irq;
-
- retu_ack_irq(arg);
-
- spin_lock(&retu_irqs_lock);
- if (list_empty(&retu_irqs_reserve)) {
- spin_unlock(&retu_irqs_lock);
- return;
- }
- irq = list_entry((&retu_irqs_reserve)->next, struct retu_irq, node);
- irq->id = arg;
- list_move_tail(&irq->node, &retu_irqs);
- spin_unlock(&retu_irqs_lock);
-
- /* wake up waiting thread */
- wake_up(&retu_user_waitqueue);
-}
-
-/*
- * This routine sets up the interrupt handler and marks an interrupt source
- * in RETU as a candidate for signal delivery to the user process.
- */
-static int retu_user_subscribe_to_irq(int id, struct file *filp)
-{
- int ret;
-
- mutex_lock(&retu_mutex);
- if ((retu_irq_subscr != NULL) && (retu_irq_subscr != filp)) {
- mutex_unlock(&retu_mutex);
- return -EBUSY;
- }
- /* Store the file pointer of the first user process registering IRQs */
- retu_irq_subscr = filp;
- mutex_unlock(&retu_mutex);
-
- if (retu_irq_bits & (1 << id))
- return 0;
-
- ret = retu_request_irq(id, retu_user_irq_handler, id, "");
- if (ret < 0)
- return ret;
-
- /* Mark that this interrupt has a handler */
- retu_irq_bits |= 1 << id;
-
- return 0;
-}
-
-/*
- * Unregisters all RETU interrupt handlers.
- */
-static void retu_unreg_irq_handlers(void)
-{
- int id;
-
- if (!retu_irq_bits)
- return;
-
- for (id = 0; id < MAX_RETU_IRQ_HANDLERS; id++)
- if (retu_irq_bits & (1 << id))
- retu_free_irq(id);
-
- retu_irq_bits = 0;
-}
-
-/*
- * Write to RETU register.
- * Returns 0 upon success, a negative error value otherwise.
- */
-static int retu_user_write_with_mask(u32 field, u16 value)
-{
- u32 mask;
- u32 reg;
- u_short tmp;
- unsigned long flags;
-
- mask = MASK(field);
- reg = REG(field);
-
- /* Detect bad mask and reg */
- if (mask == 0 || reg > RETU_REG_MAX ||
- retu_access_bits[reg] == READ_ONLY) {
- printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
- reg, mask);
- return -EINVAL;
- }
-
- /* Justify value according to mask */
- while (!(mask & 1)) {
- value = value << 1;
- mask = mask >> 1;
- }
-
- spin_lock_irqsave(&retu_lock, flags);
- if (retu_access_bits[reg] == TOGGLE) {
- /* No need to detect previous content of register */
- tmp = 0;
- } else {
- /* Read current value of register */
- tmp = retu_read_reg(reg);
- }
-
- /* Generate new value */
- tmp = (tmp & ~MASK(field)) | (value & MASK(field));
- /* Write data to RETU */
- retu_write_reg(reg, tmp);
- spin_unlock_irqrestore(&retu_lock, flags);
-
- return 0;
-}
-
-/*
- * Read RETU register.
- */
-static u32 retu_user_read_with_mask(u32 field)
-{
- u_short value;
- u32 mask, reg;
-
- mask = MASK(field);
- reg = REG(field);
-
- /* Detect bad mask and reg */
- if (mask == 0 || reg > RETU_REG_MAX) {
- printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
- reg, mask);
- return -EINVAL;
- }
-
- /* Read the register */
- value = retu_read_reg(reg) & mask;
-
- /* Right justify value */
- while (!(mask & 1)) {
- value = value >> 1;
- mask = mask >> 1;
- }
-
- return value;
-}
-
-/*
- * Close device
- */
-static int retu_close(struct inode *inode, struct file *filp)
-{
- /* Unregister all interrupts that have been registered */
- if (retu_irq_subscr == filp) {
- retu_unreg_irq_handlers();
- retu_irq_subscr = NULL;
- }
-
- return 0;
-}
-
-/*
- * Device control (ioctl)
- */
-static long retu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- struct retu_tahvo_write_parms par;
- int ret;
-
- switch (cmd) {
- case URT_IOCT_IRQ_SUBSCR:
- return retu_user_subscribe_to_irq(arg, filp);
- case RETU_IOCH_READ:
- return retu_user_read_with_mask(arg);
- case RETU_IOCX_WRITE:
- ret = copy_from_user(&par, (void __user *) arg, sizeof(par));
- if (ret)
- printk(KERN_ERR "copy_from_user failed: %d\n", ret);
- par.result = retu_user_write_with_mask(par.field, par.value);
- ret = copy_to_user((void __user *) arg, &par, sizeof(par));
- if (ret)
- printk(KERN_ERR "copy_to_user failed: %d\n", ret);
- break;
- case RETU_IOCH_ADC_READ:
- return retu_read_adc(arg);
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-/*
- * Read from device
- */
-static ssize_t retu_read(struct file *filp, char *buf, size_t count,
- loff_t * offp)
-{
- struct retu_irq *irq;
-
- u32 nr, i;
-
- /* read not permitted if neither filp nor anyone has registered IRQs */
- if (retu_irq_subscr != filp)
- return -EPERM;
-
- if ((count < sizeof(u32)) || ((count % sizeof(u32)) != 0))
- return -EINVAL;
-
- nr = count / sizeof(u32);
-
- for (i = 0; i < nr; i++) {
- unsigned long flags;
- u32 irq_id;
- int ret;
-
- ret = wait_event_interruptible(retu_user_waitqueue,
- !list_empty(&retu_irqs));
- if (ret < 0)
- return ret;
-
- spin_lock_irqsave(&retu_irqs_lock, flags);
- irq = list_entry((&retu_irqs)->next, struct retu_irq, node);
- irq_id = irq->id;
- list_move(&irq->node, &retu_irqs_reserve);
- spin_unlock_irqrestore(&retu_irqs_lock, flags);
-
- ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
- sizeof(irq_id));
- if (ret)
- printk(KERN_ERR "copy_to_user failed: %d\n", ret);
- }
-
- return count;
-}
-
-/*
- * Poll method
- */
-static unsigned retu_poll(struct file *filp, struct poll_table_struct *pt)
-{
- if (!list_empty(&retu_irqs))
- return POLLIN;
-
- poll_wait(filp, &retu_user_waitqueue, pt);
-
- if (!list_empty(&retu_irqs))
- return POLLIN;
- else
- return 0;
-}
-
-static struct file_operations retu_user_fileops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = retu_ioctl,
- .read = retu_read,
- .release = retu_close,
- .poll = retu_poll
-};
-
-static struct miscdevice retu_device = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "retu",
- .fops = &retu_user_fileops
-};
-
-/*
- * Initialization
- *
- * @return 0 if successful, error value otherwise.
- */
-int retu_user_init(void)
-{
- struct retu_irq *irq;
- int res, i;
-
- irq = kzalloc(sizeof(*irq) * RETU_MAX_IRQ_BUF_LEN, GFP_KERNEL);
- if (irq == NULL) {
- printk(KERN_ERR PFX "kzalloc failed\n");
- return -ENOMEM;
- }
-
- for (i = 0; i < RETU_MAX_IRQ_BUF_LEN; i++)
- list_add(&irq[i].node, &retu_irqs_reserve);
-
- retu_irq_block = irq;
-
- spin_lock_init(&retu_irqs_lock);
- mutex_init(&retu_mutex);
-
- /* Request a misc device */
- res = misc_register(&retu_device);
- if (res < 0) {
- printk(KERN_ERR PFX "unable to register misc device for %s\n",
- retu_device.name);
- kfree(irq);
- return res;
- }
-
- return 0;
-}
-
-/*
- * Cleanup.
- */
-void retu_user_cleanup(void)
-{
- /* Unregister our misc device */
- misc_deregister(&retu_device);
- /* Unregister and disable all RETU interrupts used by this module */
- retu_unreg_irq_handlers();
- kfree(retu_irq_block);
-}
-
-MODULE_DESCRIPTION("Retu ASIC user space functions");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mikko Ylinen");
diff --git a/drivers/cbus/retu.c b/drivers/cbus/retu.c
index a2977c9..f44d770 100644
--- a/drivers/cbus/retu.c
+++ b/drivers/cbus/retu.c
@@ -376,10 +376,6 @@ static int retu_allocate_children(struct device *parent)
if (!child)
return -ENOMEM;
- child = retu_allocate_child("retu-user", parent);
- if (!child)
- return -ENOMEM;
-
child = retu_allocate_child("retu-wdt", parent);
if (!child)
return -ENOMEM;
@@ -428,21 +424,9 @@ static int __init retu_probe(struct platform_device *pdev)
/* Register power off function */
pm_power_off = retu_power_off;
-#ifdef CONFIG_CBUS_RETU_USER
- /* Initialize user-space interface */
- if (retu_user_init() < 0) {
- dev_err(&pdev->dev, "Unable to initialize driver\n");
- free_irq(irq, 0);
- return ret;
- }
-#endif
-
ret = retu_allocate_children(&pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to allocate Retu children\n");
-#ifdef CONFIG_CBUS_RETU_USER
- retu_user_cleanup();
-#endif
retu_write_reg(RETU_REG_IMR, 0xffff);
free_irq(irq, 0);
tasklet_kill(&retu_tasklet);
@@ -458,9 +442,6 @@ static int __exit retu_remove(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
-#ifdef CONFIG_CBUS_RETU_USER
- retu_user_cleanup();
-#endif
/* Mask all RETU interrupts */
retu_write_reg(RETU_REG_IMR, 0xffff);
free_irq(irq, 0);
diff --git a/drivers/cbus/retu.h b/drivers/cbus/retu.h
index cf3cf20..f459768 100644
--- a/drivers/cbus/retu.h
+++ b/drivers/cbus/retu.h
@@ -68,11 +68,6 @@ void retu_enable_irq(int id);
void retu_disable_irq(int id);
void retu_ack_irq(int id);
-#ifdef CONFIG_CBUS_RETU_USER
-int retu_user_init(void);
-void retu_user_cleanup(void);
-#endif
-
extern spinlock_t retu_lock;
#endif /* __DRIVERS_CBUS_RETU_H */
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 02/13] cbus: retu: give it a context structure
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 01/13] cbus: retu: get rid of retu-user.c Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 03/13] cbus: retu: move module_* close to the matching symbol Felipe Balbi
` (11 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
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 | 123 ++++++++++++++++++++++++++++++++++-----------------
drivers/cbus/retu.h | 2 -
2 files changed, 82 insertions(+), 43 deletions(-)
diff --git a/drivers/cbus/retu.c b/drivers/cbus/retu.c
index f44d770..39d4fa4 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 ||
@@ -392,30 +412,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;
}
@@ -429,7 +465,9 @@ static int __init retu_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Unable to allocate Retu children\n");
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;
}
@@ -438,14 +476,17 @@ 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);
/* 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 f459768..ada7f2e 100644
--- a/drivers/cbus/retu.h
+++ b/drivers/cbus/retu.h
@@ -68,6 +68,4 @@ void retu_enable_irq(int id);
void retu_disable_irq(int id);
void retu_ack_irq(int id);
-extern spinlock_t retu_lock;
-
#endif /* __DRIVERS_CBUS_RETU_H */
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 03/13] cbus: retu: move module_* close to the matching symbol
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 01/13] cbus: retu: get rid of retu-user.c Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 02/13] cbus: retu: give it a context structure Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 04/13] cbus: retu: cleanup error path Felipe Balbi
` (10 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Just to make checkpatch.pl a bit happier, move
subsys_initcall() and module_exit() closer to
the init and exit functions of the driver.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/retu.c | 11 +----------
1 files changed, 1 insertions(+), 10 deletions(-)
diff --git a/drivers/cbus/retu.c b/drivers/cbus/retu.c
index 39d4fa4..0053d43 100644
--- a/drivers/cbus/retu.c
+++ b/drivers/cbus/retu.c
@@ -498,25 +498,16 @@ static struct platform_driver retu_driver = {
},
};
-/**
- * retu_init - initialise Retu driver
- *
- * Initialise the Retu driver and return 0 if everything worked ok
- */
static int __init retu_init(void)
{
return platform_driver_probe(&retu_driver, retu_probe);
}
+subsys_initcall(retu_init);
-/*
- * Cleanup
- */
static void __exit retu_exit(void)
{
platform_driver_unregister(&retu_driver);
}
-
-subsys_initcall(retu_init);
module_exit(retu_exit);
MODULE_DESCRIPTION("Retu ASIC control");
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 04/13] cbus: retu: cleanup error path
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (2 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 03/13] cbus: retu: move module_* close to the matching symbol Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 05/13] arm: omap: irqs: add CBUS_RETU_IRQ_BASE and CBUS_RETU_IRQ_END Felipe Balbi
` (9 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Trivial cleanup patch shuffling error path
around.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/retu.c | 29 +++++++++++++++++------------
1 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/cbus/retu.c b/drivers/cbus/retu.c
index 0053d43..7e67e1a 100644
--- a/drivers/cbus/retu.c
+++ b/drivers/cbus/retu.c
@@ -413,14 +413,15 @@ static int retu_allocate_children(struct device *parent)
static int __init retu_probe(struct platform_device *pdev)
{
struct retu *retu;
+
+ int ret = -ENOMEM;
int rev;
- int ret;
int irq;
retu = kzalloc(sizeof(*retu), GFP_KERNEL);
if (!retu) {
dev_err(&pdev->dev, "not enough memory\n");
- return -ENOMEM;
+ goto err0;
}
platform_set_drvdata(pdev, retu);
@@ -449,10 +450,7 @@ static int __init retu_probe(struct platform_device *pdev)
"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;
+ goto err1;
}
set_irq_wake(irq, 1);
@@ -463,15 +461,22 @@ static int __init retu_probe(struct platform_device *pdev)
ret = retu_allocate_children(&pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to allocate Retu children\n");
- retu_write_reg(RETU_REG_IMR, 0xffff);
- free_irq(irq, 0);
- tasklet_kill(&retu->tasklet);
- kfree(retu);
- the_retu = NULL;
- return ret;
+ goto err2;
}
return 0;
+
+err2:
+ retu_write_reg(RETU_REG_IMR, 0xffff);
+ free_irq(irq, retu);
+
+err1:
+ tasklet_kill(&retu->tasklet);
+ kfree(retu);
+ the_retu = NULL;
+
+err0:
+ return ret;
}
static int __exit retu_remove(struct platform_device *pdev)
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 05/13] arm: omap: irqs: add CBUS_RETU_IRQ_BASE and CBUS_RETU_IRQ_END
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (3 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 04/13] cbus: retu: cleanup error path Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 06/13] arm: omap: cbus: pass irq_base and irq_end via platform_data Felipe Balbi
` (8 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
those two will be used to pass down irq_base and irq_end
to retu platform_driver.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
arch/arm/plat-omap/include/plat/irqs.h | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 2910de9..d62e795 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -411,7 +411,15 @@
#define TWL_IRQ_END TWL6030_IRQ_END
#endif
-#define NR_IRQS TWL_IRQ_END
+#define CBUS_RETU_IRQ_BASE TWL_IRQ_END
+#ifdef CONFIG_CBUS_RETU
+#define CBUS_RETU_NR_IRQS 16
+#else
+#define CBUS_RETU_NR_IRQS 0
+#endif
+#define CBUS_RETU_IRQ_END (CBUS_RETU_IRQ_BASE + CBUS_RETU_NR_IRQS)
+
+#define NR_IRQS CBUS_RETU_IRQ_END
#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 06/13] arm: omap: cbus: pass irq_base and irq_end via platform_data
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (4 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 05/13] arm: omap: irqs: add CBUS_RETU_IRQ_BASE and CBUS_RETU_IRQ_END Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 07/13] cbus: retu: move to threaded IRQ and GENIRQ Felipe Balbi
` (7 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Pass CBUS_RETU_IRQ_BASE and CBUS_RETU_IRQ_END via
platform_data to retu platform_driver.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
arch/arm/mach-omap1/board-nokia770.c | 8 ++++++++
arch/arm/mach-omap2/board-n8x0.c | 8 ++++++++
arch/arm/plat-omap/include/plat/cbus.h | 5 +++++
3 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 84797a7..d939370 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -123,11 +123,19 @@ static struct resource retu_resource[] = {
},
};
+static struct cbus_retu_platform_data nokia770_retu_data = {
+ .irq_base = CBUS_RETU_IRQ_BASE,
+ .irq_end = CBUS_RETU_IRQ_END,
+};
+
static struct platform_device retu_device = {
.name = "retu",
.id = -1,
.resource = retu_resource,
.num_resources = ARRAY_SIZE(retu_resource),
+ .dev = {
+ .platform_data = &nokia770_retu_data,
+ },
};
static struct resource tahvo_resource[] = {
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 1cb53bc..1e4bfb2 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -220,11 +220,19 @@ static struct resource retu_resource[] = {
},
};
+static struct cbus_retu_platform_data n8x0_retu_data = {
+ .irq_base = CBUS_RETU_IRQ_BASE,
+ .irq_end = CBUS_RETU_IRQ_END,
+};
+
static struct platform_device retu_device = {
.name = "retu",
.id = -1,
.resource = retu_resource,
.num_resources = ARRAY_SIZE(retu_resource),
+ .dev = {
+ .platform_data = &n8x0_retu_data,
+ },
};
static struct resource tahvo_resource[] = {
diff --git a/arch/arm/plat-omap/include/plat/cbus.h b/arch/arm/plat-omap/include/plat/cbus.h
index d938e23..1f0e8be 100644
--- a/arch/arm/plat-omap/include/plat/cbus.h
+++ b/arch/arm/plat-omap/include/plat/cbus.h
@@ -28,4 +28,9 @@ struct cbus_host_platform_data {
int sel_gpio;
};
+struct cbus_retu_platform_data {
+ int irq_base;
+ int irq_end;
+};
+
#endif /* __PLAT_CBUS_H */
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 07/13] cbus: retu: move to threaded IRQ and GENIRQ
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (5 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 06/13] arm: omap: cbus: pass irq_base and irq_end via platform_data Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 08/13] cbus: retu: headset: convert to threaded_irq Felipe Balbi
` (6 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Start moving retu to threaded IRQ and while
at that also give retu an irq_chip so children
can use generic request_threaded_irq() calls.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/Makefile | 10 +-
drivers/cbus/retu.c | 270 +++++++++++++++++++++----------------------------
drivers/cbus/retu.h | 5 -
3 files changed, 123 insertions(+), 162 deletions(-)
diff --git a/drivers/cbus/Makefile b/drivers/cbus/Makefile
index 0ad112f..3375b82 100644
--- a/drivers/cbus/Makefile
+++ b/drivers/cbus/Makefile
@@ -6,8 +6,10 @@ obj-$(CONFIG_CBUS) += cbus.o
obj-$(CONFIG_CBUS_TAHVO) += tahvo.o
obj-$(CONFIG_CBUS_RETU) += retu.o
obj-$(CONFIG_CBUS_TAHVO_USB) += tahvo-usb.o
-obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
-obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
-obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o
-obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
+
+## Disable Retu children until converted to threaded IRQ
+#obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
+#obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
+#obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
+#obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
diff --git a/drivers/cbus/retu.c b/drivers/cbus/retu.c
index 7e67e1a..fa666fe 100644
--- a/drivers/cbus/retu.c
+++ b/drivers/cbus/retu.c
@@ -33,6 +33,7 @@
#include <linux/miscdevice.h>
#include <linux/poll.h>
#include <linux/fs.h>
+#include <linux/mutex.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
@@ -43,6 +44,7 @@
#include <plat/mux.h>
#include <plat/board.h>
+#include <plat/cbus.h>
#include "cbus.h"
#include "retu.h"
@@ -53,23 +55,24 @@
struct retu {
/* Device lock */
spinlock_t lock;
- struct tasklet_struct tasklet;
+ struct mutex irq_lock;
struct device *dev;
+ int irq_base;
+ int irq_end;
+
int irq;
- bool is_vilma;
-};
+ int ack;
+ bool ack_pending;
-static struct retu *the_retu;
+ int mask;
+ bool mask_pending;
-struct retu_irq_handler_desc {
- int (*func)(unsigned long);
- unsigned long arg;
- char name[8];
+ bool is_vilma;
};
-static struct retu_irq_handler_desc retu_irq_handlers[MAX_RETU_IRQ_HANDLERS];
+static struct retu *the_retu;
int retu_get_status(void)
{
@@ -156,180 +159,137 @@ int retu_read_adc(int channel)
}
EXPORT_SYMBOL(retu_read_adc);
-static u16 retu_disable_bogus_irqs(u16 mask)
+static irqreturn_t retu_irq_handler(int irq, void *_retu)
{
- int i;
-
- for (i = 0; i < MAX_RETU_IRQ_HANDLERS; i++) {
- if (mask & (1 << i))
- continue;
- if (retu_irq_handlers[i].func != NULL)
- continue;
- /* an IRQ was enabled but we don't have a handler for it */
- printk(KERN_INFO PFX "disabling bogus IRQ %d\n", i);
- mask |= (1 << i);
- }
- return mask;
-}
+ struct retu *retu = _retu;
-/*
- * Disable given RETU interrupt
- */
-void retu_disable_irq(int id)
-{
- struct retu *retu = the_retu;
- unsigned long flags;
- u16 mask;
+ int i;
- 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);
-}
-EXPORT_SYMBOL(retu_disable_irq);
+ u16 idr;
+ u16 imr;
-/*
- * Enable given RETU interrupt
- */
-void retu_enable_irq(int id)
-{
- struct retu *retu = the_retu;
- unsigned long flags;
- u16 mask;
+ idr = retu_read_reg(RETU_REG_IDR);
+ imr = retu_read_reg(RETU_REG_IMR);
+ idr &= ~imr;
- if (id == 3) {
- printk("Enabling Retu IRQ %d\n", id);
- dump_stack();
+ if (!idr) {
+ dev_vdbg(retu->dev, "No IRQ, spurious?\n");
+ return IRQ_NONE;
}
- 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);
+ for (i = 0; idr != 0; i++, idr >>= 1) {
+ if (!(idr & 1))
+ continue;
+
+ handle_nested_irq(i);
+ }
+
+ return IRQ_HANDLED;
}
-EXPORT_SYMBOL(retu_enable_irq);
-/*
- * Acknowledge given RETU interrupt
- */
-void retu_ack_irq(int id)
+/* -------------------------------------------------------------------------- */
+
+static void retu_irq_mask(struct irq_data *data)
{
- retu_write_reg(RETU_REG_IDR, 1 << id);
+ struct retu *retu = irq_data_get_irq_chip_data(data);
+ int irq = data->irq;
+
+ retu->mask |= (1 << (irq - retu->irq_base));
+ retu->mask_pending = true;
}
-EXPORT_SYMBOL(retu_ack_irq);
-/*
- * RETU interrupt handler. Only schedules the tasklet.
- */
-static irqreturn_t retu_irq_handler(int irq, void *_retu)
+static void retu_irq_unmask(struct irq_data *data)
{
- struct retu *retu = _retu;
+ struct retu *retu = irq_data_get_irq_chip_data(data);
+ int irq = data->irq;
- tasklet_schedule(&retu->tasklet);
+ retu->mask &= ~(1 << (irq - retu->irq_base));
+ retu->mask_pending = true;
- return IRQ_HANDLED;
}
-/*
- * Tasklet handler
- */
-static void retu_tasklet_handler(unsigned long data)
+static void retu_irq_ack(struct irq_data *data)
{
- struct retu_irq_handler_desc *hnd;
- u16 id;
- u16 im;
- int i;
-
- for (;;) {
- id = retu_read_reg(RETU_REG_IDR);
- im = ~retu_read_reg(RETU_REG_IMR);
- id &= im;
-
- if (!id)
- break;
-
- for (i = 0; id != 0; i++, id >>= 1) {
- if (!(id & 1))
- continue;
- hnd = &retu_irq_handlers[i];
- if (hnd->func == NULL) {
- /* Spurious retu interrupt - disable and ack it */
- printk(KERN_INFO "Spurious Retu interrupt "
- "(id %d)\n", i);
- retu_disable_irq(i);
- retu_ack_irq(i);
- continue;
- }
- hnd->func(hnd->arg);
- /*
- * Don't acknowledge the interrupt here
- * It must be done explicitly
- */
- }
- }
+ struct retu *retu = irq_data_get_irq_chip_data(data);
+ int irq = data->irq;
+
+ retu->ack |= (1 << (irq - retu->irq_base));
+ retu->ack_pending = true;
}
-/*
- * Register the handler for a given RETU interrupt source.
- */
-int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
+static void retu_bus_lock(struct irq_data *data)
{
- struct retu *retu = the_retu;
- struct retu_irq_handler_desc *hnd;
+ struct retu *retu = irq_data_get_irq_chip_data(data);
- if (!retu)
- return -ENODEV;
+ mutex_lock(&retu->irq_lock);
+}
- if (irq_handler == NULL || id >= MAX_RETU_IRQ_HANDLERS ||
- name == NULL) {
- printk(KERN_ERR PFX "Invalid arguments to %s\n",
- __FUNCTION__);
- return -EINVAL;
+static void retu_bus_sync_unlock(struct irq_data *data)
+{
+ struct retu *retu = irq_data_get_irq_chip_data(data);
+
+ if (retu->mask_pending) {
+ retu_write_reg(RETU_REG_IMR, retu->mask);
+ retu->mask_pending = false;
}
- hnd = &retu_irq_handlers[id];
- if (hnd->func != NULL) {
- printk(KERN_ERR PFX "IRQ %d already reserved\n", id);
- return -EBUSY;
+
+ if (retu->ack_pending) {
+ retu_write_reg(RETU_REG_IDR, retu->ack);
+ retu->ack_pending = false;
}
- printk(KERN_INFO PFX "Registering interrupt %d for device %s\n",
- id, name);
- hnd->func = irq_handler;
- hnd->arg = arg;
- strlcpy(hnd->name, name, sizeof(hnd->name));
- retu_ack_irq(id);
- retu_enable_irq(id);
+ mutex_unlock(&retu->irq_lock);
+}
- return 0;
+static struct irq_chip retu_irq_chip = {
+ .name = "retu",
+ .irq_bus_lock = retu_bus_lock,
+ .irq_bus_sync_unlock = retu_bus_sync_unlock,
+ .irq_mask = retu_irq_mask,
+ .irq_unmask = retu_irq_unmask,
+ .irq_ack = retu_irq_ack,
+};
+
+static inline void retu_irq_setup(int irq)
+{
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID);
+#else
+ set_irq_noprobe(irq);
+#endif
}
-EXPORT_SYMBOL(retu_request_irq);
-/*
- * Unregister the handler for a given RETU interrupt source.
- */
-void retu_free_irq(int id)
+static void retu_irq_init(struct retu *retu)
{
- struct retu_irq_handler_desc *hnd;
+ int base = retu->irq_base;
+ int end = retu->irq_end;
+ int irq;
- if (id >= MAX_RETU_IRQ_HANDLERS) {
- printk(KERN_ERR PFX "Invalid argument to %s\n",
- __FUNCTION__);
- return;
- }
- hnd = &retu_irq_handlers[id];
- if (hnd->func == NULL) {
- printk(KERN_ERR PFX "IRQ %d already freed\n", id);
- return;
+ for (irq = base; irq < end; irq++) {
+ set_irq_chip_data(irq, retu);
+ set_irq_chip_and_handler(irq, &retu_irq_chip,
+ handle_simple_irq);
+ set_irq_nested_thread(irq, 1);
+ retu_irq_setup(irq);
}
+}
+
+static void retu_irq_exit(struct retu *retu)
+{
+ int base = retu->irq_base;
+ int end = retu->irq_end;
+ int irq;
- retu_disable_irq(id);
- hnd->func = NULL;
+ for (irq = base; irq < end; irq++) {
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, 0);
+#endif
+ set_irq_chip_and_handler(irq, NULL, NULL);
+ set_irq_chip_data(irq, NULL);
+ }
}
-EXPORT_SYMBOL(retu_free_irq);
+
+/* -------------------------------------------------------------------------- */
/**
* retu_power_off - Shut down power to system
@@ -413,6 +373,7 @@ static int retu_allocate_children(struct device *parent)
static int __init retu_probe(struct platform_device *pdev)
{
struct retu *retu;
+ struct cbus_retu_platform_data *pdata = pdev->dev.platform_data;
int ret = -ENOMEM;
int rev;
@@ -428,12 +389,16 @@ static int __init retu_probe(struct platform_device *pdev)
the_retu = retu;
/* Prepare tasklet */
- tasklet_init(&retu->tasklet, retu_tasklet_handler, 0);
spin_lock_init(&retu->lock);
+ mutex_init(&retu->irq_lock);
irq = platform_get_irq(pdev, 0);
retu->irq = irq;
+ retu->irq_base = pdata->irq_base;
+ retu->irq_end = pdata->irq_end;
+
+ retu_irq_init(retu);
rev = retu_read_reg(RETU_REG_ASICR) & 0xff;
if (rev & (1 << 7))
@@ -446,7 +411,7 @@ static int __init retu_probe(struct platform_device *pdev)
/* Mask all RETU interrupts */
retu_write_reg(RETU_REG_IMR, 0xffff);
- ret = request_irq(irq, retu_irq_handler, 0,
+ ret = request_threaded_irq(irq, NULL, retu_irq_handler, 0,
"retu", retu);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to register IRQ handler\n");
@@ -471,7 +436,6 @@ err2:
free_irq(irq, retu);
err1:
- tasklet_kill(&retu->tasklet);
kfree(retu);
the_retu = NULL;
@@ -489,7 +453,7 @@ static int __exit retu_remove(struct platform_device *pdev)
/* Mask all RETU interrupts */
retu_write_reg(RETU_REG_IMR, 0xffff);
free_irq(irq, retu);
- tasklet_kill(&retu->tasklet);
+ retu_irq_exit(retu);
kfree(retu);
the_retu = NULL;
diff --git a/drivers/cbus/retu.h b/drivers/cbus/retu.h
index ada7f2e..1b05f3e 100644
--- a/drivers/cbus/retu.h
+++ b/drivers/cbus/retu.h
@@ -62,10 +62,5 @@ int retu_read_reg(unsigned reg);
void retu_write_reg(unsigned reg, u16 val);
void retu_set_clear_reg_bits(unsigned reg, u16 set, u16 clear);
int retu_read_adc(int channel);
-int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name);
-void retu_free_irq(int id);
-void retu_enable_irq(int id);
-void retu_disable_irq(int id);
-void retu_ack_irq(int id);
#endif /* __DRIVERS_CBUS_RETU_H */
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 08/13] cbus: retu: headset: convert to threaded_irq
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (6 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 07/13] cbus: retu: move to threaded IRQ and GENIRQ Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 09/13] cbus: retu-pwrbutton: convert to threaded irq Felipe Balbi
` (5 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
use the new irq_chip added to retu.c.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/Makefile | 2 +-
drivers/cbus/retu-headset.c | 22 ++++++++++++----------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/cbus/Makefile b/drivers/cbus/Makefile
index 3375b82..841bed5 100644
--- a/drivers/cbus/Makefile
+++ b/drivers/cbus/Makefile
@@ -12,4 +12,4 @@ obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o
#obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
#obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
#obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
-#obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
+obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
diff --git a/drivers/cbus/retu-headset.c b/drivers/cbus/retu-headset.c
index f5fb50c..2aa4d30 100644
--- a/drivers/cbus/retu-headset.c
+++ b/drivers/cbus/retu-headset.c
@@ -22,6 +22,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/input.h>
@@ -84,7 +86,6 @@ static void retu_headset_det_enable(struct retu_headset *hs)
if (!hs->detection_enabled) {
hs->detection_enabled = 1;
retu_set_clear_reg_bits(RETU_REG_CC1, (1 << 10) | (1 << 8), 0);
- retu_enable_irq(RETU_INT_HOOK);
}
mutex_unlock(&hs->mutex);
}
@@ -96,7 +97,6 @@ static void retu_headset_det_disable(struct retu_headset *hs)
mutex_lock(&hs->mutex);
if (hs->detection_enabled) {
hs->detection_enabled = 0;
- retu_disable_irq(RETU_INT_HOOK);
del_timer_sync(&hs->enable_timer);
del_timer_sync(&hs->detect_timer);
spin_lock_irqsave(&hs->lock, flags);
@@ -177,12 +177,11 @@ static DEVICE_ATTR(enable_det, S_IRUGO | S_IWUSR | S_IWGRP,
retu_headset_enable_det_show,
retu_headset_enable_det_store);
-static void retu_headset_hook_interrupt(unsigned long arg)
+static irqreturn_t retu_headset_hook_interrupt(int irq, void *_hs)
{
- struct retu_headset *hs = (struct retu_headset *) arg;
- unsigned long flags;
+ struct retu_headset *hs = _hs;
+ unsigned long flags;
- retu_ack_irq(RETU_INT_HOOK);
spin_lock_irqsave(&hs->lock, flags);
if (!hs->pressed) {
/* Headset button was just pressed down. */
@@ -192,6 +191,8 @@ static void retu_headset_hook_interrupt(unsigned long arg)
spin_unlock_irqrestore(&hs->lock, flags);
retu_set_clear_reg_bits(RETU_REG_CC1, 0, (1 << 10) | (1 << 8));
mod_timer(&hs->enable_timer, jiffies + msecs_to_jiffies(50));
+
+ return IRQ_HANDLED;
}
static void retu_headset_enable_timer(unsigned long arg)
@@ -257,13 +258,13 @@ static int __init retu_headset_probe(struct platform_device *pdev)
setup_timer(&hs->detect_timer, retu_headset_detect_timer,
(unsigned long) hs);
- r = retu_request_irq(RETU_INT_HOOK, retu_headset_hook_interrupt,
- (unsigned long) hs, "hookdet");
+ r = request_threaded_irq(RETU_INT_HOOK, NULL,
+ retu_headset_hook_interrupt, 0, "hookdet", hs);
if (r != 0) {
dev_err(&pdev->dev, "hookdet IRQ not available\n");
goto err6;
}
- retu_disable_irq(RETU_INT_HOOK);
+
return 0;
err6:
device_remove_file(&pdev->dev, &dev_attr_enable_det);
@@ -289,9 +290,10 @@ static int retu_headset_remove(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_enable_det);
retu_headset_disable(hs);
retu_headset_det_disable(hs);
- retu_free_irq(RETU_INT_HOOK);
+ free_irq(RETU_INT_HOOK, hs);
input_unregister_device(hs->idev);
input_free_device(hs->idev);
+
return 0;
}
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 09/13] cbus: retu-pwrbutton: convert to threaded irq
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (7 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 08/13] cbus: retu: headset: convert to threaded_irq Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 10/13] cbus: retu-rtc: move " Felipe Balbi
` (4 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Drop the timer function and move to threaded
irq infrastructure.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/Makefile | 2 +-
drivers/cbus/retu-pwrbutton.c | 37 +++++++++----------------------------
2 files changed, 10 insertions(+), 29 deletions(-)
diff --git a/drivers/cbus/Makefile b/drivers/cbus/Makefile
index 841bed5..23f82b4 100644
--- a/drivers/cbus/Makefile
+++ b/drivers/cbus/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_CBUS_TAHVO_USB) += tahvo-usb.o
obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o
## Disable Retu children until converted to threaded IRQ
-#obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
+obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
#obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
#obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
diff --git a/drivers/cbus/retu-pwrbutton.c b/drivers/cbus/retu-pwrbutton.c
index 6b8dfa9..2a5ccb0 100644
--- a/drivers/cbus/retu-pwrbutton.c
+++ b/drivers/cbus/retu-pwrbutton.c
@@ -30,9 +30,10 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/input.h>
-#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -46,15 +47,14 @@
struct retu_pwrbutton {
struct input_dev *idev;
- struct timer_list timer;
int state;
int irq;
};
-static void retubutton_timer_func(unsigned long arg)
+static irqreturn_t retubutton_irq(int irq, void *_pwr)
{
- struct retu_pwrbutton *pwr = (struct retu_pwrbutton *) arg;
+ struct retu_pwrbutton *pwr = _pwr;
int state;
if (retu_read_reg(RETU_REG_STATUS) & RETU_STATUS_PWRONX)
@@ -67,24 +67,10 @@ static void retubutton_timer_func(unsigned long arg)
input_sync(pwr->idev);
pwr->state = state;
}
-}
-
-/**
- * Interrupt function is called whenever power button key is pressed
- * or released.
- */
-static void retubutton_irq(unsigned long arg)
-{
- struct retu_pwrbutton *pwr = (struct retu_pwrbutton *) arg;
- retu_ack_irq(RETU_INT_PWR);
- mod_timer(&pwr->timer, jiffies + msecs_to_jiffies(PWRBTN_DELAY));
+ return IRQ_HANDLED;
}
-/**
- * Init function.
- * Allocates interrupt for power button and registers itself to input layer.
- */
static int __init retubutton_probe(struct platform_device *pdev)
{
struct retu_pwrbutton *pwr;
@@ -99,10 +85,9 @@ static int __init retubutton_probe(struct platform_device *pdev)
pwr->irq = RETU_INT_PWR;
platform_set_drvdata(pdev, pwr);
- setup_timer(&pwr->timer, retubutton_timer_func, (unsigned long) pwr);
- ret = retu_request_irq(pwr->irq, retubutton_irq, (unsigned long) pwr,
- "PwrOnX");
+ ret = request_threaded_irq(pwr->irq, NULL, retubutton_irq, 0,
+ "retu-pwrbutton", pwr);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot allocate irq\n");
goto err1;
@@ -131,7 +116,7 @@ err3:
input_free_device(pwr->idev);
err2:
- retu_free_irq(pwr->irq);
+ free_irq(pwr->irq, pwr);
err1:
kfree(pwr);
@@ -140,15 +125,11 @@ err0:
return ret;
}
-/**
- * Cleanup function which is called when driver is unloaded
- */
static int __exit retubutton_remove(struct platform_device *pdev)
{
struct retu_pwrbutton *pwr = platform_get_drvdata(pdev);
- retu_free_irq(pwr->irq);
- del_timer_sync(&pwr->timer);
+ free_irq(pwr->irq, pwr);
input_unregister_device(pwr->idev);
input_free_device(pwr->idev);
kfree(pwr);
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 10/13] cbus: retu-rtc: move to threaded irq
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (8 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 09/13] cbus: retu-pwrbutton: convert to threaded irq Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 11/13] cbus: retu-rtc: drop the reset_occurred flag Felipe Balbi
` (3 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Move to the generic threaded irq infrastructure
and drop all the retu-specific magic.
Unfortunately, due to the conversion and lack of
docs, retu_rtc_ioctl() had to be dropped, someone
else with access to docs is free to implement it
later considering the new style of the driver.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/Makefile | 2 +-
drivers/cbus/retu-rtc.c | 120 ++++++----------------------------------------
2 files changed, 17 insertions(+), 105 deletions(-)
diff --git a/drivers/cbus/Makefile b/drivers/cbus/Makefile
index 23f82b4..7bfd997 100644
--- a/drivers/cbus/Makefile
+++ b/drivers/cbus/Makefile
@@ -10,6 +10,6 @@ obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o
## Disable Retu children until converted to threaded IRQ
obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
-#obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
+obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
#obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
diff --git a/drivers/cbus/retu-rtc.c b/drivers/cbus/retu-rtc.c
index cc789ed..6e201aa 100644
--- a/drivers/cbus/retu-rtc.c
+++ b/drivers/cbus/retu-rtc.c
@@ -38,11 +38,9 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/completion.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/rtc.h>
-#include <linux/workqueue.h>
#include "cbus.h"
#include "retu.h"
@@ -50,8 +48,6 @@
struct retu_rtc {
/* device lock */
struct mutex mutex;
- struct completion sync;
- struct work_struct work;
struct device *dev;
struct rtc_device *rtc;
@@ -59,18 +55,6 @@ struct retu_rtc {
u16 reset_occurred;
};
-#define work_to_rtc(r) (container_of(r, struct retu_rtc, work))
-
-/* This function provides syncronization with the RTCS interrupt handler */
-static void retu_rtc_barrier(struct retu_rtc *rtc)
-{
- INIT_COMPLETION(rtc->sync);
- retu_ack_irq(RETU_INT_RTCS);
- retu_enable_irq(RETU_INT_RTCS);
- wait_for_completion(&rtc->sync);
- retu_disable_irq(RETU_INT_RTCS);
-}
-
static void retu_rtc_do_reset(struct retu_rtc *rtc)
{
u16 ccr1;
@@ -81,7 +65,6 @@ static void retu_rtc_do_reset(struct retu_rtc *rtc)
/* RTC in normal operating mode */
retu_write_reg(RETU_REG_CC1, ccr1 & ~0x0001);
- retu_rtc_barrier(rtc);
/* Disable alarm and RTC WD */
retu_write_reg(RETU_REG_RTCHMAR, 0x7f3f);
/* Set Calibration register to default value */
@@ -91,62 +74,33 @@ static void retu_rtc_do_reset(struct retu_rtc *rtc)
rtc->reset_occurred = 1;
}
-static void retu_rtca_disable(struct retu_rtc *rtc)
+static irqreturn_t retu_rtc_interrupt(int irq, void *_rtc)
{
- retu_disable_irq(RETU_INT_RTCA);
+ struct retu_rtc *rtc = _rtc;
+
+ mutex_lock(&rtc->mutex);
rtc->alarm_expired = 1;
- retu_rtc_barrier(rtc);
retu_write_reg(RETU_REG_RTCHMAR, (24 << 8) | 60);
-}
-
-static void retu_rtca_expired(struct work_struct *work)
-{
- struct retu_rtc *rtc = work_to_rtc(work);
-
- retu_rtca_disable(rtc);
-}
-
-/*
- * RTCHMR RTCHMAR RTCCAL must be accessed within 0.9 s since the seconds
- * interrupt has been signaled in the IDR register
- */
-static void retu_rtcs_interrupt(unsigned long _rtc)
-{
- struct retu_rtc *rtc = (struct retu_rtc *) _rtc;
-
- retu_ack_irq(RETU_INT_RTCS);
- complete_all(&rtc->sync);
-}
-
-static void retu_rtca_interrupt(unsigned long _rtc)
-{
- struct retu_rtc *rtc = (struct retu_rtc *) _rtc;
+ mutex_unlock(&rtc->mutex);
- retu_ack_irq(RETU_INT_RTCA);
- schedule_work(&rtc->work);
+ return IRQ_HANDLED;
}
static int retu_rtc_init_irq(struct retu_rtc *rtc)
{
int ret;
- ret = retu_request_irq(RETU_INT_RTCS, retu_rtcs_interrupt,
- (unsigned long) rtc, "RTCS");
+ ret = request_threaded_irq(RETU_INT_RTCS, NULL, retu_rtc_interrupt,
+ 0, "RTCS", rtc);
if (ret != 0)
return ret;
- /*
- * We will take care of enabling and disabling the interrupt
- * elsewhere, so leave it off by default..
- */
- retu_disable_irq(RETU_INT_RTCS);
- ret = retu_request_irq(RETU_INT_RTCA, retu_rtca_interrupt,
- (unsigned long) rtc, "RTCA");
+ ret = request_threaded_irq(RETU_INT_RTCA, NULL, retu_rtc_interrupt,
+ 0, "RTCA", rtc);
if (ret != 0) {
- retu_free_irq(RETU_INT_RTCS);
+ free_irq(RETU_INT_RTCS, rtc);
return ret;
}
- retu_disable_irq(RETU_INT_RTCA);
return 0;
}
@@ -231,42 +185,7 @@ static int retu_rtc_read_time(struct device *dev, struct rtc_time *tm)
return 0;
}
-#ifdef CONFIG_RTC_INTF_DEV
-
-static int retu_rtc_ioctl(struct device *dev, unsigned int cmd,
- unsigned long arg)
-{
- struct retu_rtc *rtc = dev_get_drvdata(dev);
-
- mutex_lock(&rtc->mutex);
-
- switch (cmd) {
- case RTC_AIE_OFF:
- retu_disable_irq(RETU_INT_RTCA);
- break;
- case RTC_AIE_ON:
- retu_enable_irq(RETU_INT_RTCA);
- break;
- case RTC_UIE_OFF:
- retu_disable_irq(RETU_INT_RTCS);
- break;
- case RTC_UIE_ON:
- retu_enable_irq(RETU_INT_RTCS);
- break;
- default:
- return -ENOIOCTLCMD;
- }
-
- mutex_unlock(&rtc->mutex);
-
- return 0;
-}
-#else
-#define retu_rtc_ioctl NULL
-#endif
-
static struct rtc_class_ops retu_rtc_ops = {
- .ioctl = retu_rtc_ioctl,
.read_time = retu_rtc_read_time,
.set_time = retu_rtc_set_time,
.read_alarm = retu_rtc_read_alarm,
@@ -287,9 +206,7 @@ static int __init retu_rtc_probe(struct platform_device *pdev)
rtc->dev = &pdev->dev;
platform_set_drvdata(pdev, rtc);
- INIT_WORK(&rtc->work, retu_rtca_expired);
mutex_init(&rtc->mutex);
- init_completion(&rtc->sync);
r = retu_get_status();
if (!r) {
@@ -324,10 +241,8 @@ static int __init retu_rtc_probe(struct platform_device *pdev)
return 0;
err2:
- retu_disable_irq(RETU_INT_RTCS);
- retu_disable_irq(RETU_INT_RTCA);
- retu_free_irq(RETU_INT_RTCS);
- retu_free_irq(RETU_INT_RTCA);
+ free_irq(RETU_INT_RTCS, rtc);
+ free_irq(RETU_INT_RTCA, rtc);
err1:
kfree(rtc);
@@ -340,10 +255,8 @@ static int __devexit retu_rtc_remove(struct platform_device *pdev)
{
struct retu_rtc *rtc = platform_get_drvdata(pdev);
- retu_disable_irq(RETU_INT_RTCS);
- retu_disable_irq(RETU_INT_RTCA);
- retu_free_irq(RETU_INT_RTCS);
- retu_free_irq(RETU_INT_RTCA);
+ free_irq(RETU_INT_RTCS, rtc);
+ free_irq(RETU_INT_RTCA, rtc);
rtc_device_unregister(rtc->rtc);
kfree(rtc);
@@ -361,13 +274,12 @@ static int __init retu_rtc_init(void)
{
return platform_driver_probe(&retu_rtc_driver, retu_rtc_probe);
}
+module_init(retu_rtc_init);
static void __exit retu_rtc_exit(void)
{
platform_driver_unregister(&retu_rtc_driver);
}
-
-module_init(retu_rtc_init);
module_exit(retu_rtc_exit);
MODULE_DESCRIPTION("Retu RTC");
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 11/13] cbus: retu-rtc: drop the reset_occurred flag
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (9 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 10/13] cbus: retu-rtc: move " Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 12/13] cbus: Makefile: re-enable retu-wdt Felipe Balbi
` (2 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
that flag is never read anyway, only written,
so we can drop it.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/retu-rtc.c | 10 ++--------
1 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/cbus/retu-rtc.c b/drivers/cbus/retu-rtc.c
index 6e201aa..b2b9472 100644
--- a/drivers/cbus/retu-rtc.c
+++ b/drivers/cbus/retu-rtc.c
@@ -52,7 +52,6 @@ struct retu_rtc {
struct rtc_device *rtc;
u16 alarm_expired;
- u16 reset_occurred;
};
static void retu_rtc_do_reset(struct retu_rtc *rtc)
@@ -71,7 +70,6 @@ static void retu_rtc_do_reset(struct retu_rtc *rtc)
retu_write_reg(RETU_REG_RTCCALR, 0x00c0);
rtc->alarm_expired = 0;
- rtc->reset_occurred = 1;
}
static irqreturn_t retu_rtc_interrupt(int irq, void *_rtc)
@@ -223,14 +221,10 @@ static int __init retu_rtc_probe(struct platform_device *pdev)
goto err1;
}
- /* If the calibration register is zero, we've probably lost
- * power */
- if (retu_read_reg(RETU_REG_RTCCALR) & 0x00ff)
- rtc->reset_occurred = 0;
- else
+ /* If the calibration register is zero, we've probably lost power */
+ if (!(retu_read_reg(RETU_REG_RTCCALR) & 0x00ff))
retu_rtc_do_reset(rtc);
-
rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &
retu_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 12/13] cbus: Makefile: re-enable retu-wdt
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (10 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 11/13] cbus: retu-rtc: drop the reset_occurred flag Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 13/13] cbus: tahvo: drop tahvo-user Felipe Balbi
2011-02-10 2:43 ` [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Tony Lindgren
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
Now that all conversions have been made,
reenable retu-wdt driver.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/Makefile | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/cbus/Makefile b/drivers/cbus/Makefile
index 7bfd997..c5c3940 100644
--- a/drivers/cbus/Makefile
+++ b/drivers/cbus/Makefile
@@ -8,8 +8,7 @@ obj-$(CONFIG_CBUS_RETU) += retu.o
obj-$(CONFIG_CBUS_TAHVO_USB) += tahvo-usb.o
obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o
-## Disable Retu children until converted to threaded IRQ
obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
-#obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
+obj-$(CONFIG_CBUS_RETU_WDT) += retu-wdt.o
obj-$(CONFIG_CBUS_RETU_HEADSET) += retu-headset.o
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFT/RFC/PATCH 13/13] cbus: tahvo: drop tahvo-user
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (11 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 12/13] cbus: Makefile: re-enable retu-wdt Felipe Balbi
@ 2011-02-03 10:20 ` Felipe Balbi
2011-02-10 2:43 ` [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Tony Lindgren
13 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-03 10:20 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi
get rid of the non-standard way of accessing
the chip.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
drivers/cbus/Kconfig | 7 -
drivers/cbus/Makefile | 1 -
drivers/cbus/tahvo-user.c | 406 ---------------------------------------------
drivers/cbus/tahvo.c | 11 --
drivers/cbus/tahvo.h | 5 -
5 files changed, 0 insertions(+), 430 deletions(-)
delete mode 100644 drivers/cbus/tahvo-user.c
diff --git a/drivers/cbus/Kconfig b/drivers/cbus/Kconfig
index 9a827a2..2667dff 100644
--- a/drivers/cbus/Kconfig
+++ b/drivers/cbus/Kconfig
@@ -21,13 +21,6 @@ config CBUS_TAHVO
If you want Tahvo support, you should say Y here.
-config CBUS_TAHVO_USER
- depends on CBUS_TAHVO
- bool "Support for Tahvo user space functions"
- ---help---
- If you want support for Tahvo's user space read/write etc. functions,
- you should say Y here.
-
config CBUS_TAHVO_USB
depends on CBUS_TAHVO && USB
tristate "Support for Tahvo USB transceiver"
diff --git a/drivers/cbus/Makefile b/drivers/cbus/Makefile
index c5c3940..483c3ca 100644
--- a/drivers/cbus/Makefile
+++ b/drivers/cbus/Makefile
@@ -6,7 +6,6 @@ obj-$(CONFIG_CBUS) += cbus.o
obj-$(CONFIG_CBUS_TAHVO) += tahvo.o
obj-$(CONFIG_CBUS_RETU) += retu.o
obj-$(CONFIG_CBUS_TAHVO_USB) += tahvo-usb.o
-obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o
obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
obj-$(CONFIG_CBUS_RETU_RTC) += retu-rtc.o
diff --git a/drivers/cbus/tahvo-user.c b/drivers/cbus/tahvo-user.c
deleted file mode 100644
index 9cfc71c..0000000
--- a/drivers/cbus/tahvo-user.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/**
- * drivers/cbus/tahvo-user.c
- *
- * Tahvo user space interface functions
- *
- * Copyright (C) 2004, 2005 Nokia Corporation
- *
- * Written by Mikko Ylinen <mikko.k.ylinen@nokia.com>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file "COPYING" in the main directory of this
- * archive for more details.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/poll.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-
-#include "tahvo.h"
-
-#include "user_retu_tahvo.h"
-
-/* Maximum size of IRQ node buffer/pool */
-#define TAHVO_MAX_IRQ_BUF_LEN 16
-
-#define PFX "tahvo-user: "
-
-/* Bitmap for marking the interrupt sources as having the handlers */
-static u32 tahvo_irq_bits;
-
-/* For allowing only one user process to subscribe to the tahvo interrupts */
-static struct file *tahvo_irq_subscr = NULL;
-
-/* For poll and IRQ passing */
-struct tahvo_irq {
- u32 id;
- struct list_head node;
-};
-
-static spinlock_t tahvo_irqs_lock;
-static struct tahvo_irq *tahvo_irq_block;
-static LIST_HEAD(tahvo_irqs);
-static LIST_HEAD(tahvo_irqs_reserve);
-
-/* Wait queue - used when user wants to read the device */
-DECLARE_WAIT_QUEUE_HEAD(tahvo_user_waitqueue);
-
-/* Semaphore to protect irq subscription sequence */
-static struct mutex tahvo_mutex;
-
-/* This array specifies TAHVO register types (read/write/toggle) */
-static const u8 tahvo_access_bits[] = {
- 1,
- 4,
- 1,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 1
-};
-
-/*
- * The handler for all TAHVO interrupts.
- *
- * arg is the interrupt source in TAHVO.
- */
-static void tahvo_user_irq_handler(unsigned long arg)
-{
- struct tahvo_irq *irq;
-
- /* user has to re-enable the interrupt once ready
- * for receiving them again */
- tahvo_disable_irq(arg);
- tahvo_ack_irq(arg);
-
- spin_lock(&tahvo_irqs_lock);
- if (list_empty(&tahvo_irqs_reserve)) {
- spin_unlock(&tahvo_irqs_lock);
- return;
- }
- irq = list_entry((&tahvo_irqs_reserve)->next, struct tahvo_irq, node);
- irq->id = arg;
- list_move_tail(&irq->node, &tahvo_irqs);
- spin_unlock(&tahvo_irqs_lock);
-
- /* wake up waiting thread */
- wake_up(&tahvo_user_waitqueue);
-}
-
-/*
- * This routine sets up the interrupt handler and marks an interrupt source
- * in TAHVO as a candidate for signal delivery to the user process.
- */
-static int tahvo_user_subscribe_to_irq(int id, struct file *filp)
-{
- int ret;
-
- mutex_lock(&tahvo_mutex);
- if ((tahvo_irq_subscr != NULL) && (tahvo_irq_subscr != filp)) {
- mutex_unlock(&tahvo_mutex);
- return -EBUSY;
- }
- /* Store the file pointer of the first user process registering IRQs */
- tahvo_irq_subscr = filp;
- mutex_unlock(&tahvo_mutex);
-
- if (tahvo_irq_bits & (1 << id))
- return 0;
-
- ret = tahvo_request_irq(id, tahvo_user_irq_handler, id, "");
- if (ret < 0)
- return ret;
-
- /* Mark that this interrupt has a handler */
- tahvo_irq_bits |= 1 << id;
-
- return 0;
-}
-
-/*
- * Unregister all TAHVO interrupt handlers
- */
-static void tahvo_unreg_irq_handlers(void)
-{
- int id;
-
- if (!tahvo_irq_bits)
- return;
-
- for (id = 0; id < MAX_TAHVO_IRQ_HANDLERS; id++)
- if (tahvo_irq_bits & (1 << id))
- tahvo_free_irq(id);
-
- tahvo_irq_bits = 0;
-}
-
-/*
- * Write to TAHVO register.
- * Returns 0 upon success, a negative error value otherwise.
- */
-static int tahvo_user_write_with_mask(u32 field, u16 value)
-{
- u32 mask;
- u32 reg;
- u_short tmp;
- unsigned long flags;
-
- mask = MASK(field);
- reg = REG(field);
-
- /* Detect bad mask and reg */
- if (mask == 0 || reg > TAHVO_REG_MAX ||
- tahvo_access_bits[reg] == READ_ONLY) {
- printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
- reg, mask);
- return -EINVAL;
- }
-
- /* Justify value according to mask */
- while (!(mask & 1)) {
- value = value << 1;
- mask = mask >> 1;
- }
-
- spin_lock_irqsave(&tahvo_lock, flags);
- if (tahvo_access_bits[reg] == TOGGLE) {
- /* No need to detect previous content of register */
- tmp = 0;
- } else {
- /* Read current value of register */
- tmp = tahvo_read_reg(reg);
- }
- /* Generate a new value */
- tmp = (tmp & ~MASK(field)) | (value & MASK(field));
- /* Write data to TAHVO */
- tahvo_write_reg(reg, tmp);
- spin_unlock_irqrestore(&tahvo_lock, flags);
-
- return 0;
-}
-
-/*
- * Read TAHVO register.
- */
-static u32 tahvo_user_read_with_mask(u32 field)
-{
- u_short value;
- u32 mask, reg;
-
- mask = MASK(field);
- reg = REG(field);
-
- /* Detect bad mask and reg */
- if (mask == 0 || reg > TAHVO_REG_MAX) {
- printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
- reg, mask);
- return -EINVAL;
- }
-
- /* Read the register */
- value = tahvo_read_reg(reg) & mask;
-
- /* Right justify value */
- while (!(mask & 1)) {
- value = value >> 1;
- mask = mask >> 1;
- }
-
- return value;
-}
-
-/*
- * Close device
- */
-static int tahvo_close(struct inode *inode, struct file *filp)
-{
- /* Unregister all interrupts that have been registered */
- if (tahvo_irq_subscr == filp) {
- tahvo_unreg_irq_handlers();
- tahvo_irq_subscr = NULL;
- }
-
- return 0;
-}
-
-/*
- * Device control (ioctl)
- */
-static long tahvo_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- struct retu_tahvo_write_parms par;
- int ret;
-
- switch (cmd) {
- case URT_IOCT_IRQ_SUBSCR:
- return tahvo_user_subscribe_to_irq(arg, filp);
- case TAHVO_IOCH_READ:
- return tahvo_user_read_with_mask(arg);
- case TAHVO_IOCX_WRITE:
- ret = copy_from_user(&par, (void __user *) arg, sizeof(par));
- if (ret)
- printk(KERN_ERR "copy_from_user failed: %d\n", ret);
- par.result = tahvo_user_write_with_mask(par.field, par.value);
- ret = copy_to_user((void __user *) arg, &par, sizeof(par));
- if (ret)
- printk(KERN_ERR "copy_to_user failed: %d\n", ret);
- break;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-/*
- * Read from device
- */
-static ssize_t tahvo_read(struct file *filp, char *buf, size_t count,
- loff_t * offp)
-{
- struct tahvo_irq *irq;
-
- u32 nr, i;
-
- /* read not permitted if neither filp nor anyone has registered IRQs */
- if (tahvo_irq_subscr != filp)
- return -EPERM;
-
- if ((count < sizeof(u32)) || ((count % sizeof(u32)) != 0))
- return -EINVAL;
-
- nr = count / sizeof(u32);
-
- for (i = 0; i < nr; i++) {
- unsigned long flags;
- u32 irq_id;
- int ret;
-
- ret = wait_event_interruptible(tahvo_user_waitqueue,
- !list_empty(&tahvo_irqs));
- if (ret < 0)
- return ret;
-
- spin_lock_irqsave(&tahvo_irqs_lock, flags);
- irq = list_entry((&tahvo_irqs)->next, struct tahvo_irq, node);
- irq_id = irq->id;
- list_move(&irq->node, &tahvo_irqs_reserve);
- spin_unlock_irqrestore(&tahvo_irqs_lock, flags);
-
- ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
- sizeof(irq_id));
- if (ret)
- printk(KERN_ERR "copy_to_user failed: %d\n", ret);
- }
-
- return count;
-}
-
-/*
- * Poll method
- */
-static unsigned tahvo_poll(struct file *filp, struct poll_table_struct *pt)
-{
- if (!list_empty(&tahvo_irqs))
- return POLLIN;
-
- poll_wait(filp, &tahvo_user_waitqueue, pt);
-
- if (!list_empty(&tahvo_irqs))
- return POLLIN;
- else
- return 0;
-}
-
-static struct file_operations tahvo_user_fileops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = tahvo_ioctl,
- .read = tahvo_read,
- .release = tahvo_close,
- .poll = tahvo_poll
-};
-
-static struct miscdevice tahvo_device = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "tahvo",
- .fops = &tahvo_user_fileops
-};
-
-/*
- * Initialization
- *
- * @return 0 if successful, error value otherwise.
- */
-int tahvo_user_init(void)
-{
- struct tahvo_irq *irq;
- int res, i;
-
- irq = kzalloc(sizeof(*irq) * TAHVO_MAX_IRQ_BUF_LEN, GFP_KERNEL);
- if (irq == NULL) {
- printk(KERN_ERR PFX "kzalloc failed\n");
- return -ENOMEM;
- }
-
- for (i = 0; i < TAHVO_MAX_IRQ_BUF_LEN; i++)
- list_add(&irq[i].node, &tahvo_irqs_reserve);
-
- tahvo_irq_block = irq;
-
- spin_lock_init(&tahvo_irqs_lock);
- mutex_init(&tahvo_mutex);
-
- /* Request a misc device */
- res = misc_register(&tahvo_device);
- if (res < 0) {
- printk(KERN_ERR PFX "unable to register misc device for %s\n",
- tahvo_device.name);
- kfree(irq);
- return res;
- }
-
- return 0;
-}
-
-/*
- * Cleanup.
- */
-void tahvo_user_cleanup(void)
-{
- /* Unregister our misc device */
- misc_deregister(&tahvo_device);
- /* Unregister and disable all TAHVO interrupts */
- tahvo_unreg_irq_handlers();
- kfree(tahvo_irq_block);
-}
-
-MODULE_DESCRIPTION("Tahvo ASIC user space functions");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mikko Ylinen");
diff --git a/drivers/cbus/tahvo.c b/drivers/cbus/tahvo.c
index 9699056..8e2e669 100644
--- a/drivers/cbus/tahvo.c
+++ b/drivers/cbus/tahvo.c
@@ -338,14 +338,6 @@ static int __init tahvo_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Unable to register IRQ handler\n");
return ret;
}
-#ifdef CONFIG_CBUS_TAHVO_USER
- /* Initialize user-space interface */
- if (tahvo_user_init() < 0) {
- dev_err(&pdev->dev, "Unable to initialize driver\n");
- free_irq(irq, 0);
- return ret;
- }
-#endif
return 0;
}
@@ -355,9 +347,6 @@ static int __exit tahvo_remove(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
-#ifdef CONFIG_CBUS_TAHVO_USER
- tahvo_user_cleanup();
-#endif
/* Mask all TAHVO interrupts */
tahvo_write_reg(TAHVO_REG_IMR, 0xffff);
free_irq(irq, 0);
diff --git a/drivers/cbus/tahvo.h b/drivers/cbus/tahvo.h
index 97d6583..066aa5d 100644
--- a/drivers/cbus/tahvo.h
+++ b/drivers/cbus/tahvo.h
@@ -52,11 +52,6 @@ int tahvo_get_backlight_level(void);
int tahvo_get_max_backlight_level(void);
void tahvo_set_backlight_level(int level);
-#ifdef CONFIG_CBUS_TAHVO_USER
-int tahvo_user_init(void);
-void tahvo_user_cleanup(void);
-#endif
-
extern spinlock_t tahvo_lock;
#endif /* __DRIVERS_CBUS_TAHVO_H */
--
1.7.4.rc2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
` (12 preceding siblings ...)
2011-02-03 10:20 ` [RFT/RFC/PATCH 13/13] cbus: tahvo: drop tahvo-user Felipe Balbi
@ 2011-02-10 2:43 ` Tony Lindgren
2011-02-10 9:14 ` Felipe Balbi
13 siblings, 1 reply; 16+ messages in thread
From: Tony Lindgren @ 2011-02-10 2:43 UTC (permalink / raw)
To: Felipe Balbi; +Cc: Linux OMAP Mailing List
* Felipe Balbi <balbi@ti.com> [110203 02:20]:
> Hi Tony,
>
> When you have some extra time, could you run these on N810
> to check whether I'm on the right path ? After these patches
> all CBUS drivers are using standard request_threaded_irq()
> calls. It's one step closer into getting those in mainline.
Cool sorry it took a while, this is starting to look like
it will be pretty close to be posted for merging :)
I guess we should move files around to have:
drivers/mfd/cbus-retu.c
drivers/mfd/cbus-tahvo.c
drivers/rtc/rtc-cbus-retu.c
...
Anything else remaining to do?
Also the following patch was needed to get this to boot
with interrupts working. Maybe you have a better plan
for getting the retu irq_base?
Anyways, since n8x0 boots and stays up, we know it's
working, so I've pushed them all to the cbus branch.
Regards,
Tony
From: Tony Lindgren <tony@atomide.com>
Date: Wed, 9 Feb 2011 18:36:16 -0800
Subject: [PATCH] cbus: Fix nested interrupts for retu
We need to add the retu irq base number to the interrupt
number for children.
This could be done by passing the interrupt base for
children in platform_data also I guess.
Signed-off-by: Tony Lindgren <tony@atomide.com>
--- a/drivers/cbus/retu-headset.c
+++ b/drivers/cbus/retu-headset.c
@@ -258,7 +258,7 @@ static int __init retu_headset_probe(struct platform_device *pdev)
setup_timer(&hs->detect_timer, retu_headset_detect_timer,
(unsigned long) hs);
- r = request_threaded_irq(RETU_INT_HOOK, NULL,
+ r = request_threaded_irq(CBUS_RETU_IRQ_BASE + RETU_INT_HOOK, NULL,
retu_headset_hook_interrupt, 0, "hookdet", hs);
if (r != 0) {
dev_err(&pdev->dev, "hookdet IRQ not available\n");
@@ -290,7 +290,7 @@ static int retu_headset_remove(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_enable_det);
retu_headset_disable(hs);
retu_headset_det_disable(hs);
- free_irq(RETU_INT_HOOK, hs);
+ free_irq(CBUS_RETU_IRQ_BASE + RETU_INT_HOOK, hs);
input_unregister_device(hs->idev);
input_free_device(hs->idev);
--- a/drivers/cbus/retu-pwrbutton.c
+++ b/drivers/cbus/retu-pwrbutton.c
@@ -83,7 +83,7 @@ static int __init retubutton_probe(struct platform_device *pdev)
goto err0;
}
- pwr->irq = RETU_INT_PWR;
+ pwr->irq = CBUS_RETU_IRQ_BASE + RETU_INT_PWR;
platform_set_drvdata(pdev, pwr);
ret = request_threaded_irq(pwr->irq, NULL, retubutton_irq, 0,
--- a/drivers/cbus/retu-rtc.c
+++ b/drivers/cbus/retu-rtc.c
@@ -88,15 +88,15 @@ static int retu_rtc_init_irq(struct retu_rtc *rtc)
{
int ret;
- ret = request_threaded_irq(RETU_INT_RTCS, NULL, retu_rtc_interrupt,
+ ret = request_threaded_irq(CBUS_RETU_IRQ_BASE + RETU_INT_RTCS, NULL, retu_rtc_interrupt,
0, "RTCS", rtc);
if (ret != 0)
return ret;
- ret = request_threaded_irq(RETU_INT_RTCA, NULL, retu_rtc_interrupt,
+ ret = request_threaded_irq(CBUS_RETU_IRQ_BASE + RETU_INT_RTCA, NULL, retu_rtc_interrupt,
0, "RTCA", rtc);
if (ret != 0) {
- free_irq(RETU_INT_RTCS, rtc);
+ free_irq(CBUS_RETU_IRQ_BASE + RETU_INT_RTCS, rtc);
return ret;
}
@@ -235,8 +235,8 @@ static int __init retu_rtc_probe(struct platform_device *pdev)
return 0;
err2:
- free_irq(RETU_INT_RTCS, rtc);
- free_irq(RETU_INT_RTCA, rtc);
+ free_irq(CBUS_RETU_IRQ_BASE + RETU_INT_RTCS, rtc);
+ free_irq(CBUS_RETU_IRQ_BASE + RETU_INT_RTCA, rtc);
err1:
kfree(rtc);
@@ -249,8 +249,8 @@ static int __devexit retu_rtc_remove(struct platform_device *pdev)
{
struct retu_rtc *rtc = platform_get_drvdata(pdev);
- free_irq(RETU_INT_RTCS, rtc);
- free_irq(RETU_INT_RTCA, rtc);
+ free_irq(CBUS_RETU_IRQ_BASE + RETU_INT_RTCS, rtc);
+ free_irq(CBUS_RETU_IRQ_BASE + RETU_INT_RTCA, rtc);
rtc_device_unregister(rtc->rtc);
kfree(rtc);
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ
2011-02-10 2:43 ` [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Tony Lindgren
@ 2011-02-10 9:14 ` Felipe Balbi
0 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2011-02-10 9:14 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Felipe Balbi, Linux OMAP Mailing List
Hi,
On Wed, Feb 09, 2011 at 06:43:49PM -0800, Tony Lindgren wrote:
> * Felipe Balbi <balbi@ti.com> [110203 02:20]:
> > Hi Tony,
> >
> > When you have some extra time, could you run these on N810
> > to check whether I'm on the right path ? After these patches
> > all CBUS drivers are using standard request_threaded_irq()
> > calls. It's one step closer into getting those in mainline.
>
> Cool sorry it took a while, this is starting to look like
no problem ;-)
> it will be pretty close to be posted for merging :)
yeah, I guess so too.
> I guess we should move files around to have:
>
> drivers/mfd/cbus-retu.c
> drivers/mfd/cbus-tahvo.c
>
> drivers/rtc/rtc-cbus-retu.c
sure we gotta do that.
> Anything else remaining to do?
there are a few things remaining still. The drivers aren't as good as
I'd like them to be yet.
> Also the following patch was needed to get this to boot
> with interrupts working. Maybe you have a better plan
> for getting the retu irq_base?
That's on my TODO list, I need to pass IRQ number via pdata.
> Anyways, since n8x0 boots and stays up, we know it's
> working, so I've pushed them all to the cbus branch.
Cool thanks. I'll update my local cbus branch based on yours and try to
find some time to play with the last few stuff. Maybe I'll have some
small time during the weekend which I could use to play with it.
--
balbi
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2011-02-10 9:14 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-03 10:20 [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 01/13] cbus: retu: get rid of retu-user.c Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 02/13] cbus: retu: give it a context structure Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 03/13] cbus: retu: move module_* close to the matching symbol Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 04/13] cbus: retu: cleanup error path Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 05/13] arm: omap: irqs: add CBUS_RETU_IRQ_BASE and CBUS_RETU_IRQ_END Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 06/13] arm: omap: cbus: pass irq_base and irq_end via platform_data Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 07/13] cbus: retu: move to threaded IRQ and GENIRQ Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 08/13] cbus: retu: headset: convert to threaded_irq Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 09/13] cbus: retu-pwrbutton: convert to threaded irq Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 10/13] cbus: retu-rtc: move " Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 11/13] cbus: retu-rtc: drop the reset_occurred flag Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 12/13] cbus: Makefile: re-enable retu-wdt Felipe Balbi
2011-02-03 10:20 ` [RFT/RFC/PATCH 13/13] cbus: tahvo: drop tahvo-user Felipe Balbi
2011-02-10 2:43 ` [RFT/RFC/PATCH 00/13] CBUS meets GENIRQ Tony Lindgren
2011-02-10 9:14 ` Felipe Balbi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox