Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 643 lines 18 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2025 Cix Technology Group Co., Ltd. 4 */ 5 6#include <linux/device.h> 7#include <linux/err.h> 8#include <linux/io.h> 9#include <linux/interrupt.h> 10#include <linux/kernel.h> 11#include <linux/mailbox_controller.h> 12#include <linux/module.h> 13#include <linux/platform_device.h> 14 15/* 16 * The maximum transmission size is 32 words or 128 bytes. 17 */ 18#define CIX_MBOX_MSG_WORDS 32 /* Max length = 32 words */ 19#define CIX_MBOX_MSG_LEN_MASK 0x7fL /* Max length = 128 bytes */ 20 21/* [0~7] Fast channel 22 * [8] doorbell base channel 23 * [9]fifo base channel 24 * [10] register base channel 25 */ 26#define CIX_MBOX_FAST_IDX 7 27#define CIX_MBOX_DB_IDX 8 28#define CIX_MBOX_FIFO_IDX 9 29#define CIX_MBOX_REG_IDX 10 30#define CIX_MBOX_CHANS 11 31 32/* Register define */ 33#define CIX_REG_MSG(n) (0x0 + 0x4*(n)) /* 0x0~0x7c */ 34#define CIX_REG_DB_ACK CIX_REG_MSG(CIX_MBOX_MSG_WORDS) /* 0x80 */ 35#define CIX_ERR_COMP (CIX_REG_DB_ACK + 0x4) /* 0x84 */ 36#define CIX_ERR_COMP_CLR (CIX_REG_DB_ACK + 0x8) /* 0x88 */ 37#define CIX_REG_F_INT(IDX) (CIX_ERR_COMP_CLR + 0x4*(IDX+1)) /* 0x8c~0xa8 */ 38#define CIX_FIFO_WR (CIX_REG_F_INT(CIX_MBOX_FAST_IDX+1)) /* 0xac */ 39#define CIX_FIFO_RD (CIX_FIFO_WR + 0x4) /* 0xb0 */ 40#define CIX_FIFO_STAS (CIX_FIFO_WR + 0x8) /* 0xb4 */ 41#define CIX_FIFO_WM (CIX_FIFO_WR + 0xc) /* 0xb8 */ 42#define CIX_INT_ENABLE (CIX_FIFO_WR + 0x10) /* 0xbc */ 43#define CIX_INT_ENABLE_SIDE_B (CIX_FIFO_WR + 0x14) /* 0xc0 */ 44#define CIX_INT_CLEAR (CIX_FIFO_WR + 0x18) /* 0xc4 */ 45#define CIX_INT_STATUS (CIX_FIFO_WR + 0x1c) /* 0xc8 */ 46#define CIX_FIFO_RST (CIX_FIFO_WR + 0x20) /* 0xcc */ 47 48#define CIX_MBOX_TX 0 49#define CIX_MBOX_RX 1 50 51#define CIX_DB_INT_BIT BIT(0) 52#define CIX_DB_ACK_INT_BIT BIT(1) 53 54#define CIX_FIFO_WM_DEFAULT CIX_MBOX_MSG_WORDS 55#define CIX_FIFO_STAS_WMK BIT(0) 56#define CIX_FIFO_STAS_FULL BIT(1) 57#define CIX_FIFO_STAS_EMPTY BIT(2) 58#define CIX_FIFO_STAS_UFLOW BIT(3) 59#define CIX_FIFO_STAS_OFLOW BIT(4) 60 61#define CIX_FIFO_RST_BIT BIT(0) 62 63#define CIX_DB_INT BIT(0) 64#define CIX_ACK_INT BIT(1) 65#define CIX_FIFO_FULL_INT BIT(2) 66#define CIX_FIFO_EMPTY_INT BIT(3) 67#define CIX_FIFO_WM01_INT BIT(4) 68#define CIX_FIFO_WM10_INT BIT(5) 69#define CIX_FIFO_OFLOW_INT BIT(6) 70#define CIX_FIFO_UFLOW_INT BIT(7) 71#define CIX_FIFO_N_EMPTY_INT BIT(8) 72#define CIX_FAST_CH_INT(IDX) BIT((IDX)+9) 73 74#define CIX_SHMEM_OFFSET 0x80 75 76enum cix_mbox_chan_type { 77 CIX_MBOX_TYPE_DB, 78 CIX_MBOX_TYPE_REG, 79 CIX_MBOX_TYPE_FIFO, 80 CIX_MBOX_TYPE_FAST, 81}; 82 83struct cix_mbox_con_priv { 84 enum cix_mbox_chan_type type; 85 struct mbox_chan *chan; 86 int index; 87}; 88 89struct cix_mbox_priv { 90 struct device *dev; 91 int irq; 92 int dir; 93 void __iomem *base; /* region for mailbox */ 94 struct cix_mbox_con_priv con_priv[CIX_MBOX_CHANS]; 95 struct mbox_chan mbox_chans[CIX_MBOX_CHANS]; 96 struct mbox_controller mbox; 97 bool use_shmem; 98}; 99 100/* 101 * The CIX mailbox supports four types of transfers: 102 * CIX_MBOX_TYPE_DB, CIX_MBOX_TYPE_FAST, CIX_MBOX_TYPE_REG, and CIX_MBOX_TYPE_FIFO. 103 * For the REG and FIFO types of transfers, the message format is as follows: 104 */ 105union cix_mbox_msg_reg_fifo { 106 u32 length; /* unit is byte */ 107 u32 buf[CIX_MBOX_MSG_WORDS]; /* buf[0] must be the byte length of this array */ 108}; 109 110static struct cix_mbox_priv *to_cix_mbox_priv(struct mbox_controller *mbox) 111{ 112 return container_of(mbox, struct cix_mbox_priv, mbox); 113} 114 115static void cix_mbox_write(struct cix_mbox_priv *priv, u32 val, u32 offset) 116{ 117 if (priv->use_shmem) 118 iowrite32(val, priv->base + offset - CIX_SHMEM_OFFSET); 119 else 120 iowrite32(val, priv->base + offset); 121} 122 123static u32 cix_mbox_read(struct cix_mbox_priv *priv, u32 offset) 124{ 125 if (priv->use_shmem) 126 return ioread32(priv->base + offset - CIX_SHMEM_OFFSET); 127 else 128 return ioread32(priv->base + offset); 129} 130 131static bool mbox_fifo_empty(struct mbox_chan *chan) 132{ 133 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 134 135 return ((cix_mbox_read(priv, CIX_FIFO_STAS) & CIX_FIFO_STAS_EMPTY) ? true : false); 136} 137 138/* 139 *The transmission unit of the CIX mailbox is word. 140 *The byte length should be converted into the word length. 141 */ 142static inline u32 mbox_get_msg_size(void *msg) 143{ 144 u32 len; 145 146 len = ((u32 *)msg)[0] & CIX_MBOX_MSG_LEN_MASK; 147 return DIV_ROUND_UP(len, 4); 148} 149 150static int cix_mbox_send_data_db(struct mbox_chan *chan, void *data) 151{ 152 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 153 154 /* trigger doorbell irq */ 155 cix_mbox_write(priv, CIX_DB_INT_BIT, CIX_REG_DB_ACK); 156 157 return 0; 158} 159 160static int cix_mbox_send_data_reg(struct mbox_chan *chan, void *data) 161{ 162 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 163 union cix_mbox_msg_reg_fifo *msg = data; 164 u32 len, i; 165 166 if (!data) 167 return -EINVAL; 168 169 len = mbox_get_msg_size(data); 170 for (i = 0; i < len; i++) 171 cix_mbox_write(priv, msg->buf[i], CIX_REG_MSG(i)); 172 173 /* trigger doorbell irq */ 174 cix_mbox_write(priv, CIX_DB_INT_BIT, CIX_REG_DB_ACK); 175 176 return 0; 177} 178 179static int cix_mbox_send_data_fifo(struct mbox_chan *chan, void *data) 180{ 181 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 182 union cix_mbox_msg_reg_fifo *msg = data; 183 u32 len, val, i; 184 185 if (!data) 186 return -EINVAL; 187 188 len = mbox_get_msg_size(data); 189 cix_mbox_write(priv, len, CIX_FIFO_WM); 190 for (i = 0; i < len; i++) 191 cix_mbox_write(priv, msg->buf[i], CIX_FIFO_WR); 192 193 /* Enable fifo empty interrupt */ 194 val = cix_mbox_read(priv, CIX_INT_ENABLE); 195 val |= CIX_FIFO_EMPTY_INT; 196 cix_mbox_write(priv, val, CIX_INT_ENABLE); 197 198 return 0; 199} 200 201static int cix_mbox_send_data_fast(struct mbox_chan *chan, void *data) 202{ 203 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 204 struct cix_mbox_con_priv *cp = chan->con_priv; 205 u32 *arg = (u32 *)data; 206 int index = cp->index; 207 208 if (!data) 209 return -EINVAL; 210 211 if (index < 0 || index > CIX_MBOX_FAST_IDX) { 212 dev_err(priv->dev, "Invalid Mbox index %d\n", index); 213 return -EINVAL; 214 } 215 216 cix_mbox_write(priv, arg[0], CIX_REG_F_INT(index)); 217 218 return 0; 219} 220 221static int cix_mbox_send_data(struct mbox_chan *chan, void *data) 222{ 223 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 224 struct cix_mbox_con_priv *cp = chan->con_priv; 225 226 if (priv->dir != CIX_MBOX_TX) { 227 dev_err(priv->dev, "Invalid Mbox dir %d\n", priv->dir); 228 return -EINVAL; 229 } 230 231 switch (cp->type) { 232 case CIX_MBOX_TYPE_DB: 233 cix_mbox_send_data_db(chan, data); 234 break; 235 case CIX_MBOX_TYPE_REG: 236 cix_mbox_send_data_reg(chan, data); 237 break; 238 case CIX_MBOX_TYPE_FIFO: 239 cix_mbox_send_data_fifo(chan, data); 240 break; 241 case CIX_MBOX_TYPE_FAST: 242 cix_mbox_send_data_fast(chan, data); 243 break; 244 default: 245 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type); 246 return -EINVAL; 247 } 248 return 0; 249} 250 251static void cix_mbox_isr_db(struct mbox_chan *chan) 252{ 253 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 254 u32 int_status; 255 256 int_status = cix_mbox_read(priv, CIX_INT_STATUS); 257 258 if (priv->dir == CIX_MBOX_RX) { 259 /* rx interrupt is triggered */ 260 if (int_status & CIX_DB_INT) { 261 cix_mbox_write(priv, CIX_DB_INT, CIX_INT_CLEAR); 262 mbox_chan_received_data(chan, NULL); 263 /* trigger ack interrupt */ 264 cix_mbox_write(priv, CIX_DB_ACK_INT_BIT, CIX_REG_DB_ACK); 265 } 266 } else { 267 /* tx ack interrupt is triggered */ 268 if (int_status & CIX_ACK_INT) { 269 cix_mbox_write(priv, CIX_ACK_INT, CIX_INT_CLEAR); 270 mbox_chan_received_data(chan, NULL); 271 } 272 } 273} 274 275static void cix_mbox_isr_reg(struct mbox_chan *chan) 276{ 277 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 278 u32 int_status; 279 280 int_status = cix_mbox_read(priv, CIX_INT_STATUS); 281 282 if (priv->dir == CIX_MBOX_RX) { 283 /* rx interrupt is triggered */ 284 if (int_status & CIX_DB_INT) { 285 u32 data[CIX_MBOX_MSG_WORDS], len, i; 286 287 cix_mbox_write(priv, CIX_DB_INT, CIX_INT_CLEAR); 288 data[0] = cix_mbox_read(priv, CIX_REG_MSG(0)); 289 len = mbox_get_msg_size(data); 290 for (i = 1; i < len; i++) 291 data[i] = cix_mbox_read(priv, CIX_REG_MSG(i)); 292 293 /* trigger ack interrupt */ 294 cix_mbox_write(priv, CIX_DB_ACK_INT_BIT, CIX_REG_DB_ACK); 295 mbox_chan_received_data(chan, data); 296 } 297 } else { 298 /* tx ack interrupt is triggered */ 299 if (int_status & CIX_ACK_INT) { 300 cix_mbox_write(priv, CIX_ACK_INT, CIX_INT_CLEAR); 301 mbox_chan_txdone(chan, 0); 302 } 303 } 304} 305 306static void cix_mbox_isr_fifo(struct mbox_chan *chan) 307{ 308 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 309 u32 int_status, status; 310 311 int_status = cix_mbox_read(priv, CIX_INT_STATUS); 312 313 if (priv->dir == CIX_MBOX_RX) { 314 /* FIFO waterMark interrupt is generated */ 315 if (int_status & (CIX_FIFO_FULL_INT | CIX_FIFO_WM01_INT)) { 316 u32 data[CIX_MBOX_MSG_WORDS] = { 0 }, i = 0; 317 318 cix_mbox_write(priv, (CIX_FIFO_FULL_INT | CIX_FIFO_WM01_INT), 319 CIX_INT_CLEAR); 320 do { 321 data[i++] = cix_mbox_read(priv, CIX_FIFO_RD); 322 } while (!mbox_fifo_empty(chan) && i < CIX_MBOX_MSG_WORDS); 323 324 mbox_chan_received_data(chan, data); 325 } 326 /* FIFO underflow is generated */ 327 if (int_status & CIX_FIFO_UFLOW_INT) { 328 status = cix_mbox_read(priv, CIX_FIFO_STAS); 329 dev_err(priv->dev, "fifo underflow: int_stats %d\n", status); 330 cix_mbox_write(priv, CIX_FIFO_UFLOW_INT, CIX_INT_CLEAR); 331 } 332 } else { 333 /* FIFO empty interrupt is generated */ 334 if (int_status & CIX_FIFO_EMPTY_INT) { 335 u32 val; 336 337 cix_mbox_write(priv, CIX_FIFO_EMPTY_INT, CIX_INT_CLEAR); 338 /* Disable empty irq*/ 339 val = cix_mbox_read(priv, CIX_INT_ENABLE); 340 val &= ~CIX_FIFO_EMPTY_INT; 341 cix_mbox_write(priv, val, CIX_INT_ENABLE); 342 mbox_chan_txdone(chan, 0); 343 } 344 /* FIFO overflow is generated */ 345 if (int_status & CIX_FIFO_OFLOW_INT) { 346 status = cix_mbox_read(priv, CIX_FIFO_STAS); 347 dev_err(priv->dev, "fifo overflow: int_stats %d\n", status); 348 cix_mbox_write(priv, CIX_FIFO_OFLOW_INT, CIX_INT_CLEAR); 349 } 350 } 351} 352 353static void cix_mbox_isr_fast(struct mbox_chan *chan) 354{ 355 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 356 struct cix_mbox_con_priv *cp = chan->con_priv; 357 u32 int_status, data; 358 359 /* no irq will be trigger for TX dir mbox */ 360 if (priv->dir != CIX_MBOX_RX) 361 return; 362 363 int_status = cix_mbox_read(priv, CIX_INT_STATUS); 364 365 if (int_status & CIX_FAST_CH_INT(cp->index)) { 366 cix_mbox_write(priv, CIX_FAST_CH_INT(cp->index), CIX_INT_CLEAR); 367 data = cix_mbox_read(priv, CIX_REG_F_INT(cp->index)); 368 mbox_chan_received_data(chan, &data); 369 } 370} 371 372static irqreturn_t cix_mbox_isr(int irq, void *arg) 373{ 374 struct mbox_chan *chan = arg; 375 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 376 struct cix_mbox_con_priv *cp = chan->con_priv; 377 378 switch (cp->type) { 379 case CIX_MBOX_TYPE_DB: 380 cix_mbox_isr_db(chan); 381 break; 382 case CIX_MBOX_TYPE_REG: 383 cix_mbox_isr_reg(chan); 384 break; 385 case CIX_MBOX_TYPE_FIFO: 386 cix_mbox_isr_fifo(chan); 387 break; 388 case CIX_MBOX_TYPE_FAST: 389 cix_mbox_isr_fast(chan); 390 break; 391 default: 392 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type); 393 return IRQ_NONE; 394 } 395 396 return IRQ_HANDLED; 397} 398 399static int cix_mbox_startup(struct mbox_chan *chan) 400{ 401 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 402 struct cix_mbox_con_priv *cp = chan->con_priv; 403 int index = cp->index, ret; 404 u32 val; 405 406 ret = request_irq(priv->irq, cix_mbox_isr, IRQF_NO_SUSPEND, 407 dev_name(priv->dev), chan); 408 if (ret) { 409 dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq); 410 return ret; 411 } 412 413 switch (cp->type) { 414 case CIX_MBOX_TYPE_DB: 415 /* Overwrite txdone_method for DB channel */ 416 chan->txdone_method = MBOX_TXDONE_BY_ACK; 417 fallthrough; 418 case CIX_MBOX_TYPE_REG: 419 if (priv->dir == CIX_MBOX_TX) { 420 /* Enable ACK interrupt */ 421 val = cix_mbox_read(priv, CIX_INT_ENABLE); 422 val |= CIX_ACK_INT; 423 cix_mbox_write(priv, val, CIX_INT_ENABLE); 424 } else { 425 /* Enable Doorbell interrupt */ 426 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B); 427 val |= CIX_DB_INT; 428 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B); 429 } 430 break; 431 case CIX_MBOX_TYPE_FIFO: 432 /* reset fifo */ 433 cix_mbox_write(priv, CIX_FIFO_RST_BIT, CIX_FIFO_RST); 434 /* set default watermark */ 435 cix_mbox_write(priv, CIX_FIFO_WM_DEFAULT, CIX_FIFO_WM); 436 if (priv->dir == CIX_MBOX_TX) { 437 /* Enable fifo overflow interrupt */ 438 val = cix_mbox_read(priv, CIX_INT_ENABLE); 439 val |= CIX_FIFO_OFLOW_INT; 440 cix_mbox_write(priv, val, CIX_INT_ENABLE); 441 } else { 442 /* Enable fifo full/underflow interrupt */ 443 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B); 444 val |= CIX_FIFO_UFLOW_INT|CIX_FIFO_WM01_INT; 445 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B); 446 } 447 break; 448 case CIX_MBOX_TYPE_FAST: 449 /* Only RX channel has intterupt */ 450 if (priv->dir == CIX_MBOX_RX) { 451 if (index < 0 || index > CIX_MBOX_FAST_IDX) { 452 dev_err(priv->dev, "Invalid index %d\n", index); 453 ret = -EINVAL; 454 goto failed; 455 } 456 /* enable fast channel interrupt */ 457 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B); 458 val |= CIX_FAST_CH_INT(index); 459 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B); 460 } 461 break; 462 default: 463 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type); 464 ret = -EINVAL; 465 goto failed; 466 } 467 return 0; 468 469failed: 470 free_irq(priv->irq, chan); 471 return ret; 472} 473 474static void cix_mbox_shutdown(struct mbox_chan *chan) 475{ 476 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox); 477 struct cix_mbox_con_priv *cp = chan->con_priv; 478 int index = cp->index; 479 u32 val; 480 481 switch (cp->type) { 482 case CIX_MBOX_TYPE_DB: 483 case CIX_MBOX_TYPE_REG: 484 if (priv->dir == CIX_MBOX_TX) { 485 /* Disable ACK interrupt */ 486 val = cix_mbox_read(priv, CIX_INT_ENABLE); 487 val &= ~CIX_ACK_INT; 488 cix_mbox_write(priv, val, CIX_INT_ENABLE); 489 } else if (priv->dir == CIX_MBOX_RX) { 490 /* Disable Doorbell interrupt */ 491 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B); 492 val &= ~CIX_DB_INT; 493 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B); 494 } 495 break; 496 case CIX_MBOX_TYPE_FIFO: 497 if (priv->dir == CIX_MBOX_TX) { 498 /* Disable empty/fifo overflow irq*/ 499 val = cix_mbox_read(priv, CIX_INT_ENABLE); 500 val &= ~(CIX_FIFO_EMPTY_INT | CIX_FIFO_OFLOW_INT); 501 cix_mbox_write(priv, val, CIX_INT_ENABLE); 502 } else if (priv->dir == CIX_MBOX_RX) { 503 /* Disable fifo WM01/underflow interrupt */ 504 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B); 505 val &= ~(CIX_FIFO_UFLOW_INT | CIX_FIFO_WM01_INT); 506 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B); 507 } 508 break; 509 case CIX_MBOX_TYPE_FAST: 510 if (priv->dir == CIX_MBOX_RX) { 511 if (index < 0 || index > CIX_MBOX_FAST_IDX) { 512 dev_err(priv->dev, "Invalid index %d\n", index); 513 break; 514 } 515 /* Disable fast channel interrupt */ 516 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B); 517 val &= ~CIX_FAST_CH_INT(index); 518 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B); 519 } 520 break; 521 522 default: 523 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type); 524 break; 525 } 526 527 free_irq(priv->irq, chan); 528} 529 530static const struct mbox_chan_ops cix_mbox_chan_ops = { 531 .send_data = cix_mbox_send_data, 532 .startup = cix_mbox_startup, 533 .shutdown = cix_mbox_shutdown, 534}; 535 536static void cix_mbox_init(struct cix_mbox_priv *priv) 537{ 538 struct cix_mbox_con_priv *cp; 539 int i; 540 541 for (i = 0; i < CIX_MBOX_CHANS; i++) { 542 cp = &priv->con_priv[i]; 543 cp->index = i; 544 cp->chan = &priv->mbox_chans[i]; 545 priv->mbox_chans[i].con_priv = cp; 546 if (cp->index <= CIX_MBOX_FAST_IDX) 547 cp->type = CIX_MBOX_TYPE_FAST; 548 if (cp->index == CIX_MBOX_DB_IDX) 549 cp->type = CIX_MBOX_TYPE_DB; 550 if (cp->index == CIX_MBOX_FIFO_IDX) 551 cp->type = CIX_MBOX_TYPE_FIFO; 552 if (cp->index == CIX_MBOX_REG_IDX) 553 cp->type = CIX_MBOX_TYPE_REG; 554 } 555} 556 557static int cix_mbox_probe(struct platform_device *pdev) 558{ 559 struct device *dev = &pdev->dev; 560 struct cix_mbox_priv *priv; 561 struct resource *res; 562 const char *dir_str; 563 int ret; 564 565 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 566 if (!priv) 567 return -ENOMEM; 568 569 priv->dev = dev; 570 priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 571 if (IS_ERR(priv->base)) 572 return PTR_ERR(priv->base); 573 574 /* 575 * The first 0x80 bytes of the register space of the cix mailbox controller 576 * can be used as shared memory for clients. When this shared memory is in 577 * use, the base address of the mailbox is offset by 0x80. Therefore, when 578 * performing subsequent read/write operations, it is necessary to subtract 579 * the offset CIX_SHMEM_OFFSET. 580 * 581 * When the base address of the mailbox is offset by 0x80, it indicates 582 * that shmem is in use. 583 */ 584 priv->use_shmem = !!(res->start & CIX_SHMEM_OFFSET); 585 586 priv->irq = platform_get_irq(pdev, 0); 587 if (priv->irq < 0) 588 return priv->irq; 589 590 if (device_property_read_string(dev, "cix,mbox-dir", &dir_str)) { 591 dev_err(priv->dev, "cix,mbox_dir property not found\n"); 592 return -EINVAL; 593 } 594 595 if (!strcmp(dir_str, "tx")) 596 priv->dir = 0; 597 else if (!strcmp(dir_str, "rx")) 598 priv->dir = 1; 599 else { 600 dev_err(priv->dev, "cix,mbox_dir=%s is not expected\n", dir_str); 601 return -EINVAL; 602 } 603 604 cix_mbox_init(priv); 605 606 priv->mbox.dev = dev; 607 priv->mbox.ops = &cix_mbox_chan_ops; 608 priv->mbox.chans = priv->mbox_chans; 609 priv->mbox.txdone_irq = true; 610 priv->mbox.num_chans = CIX_MBOX_CHANS; 611 priv->mbox.of_xlate = NULL; 612 613 platform_set_drvdata(pdev, priv); 614 ret = devm_mbox_controller_register(dev, &priv->mbox); 615 if (ret) 616 dev_err(dev, "Failed to register mailbox %d\n", ret); 617 618 return ret; 619} 620 621static const struct of_device_id cix_mbox_dt_ids[] = { 622 { .compatible = "cix,sky1-mbox" }, 623 { }, 624}; 625MODULE_DEVICE_TABLE(of, cix_mbox_dt_ids); 626 627static struct platform_driver cix_mbox_driver = { 628 .probe = cix_mbox_probe, 629 .driver = { 630 .name = "cix_mbox", 631 .of_match_table = cix_mbox_dt_ids, 632 }, 633}; 634 635static int __init cix_mailbox_init(void) 636{ 637 return platform_driver_register(&cix_mbox_driver); 638} 639arch_initcall(cix_mailbox_init); 640 641MODULE_AUTHOR("Cix Technology Group Co., Ltd."); 642MODULE_DESCRIPTION("CIX mailbox driver"); 643MODULE_LICENSE("GPL");