summaryrefslogtreecommitdiffstats
path: root/drivers/mailbox/omap-mailbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mailbox/omap-mailbox.c')
-rw-r--r--drivers/mailbox/omap-mailbox.c520
1 files changed, 109 insertions, 411 deletions
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index c961706fe6..7a87424657 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -19,7 +19,6 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <linux/omap-mailbox.h>
#include <linux/mailbox_controller.h>
#include <linux/mailbox_client.h>
@@ -51,6 +50,11 @@
#define MBOX_INTR_CFG_TYPE1 0
#define MBOX_INTR_CFG_TYPE2 1
+typedef enum {
+ IRQ_TX = 1,
+ IRQ_RX = 2,
+} omap_mbox_irq_t;
+
struct omap_mbox_fifo {
unsigned long msg;
unsigned long fifo_stat;
@@ -61,14 +65,6 @@ struct omap_mbox_fifo {
u32 intr_bit;
};
-struct omap_mbox_queue {
- spinlock_t lock;
- struct kfifo fifo;
- struct work_struct work;
- struct omap_mbox *mbox;
- bool full;
-};
-
struct omap_mbox_match_data {
u32 intr_type;
};
@@ -81,29 +77,11 @@ struct omap_mbox_device {
u32 num_users;
u32 num_fifos;
u32 intr_type;
- struct omap_mbox **mboxes;
- struct mbox_controller controller;
- struct list_head elem;
-};
-
-struct omap_mbox_fifo_info {
- int tx_id;
- int tx_usr;
- int tx_irq;
-
- int rx_id;
- int rx_usr;
- int rx_irq;
-
- const char *name;
- bool send_no_irq;
};
struct omap_mbox {
const char *name;
int irq;
- struct omap_mbox_queue *rxq;
- struct device *dev;
struct omap_mbox_device *parent;
struct omap_mbox_fifo tx_fifo;
struct omap_mbox_fifo rx_fifo;
@@ -112,22 +90,6 @@ struct omap_mbox {
bool send_no_irq;
};
-/* global variables for the mailbox devices */
-static DEFINE_MUTEX(omap_mbox_devices_lock);
-static LIST_HEAD(omap_mbox_devices);
-
-static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
-module_param(mbox_kfifo_size, uint, S_IRUGO);
-MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
-
-static struct omap_mbox *mbox_chan_to_omap_mbox(struct mbox_chan *chan)
-{
- if (!chan || !chan->con_priv)
- return NULL;
-
- return (struct omap_mbox *)chan->con_priv;
-}
-
static inline
unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
{
@@ -197,7 +159,7 @@ static int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
return (int)(enable & status & bit);
}
-static void _omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+static void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
u32 l;
struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
@@ -210,7 +172,7 @@ static void _omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, l, irqenable);
}
-static void _omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+static void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
{
struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
&mbox->tx_fifo : &mbox->rx_fifo;
@@ -227,87 +189,27 @@ static void _omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, bit, irqdisable);
}
-void omap_mbox_enable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
-{
- struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
-
- if (WARN_ON(!mbox))
- return;
-
- _omap_mbox_enable_irq(mbox, irq);
-}
-EXPORT_SYMBOL(omap_mbox_enable_irq);
-
-void omap_mbox_disable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
-{
- struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
-
- if (WARN_ON(!mbox))
- return;
-
- _omap_mbox_disable_irq(mbox, irq);
-}
-EXPORT_SYMBOL(omap_mbox_disable_irq);
-
-/*
- * Message receiver(workqueue)
- */
-static void mbox_rx_work(struct work_struct *work)
-{
- struct omap_mbox_queue *mq =
- container_of(work, struct omap_mbox_queue, work);
- mbox_msg_t data;
- u32 msg;
- int len;
-
- while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
- len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
- WARN_ON(len != sizeof(msg));
- data = msg;
-
- mbox_chan_received_data(mq->mbox->chan, (void *)data);
- spin_lock_irq(&mq->lock);
- if (mq->full) {
- mq->full = false;
- _omap_mbox_enable_irq(mq->mbox, IRQ_RX);
- }
- spin_unlock_irq(&mq->lock);
- }
-}
-
/*
* Mailbox interrupt handler
*/
static void __mbox_tx_interrupt(struct omap_mbox *mbox)
{
- _omap_mbox_disable_irq(mbox, IRQ_TX);
+ omap_mbox_disable_irq(mbox, IRQ_TX);
ack_mbox_irq(mbox, IRQ_TX);
mbox_chan_txdone(mbox->chan, 0);
}
static void __mbox_rx_interrupt(struct omap_mbox *mbox)
{
- struct omap_mbox_queue *mq = mbox->rxq;
u32 msg;
- int len;
while (!mbox_fifo_empty(mbox)) {
- if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
- _omap_mbox_disable_irq(mbox, IRQ_RX);
- mq->full = true;
- goto nomem;
- }
-
msg = mbox_fifo_read(mbox);
-
- len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
- WARN_ON(len != sizeof(msg));
+ mbox_chan_received_data(mbox->chan, (void *)(uintptr_t)msg);
}
- /* no more messages in the fifo. clear IRQ source. */
+ /* clear IRQ source. */
ack_mbox_irq(mbox, IRQ_RX);
-nomem:
- schedule_work(&mbox->rxq->work);
}
static irqreturn_t mbox_interrupt(int irq, void *p)
@@ -323,188 +225,35 @@ static irqreturn_t mbox_interrupt(int irq, void *p)
return IRQ_HANDLED;
}
-static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
- void (*work)(struct work_struct *))
-{
- struct omap_mbox_queue *mq;
-
- if (!work)
- return NULL;
-
- mq = kzalloc(sizeof(*mq), GFP_KERNEL);
- if (!mq)
- return NULL;
-
- spin_lock_init(&mq->lock);
-
- if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL))
- goto error;
-
- INIT_WORK(&mq->work, work);
- return mq;
-
-error:
- kfree(mq);
- return NULL;
-}
-
-static void mbox_queue_free(struct omap_mbox_queue *q)
-{
- kfifo_free(&q->fifo);
- kfree(q);
-}
-
static int omap_mbox_startup(struct omap_mbox *mbox)
{
int ret = 0;
- struct omap_mbox_queue *mq;
- mq = mbox_queue_alloc(mbox, mbox_rx_work);
- if (!mq)
- return -ENOMEM;
- mbox->rxq = mq;
- mq->mbox = mbox;
-
- ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
- mbox->name, mbox);
+ ret = request_threaded_irq(mbox->irq, NULL, mbox_interrupt,
+ IRQF_SHARED | IRQF_ONESHOT, mbox->name,
+ mbox);
if (unlikely(ret)) {
pr_err("failed to register mailbox interrupt:%d\n", ret);
- goto fail_request_irq;
+ return ret;
}
if (mbox->send_no_irq)
mbox->chan->txdone_method = TXDONE_BY_ACK;
- _omap_mbox_enable_irq(mbox, IRQ_RX);
+ omap_mbox_enable_irq(mbox, IRQ_RX);
return 0;
-
-fail_request_irq:
- mbox_queue_free(mbox->rxq);
- return ret;
}
static void omap_mbox_fini(struct omap_mbox *mbox)
{
- _omap_mbox_disable_irq(mbox, IRQ_RX);
+ omap_mbox_disable_irq(mbox, IRQ_RX);
free_irq(mbox->irq, mbox);
- flush_work(&mbox->rxq->work);
- mbox_queue_free(mbox->rxq);
-}
-
-static struct omap_mbox *omap_mbox_device_find(struct omap_mbox_device *mdev,
- const char *mbox_name)
-{
- struct omap_mbox *_mbox, *mbox = NULL;
- struct omap_mbox **mboxes = mdev->mboxes;
- int i;
-
- if (!mboxes)
- return NULL;
-
- for (i = 0; (_mbox = mboxes[i]); i++) {
- if (!strcmp(_mbox->name, mbox_name)) {
- mbox = _mbox;
- break;
- }
- }
- return mbox;
-}
-
-struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
- const char *chan_name)
-{
- struct device *dev = cl->dev;
- struct omap_mbox *mbox = NULL;
- struct omap_mbox_device *mdev;
- int ret;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- if (dev->of_node) {
- pr_err("%s: please use mbox_request_channel(), this API is supported only for OMAP non-DT usage\n",
- __func__);
- return ERR_PTR(-ENODEV);
- }
-
- mutex_lock(&omap_mbox_devices_lock);
- list_for_each_entry(mdev, &omap_mbox_devices, elem) {
- mbox = omap_mbox_device_find(mdev, chan_name);
- if (mbox)
- break;
- }
- mutex_unlock(&omap_mbox_devices_lock);
-
- if (!mbox || !mbox->chan)
- return ERR_PTR(-ENOENT);
-
- ret = mbox_bind_client(mbox->chan, cl);
- if (ret)
- return ERR_PTR(ret);
-
- return mbox->chan;
-}
-EXPORT_SYMBOL(omap_mbox_request_channel);
-
-static struct class omap_mbox_class = { .name = "mbox", };
-
-static int omap_mbox_register(struct omap_mbox_device *mdev)
-{
- int ret;
- int i;
- struct omap_mbox **mboxes;
-
- if (!mdev || !mdev->mboxes)
- return -EINVAL;
-
- mboxes = mdev->mboxes;
- for (i = 0; mboxes[i]; i++) {
- struct omap_mbox *mbox = mboxes[i];
-
- mbox->dev = device_create(&omap_mbox_class, mdev->dev,
- 0, mbox, "%s", mbox->name);
- if (IS_ERR(mbox->dev)) {
- ret = PTR_ERR(mbox->dev);
- goto err_out;
- }
- }
-
- mutex_lock(&omap_mbox_devices_lock);
- list_add(&mdev->elem, &omap_mbox_devices);
- mutex_unlock(&omap_mbox_devices_lock);
-
- ret = devm_mbox_controller_register(mdev->dev, &mdev->controller);
-
-err_out:
- if (ret) {
- while (i--)
- device_unregister(mboxes[i]->dev);
- }
- return ret;
-}
-
-static int omap_mbox_unregister(struct omap_mbox_device *mdev)
-{
- int i;
- struct omap_mbox **mboxes;
-
- if (!mdev || !mdev->mboxes)
- return -EINVAL;
-
- mutex_lock(&omap_mbox_devices_lock);
- list_del(&mdev->elem);
- mutex_unlock(&omap_mbox_devices_lock);
-
- mboxes = mdev->mboxes;
- for (i = 0; mboxes[i]; i++)
- device_unregister(mboxes[i]->dev);
- return 0;
}
static int omap_mbox_chan_startup(struct mbox_chan *chan)
{
- struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+ struct omap_mbox *mbox = chan->con_priv;
struct omap_mbox_device *mdev = mbox->parent;
int ret = 0;
@@ -519,7 +268,7 @@ static int omap_mbox_chan_startup(struct mbox_chan *chan)
static void omap_mbox_chan_shutdown(struct mbox_chan *chan)
{
- struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+ struct omap_mbox *mbox = chan->con_priv;
struct omap_mbox_device *mdev = mbox->parent;
mutex_lock(&mdev->cfg_lock);
@@ -530,41 +279,40 @@ static void omap_mbox_chan_shutdown(struct mbox_chan *chan)
static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, u32 msg)
{
- int ret = -EBUSY;
+ if (mbox_fifo_full(mbox))
+ return -EBUSY;
- if (!mbox_fifo_full(mbox)) {
- _omap_mbox_enable_irq(mbox, IRQ_RX);
- mbox_fifo_write(mbox, msg);
- ret = 0;
- _omap_mbox_disable_irq(mbox, IRQ_RX);
+ omap_mbox_enable_irq(mbox, IRQ_RX);
+ mbox_fifo_write(mbox, msg);
+ omap_mbox_disable_irq(mbox, IRQ_RX);
- /* we must read and ack the interrupt directly from here */
- mbox_fifo_read(mbox);
- ack_mbox_irq(mbox, IRQ_RX);
- }
+ /* we must read and ack the interrupt directly from here */
+ mbox_fifo_read(mbox);
+ ack_mbox_irq(mbox, IRQ_RX);
- return ret;
+ return 0;
}
static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 msg)
{
- int ret = -EBUSY;
-
- if (!mbox_fifo_full(mbox)) {
- mbox_fifo_write(mbox, msg);
- ret = 0;
+ if (mbox_fifo_full(mbox)) {
+ /* always enable the interrupt */
+ omap_mbox_enable_irq(mbox, IRQ_TX);
+ return -EBUSY;
}
+ mbox_fifo_write(mbox, msg);
+
/* always enable the interrupt */
- _omap_mbox_enable_irq(mbox, IRQ_TX);
- return ret;
+ omap_mbox_enable_irq(mbox, IRQ_TX);
+ return 0;
}
static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data)
{
- struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+ struct omap_mbox *mbox = chan->con_priv;
int ret;
- u32 msg = omap_mbox_message(data);
+ u32 msg = (u32)(uintptr_t)(data);
if (!mbox)
return -EINVAL;
@@ -666,8 +414,9 @@ static struct mbox_chan *omap_mbox_of_xlate(struct mbox_controller *controller,
struct device_node *node;
struct omap_mbox_device *mdev;
struct omap_mbox *mbox;
+ int i;
- mdev = container_of(controller, struct omap_mbox_device, controller);
+ mdev = dev_get_drvdata(controller->dev);
if (WARN_ON(!mdev))
return ERR_PTR(-EINVAL);
@@ -678,22 +427,29 @@ static struct mbox_chan *omap_mbox_of_xlate(struct mbox_controller *controller,
return ERR_PTR(-ENODEV);
}
- mbox = omap_mbox_device_find(mdev, node->name);
+ for (i = 0; i < controller->num_chans; i++) {
+ mbox = controller->chans[i].con_priv;
+ if (!strcmp(mbox->name, node->name)) {
+ of_node_put(node);
+ return &controller->chans[i];
+ }
+ }
+
of_node_put(node);
- return mbox ? mbox->chan : ERR_PTR(-ENOENT);
+ return ERR_PTR(-ENOENT);
}
static int omap_mbox_probe(struct platform_device *pdev)
{
int ret;
struct mbox_chan *chnls;
- struct omap_mbox **list, *mbox, *mboxblk;
- struct omap_mbox_fifo_info *finfo, *finfoblk;
+ struct omap_mbox *mbox;
struct omap_mbox_device *mdev;
struct omap_mbox_fifo *fifo;
struct device_node *node = pdev->dev.of_node;
struct device_node *child;
const struct omap_mbox_match_data *match_data;
+ struct mbox_controller *controller;
u32 intr_type, info_count;
u32 num_users, num_fifos;
u32 tmp[3];
@@ -722,40 +478,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
return -ENODEV;
}
- finfoblk = devm_kcalloc(&pdev->dev, info_count, sizeof(*finfoblk),
- GFP_KERNEL);
- if (!finfoblk)
- return -ENOMEM;
-
- finfo = finfoblk;
- child = NULL;
- for (i = 0; i < info_count; i++, finfo++) {
- child = of_get_next_available_child(node, child);
- ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp,
- ARRAY_SIZE(tmp));
- if (ret)
- return ret;
- finfo->tx_id = tmp[0];
- finfo->tx_irq = tmp[1];
- finfo->tx_usr = tmp[2];
-
- ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp,
- ARRAY_SIZE(tmp));
- if (ret)
- return ret;
- finfo->rx_id = tmp[0];
- finfo->rx_irq = tmp[1];
- finfo->rx_usr = tmp[2];
-
- finfo->name = child->name;
-
- finfo->send_no_irq = of_property_read_bool(child, "ti,mbox-send-noirq");
-
- if (finfo->tx_id >= num_fifos || finfo->rx_id >= num_fifos ||
- finfo->tx_usr >= num_users || finfo->rx_usr >= num_users)
- return -EINVAL;
- }
-
mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return -ENOMEM;
@@ -769,52 +491,67 @@ static int omap_mbox_probe(struct platform_device *pdev)
if (!mdev->irq_ctx)
return -ENOMEM;
- /* allocate one extra for marking end of list */
- list = devm_kcalloc(&pdev->dev, info_count + 1, sizeof(*list),
- GFP_KERNEL);
- if (!list)
- return -ENOMEM;
-
chnls = devm_kcalloc(&pdev->dev, info_count + 1, sizeof(*chnls),
GFP_KERNEL);
if (!chnls)
return -ENOMEM;
- mboxblk = devm_kcalloc(&pdev->dev, info_count, sizeof(*mbox),
- GFP_KERNEL);
- if (!mboxblk)
- return -ENOMEM;
+ child = NULL;
+ for (i = 0; i < info_count; i++) {
+ int tx_id, tx_irq, tx_usr;
+ int rx_id, rx_usr;
+
+ mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
+ if (!mbox)
+ return -ENOMEM;
+
+ child = of_get_next_available_child(node, child);
+ ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp,
+ ARRAY_SIZE(tmp));
+ if (ret)
+ return ret;
+ tx_id = tmp[0];
+ tx_irq = tmp[1];
+ tx_usr = tmp[2];
+
+ ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp,
+ ARRAY_SIZE(tmp));
+ if (ret)
+ return ret;
+ rx_id = tmp[0];
+ /* rx_irq = tmp[1]; */
+ rx_usr = tmp[2];
+
+ if (tx_id >= num_fifos || rx_id >= num_fifos ||
+ tx_usr >= num_users || rx_usr >= num_users)
+ return -EINVAL;
- mbox = mboxblk;
- finfo = finfoblk;
- for (i = 0; i < info_count; i++, finfo++) {
fifo = &mbox->tx_fifo;
- fifo->msg = MAILBOX_MESSAGE(finfo->tx_id);
- fifo->fifo_stat = MAILBOX_FIFOSTATUS(finfo->tx_id);
- fifo->intr_bit = MAILBOX_IRQ_NOTFULL(finfo->tx_id);
- fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->tx_usr);
- fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->tx_usr);
- fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->tx_usr);
+ fifo->msg = MAILBOX_MESSAGE(tx_id);
+ fifo->fifo_stat = MAILBOX_FIFOSTATUS(tx_id);
+ fifo->intr_bit = MAILBOX_IRQ_NOTFULL(tx_id);
+ fifo->irqenable = MAILBOX_IRQENABLE(intr_type, tx_usr);
+ fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, tx_usr);
+ fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, tx_usr);
fifo = &mbox->rx_fifo;
- fifo->msg = MAILBOX_MESSAGE(finfo->rx_id);
- fifo->msg_stat = MAILBOX_MSGSTATUS(finfo->rx_id);
- fifo->intr_bit = MAILBOX_IRQ_NEWMSG(finfo->rx_id);
- fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->rx_usr);
- fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->rx_usr);
- fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->rx_usr);
-
- mbox->send_no_irq = finfo->send_no_irq;
+ fifo->msg = MAILBOX_MESSAGE(rx_id);
+ fifo->msg_stat = MAILBOX_MSGSTATUS(rx_id);
+ fifo->intr_bit = MAILBOX_IRQ_NEWMSG(rx_id);
+ fifo->irqenable = MAILBOX_IRQENABLE(intr_type, rx_usr);
+ fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, rx_usr);
+ fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, rx_usr);
+
+ mbox->send_no_irq = of_property_read_bool(child, "ti,mbox-send-noirq");
mbox->intr_type = intr_type;
mbox->parent = mdev;
- mbox->name = finfo->name;
- mbox->irq = platform_get_irq(pdev, finfo->tx_irq);
+ mbox->name = child->name;
+ mbox->irq = platform_get_irq(pdev, tx_irq);
if (mbox->irq < 0)
return mbox->irq;
mbox->chan = &chnls[i];
chnls[i].con_priv = mbox;
- list[i] = mbox++;
}
mutex_init(&mdev->cfg_lock);
@@ -822,28 +559,30 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->num_users = num_users;
mdev->num_fifos = num_fifos;
mdev->intr_type = intr_type;
- mdev->mboxes = list;
+ controller = devm_kzalloc(&pdev->dev, sizeof(*controller), GFP_KERNEL);
+ if (!controller)
+ return -ENOMEM;
/*
* OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready
* IRQ and is needed to run the Tx state machine
*/
- mdev->controller.txdone_irq = true;
- mdev->controller.dev = mdev->dev;
- mdev->controller.ops = &omap_mbox_chan_ops;
- mdev->controller.chans = chnls;
- mdev->controller.num_chans = info_count;
- mdev->controller.of_xlate = omap_mbox_of_xlate;
- ret = omap_mbox_register(mdev);
+ controller->txdone_irq = true;
+ controller->dev = mdev->dev;
+ controller->ops = &omap_mbox_chan_ops;
+ controller->chans = chnls;
+ controller->num_chans = info_count;
+ controller->of_xlate = omap_mbox_of_xlate;
+ ret = devm_mbox_controller_register(mdev->dev, controller);
if (ret)
return ret;
platform_set_drvdata(pdev, mdev);
- pm_runtime_enable(mdev->dev);
+ devm_pm_runtime_enable(mdev->dev);
ret = pm_runtime_resume_and_get(mdev->dev);
if (ret < 0)
- goto unregister;
+ return ret;
/*
* just print the raw revision register, the format is not
@@ -854,61 +593,20 @@ static int omap_mbox_probe(struct platform_device *pdev)
ret = pm_runtime_put_sync(mdev->dev);
if (ret < 0 && ret != -ENOSYS)
- goto unregister;
+ return ret;
- devm_kfree(&pdev->dev, finfoblk);
return 0;
-
-unregister:
- pm_runtime_disable(mdev->dev);
- omap_mbox_unregister(mdev);
- return ret;
-}
-
-static void omap_mbox_remove(struct platform_device *pdev)
-{
- struct omap_mbox_device *mdev = platform_get_drvdata(pdev);
-
- pm_runtime_disable(mdev->dev);
- omap_mbox_unregister(mdev);
}
static struct platform_driver omap_mbox_driver = {
.probe = omap_mbox_probe,
- .remove_new = omap_mbox_remove,
.driver = {
.name = "omap-mailbox",
.pm = &omap_mbox_pm_ops,
.of_match_table = of_match_ptr(omap_mailbox_of_match),
},
};
-
-static int __init omap_mbox_init(void)
-{
- int err;
-
- err = class_register(&omap_mbox_class);
- if (err)
- return err;
-
- /* kfifo size sanity check: alignment and minimal size */
- mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(u32));
- mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(u32));
-
- err = platform_driver_register(&omap_mbox_driver);
- if (err)
- class_unregister(&omap_mbox_class);
-
- return err;
-}
-subsys_initcall(omap_mbox_init);
-
-static void __exit omap_mbox_exit(void)
-{
- platform_driver_unregister(&omap_mbox_driver);
- class_unregister(&omap_mbox_class);
-}
-module_exit(omap_mbox_exit);
+module_platform_driver(omap_mbox_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");