linux/drivers/mailbox/mailbox-sti.c
<<
>>
Prefs
   1/*
   2 * STi Mailbox
   3 *
   4 * Copyright (C) 2015 ST Microelectronics
   5 *
   6 * Author: Lee Jones <lee.jones@linaro.org> for ST Microelectronics
   7 *
   8 * Based on the original driver written by;
   9 *   Alexandre Torgue, Olivier Lebreton and Loic Pallardy
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or
  14 * (at your option) any later version.
  15 */
  16
  17#include <linux/err.h>
  18#include <linux/interrupt.h>
  19#include <linux/io.h>
  20#include <linux/kernel.h>
  21#include <linux/mailbox_controller.h>
  22#include <linux/module.h>
  23#include <linux/of.h>
  24#include <linux/of_device.h>
  25#include <linux/platform_device.h>
  26#include <linux/slab.h>
  27
  28#include "mailbox.h"
  29
  30#define STI_MBOX_INST_MAX       4      /* RAM saving: Max supported instances */
  31#define STI_MBOX_CHAN_MAX       20     /* RAM saving: Max supported channels  */
  32
  33#define STI_IRQ_VAL_OFFSET      0x04   /* Read interrupt status               */
  34#define STI_IRQ_SET_OFFSET      0x24   /* Generate a Tx channel interrupt     */
  35#define STI_IRQ_CLR_OFFSET      0x44   /* Clear pending Rx interrupts         */
  36#define STI_ENA_VAL_OFFSET      0x64   /* Read enable status                  */
  37#define STI_ENA_SET_OFFSET      0x84   /* Enable a channel                    */
  38#define STI_ENA_CLR_OFFSET      0xa4   /* Disable a channel                   */
  39
  40#define MBOX_BASE(mdev, inst)   ((mdev)->base + ((inst) * 4))
  41
  42/**
  43 * STi Mailbox device data
  44 *
  45 * An IP Mailbox is currently composed of 4 instances
  46 * Each instance is currently composed of 32 channels
  47 * This means that we have 128 channels per Mailbox
  48 * A channel an be used for TX or RX
  49 *
  50 * @dev:        Device to which it is attached
  51 * @mbox:       Representation of a communication channel controller
  52 * @base:       Base address of the register mapping region
  53 * @name:       Name of the mailbox
  54 * @enabled:    Local copy of enabled channels
  55 * @lock:       Mutex protecting enabled status
  56 */
  57struct sti_mbox_device {
  58        struct device           *dev;
  59        struct mbox_controller  *mbox;
  60        void __iomem            *base;
  61        const char              *name;
  62        u32                     enabled[STI_MBOX_INST_MAX];
  63        spinlock_t              lock;
  64};
  65
  66/**
  67 * STi Mailbox platform specific configuration
  68 *
  69 * @num_inst:   Maximum number of instances in one HW Mailbox
  70 * @num_chan:   Maximum number of channel per instance
  71 */
  72struct sti_mbox_pdata {
  73        unsigned int            num_inst;
  74        unsigned int            num_chan;
  75};
  76
  77/**
  78 * STi Mailbox allocated channel information
  79 *
  80 * @mdev:       Pointer to parent Mailbox device
  81 * @instance:   Instance number channel resides in
  82 * @channel:    Channel number pertaining to this container
  83 */
  84struct sti_channel {
  85        struct sti_mbox_device  *mdev;
  86        unsigned int            instance;
  87        unsigned int            channel;
  88};
  89
  90static inline bool sti_mbox_channel_is_enabled(struct mbox_chan *chan)
  91{
  92        struct sti_channel *chan_info = chan->con_priv;
  93        struct sti_mbox_device *mdev = chan_info->mdev;
  94        unsigned int instance = chan_info->instance;
  95        unsigned int channel = chan_info->channel;
  96
  97        return mdev->enabled[instance] & BIT(channel);
  98}
  99
 100static inline
 101struct mbox_chan *sti_mbox_to_channel(struct mbox_controller *mbox,
 102                                      unsigned int instance,
 103                                      unsigned int channel)
 104{
 105        struct sti_channel *chan_info;
 106        int i;
 107
 108        for (i = 0; i < mbox->num_chans; i++) {
 109                chan_info = mbox->chans[i].con_priv;
 110                if (chan_info &&
 111                    chan_info->instance == instance &&
 112                    chan_info->channel == channel)
 113                        return &mbox->chans[i];
 114        }
 115
 116        dev_err(mbox->dev,
 117                "Channel not registered: instance: %d channel: %d\n",
 118                instance, channel);
 119
 120        return NULL;
 121}
 122
 123static void sti_mbox_enable_channel(struct mbox_chan *chan)
 124{
 125        struct sti_channel *chan_info = chan->con_priv;
 126        struct sti_mbox_device *mdev = chan_info->mdev;
 127        unsigned int instance = chan_info->instance;
 128        unsigned int channel = chan_info->channel;
 129        unsigned long flags;
 130        void __iomem *base = MBOX_BASE(mdev, instance);
 131
 132        spin_lock_irqsave(&mdev->lock, flags);
 133        mdev->enabled[instance] |= BIT(channel);
 134        writel_relaxed(BIT(channel), base + STI_ENA_SET_OFFSET);
 135        spin_unlock_irqrestore(&mdev->lock, flags);
 136}
 137
 138static void sti_mbox_disable_channel(struct mbox_chan *chan)
 139{
 140        struct sti_channel *chan_info = chan->con_priv;
 141        struct sti_mbox_device *mdev = chan_info->mdev;
 142        unsigned int instance = chan_info->instance;
 143        unsigned int channel = chan_info->channel;
 144        unsigned long flags;
 145        void __iomem *base = MBOX_BASE(mdev, instance);
 146
 147        spin_lock_irqsave(&mdev->lock, flags);
 148        mdev->enabled[instance] &= ~BIT(channel);
 149        writel_relaxed(BIT(channel), base + STI_ENA_CLR_OFFSET);
 150        spin_unlock_irqrestore(&mdev->lock, flags);
 151}
 152
 153static void sti_mbox_clear_irq(struct mbox_chan *chan)
 154{
 155        struct sti_channel *chan_info = chan->con_priv;
 156        struct sti_mbox_device *mdev = chan_info->mdev;
 157        unsigned int instance = chan_info->instance;
 158        unsigned int channel = chan_info->channel;
 159        void __iomem *base = MBOX_BASE(mdev, instance);
 160
 161        writel_relaxed(BIT(channel), base + STI_IRQ_CLR_OFFSET);
 162}
 163
 164static struct mbox_chan *sti_mbox_irq_to_channel(struct sti_mbox_device *mdev,
 165                                                 unsigned int instance)
 166{
 167        struct mbox_controller *mbox = mdev->mbox;
 168        struct mbox_chan *chan = NULL;
 169        unsigned int channel;
 170        unsigned long bits;
 171        void __iomem *base = MBOX_BASE(mdev, instance);
 172
 173        bits = readl_relaxed(base + STI_IRQ_VAL_OFFSET);
 174        if (!bits)
 175                /* No IRQs fired in specified instance */
 176                return NULL;
 177
 178        /* An IRQ has fired, find the associated channel */
 179        for (channel = 0; bits; channel++) {
 180                if (!test_and_clear_bit(channel, &bits))
 181                        continue;
 182
 183                chan = sti_mbox_to_channel(mbox, instance, channel);
 184                if (chan) {
 185                        dev_dbg(mbox->dev,
 186                                "IRQ fired on instance: %d channel: %d\n",
 187                                instance, channel);
 188                        break;
 189                }
 190        }
 191
 192        return chan;
 193}
 194
 195static irqreturn_t sti_mbox_thread_handler(int irq, void *data)
 196{
 197        struct sti_mbox_device *mdev = data;
 198        struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
 199        struct mbox_chan *chan;
 200        unsigned int instance;
 201
 202        for (instance = 0; instance < pdata->num_inst; instance++) {
 203keep_looking:
 204                chan = sti_mbox_irq_to_channel(mdev, instance);
 205                if (!chan)
 206                        continue;
 207
 208                mbox_chan_received_data(chan, NULL);
 209                sti_mbox_clear_irq(chan);
 210                sti_mbox_enable_channel(chan);
 211                goto keep_looking;
 212        }
 213
 214        return IRQ_HANDLED;
 215}
 216
 217static irqreturn_t sti_mbox_irq_handler(int irq, void *data)
 218{
 219        struct sti_mbox_device *mdev = data;
 220        struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
 221        struct sti_channel *chan_info;
 222        struct mbox_chan *chan;
 223        unsigned int instance;
 224        int ret = IRQ_NONE;
 225
 226        for (instance = 0; instance < pdata->num_inst; instance++) {
 227                chan = sti_mbox_irq_to_channel(mdev, instance);
 228                if (!chan)
 229                        continue;
 230                chan_info = chan->con_priv;
 231
 232                if (!sti_mbox_channel_is_enabled(chan)) {
 233                        dev_warn(mdev->dev,
 234                                 "Unexpected IRQ: %s\n"
 235                                 "  instance: %d: channel: %d [enabled: %x]\n",
 236                                 mdev->name, chan_info->instance,
 237                                 chan_info->channel, mdev->enabled[instance]);
 238
 239                        /* Only handle IRQ if no other valid IRQs were found */
 240                        if (ret == IRQ_NONE)
 241                                ret = IRQ_HANDLED;
 242                        continue;
 243                }
 244
 245                sti_mbox_disable_channel(chan);
 246                ret = IRQ_WAKE_THREAD;
 247        }
 248
 249        if (ret == IRQ_NONE)
 250                dev_err(mdev->dev, "Spurious IRQ - was a channel requested?\n");
 251
 252        return ret;
 253}
 254
 255static bool sti_mbox_tx_is_ready(struct mbox_chan *chan)
 256{
 257        struct sti_channel *chan_info = chan->con_priv;
 258        struct sti_mbox_device *mdev = chan_info->mdev;
 259        unsigned int instance = chan_info->instance;
 260        unsigned int channel = chan_info->channel;
 261        void __iomem *base = MBOX_BASE(mdev, instance);
 262
 263        if (!(readl_relaxed(base + STI_ENA_VAL_OFFSET) & BIT(channel))) {
 264                dev_dbg(mdev->dev, "Mbox: %s: inst: %d, chan: %d disabled\n",
 265                        mdev->name, instance, channel);
 266                return false;
 267        }
 268
 269        if (readl_relaxed(base + STI_IRQ_VAL_OFFSET) & BIT(channel)) {
 270                dev_dbg(mdev->dev, "Mbox: %s: inst: %d, chan: %d not ready\n",
 271                        mdev->name, instance, channel);
 272                return false;
 273        }
 274
 275        return true;
 276}
 277
 278static int sti_mbox_send_data(struct mbox_chan *chan, void *data)
 279{
 280        struct sti_channel *chan_info = chan->con_priv;
 281        struct sti_mbox_device *mdev = chan_info->mdev;
 282        unsigned int instance = chan_info->instance;
 283        unsigned int channel = chan_info->channel;
 284        void __iomem *base = MBOX_BASE(mdev, instance);
 285
 286        /* Send event to co-processor */
 287        writel_relaxed(BIT(channel), base + STI_IRQ_SET_OFFSET);
 288
 289        dev_dbg(mdev->dev,
 290                "Sent via Mailbox %s: instance: %d channel: %d\n",
 291                mdev->name, instance, channel);
 292
 293        return 0;
 294}
 295
 296static int sti_mbox_startup_chan(struct mbox_chan *chan)
 297{
 298        sti_mbox_clear_irq(chan);
 299        sti_mbox_enable_channel(chan);
 300
 301        return 0;
 302}
 303
 304static void sti_mbox_shutdown_chan(struct mbox_chan *chan)
 305{
 306        struct sti_channel *chan_info = chan->con_priv;
 307        struct mbox_controller *mbox = chan_info->mdev->mbox;
 308        int i;
 309
 310        for (i = 0; i < mbox->num_chans; i++)
 311                if (chan == &mbox->chans[i])
 312                        break;
 313
 314        if (mbox->num_chans == i) {
 315                dev_warn(mbox->dev, "Request to free non-existent channel\n");
 316                return;
 317        }
 318
 319        /* Reset channel */
 320        sti_mbox_disable_channel(chan);
 321        sti_mbox_clear_irq(chan);
 322        chan->con_priv = NULL;
 323}
 324
 325static struct mbox_chan *sti_mbox_xlate(struct mbox_controller *mbox,
 326                                        const struct of_phandle_args *spec)
 327{
 328        struct sti_mbox_device *mdev = dev_get_drvdata(mbox->dev);
 329        struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
 330        struct sti_channel *chan_info;
 331        struct mbox_chan *chan = NULL;
 332        unsigned int instance  = spec->args[0];
 333        unsigned int channel   = spec->args[1];
 334        int i;
 335
 336        /* Bounds checking */
 337        if (instance >= pdata->num_inst || channel  >= pdata->num_chan) {
 338                dev_err(mbox->dev,
 339                        "Invalid channel requested instance: %d channel: %d\n",
 340                        instance, channel);
 341                return ERR_PTR(-EINVAL);
 342        }
 343
 344        for (i = 0; i < mbox->num_chans; i++) {
 345                chan_info = mbox->chans[i].con_priv;
 346
 347                /* Is requested channel free? */
 348                if (chan_info &&
 349                    mbox->dev == chan_info->mdev->dev &&
 350                    instance == chan_info->instance &&
 351                    channel == chan_info->channel) {
 352
 353                        dev_err(mbox->dev, "Channel in use\n");
 354                        return ERR_PTR(-EBUSY);
 355                }
 356
 357                /*
 358                 * Find the first free slot, then continue checking
 359                 * to see if requested channel is in use
 360                 */
 361                if (!chan && !chan_info)
 362                        chan = &mbox->chans[i];
 363        }
 364
 365        if (!chan) {
 366                dev_err(mbox->dev, "No free channels left\n");
 367                return ERR_PTR(-EBUSY);
 368        }
 369
 370        chan_info = devm_kzalloc(mbox->dev, sizeof(*chan_info), GFP_KERNEL);
 371        if (!chan_info)
 372                return ERR_PTR(-ENOMEM);
 373
 374        chan_info->mdev         = mdev;
 375        chan_info->instance     = instance;
 376        chan_info->channel      = channel;
 377
 378        chan->con_priv = chan_info;
 379
 380        dev_info(mbox->dev,
 381                 "Mbox: %s: Created channel: instance: %d channel: %d\n",
 382                 mdev->name, instance, channel);
 383
 384        return chan;
 385}
 386
 387static const struct mbox_chan_ops sti_mbox_ops = {
 388        .startup        = sti_mbox_startup_chan,
 389        .shutdown       = sti_mbox_shutdown_chan,
 390        .send_data      = sti_mbox_send_data,
 391        .last_tx_done   = sti_mbox_tx_is_ready,
 392};
 393
 394static const struct sti_mbox_pdata mbox_stih407_pdata = {
 395        .num_inst       = 4,
 396        .num_chan       = 32,
 397};
 398
 399static const struct of_device_id sti_mailbox_match[] = {
 400        {
 401                .compatible = "st,stih407-mailbox",
 402                .data = (void *)&mbox_stih407_pdata
 403        },
 404        { }
 405};
 406MODULE_DEVICE_TABLE(of, sti_mailbox_match);
 407
 408static int sti_mbox_probe(struct platform_device *pdev)
 409{
 410        const struct of_device_id *match;
 411        struct mbox_controller *mbox;
 412        struct sti_mbox_device *mdev;
 413        struct device_node *np = pdev->dev.of_node;
 414        struct mbox_chan *chans;
 415        struct resource *res;
 416        int irq;
 417        int ret;
 418
 419        match = of_match_device(sti_mailbox_match, &pdev->dev);
 420        if (!match) {
 421                dev_err(&pdev->dev, "No configuration found\n");
 422                return -ENODEV;
 423        }
 424        pdev->dev.platform_data = (struct sti_mbox_pdata *) match->data;
 425
 426        mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
 427        if (!mdev)
 428                return -ENOMEM;
 429
 430        platform_set_drvdata(pdev, mdev);
 431
 432        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 433        mdev->base = devm_ioremap_resource(&pdev->dev, res);
 434        if (IS_ERR(mdev->base))
 435                return PTR_ERR(mdev->base);
 436
 437        ret = of_property_read_string(np, "mbox-name", &mdev->name);
 438        if (ret)
 439                mdev->name = np->full_name;
 440
 441        mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
 442        if (!mbox)
 443                return -ENOMEM;
 444
 445        chans = devm_kcalloc(&pdev->dev,
 446                             STI_MBOX_CHAN_MAX, sizeof(*chans), GFP_KERNEL);
 447        if (!chans)
 448                return -ENOMEM;
 449
 450        mdev->dev               = &pdev->dev;
 451        mdev->mbox              = mbox;
 452
 453        spin_lock_init(&mdev->lock);
 454
 455        /* STi Mailbox does not have a Tx-Done or Tx-Ready IRQ */
 456        mbox->txdone_irq        = false;
 457        mbox->txdone_poll       = true;
 458        mbox->txpoll_period     = 100;
 459        mbox->ops               = &sti_mbox_ops;
 460        mbox->dev               = mdev->dev;
 461        mbox->of_xlate          = sti_mbox_xlate;
 462        mbox->chans             = chans;
 463        mbox->num_chans         = STI_MBOX_CHAN_MAX;
 464
 465        ret = devm_mbox_controller_register(&pdev->dev, mbox);
 466        if (ret)
 467                return ret;
 468
 469        /* It's okay for Tx Mailboxes to not supply IRQs */
 470        irq = platform_get_irq(pdev, 0);
 471        if (irq < 0) {
 472                dev_info(&pdev->dev,
 473                         "%s: Registered Tx only Mailbox\n", mdev->name);
 474                return 0;
 475        }
 476
 477        ret = devm_request_threaded_irq(&pdev->dev, irq,
 478                                        sti_mbox_irq_handler,
 479                                        sti_mbox_thread_handler,
 480                                        IRQF_ONESHOT, mdev->name, mdev);
 481        if (ret) {
 482                dev_err(&pdev->dev, "Can't claim IRQ %d\n", irq);
 483                return -EINVAL;
 484        }
 485
 486        dev_info(&pdev->dev, "%s: Registered Tx/Rx Mailbox\n", mdev->name);
 487
 488        return 0;
 489}
 490
 491static struct platform_driver sti_mbox_driver = {
 492        .probe = sti_mbox_probe,
 493        .driver = {
 494                .name = "sti-mailbox",
 495                .of_match_table = sti_mailbox_match,
 496        },
 497};
 498module_platform_driver(sti_mbox_driver);
 499
 500MODULE_LICENSE("GPL");
 501MODULE_DESCRIPTION("STMicroelectronics Mailbox Controller");
 502MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org");
 503MODULE_ALIAS("platform:mailbox-sti");
 504