Commit 76044b05 authored by Tony Lindgren's avatar Tony Lindgren

Merge branch 'for-tony-mailbox'

Conflicts:

	arch/arm/plat-omap/Kconfig
	arch/arm/plat-omap/include/mach/omap34xx.h
	arch/arm/plat-omap/mailbox.c
parents 4a374e24 bf71df90
......@@ -86,7 +86,7 @@ static struct resource mbox_resources[] = {
};
static struct platform_device mbox_device = {
.name = "mailbox",
.name = "omap1-mailbox",
.id = -1,
.num_resources = ARRAY_SIZE(mbox_resources),
.resource = mbox_resources,
......
/*
* Mailbox reservation modules for DSP
*
* Copyright (C) 2006 Nokia Corporation
* Copyright (C) 2006-2008 Nokia Corporation
* Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
*
* This file is subject to the terms and conditions of the GNU General Public
......@@ -17,6 +17,8 @@
#include <mach/mailbox.h>
#include <mach/irqs.h>
#define DRV_NAME "omap1-mailbox"
#define MAILBOX_ARM2DSP1 0x00
#define MAILBOX_ARM2DSP1b 0x04
#define MAILBOX_DSP2ARM1 0x08
......@@ -27,7 +29,7 @@
#define MAILBOX_DSP2ARM1_Flag 0x1c
#define MAILBOX_DSP2ARM2_Flag 0x20
unsigned long mbox_base;
static void __iomem *mbox_base;
struct omap_mbox1_fifo {
unsigned long cmd;
......@@ -40,14 +42,14 @@ struct omap_mbox1_priv {
struct omap_mbox1_fifo rx_fifo;
};
static inline int mbox_read_reg(unsigned int reg)
static inline int mbox_read_reg(size_t ofs)
{
return __raw_readw(mbox_base + reg);
return __raw_readw(mbox_base + ofs);
}
static inline void mbox_write_reg(unsigned int val, unsigned int reg)
static inline void mbox_write_reg(u32 val, size_t ofs)
{
__raw_writew(val, mbox_base + reg);
__raw_writew(val, mbox_base + ofs);
}
/* msg */
......@@ -143,7 +145,7 @@ struct omap_mbox mbox_dsp_info = {
};
EXPORT_SYMBOL(mbox_dsp_info);
static int __init omap1_mbox_probe(struct platform_device *pdev)
static int __devinit omap1_mbox_probe(struct platform_device *pdev)
{
struct resource *res;
int ret = 0;
......@@ -170,12 +172,10 @@ static int __init omap1_mbox_probe(struct platform_device *pdev)
}
mbox_dsp_info.irq = res->start;
ret = omap_mbox_register(&mbox_dsp_info);
return ret;
return omap_mbox_register(&pdev->dev, &mbox_dsp_info);
}
static int omap1_mbox_remove(struct platform_device *pdev)
static int __devexit omap1_mbox_remove(struct platform_device *pdev)
{
omap_mbox_unregister(&mbox_dsp_info);
......@@ -184,9 +184,9 @@ static int omap1_mbox_remove(struct platform_device *pdev)
static struct platform_driver omap1_mbox_driver = {
.probe = omap1_mbox_probe,
.remove = omap1_mbox_remove,
.remove = __devexit_p(omap1_mbox_remove),
.driver = {
.name = "mailbox",
.name = DRV_NAME,
},
};
......@@ -203,4 +203,7 @@ static void __exit omap1_mbox_exit(void)
module_init(omap1_mbox_init);
module_exit(omap1_mbox_exit);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions");
MODULE_AUTHOR("Hiroshi DOYU" <Hiroshi.DOYU@nokia.com>);
MODULE_ALIAS("platform:"DRV_NAME);
......@@ -85,13 +85,14 @@ static inline void omap_init_camera(void)
}
#endif
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
static struct resource mbox_resources[] = {
#define MBOX_REG_SIZE 0x120
static struct resource omap2_mbox_resources[] = {
{
.start = OMAP2_MBOX_BASE,
.end = OMAP2_MBOX_BASE + 0x11f,
.start = OMAP24XX_MAILBOX_BASE,
.end = OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
......@@ -104,20 +105,39 @@ static struct resource mbox_resources[] = {
},
};
static struct resource omap3_mbox_resources[] = {
{
.start = OMAP34XX_MAILBOX_BASE,
.end = OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_34XX_MAIL_U0_MPU,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device mbox_device = {
.name = "mailbox",
.name = "omap2-mailbox",
.id = -1,
.num_resources = ARRAY_SIZE(mbox_resources),
.resource = mbox_resources,
};
static inline void omap_init_mbox(void)
{
if (cpu_is_omap2420()) {
mbox_device.num_resources = ARRAY_SIZE(omap2_mbox_resources);
mbox_device.resource = omap2_mbox_resources;
} else if (cpu_is_omap3430()) {
mbox_device.num_resources = ARRAY_SIZE(omap3_mbox_resources);
mbox_device.resource = omap3_mbox_resources;
} else {
return;
}
platform_device_register(&mbox_device);
}
#else
static inline void omap_init_mbox(void) { }
#endif
#endif /* CONFIG_OMAP_MBOX_FWK */
#if defined(CONFIG_OMAP_STI)
......
/*
* Mailbox reservation modules for OMAP2
* Mailbox reservation modules for OMAP2/3
*
* Copyright (C) 2006 Nokia Corporation
* Copyright (C) 2006-2008 Nokia Corporation
* Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
* and Paul Mundt <paul.mundt@nokia.com>
* and Paul Mundt
*
* 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
......@@ -18,40 +18,23 @@
#include <mach/mailbox.h>
#include <mach/irqs.h>
#define MAILBOX_REVISION 0x00
#define MAILBOX_SYSCONFIG 0x10
#define MAILBOX_SYSSTATUS 0x14
#define MAILBOX_MESSAGE_0 0x40
#define MAILBOX_MESSAGE_1 0x44
#define MAILBOX_MESSAGE_2 0x48
#define MAILBOX_MESSAGE_3 0x4c
#define MAILBOX_MESSAGE_4 0x50
#define MAILBOX_MESSAGE_5 0x54
#define MAILBOX_FIFOSTATUS_0 0x80
#define MAILBOX_FIFOSTATUS_1 0x84
#define MAILBOX_FIFOSTATUS_2 0x88
#define MAILBOX_FIFOSTATUS_3 0x8c
#define MAILBOX_FIFOSTATUS_4 0x90
#define MAILBOX_FIFOSTATUS_5 0x94
#define MAILBOX_MSGSTATUS_0 0xc0
#define MAILBOX_MSGSTATUS_1 0xc4
#define MAILBOX_MSGSTATUS_2 0xc8
#define MAILBOX_MSGSTATUS_3 0xcc
#define MAILBOX_MSGSTATUS_4 0xd0
#define MAILBOX_MSGSTATUS_5 0xd4
#define MAILBOX_IRQSTATUS_0 0x100
#define MAILBOX_IRQENABLE_0 0x104
#define MAILBOX_IRQSTATUS_1 0x108
#define MAILBOX_IRQENABLE_1 0x10c
#define MAILBOX_IRQSTATUS_2 0x110
#define MAILBOX_IRQENABLE_2 0x114
#define MAILBOX_IRQSTATUS_3 0x118
#define MAILBOX_IRQENABLE_3 0x11c
static unsigned long mbox_base;
#define MAILBOX_IRQ_NOTFULL(n) (1 << (2 * (n) + 1))
#define MAILBOX_IRQ_NEWMSG(n) (1 << (2 * (n)))
#define DRV_NAME "omap2-mailbox"
#define MAILBOX_REVISION 0x000
#define MAILBOX_SYSCONFIG 0x010
#define MAILBOX_SYSSTATUS 0x014
#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
#define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
#define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
#define MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
#define MAILBOX_IRQENABLE(u) (0x108 + 8 * (u))
#define MAILBOX_IRQ_NEWMSG(u) (1 << (2 * (u)))
#define MAILBOX_IRQ_NOTFULL(u) (1 << (2 * (u) + 1))
#define MBOX_REG_SIZE 0x120
static void __iomem *mbox_base;
struct omap_mbox2_fifo {
unsigned long msg;
......@@ -66,6 +49,7 @@ struct omap_mbox2_priv {
unsigned long irqstatus;
u32 newmsg_bit;
u32 notfull_bit;
char ctx[MBOX_REG_SIZE];
};
static struct clk *mbox_ick_handle;
......@@ -73,14 +57,14 @@ static struct clk *mbox_ick_handle;
static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq);
static inline unsigned int mbox_read_reg(unsigned int reg)
static inline unsigned int mbox_read_reg(size_t ofs)
{
return __raw_readl(mbox_base + reg);
return __raw_readl(mbox_base + ofs);
}
static inline void mbox_write_reg(unsigned int val, unsigned int reg)
static inline void mbox_write_reg(u32 val, size_t ofs)
{
__raw_writel(val, mbox_base + reg);
__raw_writel(val, mbox_base + ofs);
}
/* Mailbox H/W preparations */
......@@ -95,6 +79,9 @@ static int omap2_mbox_startup(struct omap_mbox *mbox)
}
clk_enable(mbox_ick_handle);
l = mbox_read_reg(MAILBOX_REVISION);
pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
/* set smart-idle & autoidle */
l = mbox_read_reg(MAILBOX_SYSCONFIG);
l |= 0x00000011;
......@@ -183,6 +170,36 @@ static int omap2_mbox_is_irq(struct omap_mbox *mbox,
return (enable & status & bit);
}
static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
{
int i;
struct omap_mbox2_priv *p = mbox->priv;
for (i = 0; i < MBOX_REG_SIZE; i += sizeof(u32)) {
u32 val;
val = mbox_read_reg(i);
*(u32 *)(p->ctx + i) = val;
dev_dbg(mbox->dev, "%s\t[%02d] %08x\n", __func__, i, val);
}
}
static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
{
int i;
struct omap_mbox2_priv *p = mbox->priv;
for (i = 0; i < MBOX_REG_SIZE; i += sizeof(u32)) {
u32 val;
val = *(u32 *)(p->ctx + i);
mbox_write_reg(val, i);
dev_dbg(mbox->dev, "%s\t[%02d] %08x\n", __func__, i, val);
}
}
static struct omap_mbox_ops omap2_mbox_ops = {
.type = OMAP_MBOX_TYPE2,
.startup = omap2_mbox_startup,
......@@ -195,6 +212,8 @@ static struct omap_mbox_ops omap2_mbox_ops = {
.disable_irq = omap2_mbox_disable_irq,
.ack_irq = omap2_mbox_ack_irq,
.is_irq = omap2_mbox_is_irq,
.save_ctx = omap2_mbox_save_ctx,
.restore_ctx = omap2_mbox_restore_ctx,
};
/*
......@@ -209,15 +228,15 @@ static struct omap_mbox_ops omap2_mbox_ops = {
/* DSP */
static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE_0,
.fifo_stat = MAILBOX_FIFOSTATUS_0,
.msg = MAILBOX_MESSAGE(0),
.fifo_stat = MAILBOX_FIFOSTATUS(0),
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE_1,
.msg_stat = MAILBOX_MSGSTATUS_1,
.msg = MAILBOX_MESSAGE(1),
.msg_stat = MAILBOX_MSGSTATUS(1),
},
.irqenable = MAILBOX_IRQENABLE_0,
.irqstatus = MAILBOX_IRQSTATUS_0,
.irqenable = MAILBOX_IRQENABLE(0),
.irqstatus = MAILBOX_IRQSTATUS(0),
.notfull_bit = MAILBOX_IRQ_NOTFULL(0),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
};
......@@ -229,18 +248,18 @@ struct omap_mbox mbox_dsp_info = {
};
EXPORT_SYMBOL(mbox_dsp_info);
/* IVA */
#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
static struct omap_mbox2_priv omap2_mbox_iva_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE_2,
.fifo_stat = MAILBOX_FIFOSTATUS_2,
.msg = MAILBOX_MESSAGE(2),
.fifo_stat = MAILBOX_FIFOSTATUS(2),
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE_3,
.msg_stat = MAILBOX_MSGSTATUS_3,
.msg = MAILBOX_MESSAGE(3),
.msg_stat = MAILBOX_MSGSTATUS(3),
},
.irqenable = MAILBOX_IRQENABLE_3,
.irqstatus = MAILBOX_IRQSTATUS_3,
.irqenable = MAILBOX_IRQENABLE(3),
.irqstatus = MAILBOX_IRQSTATUS(3),
.notfull_bit = MAILBOX_IRQ_NOTFULL(2),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
};
......@@ -250,17 +269,12 @@ static struct omap_mbox mbox_iva_info = {
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_iva_priv,
};
#endif
static int __init omap2_mbox_probe(struct platform_device *pdev)
static int __devinit omap2_mbox_probe(struct platform_device *pdev)
{
struct resource *res;
int ret = 0;
if (pdev->num_resources != 3) {
dev_err(&pdev->dev, "invalid number of resources: %d\n",
pdev->num_resources);
return -ENODEV;
}
int ret;
/* MBOX base */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......@@ -268,42 +282,62 @@ static int __init omap2_mbox_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "invalid mem resource\n");
return -ENODEV;
}
mbox_base = res->start;
mbox_base = ioremap(res->start, res->end - res->start);
if (!mbox_base)
return -ENOMEM;
/* DSP IRQ */
/* DSP or IVA2 IRQ */
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid irq resource\n");
return -ENODEV;
ret = -ENODEV;
goto err_dsp;
}
mbox_dsp_info.irq = res->start;
ret = omap_mbox_register(&mbox_dsp_info);
ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info);
if (ret)
goto err_dsp;
#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
if (cpu_is_omap2420()) {
/* IVA IRQ */
res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid irq resource\n");
return -ENODEV;
ret = -ENODEV;
goto err_iva1;
}
mbox_iva_info.irq = res->start;
ret = omap_mbox_register(&pdev->dev, &mbox_iva_info);
if (ret)
goto err_iva1;
}
#endif
return 0;
ret = omap_mbox_register(&mbox_iva_info);
err_iva1:
omap_mbox_unregister(&mbox_dsp_info);
err_dsp:
iounmap(mbox_base);
return ret;
}
static int omap2_mbox_remove(struct platform_device *pdev)
static int __devexit omap2_mbox_remove(struct platform_device *pdev)
{
#if defined(CONFIG_ARCH_OMAP2420)
omap_mbox_unregister(&mbox_iva_info);
#endif
omap_mbox_unregister(&mbox_dsp_info);
iounmap(mbox_base);
return 0;
}
static struct platform_driver omap2_mbox_driver = {
.probe = omap2_mbox_probe,
.remove = omap2_mbox_remove,
.remove = __devexit_p(omap2_mbox_remove),
.driver = {
.name = "mailbox",
.name = DRV_NAME,
},
};
......@@ -320,4 +354,7 @@ static void __exit omap2_mbox_exit(void)
module_init(omap2_mbox_init);
module_exit(omap2_mbox_exit);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("omap mailbox: omap2/3 architecture specific functions");
MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>, Paul Mundt");
MODULE_ALIAS("platform:"DRV_NAME);
......@@ -180,7 +180,7 @@ config OMAP_MBOX_FWK
default n
help
Say Y here if you want to use OMAP Mailbox framework support for
DSP and IVA1.0 in OMAP1/2.
DSP, IVA1.0 and IVA2 in OMAP1/2/3.
choice
prompt "System timer"
......
......@@ -33,6 +33,9 @@ struct omap_mbox_ops {
void (*disable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
/* ctx */
void (*save_ctx)(struct omap_mbox *mbox);
void (*restore_ctx)(struct omap_mbox *mbox);
};
struct omap_mbox_queue {
......@@ -53,7 +56,7 @@ struct omap_mbox {
mbox_msg_t seq_snd, seq_rcv;
struct device dev;
struct device *dev;
struct omap_mbox *next;
void *priv;
......@@ -67,7 +70,27 @@ void omap_mbox_init_seq(struct omap_mbox *);
struct omap_mbox *omap_mbox_get(const char *);
void omap_mbox_put(struct omap_mbox *);
int omap_mbox_register(struct omap_mbox *);
int omap_mbox_register(struct device *parent, struct omap_mbox *);
int omap_mbox_unregister(struct omap_mbox *);
static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
{
if (!mbox->ops->save_ctx) {
dev_err(mbox->dev, "%s:\tno save\n", __func__);
return;
}
mbox->ops->save_ctx(mbox);
}
static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
{
if (!mbox->ops->restore_ctx) {
dev_err(mbox->dev, "%s:\tno restore\n", __func__);
return;
}
mbox->ops->restore_ctx(mbox);
}
#endif /* MAILBOX_H */
......@@ -64,6 +64,7 @@
#define OMAP2_PRM_BASE OMAP3430_PRM_BASE
#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP34XX_IC_BASE)
#define OMAP34XX_CAMERA_BASE (L4_34XX_BASE + 0xBC000)
#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000)
#endif
......
/*
* OMAP mailbox driver
*
* Copyright (C) 2006 Nokia Corporation. All rights reserved.
* Copyright (C) 2006-2008 Nokia Corporation. All rights reserved.
*
* Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* Restructured by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
* Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -22,21 +21,98 @@
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/blkdev.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <mach/mailbox.h>
#include "mailbox.h"
static int enable_seq_bit;
module_param(enable_seq_bit, bool, 0);
MODULE_PARM_DESC(enable_seq_bit, "Enable sequence bit checking.");
static struct omap_mbox *mboxes;
static DEFINE_RWLOCK(mboxes_lock);
/*
* Mailbox sequence bit API
*/
/* seq_rcv should be initialized with any value other than
* 0 and 1 << 31, to allow either value for the first
* message. */
static inline void mbox_seq_init(struct omap_mbox *mbox)
{
if (!enable_seq_bit)
return;
/* any value other than 0 and 1 << 31 */
mbox->seq_rcv = 0xffffffff;
}
static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
{
if (!enable_seq_bit)
return;
/* add seq_snd to msg */
*msg = (*msg & 0x7fffffff) | mbox->seq_snd;
/* flip seq_snd */
mbox->seq_snd ^= 1 << 31;
}
static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
{
mbox_msg_t seq;
if (!enable_seq_bit)
return 0;
seq = msg & (1 << 31);
if (seq == mbox->seq_rcv)
return -1;
mbox->seq_rcv = seq;
return 0;
}
/* Mailbox FIFO handle functions */
static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
{
return mbox->ops->fifo_read(mbox);
}
static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
{
mbox->ops->fifo_write(mbox, msg);
}
static inline int mbox_fifo_empty(struct omap_mbox *mbox)
{
return mbox->ops->fifo_empty(mbox);
}
static inline int mbox_fifo_full(struct omap_mbox *mbox)
{
return mbox->ops->fifo_full(mbox);
}
/* Mailbox IRQ handle functions */
static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
mbox->ops->enable_irq(mbox, irq);
}
static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
mbox->ops->disable_irq(mbox, irq);
}
static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
if (mbox->ops->ack_irq)
mbox->ops->ack_irq(mbox, irq);
}
static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
return mbox->ops->is_irq(mbox, irq);
}
/* Mailbox Sequence Bit function */
void omap_mbox_init_seq(struct omap_mbox *mbox)
{
......@@ -136,7 +212,7 @@ static void mbox_rx_work(struct work_struct *work)
unsigned long flags;
if (mbox->rxq->callback == NULL) {
sysfs_notify(&mbox->dev.kobj, NULL, "mbox");
sysfs_notify(&mbox->dev->kobj, NULL, "mbox");
return;
}
......@@ -204,7 +280,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
/* no more messages in the fifo. clear IRQ source. */
ack_mbox_irq(mbox, IRQ_RX);
enable_mbox_irq(mbox, IRQ_RX);
nomem:
nomem:
schedule_work(&mbox->rxq->work);
}
......@@ -286,7 +362,7 @@ static ssize_t mbox_show(struct class *class, char *buf)
static CLASS_ATTR(mbox, S_IRUGO, mbox_show, NULL);
static struct class omap_mbox_class = {
.name = "omap_mbox",
.name = "omap-mailbox",
};
static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
......@@ -333,21 +409,6 @@ static int omap_mbox_init(struct omap_mbox *mbox)
return ret;
}
mbox->dev.class = &omap_mbox_class;
dev_set_name(&mbox->dev, "%s", mbox->name);
dev_set_drvdata(&mbox->dev, mbox);
ret = device_register(&mbox->dev);
if (unlikely(ret))
goto fail_device_reg;
ret = device_create_file(&mbox->dev, &dev_attr_mbox);
if (unlikely(ret)) {
printk(KERN_ERR
"device_create_file failed: %d\n", ret);
goto fail_create_mbox;
}
ret = request_irq(mbox->irq, mbox_interrupt, IRQF_DISABLED,
mbox->name, mbox);
if (unlikely(ret)) {
......@@ -377,10 +438,6 @@ static int omap_mbox_init(struct omap_mbox *mbox)
fail_alloc_txq:
free_irq(mbox->irq, mbox);
fail_request_irq:
device_remove_file(&mbox->dev, &dev_attr_mbox);
fail_create_mbox:
device_unregister(&mbox->dev);
fail_device_reg:
if (unlikely(mbox->ops->shutdown))
mbox->ops->shutdown(mbox);
......@@ -393,8 +450,6 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
mbox_queue_free(mbox->rxq);
free_irq(mbox->irq, mbox);
device_remove_file(&mbox->dev, &dev_attr_mbox);
class_unregister(&omap_mbox_class);
if (unlikely(mbox->ops->shutdown))
mbox->ops->shutdown(mbox);
......@@ -440,7 +495,7 @@ void omap_mbox_put(struct omap_mbox *mbox)
}
EXPORT_SYMBOL(omap_mbox_put);
int omap_mbox_register(struct omap_mbox *mbox)
int omap_mbox_register(struct device *parent, struct omap_mbox *mbox)
{
int ret = 0;
struct omap_mbox **tmp;
......@@ -450,14 +505,31 @@ int omap_mbox_register(struct omap_mbox *mbox)
if (mbox->next)
return -EBUSY;
mbox->dev = device_create(&omap_mbox_class,
parent, 0, mbox, "%s", mbox->name);
if (IS_ERR(mbox->dev))
return PTR_ERR(mbox->dev);
ret = device_create_file(mbox->dev, &dev_attr_mbox);
if (ret)
goto err_sysfs;
write_lock(&mboxes_lock);
tmp = find_mboxes(mbox->name);
if (*tmp)
if (*tmp) {
ret = -EBUSY;
else
write_unlock(&mboxes_lock);
goto err_find;
}
*tmp = mbox;
write_unlock(&mboxes_lock);
return 0;
err_find:
device_remove_file(mbox->dev, &dev_attr_mbox);
err_sysfs:
device_unregister(mbox->dev);
return ret;
}
EXPORT_SYMBOL(omap_mbox_register);
......@@ -473,6 +545,8 @@ int omap_mbox_unregister(struct omap_mbox *mbox)
*tmp = mbox->next;
mbox->next = NULL;
write_unlock(&mboxes_lock);
device_remove_file(mbox->dev, &dev_attr_mbox);
device_unregister(mbox->dev);
return 0;
}
tmp = &(*tmp)->next;
......@@ -501,4 +575,6 @@ static void __exit omap_mbox_class_exit(void)
subsys_initcall(omap_mbox_class_init);
module_exit(omap_mbox_class_exit);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
MODULE_AUTHOR("Toshihiro Kobayashi and Hiroshi DOYU");
/*
* Mailbox internal functions
*
* Copyright (C) 2006 Nokia Corporation
* Written by: Hiroshi DOYU <Hiroshi.DOYU@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.
*/
#ifndef __ARCH_ARM_PLAT_MAILBOX_H
#define __ARCH_ARM_PLAT_MAILBOX_H
/*
* Mailbox sequence bit API
*/
#if defined(CONFIG_ARCH_OMAP1)
# define MBOX_USE_SEQ_BIT
#elif defined(CONFIG_ARCH_OMAP2)
# define MBOX_USE_SEQ_BIT
#endif
#ifdef MBOX_USE_SEQ_BIT
/* seq_rcv should be initialized with any value other than
* 0 and 1 << 31, to allow either value for the first
* message. */
static inline void mbox_seq_init(struct omap_mbox *mbox)
{
/* any value other than 0 and 1 << 31 */
mbox->seq_rcv = 0xffffffff;
}
static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
{
/* add seq_snd to msg */
*msg = (*msg & 0x7fffffff) | mbox->seq_snd;
/* flip seq_snd */
mbox->seq_snd ^= 1 << 31;
}
static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
{
mbox_msg_t seq = msg & (1 << 31);
if (seq == mbox->seq_rcv)
return -1;
mbox->seq_rcv = seq;
return 0;
}
#else
static inline void mbox_seq_init(struct omap_mbox *mbox)
{
}
static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
{
}
static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
{
return 0;
}
#endif
/* Mailbox FIFO handle functions */
static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
{
return mbox->ops->fifo_read(mbox);
}
static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
{
mbox->ops->fifo_write(mbox, msg);
}
static inline int mbox_fifo_empty(struct omap_mbox *mbox)
{
return mbox->ops->fifo_empty(mbox);
}
static inline int mbox_fifo_full(struct omap_mbox *mbox)
{
return mbox->ops->fifo_full(mbox);
}
/* Mailbox IRQ handle functions */
static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
mbox->ops->enable_irq(mbox, irq);
}
static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
mbox->ops->disable_irq(mbox, irq);
}
static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
if (mbox->ops->ack_irq)
mbox->ops->ack_irq(mbox, irq);
}
static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
return mbox->ops->is_irq(mbox, irq);
}
#endif /* __ARCH_ARM_PLAT_MAILBOX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment