FILE
mctp-i3c.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/mctp/mctp-i3c.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Implements DMTF specification 4 * "DSP0233 Management Component Transport Protocol (MCTP) I3C Transport 5 * Binding" 6 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0233_1.0.0.pdf 7 * 8 * Copyright (c) 2023 Code Construct 9 */ 10 11#include <linux/module.h> 12#include <linux/netdevice.h> 13#include <linux/i3c/device.h> 14#include <linux/i3c/master.h> 15#include <linux/if_arp.h> 16#include <linux/unaligned.h> 17#include <net/mctp.h> 18#include <net/mctpdevice.h> 19 20#define MCTP_I3C_MAXBUF 65536 21/* 48 bit Provisioned Id */ 22#define PID_SIZE 6 23 24/* 64 byte payload, 4 byte MCTP header */ 25static const int MCTP_I3C_MINMTU = 64 + 4; 26/* One byte less to allow for the PEC */ 27static const int MCTP_I3C_MAXMTU = MCTP_I3C_MAXBUF - 1; 28/* 4 byte MCTP header, no data, 1 byte PEC */ 29static const int MCTP_I3C_MINLEN = 4 + 1; 30 31/* Sufficient for 64kB at min mtu */ 32static const int MCTP_I3C_TX_QUEUE_LEN = 1100; 33 34/* Somewhat arbitrary */ 35static const int MCTP_I3C_IBI_SLOTS = 8; 36 37/* Mandatory Data Byte in an IBI, from DSP0233 */ 38#define I3C_MDB_MCTP 0xAE 39/* From MIPI Device Characteristics Register (DCR) Assignments */ 40#define I3C_DCR_MCTP 0xCC 41 42static const char *MCTP_I3C_OF_PROP = "mctp-controller"; 43 44/* List of mctp_i3c_busdev */ 45static LIST_HEAD(busdevs); 46/* Protects busdevs, as well as mctp_i3c_bus.devs lists */ 47static DEFINE_MUTEX(busdevs_lock); 48 49struct mctp_i3c_bus { 50 struct net_device *ndev; 51 52 struct task_struct *tx_thread; 53 wait_queue_head_t tx_wq; 54 /* tx_lock protects tx_skb and devs */ 55 spinlock_t tx_lock; 56 /* Next skb to transmit */ 57 struct sk_buff *tx_skb; 58 /* Scratch buffer for xmit */ 59 u8 tx_scratch[MCTP_I3C_MAXBUF]; 60 61 /* Element of busdevs */ 62 struct list_head list; 63 64 /* Provisioned ID of our controller */ 65 u64 pid; 66 67 struct i3c_bus *bus; 68 /* Head of mctp_i3c_device.list. Protected by busdevs_lock */ 69 struct list_head devs; 70}; 71 72struct mctp_i3c_device { 73 struct i3c_device *i3c; 74 struct mctp_i3c_bus *mbus; 75 struct list_head list; /* Element of mctp_i3c_bus.devs */ 76 77 /* Held while tx_thread is using this device */ 78 struct mutex lock; 79 80 /* Whether BCR indicates MDB is present in IBI */ 81 bool have_mdb; 82 /* I3C dynamic address */ 83 u8 addr; 84 /* Maximum read length */ 85 u16 mrl; 86 /* Maximum write length */ 87 u16 mwl; 88 /* Provisioned ID */ 89 u64 pid; 90}; 91 92/* We synthesise a mac header using the Provisioned ID. 93 * Used to pass dest to mctp_i3c_start_xmit. 94 */ 95struct mctp_i3c_internal_hdr { 96 u8 dest[PID_SIZE]; 97 u8 source[PID_SIZE]; 98} __packed; 99 100static int mctp_i3c_read(struct mctp_i3c_device *mi) 101{ 102 struct i3c_xfer xfer = { .rnw = 1, .len = mi->mrl }; 103 struct net_device_stats *stats = &mi->mbus->ndev->stats; 104 struct mctp_i3c_internal_hdr *ihdr = NULL; 105 struct sk_buff *skb = NULL; 106 struct mctp_skb_cb *cb; 107 int net_status, rc; 108 u8 pec, addr; 109 110 skb = netdev_alloc_skb(mi->mbus->ndev, 111 mi->mrl + sizeof(struct mctp_i3c_internal_hdr)); 112 if (!skb) { 113 stats->rx_dropped++; 114 rc = -ENOMEM; 115 goto err; 116 } 117 118 skb->protocol = htons(ETH_P_MCTP); 119 /* Create a header for internal use */ 120 skb_reset_mac_header(skb); 121 ihdr = skb_put(skb, sizeof(struct mctp_i3c_internal_hdr)); 122 put_unaligned_be48(mi->pid, ihdr->source); 123 put_unaligned_be48(mi->mbus->pid, ihdr->dest); 124 skb_pull(skb, sizeof(struct mctp_i3c_internal_hdr)); 125 126 xfer.data.in = skb_put(skb, mi->mrl); 127 128 /* Make sure netif_rx() is read in the same order as i3c. */ 129 mutex_lock(&mi->lock); 130 rc = i3c_device_do_xfers(mi->i3c, &xfer, 1, I3C_SDR); 131 if (rc < 0) 132 goto err; 133 134 if (WARN_ON_ONCE(xfer.len > mi->mrl)) { 135 /* Bad i3c bus driver */ 136 rc = -EIO; 137 goto err; 138 } 139 if (xfer.len < MCTP_I3C_MINLEN) { 140 stats->rx_length_errors++; 141 rc = -EIO; 142 goto err; 143 } 144 145 /* check PEC, including address byte */ 146 addr = mi->addr << 1 | 1; 147 pec = i2c_smbus_pec(0, &addr, 1); 148 pec = i2c_smbus_pec(pec, xfer.data.in, xfer.len - 1); 149 if (pec != ((u8 *)xfer.data.in)[xfer.len - 1]) { 150 stats->rx_crc_errors++; 151 rc = -EINVAL; 152 goto err; 153 } 154 155 /* Remove PEC */ 156 skb_trim(skb, xfer.len - 1); 157 158 cb = __mctp_cb(skb); 159 cb->halen = PID_SIZE; 160 put_unaligned_be48(mi->pid, cb->haddr); 161 162 net_status = netif_rx(skb); 163 164 if (net_status == NET_RX_SUCCESS) { 165 stats->rx_packets++; 166 stats->rx_bytes += xfer.len - 1; 167 } else { 168 stats->rx_dropped++; 169 } 170 171 mutex_unlock(&mi->lock); 172 return 0; 173err: 174 mutex_unlock(&mi->lock); 175 kfree_skb(skb); 176 return rc; 177} 178 179static void mctp_i3c_ibi_handler(struct i3c_device *i3c, 180 const struct i3c_ibi_payload *payload) 181{ 182 struct mctp_i3c_device *mi = i3cdev_get_drvdata(i3c); 183 184 if (WARN_ON_ONCE(!mi)) 185 return; 186 187 if (mi->have_mdb) { 188 if (payload->len > 0) { 189 if (((u8 *)payload->data)[0] != I3C_MDB_MCTP) { 190 /* Not a mctp-i3c interrupt, ignore it */ 191 return; 192 } 193 } else { 194 /* The BCR advertised a Mandatory Data Byte but the 195 * device didn't send one. 196 */ 197 dev_warn_once(i3cdev_to_dev(i3c), "IBI with missing MDB"); 198 } 199 } 200 201 mctp_i3c_read(mi); 202} 203 204static int mctp_i3c_setup(struct mctp_i3c_device *mi) 205{ 206 const struct i3c_ibi_setup ibi = { 207 .max_payload_len = 1, 208 .num_slots = MCTP_I3C_IBI_SLOTS, 209 .handler = mctp_i3c_ibi_handler, 210 }; 211 struct i3c_device_info info; 212 int rc; 213 214 i3c_device_get_info(mi->i3c, &info); 215 mi->have_mdb = info.bcr & BIT(2); 216 mi->addr = info.dyn_addr; 217 mi->mwl = info.max_write_len; 218 mi->mrl = info.max_read_len; 219 mi->pid = info.pid; 220 221 rc = i3c_device_request_ibi(mi->i3c, &ibi); 222 if (rc == -ENOTSUPP) { 223 /* This driver only supports In-Band Interrupt mode. 224 * Support for Polling Mode could be added if required. 225 * (ENOTSUPP is from the i3c layer, not EOPNOTSUPP). 226 */ 227 dev_warn(i3cdev_to_dev(mi->i3c), 228 "Failed, bus driver doesn't support In-Band Interrupts"); 229 goto err; 230 } else if (rc < 0) { 231 dev_err(i3cdev_to_dev(mi->i3c), 232 "Failed requesting IBI (%d)\n", rc); 233 goto err; 234 } 235 236 rc = i3c_device_enable_ibi(mi->i3c); 237 if (rc < 0) { 238 /* Assume a driver supporting request_ibi also 239 * supports enable_ibi. 240 */ 241 dev_err(i3cdev_to_dev(mi->i3c), "Failed enabling IBI (%d)\n", rc); 242 goto err_free_ibi; 243 } 244 245 return 0; 246 247err_free_ibi: 248 i3c_device_free_ibi(mi->i3c); 249 250err: 251 return rc; 252} 253 254/* Adds a new MCTP i3c_device to a bus */ 255static int mctp_i3c_add_device(struct mctp_i3c_bus *mbus, 256 struct i3c_device *i3c) 257__must_hold(&busdevs_lock) 258{ 259 struct mctp_i3c_device *mi = NULL; 260 int rc; 261 262 mi = kzalloc(sizeof(*mi), GFP_KERNEL); 263 if (!mi) { 264 rc = -ENOMEM; 265 goto err; 266 } 267 mi->mbus = mbus; 268 mi->i3c = i3c; 269 mutex_init(&mi->lock); 270 list_add(&mi->list, &mbus->devs); 271 272 i3cdev_set_drvdata(i3c, mi); 273 rc = mctp_i3c_setup(mi); 274 if (rc < 0) 275 goto err_free; 276 277 return 0; 278 279err_free: 280 list_del(&mi->list); 281 kfree(mi); 282 283err: 284 dev_warn(i3cdev_to_dev(i3c), "Error adding mctp-i3c device, %d\n", rc); 285 return rc; 286} 287 288static int mctp_i3c_probe(struct i3c_device *i3c) 289{ 290 struct mctp_i3c_bus *b = NULL, *mbus = NULL; 291 292 /* Look for a known bus */ 293 mutex_lock(&busdevs_lock); 294 list_for_each_entry(b, &busdevs, list) 295 if (b->bus == i3c->bus) { 296 mbus = b; 297 break; 298 } 299 mutex_unlock(&busdevs_lock); 300 301 if (!mbus) { 302 /* probably no "mctp-controller" property on the i3c bus */ 303 return -ENODEV; 304 } 305 306 return mctp_i3c_add_device(mbus, i3c); 307} 308 309static void mctp_i3c_remove_device(struct mctp_i3c_device *mi) 310__must_hold(&busdevs_lock) 311{ 312 /* Ensure the tx thread isn't using the device */ 313 mutex_lock(&mi->lock); 314 315 /* Counterpart of mctp_i3c_setup */ 316 i3c_device_disable_ibi(mi->i3c); 317 i3c_device_free_ibi(mi->i3c); 318 319 /* Counterpart of mctp_i3c_add_device */ 320 i3cdev_set_drvdata(mi->i3c, NULL); 321 list_del(&mi->list); 322 323 /* Safe to unlock after removing from the list */ 324 mutex_unlock(&mi->lock); 325 kfree(mi); 326} 327 328static void mctp_i3c_remove(struct i3c_device *i3c) 329{ 330 struct mctp_i3c_device *mi = i3cdev_get_drvdata(i3c); 331 332 /* We my have received a Bus Remove notify prior to device remove, 333 * so mi will already be removed. 334 */ 335 if (!mi) 336 return; 337 338 mutex_lock(&busdevs_lock); 339 mctp_i3c_remove_device(mi); 340 mutex_unlock(&busdevs_lock); 341} 342 343/* Returns the device for an address, with mi->lock held */ 344static struct mctp_i3c_device * 345mctp_i3c_lookup(struct mctp_i3c_bus *mbus, u64 pid) 346{ 347 struct mctp_i3c_device *mi = NULL, *ret = NULL; 348 349 mutex_lock(&busdevs_lock); 350 list_for_each_entry(mi, &mbus->devs, list) 351 if (mi->pid == pid) { 352 ret = mi; 353 mutex_lock(&mi->lock); 354 break; 355 } 356 mutex_unlock(&busdevs_lock); 357 return ret; 358} 359 360static void mctp_i3c_xmit(struct mctp_i3c_bus *mbus, struct sk_buff *skb) 361{ 362 struct net_device_stats *stats = &mbus->ndev->stats; 363 struct i3c_xfer xfer = { .rnw = false }; 364 struct mctp_i3c_internal_hdr *ihdr = NULL; 365 struct mctp_i3c_device *mi = NULL; 366 unsigned int data_len; 367 u8 *data = NULL; 368 u8 addr, pec; 369 int rc = 0; 370 u64 pid; 371 372 skb_pull(skb, sizeof(struct mctp_i3c_internal_hdr)); 373 data_len = skb->len; 374 375 ihdr = (void *)skb_mac_header(skb); 376 377 pid = get_unaligned_be48(ihdr->dest); 378 mi = mctp_i3c_lookup(mbus, pid); 379 if (!mi) { 380 /* I3C endpoint went away after the packet was enqueued? */ 381 stats->tx_dropped++; 382 goto out; 383 } 384 385 if (WARN_ON_ONCE(data_len + 1 > MCTP_I3C_MAXBUF)) 386 goto out; 387 388 if (data_len + 1 > (unsigned int)mi->mwl) { 389 /* Route MTU was larger than supported by the endpoint */ 390 stats->tx_dropped++; 391 goto out; 392 } 393 394 /* Need a linear buffer with space for the PEC */ 395 xfer.len = data_len + 1; 396 if (skb_tailroom(skb) >= 1) { 397 skb_put(skb, 1); 398 data = skb->data; 399 } else { 400 /* Otherwise need to copy the buffer */ 401 skb_copy_bits(skb, 0, mbus->tx_scratch, skb->len); 402 data = mbus->tx_scratch; 403 } 404 405 /* PEC calculation */ 406 addr = mi->addr << 1; 407 pec = i2c_smbus_pec(0, &addr, 1); 408 pec = i2c_smbus_pec(pec, data, data_len); 409 data[data_len] = pec; 410 411 xfer.data.out = data; 412 rc = i3c_device_do_xfers(mi->i3c, &xfer, 1, I3C_SDR); 413 if (rc == 0) { 414 stats->tx_bytes += data_len; 415 stats->tx_packets++; 416 } else { 417 stats->tx_errors++; 418 } 419 420out: 421 if (mi) 422 mutex_unlock(&mi->lock); 423} 424 425static int mctp_i3c_tx_thread(void *data) 426{ 427 struct mctp_i3c_bus *mbus = data; 428 struct sk_buff *skb; 429 430 for (;;) { 431 if (kthread_should_stop()) 432 break; 433 434 spin_lock_bh(&mbus->tx_lock); 435 skb = mbus->tx_skb; 436 mbus->tx_skb = NULL; 437 spin_unlock_bh(&mbus->tx_lock); 438 439 if (netif_queue_stopped(mbus->ndev)) 440 netif_wake_queue(mbus->ndev); 441 442 if (skb) { 443 mctp_i3c_xmit(mbus, skb); 444 kfree_skb(skb); 445 } else { 446 wait_event_idle(mbus->tx_wq, 447 mbus->tx_skb || kthread_should_stop()); 448 } 449 } 450 451 return 0; 452} 453 454static netdev_tx_t mctp_i3c_start_xmit(struct sk_buff *skb, 455 struct net_device *ndev) 456{ 457 struct mctp_i3c_bus *mbus = netdev_priv(ndev); 458 netdev_tx_t ret; 459 460 spin_lock(&mbus->tx_lock); 461 netif_stop_queue(ndev); 462 if (mbus->tx_skb) { 463 dev_warn_ratelimited(&ndev->dev, "TX with queue stopped"); 464 ret = NETDEV_TX_BUSY; 465 } else { 466 mbus->tx_skb = skb; 467 ret = NETDEV_TX_OK; 468 } 469 spin_unlock(&mbus->tx_lock); 470 471 if (ret == NETDEV_TX_OK) 472 wake_up(&mbus->tx_wq); 473 474 return ret; 475} 476 477static void mctp_i3c_bus_free(struct mctp_i3c_bus *mbus) 478__must_hold(&busdevs_lock) 479{ 480 struct mctp_i3c_device *mi = NULL, *tmp = NULL; 481 482 if (mbus->tx_thread) { 483 kthread_stop(mbus->tx_thread); 484 mbus->tx_thread = NULL; 485 } 486 487 /* Remove any child devices */ 488 list_for_each_entry_safe(mi, tmp, &mbus->devs, list) { 489 mctp_i3c_remove_device(mi); 490 } 491 492 kfree_skb(mbus->tx_skb); 493 list_del(&mbus->list); 494} 495 496static void mctp_i3c_ndo_uninit(struct net_device *ndev) 497{ 498 struct mctp_i3c_bus *mbus = netdev_priv(ndev); 499 500 /* Perform cleanup here to ensure there are no remaining references */ 501 mctp_i3c_bus_free(mbus); 502} 503 504static int mctp_i3c_header_create(struct sk_buff *skb, struct net_device *dev, 505 unsigned short type, const void *daddr, 506 const void *saddr, unsigned int len) 507{ 508 struct mctp_i3c_internal_hdr *ihdr; 509 int rc; 510 511 if (!daddr || !saddr) 512 return -EINVAL; 513 514 rc = skb_cow_head(skb, sizeof(struct mctp_i3c_internal_hdr)); 515 if (rc) 516 return rc; 517 518 skb_push(skb, sizeof(struct mctp_i3c_internal_hdr)); 519 skb_reset_mac_header(skb); 520 ihdr = (void *)skb_mac_header(skb); 521 memcpy(ihdr->dest, daddr, PID_SIZE); 522 memcpy(ihdr->source, saddr, PID_SIZE); 523 return 0; 524} 525 526static const struct net_device_ops mctp_i3c_ops = { 527 .ndo_start_xmit = mctp_i3c_start_xmit, 528 .ndo_uninit = mctp_i3c_ndo_uninit, 529}; 530 531static const struct header_ops mctp_i3c_headops = { 532 .create = mctp_i3c_header_create, 533}; 534 535static void mctp_i3c_net_setup(struct net_device *dev) 536{ 537 dev->type = ARPHRD_MCTP; 538 539 dev->mtu = MCTP_I3C_MAXMTU; 540 dev->min_mtu = MCTP_I3C_MINMTU; 541 dev->max_mtu = MCTP_I3C_MAXMTU; 542 dev->tx_queue_len = MCTP_I3C_TX_QUEUE_LEN; 543 544 dev->hard_header_len = sizeof(struct mctp_i3c_internal_hdr); 545 dev->addr_len = PID_SIZE; 546 547 dev->netdev_ops = &mctp_i3c_ops; 548 dev->header_ops = &mctp_i3c_headops; 549} 550 551static bool mctp_i3c_is_mctp_controller(struct i3c_bus *bus) 552{ 553 struct i3c_dev_desc *master = bus->cur_master; 554 555 if (!master) 556 return false; 557 558 return of_property_read_bool(master->common.master->dev.of_node, 559 MCTP_I3C_OF_PROP); 560} 561 562/* Returns the Provisioned Id of a local bus master */ 563static int mctp_i3c_bus_local_pid(struct i3c_bus *bus, u64 *ret_pid) 564{ 565 struct i3c_dev_desc *master; 566 567 master = bus->cur_master; 568 if (WARN_ON_ONCE(!master)) 569 return -ENOENT; 570 *ret_pid = master->info.pid; 571 572 return 0; 573} 574 575/* Returns an ERR_PTR on failure */ 576static struct mctp_i3c_bus *mctp_i3c_bus_add(struct i3c_bus *bus) 577__must_hold(&busdevs_lock) 578{ 579 struct mctp_i3c_bus *mbus = NULL; 580 struct net_device *ndev = NULL; 581 char namebuf[IFNAMSIZ]; 582 u8 addr[PID_SIZE]; 583 int rc; 584 585 if (!mctp_i3c_is_mctp_controller(bus)) 586 return ERR_PTR(-ENOENT); 587 588 snprintf(namebuf, sizeof(namebuf), "mctpi3c%d", bus->id); 589 ndev = alloc_netdev(sizeof(*mbus), namebuf, NET_NAME_ENUM, 590 mctp_i3c_net_setup); 591 if (!ndev) { 592 rc = -ENOMEM; 593 goto err; 594 } 595 596 mbus = netdev_priv(ndev); 597 mbus->ndev = ndev; 598 mbus->bus = bus; 599 INIT_LIST_HEAD(&mbus->devs); 600 list_add(&mbus->list, &busdevs); 601 602 rc = mctp_i3c_bus_local_pid(bus, &mbus->pid); 603 if (rc < 0) { 604 dev_err(&ndev->dev, "No I3C PID available\n"); 605 goto err_free_uninit; 606 } 607 put_unaligned_be48(mbus->pid, addr); 608 dev_addr_set(ndev, addr); 609 610 init_waitqueue_head(&mbus->tx_wq); 611 spin_lock_init(&mbus->tx_lock); 612 mbus->tx_thread = kthread_run(mctp_i3c_tx_thread, mbus, 613 "%s/tx", ndev->name); 614 if (IS_ERR(mbus->tx_thread)) { 615 dev_warn(&ndev->dev, "Error creating thread: %pe\n", 616 mbus->tx_thread); 617 rc = PTR_ERR(mbus->tx_thread); 618 mbus->tx_thread = NULL; 619 goto err_free_uninit; 620 } 621 622 rc = mctp_register_netdev(ndev, NULL, MCTP_PHYS_BINDING_I3C); 623 if (rc < 0) { 624 dev_warn(&ndev->dev, "netdev register failed: %d\n", rc); 625 goto err_free_netdev; 626 } 627 return mbus; 628 629err_free_uninit: 630 /* uninit will not get called if a netdev has not been registered, 631 * so we perform the same mbus cleanup manually. 632 */ 633 mctp_i3c_bus_free(mbus); 634 635err_free_netdev: 636 free_netdev(ndev); 637 638err: 639 return ERR_PTR(rc); 640} 641 642static void mctp_i3c_bus_remove(struct mctp_i3c_bus *mbus) 643__must_hold(&busdevs_lock) 644{ 645 /* Unregister calls through to ndo_uninit -> mctp_i3c_bus_free() */ 646 mctp_unregister_netdev(mbus->ndev); 647 648 free_netdev(mbus->ndev); 649 /* mbus is deallocated */ 650} 651 652/* Removes all mctp-i3c busses */ 653static void mctp_i3c_bus_remove_all(void) 654{ 655 struct mctp_i3c_bus *mbus = NULL, *tmp = NULL; 656 657 mutex_lock(&busdevs_lock); 658 list_for_each_entry_safe(mbus, tmp, &busdevs, list) { 659 mctp_i3c_bus_remove(mbus); 660 } 661 mutex_unlock(&busdevs_lock); 662} 663 664/* Adds a i3c_bus if it isn't already in the busdevs list. 665 * Suitable as an i3c_for_each_bus_locked callback. 666 */ 667static int mctp_i3c_bus_add_new(struct i3c_bus *bus, void *data) 668{ 669 struct mctp_i3c_bus *mbus = NULL, *tmp = NULL; 670 bool exists = false; 671 672 mutex_lock(&busdevs_lock); 673 list_for_each_entry_safe(mbus, tmp, &busdevs, list) 674 if (mbus->bus == bus) 675 exists = true; 676 677 /* It is OK for a bus to already exist. That can occur due to 678 * the race in mod_init between notifier and for_each_bus 679 */ 680 if (!exists) 681 mctp_i3c_bus_add(bus); 682 mutex_unlock(&busdevs_lock); 683 return 0; 684} 685 686static void mctp_i3c_notify_bus_remove(struct i3c_bus *bus) 687{ 688 struct mctp_i3c_bus *mbus = NULL, *tmp; 689 690 mutex_lock(&busdevs_lock); 691 list_for_each_entry_safe(mbus, tmp, &busdevs, list) 692 if (mbus->bus == bus) 693 mctp_i3c_bus_remove(mbus); 694 mutex_unlock(&busdevs_lock); 695} 696 697static int mctp_i3c_notifier_call(struct notifier_block *nb, 698 unsigned long action, void *data) 699{ 700 switch (action) { 701 case I3C_NOTIFY_BUS_ADD: 702 mctp_i3c_bus_add_new((struct i3c_bus *)data, NULL); 703 break; 704 case I3C_NOTIFY_BUS_REMOVE: 705 mctp_i3c_notify_bus_remove((struct i3c_bus *)data); 706 break; 707 } 708 return NOTIFY_DONE; 709} 710 711static struct notifier_block mctp_i3c_notifier = { 712 .notifier_call = mctp_i3c_notifier_call, 713}; 714 715static const struct i3c_device_id mctp_i3c_ids[] = { 716 I3C_CLASS(I3C_DCR_MCTP, NULL), 717 { 0 }, 718}; 719 720static struct i3c_driver mctp_i3c_driver = { 721 .driver = { 722 .name = "mctp-i3c", 723 }, 724 .probe = mctp_i3c_probe, 725 .remove = mctp_i3c_remove, 726 .id_table = mctp_i3c_ids, 727}; 728 729static __init int mctp_i3c_mod_init(void) 730{ 731 int rc; 732 733 rc = i3c_register_notifier(&mctp_i3c_notifier); 734 if (rc < 0) { 735 i3c_driver_unregister(&mctp_i3c_driver); 736 return rc; 737 } 738 739 i3c_for_each_bus_locked(mctp_i3c_bus_add_new, NULL); 740 741 rc = i3c_driver_register(&mctp_i3c_driver); 742 if (rc < 0) 743 return rc; 744 745 return 0; 746} 747 748static __exit void mctp_i3c_mod_exit(void) 749{ 750 int rc; 751 752 i3c_driver_unregister(&mctp_i3c_driver); 753 754 rc = i3c_unregister_notifier(&mctp_i3c_notifier); 755 if (rc < 0) 756 pr_warn("MCTP I3C could not unregister notifier, %d\n", rc); 757 758 mctp_i3c_bus_remove_all(); 759} 760 761module_init(mctp_i3c_mod_init); 762module_exit(mctp_i3c_mod_exit); 763 764MODULE_DEVICE_TABLE(i3c, mctp_i3c_ids); 765MODULE_DESCRIPTION("MCTP I3C device"); 766MODULE_LICENSE("GPL"); 767MODULE_AUTHOR("Matt Johnston <matt@codeconstruct.com.au>");
~/
Read-only file preview.