diff options
Diffstat (limited to 'drivers/mailbox/omap-mailbox.c')
-rw-r--r-- | drivers/mailbox/omap-mailbox.c | 520 |
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"); |