linux/drivers/mailbox/imx-mailbox.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
   4 */
   5
   6#include <linux/clk.h>
   7#include <linux/firmware/imx/ipc.h>
   8#include <linux/interrupt.h>
   9#include <linux/io.h>
  10#include <linux/iopoll.h>
  11#include <linux/kernel.h>
  12#include <linux/mailbox_controller.h>
  13#include <linux/module.h>
  14#include <linux/of_device.h>
  15#include <linux/pm_runtime.h>
  16#include <linux/slab.h>
  17
  18#define IMX_MU_xSR_GIPn(x)      BIT(28 + (3 - (x)))
  19#define IMX_MU_xSR_RFn(x)       BIT(24 + (3 - (x)))
  20#define IMX_MU_xSR_TEn(x)       BIT(20 + (3 - (x)))
  21#define IMX_MU_xSR_BRDIP        BIT(9)
  22
  23/* General Purpose Interrupt Enable */
  24#define IMX_MU_xCR_GIEn(x)      BIT(28 + (3 - (x)))
  25/* Receive Interrupt Enable */
  26#define IMX_MU_xCR_RIEn(x)      BIT(24 + (3 - (x)))
  27/* Transmit Interrupt Enable */
  28#define IMX_MU_xCR_TIEn(x)      BIT(20 + (3 - (x)))
  29/* General Purpose Interrupt Request */
  30#define IMX_MU_xCR_GIRn(x)      BIT(16 + (3 - (x)))
  31
  32#define IMX_MU_CHANS            16
  33/* TX0/RX0/RXDB[0-3] */
  34#define IMX_MU_SCU_CHANS        6
  35#define IMX_MU_CHAN_NAME_SIZE   20
  36
  37enum imx_mu_chan_type {
  38        IMX_MU_TYPE_TX,         /* Tx */
  39        IMX_MU_TYPE_RX,         /* Rx */
  40        IMX_MU_TYPE_TXDB,       /* Tx doorbell */
  41        IMX_MU_TYPE_RXDB,       /* Rx doorbell */
  42};
  43
  44struct imx_sc_rpc_msg_max {
  45        struct imx_sc_rpc_msg hdr;
  46        u32 data[7];
  47};
  48
  49struct imx_mu_con_priv {
  50        unsigned int            idx;
  51        char                    irq_desc[IMX_MU_CHAN_NAME_SIZE];
  52        enum imx_mu_chan_type   type;
  53        struct mbox_chan        *chan;
  54        struct tasklet_struct   txdb_tasklet;
  55};
  56
  57struct imx_mu_priv {
  58        struct device           *dev;
  59        void __iomem            *base;
  60        spinlock_t              xcr_lock; /* control register lock */
  61
  62        struct mbox_controller  mbox;
  63        struct mbox_chan        mbox_chans[IMX_MU_CHANS];
  64
  65        struct imx_mu_con_priv  con_priv[IMX_MU_CHANS];
  66        const struct imx_mu_dcfg        *dcfg;
  67        struct clk              *clk;
  68        int                     irq;
  69
  70        u32 xcr;
  71
  72        bool                    side_b;
  73};
  74
  75struct imx_mu_dcfg {
  76        int (*tx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data);
  77        int (*rx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
  78        void (*init)(struct imx_mu_priv *priv);
  79        u32     xTR[4];         /* Transmit Registers */
  80        u32     xRR[4];         /* Receive Registers */
  81        u32     xSR;            /* Status Register */
  82        u32     xCR;            /* Control Register */
  83};
  84
  85static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)
  86{
  87        return container_of(mbox, struct imx_mu_priv, mbox);
  88}
  89
  90static void imx_mu_write(struct imx_mu_priv *priv, u32 val, u32 offs)
  91{
  92        iowrite32(val, priv->base + offs);
  93}
  94
  95static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)
  96{
  97        return ioread32(priv->base + offs);
  98}
  99
 100static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, u32 set, u32 clr)
 101{
 102        unsigned long flags;
 103        u32 val;
 104
 105        spin_lock_irqsave(&priv->xcr_lock, flags);
 106        val = imx_mu_read(priv, priv->dcfg->xCR);
 107        val &= ~clr;
 108        val |= set;
 109        imx_mu_write(priv, val, priv->dcfg->xCR);
 110        spin_unlock_irqrestore(&priv->xcr_lock, flags);
 111
 112        return val;
 113}
 114
 115static int imx_mu_generic_tx(struct imx_mu_priv *priv,
 116                             struct imx_mu_con_priv *cp,
 117                             void *data)
 118{
 119        u32 *arg = data;
 120
 121        switch (cp->type) {
 122        case IMX_MU_TYPE_TX:
 123                imx_mu_write(priv, *arg, priv->dcfg->xTR[cp->idx]);
 124                imx_mu_xcr_rmw(priv, IMX_MU_xCR_TIEn(cp->idx), 0);
 125                break;
 126        case IMX_MU_TYPE_TXDB:
 127                imx_mu_xcr_rmw(priv, IMX_MU_xCR_GIRn(cp->idx), 0);
 128                tasklet_schedule(&cp->txdb_tasklet);
 129                break;
 130        default:
 131                dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
 132                return -EINVAL;
 133        }
 134
 135        return 0;
 136}
 137
 138static int imx_mu_generic_rx(struct imx_mu_priv *priv,
 139                             struct imx_mu_con_priv *cp)
 140{
 141        u32 dat;
 142
 143        dat = imx_mu_read(priv, priv->dcfg->xRR[cp->idx]);
 144        mbox_chan_received_data(cp->chan, (void *)&dat);
 145
 146        return 0;
 147}
 148
 149static int imx_mu_scu_tx(struct imx_mu_priv *priv,
 150                         struct imx_mu_con_priv *cp,
 151                         void *data)
 152{
 153        struct imx_sc_rpc_msg_max *msg = data;
 154        u32 *arg = data;
 155        int i, ret;
 156        u32 xsr;
 157
 158        switch (cp->type) {
 159        case IMX_MU_TYPE_TX:
 160                /*
 161                 * msg->hdr.size specifies the number of u32 words while
 162                 * sizeof yields bytes.
 163                 */
 164
 165                if (msg->hdr.size > sizeof(*msg) / 4) {
 166                        /*
 167                         * The real message size can be different to
 168                         * struct imx_sc_rpc_msg_max size
 169                         */
 170                        dev_err(priv->dev, "Maximal message size (%zu bytes) exceeded on TX; got: %i bytes\n", sizeof(*msg), msg->hdr.size << 2);
 171                        return -EINVAL;
 172                }
 173
 174                for (i = 0; i < 4 && i < msg->hdr.size; i++)
 175                        imx_mu_write(priv, *arg++, priv->dcfg->xTR[i % 4]);
 176                for (; i < msg->hdr.size; i++) {
 177                        ret = readl_poll_timeout(priv->base + priv->dcfg->xSR,
 178                                                 xsr,
 179                                                 xsr & IMX_MU_xSR_TEn(i % 4),
 180                                                 0, 100);
 181                        if (ret) {
 182                                dev_err(priv->dev, "Send data index: %d timeout\n", i);
 183                                return ret;
 184                        }
 185                        imx_mu_write(priv, *arg++, priv->dcfg->xTR[i % 4]);
 186                }
 187
 188                imx_mu_xcr_rmw(priv, IMX_MU_xCR_TIEn(cp->idx), 0);
 189                break;
 190        default:
 191                dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
 192                return -EINVAL;
 193        }
 194
 195        return 0;
 196}
 197
 198static int imx_mu_scu_rx(struct imx_mu_priv *priv,
 199                         struct imx_mu_con_priv *cp)
 200{
 201        struct imx_sc_rpc_msg_max msg;
 202        u32 *data = (u32 *)&msg;
 203        int i, ret;
 204        u32 xsr;
 205
 206        imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_RIEn(0));
 207        *data++ = imx_mu_read(priv, priv->dcfg->xRR[0]);
 208
 209        if (msg.hdr.size > sizeof(msg) / 4) {
 210                dev_err(priv->dev, "Maximal message size (%zu bytes) exceeded on RX; got: %i bytes\n", sizeof(msg), msg.hdr.size << 2);
 211                return -EINVAL;
 212        }
 213
 214        for (i = 1; i < msg.hdr.size; i++) {
 215                ret = readl_poll_timeout(priv->base + priv->dcfg->xSR, xsr,
 216                                         xsr & IMX_MU_xSR_RFn(i % 4), 0, 100);
 217                if (ret) {
 218                        dev_err(priv->dev, "timeout read idx %d\n", i);
 219                        return ret;
 220                }
 221                *data++ = imx_mu_read(priv, priv->dcfg->xRR[i % 4]);
 222        }
 223
 224        imx_mu_xcr_rmw(priv, IMX_MU_xCR_RIEn(0), 0);
 225        mbox_chan_received_data(cp->chan, (void *)&msg);
 226
 227        return 0;
 228}
 229
 230static void imx_mu_txdb_tasklet(unsigned long data)
 231{
 232        struct imx_mu_con_priv *cp = (struct imx_mu_con_priv *)data;
 233
 234        mbox_chan_txdone(cp->chan, 0);
 235}
 236
 237static irqreturn_t imx_mu_isr(int irq, void *p)
 238{
 239        struct mbox_chan *chan = p;
 240        struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
 241        struct imx_mu_con_priv *cp = chan->con_priv;
 242        u32 val, ctrl;
 243
 244        ctrl = imx_mu_read(priv, priv->dcfg->xCR);
 245        val = imx_mu_read(priv, priv->dcfg->xSR);
 246
 247        switch (cp->type) {
 248        case IMX_MU_TYPE_TX:
 249                val &= IMX_MU_xSR_TEn(cp->idx) &
 250                        (ctrl & IMX_MU_xCR_TIEn(cp->idx));
 251                break;
 252        case IMX_MU_TYPE_RX:
 253                val &= IMX_MU_xSR_RFn(cp->idx) &
 254                        (ctrl & IMX_MU_xCR_RIEn(cp->idx));
 255                break;
 256        case IMX_MU_TYPE_RXDB:
 257                val &= IMX_MU_xSR_GIPn(cp->idx) &
 258                        (ctrl & IMX_MU_xCR_GIEn(cp->idx));
 259                break;
 260        default:
 261                break;
 262        }
 263
 264        if (!val)
 265                return IRQ_NONE;
 266
 267        if (val == IMX_MU_xSR_TEn(cp->idx)) {
 268                imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx));
 269                mbox_chan_txdone(chan, 0);
 270        } else if (val == IMX_MU_xSR_RFn(cp->idx)) {
 271                priv->dcfg->rx(priv, cp);
 272        } else if (val == IMX_MU_xSR_GIPn(cp->idx)) {
 273                imx_mu_write(priv, IMX_MU_xSR_GIPn(cp->idx), priv->dcfg->xSR);
 274                mbox_chan_received_data(chan, NULL);
 275        } else {
 276                dev_warn_ratelimited(priv->dev, "Not handled interrupt\n");
 277                return IRQ_NONE;
 278        }
 279
 280        return IRQ_HANDLED;
 281}
 282
 283static int imx_mu_send_data(struct mbox_chan *chan, void *data)
 284{
 285        struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
 286        struct imx_mu_con_priv *cp = chan->con_priv;
 287
 288        return priv->dcfg->tx(priv, cp, data);
 289}
 290
 291static int imx_mu_startup(struct mbox_chan *chan)
 292{
 293        struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
 294        struct imx_mu_con_priv *cp = chan->con_priv;
 295        unsigned long irq_flag = IRQF_SHARED;
 296        int ret;
 297
 298        pm_runtime_get_sync(priv->dev);
 299        if (cp->type == IMX_MU_TYPE_TXDB) {
 300                /* Tx doorbell don't have ACK support */
 301                tasklet_init(&cp->txdb_tasklet, imx_mu_txdb_tasklet,
 302                             (unsigned long)cp);
 303                return 0;
 304        }
 305
 306        /* IPC MU should be with IRQF_NO_SUSPEND set */
 307        if (!priv->dev->pm_domain)
 308                irq_flag |= IRQF_NO_SUSPEND;
 309
 310        ret = request_irq(priv->irq, imx_mu_isr, irq_flag,
 311                          cp->irq_desc, chan);
 312        if (ret) {
 313                dev_err(priv->dev,
 314                        "Unable to acquire IRQ %d\n", priv->irq);
 315                return ret;
 316        }
 317
 318        switch (cp->type) {
 319        case IMX_MU_TYPE_RX:
 320                imx_mu_xcr_rmw(priv, IMX_MU_xCR_RIEn(cp->idx), 0);
 321                break;
 322        case IMX_MU_TYPE_RXDB:
 323                imx_mu_xcr_rmw(priv, IMX_MU_xCR_GIEn(cp->idx), 0);
 324                break;
 325        default:
 326                break;
 327        }
 328
 329        return 0;
 330}
 331
 332static void imx_mu_shutdown(struct mbox_chan *chan)
 333{
 334        struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
 335        struct imx_mu_con_priv *cp = chan->con_priv;
 336
 337        if (cp->type == IMX_MU_TYPE_TXDB) {
 338                tasklet_kill(&cp->txdb_tasklet);
 339                pm_runtime_put_sync(priv->dev);
 340                return;
 341        }
 342
 343        switch (cp->type) {
 344        case IMX_MU_TYPE_TX:
 345                imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx));
 346                break;
 347        case IMX_MU_TYPE_RX:
 348                imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_RIEn(cp->idx));
 349                break;
 350        case IMX_MU_TYPE_RXDB:
 351                imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_GIEn(cp->idx));
 352                break;
 353        default:
 354                break;
 355        }
 356
 357        free_irq(priv->irq, chan);
 358        pm_runtime_put_sync(priv->dev);
 359}
 360
 361static const struct mbox_chan_ops imx_mu_ops = {
 362        .send_data = imx_mu_send_data,
 363        .startup = imx_mu_startup,
 364        .shutdown = imx_mu_shutdown,
 365};
 366
 367static struct mbox_chan *imx_mu_scu_xlate(struct mbox_controller *mbox,
 368                                          const struct of_phandle_args *sp)
 369{
 370        u32 type, idx, chan;
 371
 372        if (sp->args_count != 2) {
 373                dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
 374                return ERR_PTR(-EINVAL);
 375        }
 376
 377        type = sp->args[0]; /* channel type */
 378        idx = sp->args[1]; /* index */
 379
 380        switch (type) {
 381        case IMX_MU_TYPE_TX:
 382        case IMX_MU_TYPE_RX:
 383                if (idx != 0)
 384                        dev_err(mbox->dev, "Invalid chan idx: %d\n", idx);
 385                chan = type;
 386                break;
 387        case IMX_MU_TYPE_RXDB:
 388                chan = 2 + idx;
 389                break;
 390        default:
 391                dev_err(mbox->dev, "Invalid chan type: %d\n", type);
 392                return ERR_PTR(-EINVAL);
 393        }
 394
 395        if (chan >= mbox->num_chans) {
 396                dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);
 397                return ERR_PTR(-EINVAL);
 398        }
 399
 400        return &mbox->chans[chan];
 401}
 402
 403static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox,
 404                                       const struct of_phandle_args *sp)
 405{
 406        u32 type, idx, chan;
 407
 408        if (sp->args_count != 2) {
 409                dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
 410                return ERR_PTR(-EINVAL);
 411        }
 412
 413        type = sp->args[0]; /* channel type */
 414        idx = sp->args[1]; /* index */
 415        chan = type * 4 + idx;
 416
 417        if (chan >= mbox->num_chans) {
 418                dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);
 419                return ERR_PTR(-EINVAL);
 420        }
 421
 422        return &mbox->chans[chan];
 423}
 424
 425static void imx_mu_init_generic(struct imx_mu_priv *priv)
 426{
 427        unsigned int i;
 428
 429        for (i = 0; i < IMX_MU_CHANS; i++) {
 430                struct imx_mu_con_priv *cp = &priv->con_priv[i];
 431
 432                cp->idx = i % 4;
 433                cp->type = i >> 2;
 434                cp->chan = &priv->mbox_chans[i];
 435                priv->mbox_chans[i].con_priv = cp;
 436                snprintf(cp->irq_desc, sizeof(cp->irq_desc),
 437                         "imx_mu_chan[%i-%i]", cp->type, cp->idx);
 438        }
 439
 440        priv->mbox.num_chans = IMX_MU_CHANS;
 441        priv->mbox.of_xlate = imx_mu_xlate;
 442
 443        if (priv->side_b)
 444                return;
 445
 446        /* Set default MU configuration */
 447        imx_mu_write(priv, 0, priv->dcfg->xCR);
 448}
 449
 450static void imx_mu_init_scu(struct imx_mu_priv *priv)
 451{
 452        unsigned int i;
 453
 454        for (i = 0; i < IMX_MU_SCU_CHANS; i++) {
 455                struct imx_mu_con_priv *cp = &priv->con_priv[i];
 456
 457                cp->idx = i < 2 ? 0 : i - 2;
 458                cp->type = i < 2 ? i : IMX_MU_TYPE_RXDB;
 459                cp->chan = &priv->mbox_chans[i];
 460                priv->mbox_chans[i].con_priv = cp;
 461                snprintf(cp->irq_desc, sizeof(cp->irq_desc),
 462                         "imx_mu_chan[%i-%i]", cp->type, cp->idx);
 463        }
 464
 465        priv->mbox.num_chans = IMX_MU_SCU_CHANS;
 466        priv->mbox.of_xlate = imx_mu_scu_xlate;
 467
 468        /* Set default MU configuration */
 469        imx_mu_write(priv, 0, priv->dcfg->xCR);
 470}
 471
 472static int imx_mu_probe(struct platform_device *pdev)
 473{
 474        struct device *dev = &pdev->dev;
 475        struct device_node *np = dev->of_node;
 476        struct imx_mu_priv *priv;
 477        const struct imx_mu_dcfg *dcfg;
 478        int ret;
 479
 480        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 481        if (!priv)
 482                return -ENOMEM;
 483
 484        priv->dev = dev;
 485
 486        priv->base = devm_platform_ioremap_resource(pdev, 0);
 487        if (IS_ERR(priv->base))
 488                return PTR_ERR(priv->base);
 489
 490        priv->irq = platform_get_irq(pdev, 0);
 491        if (priv->irq < 0)
 492                return priv->irq;
 493
 494        dcfg = of_device_get_match_data(dev);
 495        if (!dcfg)
 496                return -EINVAL;
 497        priv->dcfg = dcfg;
 498
 499        priv->clk = devm_clk_get(dev, NULL);
 500        if (IS_ERR(priv->clk)) {
 501                if (PTR_ERR(priv->clk) != -ENOENT)
 502                        return PTR_ERR(priv->clk);
 503
 504                priv->clk = NULL;
 505        }
 506
 507        ret = clk_prepare_enable(priv->clk);
 508        if (ret) {
 509                dev_err(dev, "Failed to enable clock\n");
 510                return ret;
 511        }
 512
 513        priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");
 514
 515        priv->dcfg->init(priv);
 516
 517        spin_lock_init(&priv->xcr_lock);
 518
 519        priv->mbox.dev = dev;
 520        priv->mbox.ops = &imx_mu_ops;
 521        priv->mbox.chans = priv->mbox_chans;
 522        priv->mbox.txdone_irq = true;
 523
 524        platform_set_drvdata(pdev, priv);
 525
 526        ret = devm_mbox_controller_register(dev, &priv->mbox);
 527        if (ret) {
 528                clk_disable_unprepare(priv->clk);
 529                return ret;
 530        }
 531
 532        pm_runtime_enable(dev);
 533
 534        ret = pm_runtime_get_sync(dev);
 535        if (ret < 0) {
 536                pm_runtime_put_noidle(dev);
 537                goto disable_runtime_pm;
 538        }
 539
 540        ret = pm_runtime_put_sync(dev);
 541        if (ret < 0)
 542                goto disable_runtime_pm;
 543
 544        clk_disable_unprepare(priv->clk);
 545
 546        return 0;
 547
 548disable_runtime_pm:
 549        pm_runtime_disable(dev);
 550        clk_disable_unprepare(priv->clk);
 551        return ret;
 552}
 553
 554static int imx_mu_remove(struct platform_device *pdev)
 555{
 556        struct imx_mu_priv *priv = platform_get_drvdata(pdev);
 557
 558        pm_runtime_disable(priv->dev);
 559
 560        return 0;
 561}
 562
 563static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
 564        .tx     = imx_mu_generic_tx,
 565        .rx     = imx_mu_generic_rx,
 566        .init   = imx_mu_init_generic,
 567        .xTR    = {0x0, 0x4, 0x8, 0xc},
 568        .xRR    = {0x10, 0x14, 0x18, 0x1c},
 569        .xSR    = 0x20,
 570        .xCR    = 0x24,
 571};
 572
 573static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
 574        .tx     = imx_mu_generic_tx,
 575        .rx     = imx_mu_generic_rx,
 576        .init   = imx_mu_init_generic,
 577        .xTR    = {0x20, 0x24, 0x28, 0x2c},
 578        .xRR    = {0x40, 0x44, 0x48, 0x4c},
 579        .xSR    = 0x60,
 580        .xCR    = 0x64,
 581};
 582
 583static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
 584        .tx     = imx_mu_scu_tx,
 585        .rx     = imx_mu_scu_rx,
 586        .init   = imx_mu_init_scu,
 587        .xTR    = {0x0, 0x4, 0x8, 0xc},
 588        .xRR    = {0x10, 0x14, 0x18, 0x1c},
 589        .xSR    = 0x20,
 590        .xCR    = 0x24,
 591};
 592
 593static const struct of_device_id imx_mu_dt_ids[] = {
 594        { .compatible = "fsl,imx7ulp-mu", .data = &imx_mu_cfg_imx7ulp },
 595        { .compatible = "fsl,imx6sx-mu", .data = &imx_mu_cfg_imx6sx },
 596        { .compatible = "fsl,imx8-mu-scu", .data = &imx_mu_cfg_imx8_scu },
 597        { },
 598};
 599MODULE_DEVICE_TABLE(of, imx_mu_dt_ids);
 600
 601static int __maybe_unused imx_mu_suspend_noirq(struct device *dev)
 602{
 603        struct imx_mu_priv *priv = dev_get_drvdata(dev);
 604
 605        if (!priv->clk)
 606                priv->xcr = imx_mu_read(priv, priv->dcfg->xCR);
 607
 608        return 0;
 609}
 610
 611static int __maybe_unused imx_mu_resume_noirq(struct device *dev)
 612{
 613        struct imx_mu_priv *priv = dev_get_drvdata(dev);
 614
 615        /*
 616         * ONLY restore MU when context lost, the TIE could
 617         * be set during noirq resume as there is MU data
 618         * communication going on, and restore the saved
 619         * value will overwrite the TIE and cause MU data
 620         * send failed, may lead to system freeze. This issue
 621         * is observed by testing freeze mode suspend.
 622         */
 623        if (!imx_mu_read(priv, priv->dcfg->xCR) && !priv->clk)
 624                imx_mu_write(priv, priv->xcr, priv->dcfg->xCR);
 625
 626        return 0;
 627}
 628
 629static int __maybe_unused imx_mu_runtime_suspend(struct device *dev)
 630{
 631        struct imx_mu_priv *priv = dev_get_drvdata(dev);
 632
 633        clk_disable_unprepare(priv->clk);
 634
 635        return 0;
 636}
 637
 638static int __maybe_unused imx_mu_runtime_resume(struct device *dev)
 639{
 640        struct imx_mu_priv *priv = dev_get_drvdata(dev);
 641        int ret;
 642
 643        ret = clk_prepare_enable(priv->clk);
 644        if (ret)
 645                dev_err(dev, "failed to enable clock\n");
 646
 647        return ret;
 648}
 649
 650static const struct dev_pm_ops imx_mu_pm_ops = {
 651        SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_mu_suspend_noirq,
 652                                      imx_mu_resume_noirq)
 653        SET_RUNTIME_PM_OPS(imx_mu_runtime_suspend,
 654                           imx_mu_runtime_resume, NULL)
 655};
 656
 657static struct platform_driver imx_mu_driver = {
 658        .probe          = imx_mu_probe,
 659        .remove         = imx_mu_remove,
 660        .driver = {
 661                .name   = "imx_mu",
 662                .of_match_table = imx_mu_dt_ids,
 663                .pm = &imx_mu_pm_ops,
 664        },
 665};
 666module_platform_driver(imx_mu_driver);
 667
 668MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
 669MODULE_DESCRIPTION("Message Unit driver for i.MX");
 670MODULE_LICENSE("GPL v2");
 671