linux/drivers/net/ethernet/mellanox/mlxsw/i2c.c
<<
>>
Prefs
   1/*
   2 * drivers/net/ethernet/mellanox/mlxsw/i2c.c
   3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
   4 * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
   5 *
   6 * Redistribution and use in source and binary forms, with or without
   7 * modification, are permitted provided that the following conditions are met:
   8 *
   9 * 1. Redistributions of source code must retain the above copyright
  10 *    notice, this list of conditions and the following disclaimer.
  11 * 2. Redistributions in binary form must reproduce the above copyright
  12 *    notice, this list of conditions and the following disclaimer in the
  13 *    documentation and/or other materials provided with the distribution.
  14 * 3. Neither the names of the copyright holders nor the names of its
  15 *    contributors may be used to endorse or promote products derived from
  16 *    this software without specific prior written permission.
  17 *
  18 * Alternatively, this software may be distributed under the terms of the
  19 * GNU General Public License ("GPL") version 2 as published by the Free
  20 * Software Foundation.
  21 *
  22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32 * POSSIBILITY OF SUCH DAMAGE.
  33 */
  34
  35#include <linux/err.h>
  36#include <linux/i2c.h>
  37#include <linux/init.h>
  38#include <linux/jiffies.h>
  39#include <linux/kernel.h>
  40#include <linux/mutex.h>
  41#include <linux/module.h>
  42#include <linux/mod_devicetable.h>
  43#include <linux/slab.h>
  44
  45#include "cmd.h"
  46#include "core.h"
  47#include "i2c.h"
  48
  49static const char mlxsw_i2c_driver_name[] = "mlxsw_i2c";
  50
  51#define MLXSW_I2C_CIR2_BASE             0x72000
  52#define MLXSW_I2C_CIR_STATUS_OFF        0x18
  53#define MLXSW_I2C_CIR2_OFF_STATUS       (MLXSW_I2C_CIR2_BASE + \
  54                                         MLXSW_I2C_CIR_STATUS_OFF)
  55#define MLXSW_I2C_OPMOD_SHIFT           12
  56#define MLXSW_I2C_GO_BIT_SHIFT          23
  57#define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24
  58#define MLXSW_I2C_GO_BIT                BIT(MLXSW_I2C_GO_BIT_SHIFT)
  59#define MLXSW_I2C_GO_OPMODE             BIT(MLXSW_I2C_OPMOD_SHIFT)
  60#define MLXSW_I2C_SET_IMM_CMD           (MLXSW_I2C_GO_OPMODE | \
  61                                         MLXSW_CMD_OPCODE_QUERY_FW)
  62#define MLXSW_I2C_PUSH_IMM_CMD          (MLXSW_I2C_GO_BIT | \
  63                                         MLXSW_I2C_SET_IMM_CMD)
  64#define MLXSW_I2C_SET_CMD               (MLXSW_CMD_OPCODE_ACCESS_REG)
  65#define MLXSW_I2C_PUSH_CMD              (MLXSW_I2C_GO_BIT | MLXSW_I2C_SET_CMD)
  66#define MLXSW_I2C_TLV_HDR_SIZE          0x10
  67#define MLXSW_I2C_ADDR_WIDTH            4
  68#define MLXSW_I2C_PUSH_CMD_SIZE         (MLXSW_I2C_ADDR_WIDTH + 4)
  69#define MLXSW_I2C_READ_SEMA_SIZE        4
  70#define MLXSW_I2C_PREP_SIZE             (MLXSW_I2C_ADDR_WIDTH + 28)
  71#define MLXSW_I2C_MBOX_SIZE             20
  72#define MLXSW_I2C_MBOX_OUT_PARAM_OFF    12
  73#define MLXSW_I2C_MAX_BUFF_SIZE         32
  74#define MLXSW_I2C_MBOX_OFFSET_BITS      20
  75#define MLXSW_I2C_MBOX_SIZE_BITS        12
  76#define MLXSW_I2C_ADDR_BUF_SIZE         4
  77#define MLXSW_I2C_BLK_MAX               32
  78#define MLXSW_I2C_RETRY                 5
  79#define MLXSW_I2C_TIMEOUT_MSECS         5000
  80
  81/**
  82 * struct mlxsw_i2c - device private data:
  83 * @cmd.mb_size_in: input mailbox size;
  84 * @cmd.mb_off_in: input mailbox offset in register space;
  85 * @cmd.mb_size_out: output mailbox size;
  86 * @cmd.mb_off_out: output mailbox offset in register space;
  87 * @cmd.lock: command execution lock;
  88 * @dev: I2C device;
  89 * @core: switch core pointer;
  90 * @bus_info: bus info block;
  91 */
  92struct mlxsw_i2c {
  93        struct {
  94                u32 mb_size_in;
  95                u32 mb_off_in;
  96                u32 mb_size_out;
  97                u32 mb_off_out;
  98                struct mutex lock;
  99        } cmd;
 100        struct device *dev;
 101        struct mlxsw_core *core;
 102        struct mlxsw_bus_info bus_info;
 103};
 104
 105#define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) {    \
 106        { .addr = (_client)->addr,                              \
 107          .buf = (_addr_buf),                                   \
 108          .len = MLXSW_I2C_ADDR_BUF_SIZE,                       \
 109          .flags = 0 },                                         \
 110        { .addr = (_client)->addr,                              \
 111          .buf = (_buf),                                        \
 112          .len = (_len),                                        \
 113          .flags = I2C_M_RD } }
 114
 115#define MLXSW_I2C_WRITE_MSG(_client, _buf, _len)                \
 116        { .addr = (_client)->addr,                              \
 117          .buf = (u8 *)(_buf),                                  \
 118          .len = (_len),                                        \
 119          .flags = 0 }
 120
 121/* Routine converts in and out mail boxes offset and size. */
 122static inline void
 123mlxsw_i2c_convert_mbox(struct mlxsw_i2c *mlxsw_i2c, u8 *buf)
 124{
 125        u32 tmp;
 126
 127        /* Local in/out mailboxes: 20 bits for offset, 12 for size */
 128        tmp = be32_to_cpup((__be32 *) buf);
 129        mlxsw_i2c->cmd.mb_off_in = tmp &
 130                                   GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
 131        mlxsw_i2c->cmd.mb_size_in = (tmp & GENMASK(31,
 132                                        MLXSW_I2C_MBOX_OFFSET_BITS)) >>
 133                                        MLXSW_I2C_MBOX_OFFSET_BITS;
 134
 135        tmp = be32_to_cpup((__be32 *) (buf + MLXSW_I2C_ADDR_WIDTH));
 136        mlxsw_i2c->cmd.mb_off_out = tmp &
 137                                    GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
 138        mlxsw_i2c->cmd.mb_size_out = (tmp & GENMASK(31,
 139                                        MLXSW_I2C_MBOX_OFFSET_BITS)) >>
 140                                        MLXSW_I2C_MBOX_OFFSET_BITS;
 141}
 142
 143/* Routine obtains register size from mail box buffer. */
 144static inline int mlxsw_i2c_get_reg_size(u8 *in_mbox)
 145{
 146        u16  tmp = be16_to_cpup((__be16 *) (in_mbox + MLXSW_I2C_TLV_HDR_SIZE));
 147
 148        return (tmp & 0x7ff) * 4 + MLXSW_I2C_TLV_HDR_SIZE;
 149}
 150
 151/* Routine sets I2C device internal offset in the transaction buffer. */
 152static inline void mlxsw_i2c_set_slave_addr(u8 *buf, u32 off)
 153{
 154        __be32 *val = (__be32 *) buf;
 155
 156        *val = htonl(off);
 157}
 158
 159/* Routine waits until go bit is cleared. */
 160static int mlxsw_i2c_wait_go_bit(struct i2c_client *client,
 161                                 struct mlxsw_i2c *mlxsw_i2c, u8 *p_status)
 162{
 163        u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
 164        u8 buf[MLXSW_I2C_READ_SEMA_SIZE];
 165        int len = MLXSW_I2C_READ_SEMA_SIZE;
 166        struct i2c_msg read_sema[] =
 167                MLXSW_I2C_READ_MSG(client, addr_buf, buf, len);
 168        bool wait_done = false;
 169        unsigned long end;
 170        int i = 0, err;
 171
 172        mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_OFF_STATUS);
 173
 174        end = jiffies + msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
 175        do {
 176                u32 ctrl;
 177
 178                err = i2c_transfer(client->adapter, read_sema,
 179                                   ARRAY_SIZE(read_sema));
 180
 181                ctrl = be32_to_cpu(*(__be32 *) buf);
 182                if (err == ARRAY_SIZE(read_sema)) {
 183                        if (!(ctrl & MLXSW_I2C_GO_BIT)) {
 184                                wait_done = true;
 185                                *p_status = ctrl >>
 186                                            MLXSW_I2C_CIR_CTRL_STATUS_SHIFT;
 187                                break;
 188                        }
 189                }
 190                cond_resched();
 191        } while ((time_before(jiffies, end)) || (i++ < MLXSW_I2C_RETRY));
 192
 193        if (wait_done) {
 194                if (*p_status)
 195                        err = -EIO;
 196        } else {
 197                return -ETIMEDOUT;
 198        }
 199
 200        return err > 0 ? 0 : err;
 201}
 202
 203/* Routine posts a command to ASIC though mail box. */
 204static int mlxsw_i2c_write_cmd(struct i2c_client *client,
 205                               struct mlxsw_i2c *mlxsw_i2c,
 206                               int immediate)
 207{
 208        __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
 209                0, cpu_to_be32(MLXSW_I2C_PUSH_IMM_CMD)
 210        };
 211        __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
 212                0, 0, 0, 0, 0, 0,
 213                cpu_to_be32(client->adapter->nr & 0xffff),
 214                cpu_to_be32(MLXSW_I2C_SET_IMM_CMD)
 215        };
 216        struct i2c_msg push_cmd =
 217                MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
 218                                    MLXSW_I2C_PUSH_CMD_SIZE);
 219        struct i2c_msg prep_cmd =
 220                MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
 221        int err;
 222
 223        if (!immediate) {
 224                push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_CMD);
 225                prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_SET_CMD);
 226        }
 227        mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
 228                                 MLXSW_I2C_CIR2_BASE);
 229        mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
 230                                 MLXSW_I2C_CIR2_OFF_STATUS);
 231
 232        /* Prepare Command Interface Register for transaction */
 233        err = i2c_transfer(client->adapter, &prep_cmd, 1);
 234        if (err < 0)
 235                return err;
 236        else if (err != 1)
 237                return -EIO;
 238
 239        /* Write out Command Interface Register GO bit to push transaction */
 240        err = i2c_transfer(client->adapter, &push_cmd, 1);
 241        if (err < 0)
 242                return err;
 243        else if (err != 1)
 244                return -EIO;
 245
 246        return 0;
 247}
 248
 249/* Routine obtains mail box offsets from ASIC register space. */
 250static int mlxsw_i2c_get_mbox(struct i2c_client *client,
 251                              struct mlxsw_i2c *mlxsw_i2c)
 252{
 253        u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
 254        u8 buf[MLXSW_I2C_MBOX_SIZE];
 255        struct i2c_msg mbox_cmd[] =
 256                MLXSW_I2C_READ_MSG(client, addr_buf, buf, MLXSW_I2C_MBOX_SIZE);
 257        int err;
 258
 259        /* Read mail boxes offsets. */
 260        mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_BASE);
 261        err = i2c_transfer(client->adapter, mbox_cmd, 2);
 262        if (err != 2) {
 263                dev_err(&client->dev, "Could not obtain mail boxes\n");
 264                if (!err)
 265                        return -EIO;
 266                else
 267                        return err;
 268        }
 269
 270        /* Convert mail boxes. */
 271        mlxsw_i2c_convert_mbox(mlxsw_i2c, &buf[MLXSW_I2C_MBOX_OUT_PARAM_OFF]);
 272
 273        return err;
 274}
 275
 276/* Routine sends I2C write transaction to ASIC device. */
 277static int
 278mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
 279                u8 *p_status)
 280{
 281        struct i2c_client *client = to_i2c_client(dev);
 282        struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
 283        unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
 284        u8 tran_buf[MLXSW_I2C_MAX_BUFF_SIZE + MLXSW_I2C_ADDR_BUF_SIZE];
 285        int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;
 286        unsigned long end;
 287        struct i2c_msg write_tran =
 288                MLXSW_I2C_WRITE_MSG(client, tran_buf, MLXSW_I2C_PUSH_CMD_SIZE);
 289        int err;
 290
 291        for (i = 0; i < num; i++) {
 292                chunk_size = (in_mbox_size > MLXSW_I2C_BLK_MAX) ?
 293                             MLXSW_I2C_BLK_MAX : in_mbox_size;
 294                write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;
 295                mlxsw_i2c_set_slave_addr(tran_buf, off);
 296                memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +
 297                       MLXSW_I2C_BLK_MAX * i, chunk_size);
 298
 299                j = 0;
 300                end = jiffies + timeout;
 301                do {
 302                        err = i2c_transfer(client->adapter, &write_tran, 1);
 303                        if (err == 1)
 304                                break;
 305
 306                        cond_resched();
 307                } while ((time_before(jiffies, end)) ||
 308                         (j++ < MLXSW_I2C_RETRY));
 309
 310                if (err != 1) {
 311                        if (!err)
 312                                err = -EIO;
 313                        return err;
 314                }
 315
 316                off += chunk_size;
 317                in_mbox_size -= chunk_size;
 318        }
 319
 320        /* Prepare and write out Command Interface Register for transaction. */
 321        err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);
 322        if (err) {
 323                dev_err(&client->dev, "Could not start transaction");
 324                return -EIO;
 325        }
 326
 327        /* Wait until go bit is cleared. */
 328        err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);
 329        if (err) {
 330                dev_err(&client->dev, "HW semaphore is not released");
 331                return err;
 332        }
 333
 334        /* Validate transaction completion status. */
 335        if (*p_status) {
 336                dev_err(&client->dev, "Bad transaction completion status %x\n",
 337                        *p_status);
 338                return -EIO;
 339        }
 340
 341        return 0;
 342}
 343
 344/* Routine executes I2C command. */
 345static int
 346mlxsw_i2c_cmd(struct device *dev, size_t in_mbox_size, u8 *in_mbox,
 347              size_t out_mbox_size, u8 *out_mbox, u8 *status)
 348{
 349        struct i2c_client *client = to_i2c_client(dev);
 350        struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
 351        unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
 352        u8 tran_buf[MLXSW_I2C_ADDR_BUF_SIZE];
 353        int num, chunk_size, reg_size, i, j;
 354        int off = mlxsw_i2c->cmd.mb_off_out;
 355        unsigned long end;
 356        struct i2c_msg read_tran[] =
 357                MLXSW_I2C_READ_MSG(client, tran_buf, NULL, 0);
 358        int err;
 359
 360        WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));
 361
 362        reg_size = mlxsw_i2c_get_reg_size(in_mbox);
 363        num = reg_size / MLXSW_I2C_BLK_MAX;
 364        if (reg_size % MLXSW_I2C_BLK_MAX)
 365                num++;
 366
 367        if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
 368                dev_err(&client->dev, "Could not acquire lock");
 369                return -EINVAL;
 370        }
 371
 372        err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
 373        if (err)
 374                goto cmd_fail;
 375
 376        /* No out mailbox is case of write transaction. */
 377        if (!out_mbox) {
 378                mutex_unlock(&mlxsw_i2c->cmd.lock);
 379                return 0;
 380        }
 381
 382        /* Send read transaction to get output mailbox content. */
 383        read_tran[1].buf = out_mbox;
 384        for (i = 0; i < num; i++) {
 385                chunk_size = (reg_size > MLXSW_I2C_BLK_MAX) ?
 386                             MLXSW_I2C_BLK_MAX : reg_size;
 387                read_tran[1].len = chunk_size;
 388                mlxsw_i2c_set_slave_addr(tran_buf, off);
 389
 390                j = 0;
 391                end = jiffies + timeout;
 392                do {
 393                        err = i2c_transfer(client->adapter, read_tran,
 394                                           ARRAY_SIZE(read_tran));
 395                        if (err == ARRAY_SIZE(read_tran))
 396                                break;
 397
 398                        cond_resched();
 399                } while ((time_before(jiffies, end)) ||
 400                         (j++ < MLXSW_I2C_RETRY));
 401
 402                if (err != ARRAY_SIZE(read_tran)) {
 403                        if (!err)
 404                                err = -EIO;
 405
 406                        goto cmd_fail;
 407                }
 408
 409                off += chunk_size;
 410                reg_size -= chunk_size;
 411                read_tran[1].buf += chunk_size;
 412        }
 413
 414        mutex_unlock(&mlxsw_i2c->cmd.lock);
 415
 416        return 0;
 417
 418cmd_fail:
 419        mutex_unlock(&mlxsw_i2c->cmd.lock);
 420        return err;
 421}
 422
 423static int mlxsw_i2c_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 424                              u32 in_mod, bool out_mbox_direct,
 425                              char *in_mbox, size_t in_mbox_size,
 426                              char *out_mbox, size_t out_mbox_size,
 427                              u8 *status)
 428{
 429        struct mlxsw_i2c *mlxsw_i2c = bus_priv;
 430
 431        return mlxsw_i2c_cmd(mlxsw_i2c->dev, in_mbox_size, in_mbox,
 432                             out_mbox_size, out_mbox, status);
 433}
 434
 435static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv,
 436                                        const struct mlxsw_tx_info *tx_info)
 437{
 438        return false;
 439}
 440
 441static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb,
 442                                  const struct mlxsw_tx_info *tx_info)
 443{
 444        return 0;
 445}
 446
 447static int
 448mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
 449               const struct mlxsw_config_profile *profile,
 450               struct mlxsw_res *resources)
 451{
 452        struct mlxsw_i2c *mlxsw_i2c = bus_priv;
 453
 454        mlxsw_i2c->core = mlxsw_core;
 455
 456        return 0;
 457}
 458
 459static void mlxsw_i2c_fini(void *bus_priv)
 460{
 461        struct mlxsw_i2c *mlxsw_i2c = bus_priv;
 462
 463        mlxsw_i2c->core = NULL;
 464}
 465
 466static const struct mlxsw_bus mlxsw_i2c_bus = {
 467        .kind                   = "i2c",
 468        .init                   = mlxsw_i2c_init,
 469        .fini                   = mlxsw_i2c_fini,
 470        .skb_transmit_busy      = mlxsw_i2c_skb_transmit_busy,
 471        .skb_transmit           = mlxsw_i2c_skb_transmit,
 472        .cmd_exec               = mlxsw_i2c_cmd_exec,
 473};
 474
 475static int mlxsw_i2c_probe(struct i2c_client *client,
 476                           const struct i2c_device_id *id)
 477{
 478        struct mlxsw_i2c *mlxsw_i2c;
 479        u8 status;
 480        int err;
 481
 482        mlxsw_i2c = devm_kzalloc(&client->dev, sizeof(*mlxsw_i2c), GFP_KERNEL);
 483        if (!mlxsw_i2c)
 484                return -ENOMEM;
 485
 486        i2c_set_clientdata(client, mlxsw_i2c);
 487        mutex_init(&mlxsw_i2c->cmd.lock);
 488
 489        /* In order to use mailboxes through the i2c, special area is reserved
 490         * on the i2c address space that can be used for input and output
 491         * mailboxes. Such mailboxes are called local mailboxes. When using a
 492         * local mailbox, software should specify 0 as the Input/Output
 493         * parameters. The location of the Local Mailbox addresses on the i2c
 494         * space can be retrieved through the QUERY_FW command.
 495         * For this purpose QUERY_FW is to be issued with opcode modifier equal
 496         * 0x01. For such command the output parameter is an immediate value.
 497         * Here QUERY_FW command is invoked for ASIC probing and for getting
 498         * local mailboxes addresses from immedate output parameters.
 499         */
 500
 501        /* Prepare and write out Command Interface Register for transaction */
 502        err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 1);
 503        if (err) {
 504                dev_err(&client->dev, "Could not start transaction");
 505                goto errout;
 506        }
 507
 508        /* Wait until go bit is cleared. */
 509        err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
 510        if (err) {
 511                dev_err(&client->dev, "HW semaphore is not released");
 512                goto errout;
 513        }
 514
 515        /* Validate transaction completion status. */
 516        if (status) {
 517                dev_err(&client->dev, "Bad transaction completion status %x\n",
 518                        status);
 519                err = -EIO;
 520                goto errout;
 521        }
 522
 523        /* Get mailbox offsets. */
 524        err = mlxsw_i2c_get_mbox(client, mlxsw_i2c);
 525        if (err < 0) {
 526                dev_err(&client->dev, "Fail to get mailboxes\n");
 527                goto errout;
 528        }
 529
 530        dev_info(&client->dev, "%s mb size=%x off=0x%08x out mb size=%x off=0x%08x\n",
 531                 id->name, mlxsw_i2c->cmd.mb_size_in,
 532                 mlxsw_i2c->cmd.mb_off_in, mlxsw_i2c->cmd.mb_size_out,
 533                 mlxsw_i2c->cmd.mb_off_out);
 534
 535        /* Register device bus. */
 536        mlxsw_i2c->bus_info.device_kind = id->name;
 537        mlxsw_i2c->bus_info.device_name = client->name;
 538        mlxsw_i2c->bus_info.dev = &client->dev;
 539        mlxsw_i2c->dev = &client->dev;
 540
 541        err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
 542                                             &mlxsw_i2c_bus, mlxsw_i2c, false,
 543                                             NULL);
 544        if (err) {
 545                dev_err(&client->dev, "Fail to register core bus\n");
 546                return err;
 547        }
 548
 549        return 0;
 550
 551errout:
 552        i2c_set_clientdata(client, NULL);
 553
 554        return err;
 555}
 556
 557static int mlxsw_i2c_remove(struct i2c_client *client)
 558{
 559        struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
 560
 561        mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);
 562        mutex_destroy(&mlxsw_i2c->cmd.lock);
 563
 564        return 0;
 565}
 566
 567int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)
 568{
 569        i2c_driver->probe = mlxsw_i2c_probe;
 570        i2c_driver->remove = mlxsw_i2c_remove;
 571        return i2c_add_driver(i2c_driver);
 572}
 573EXPORT_SYMBOL(mlxsw_i2c_driver_register);
 574
 575void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)
 576{
 577        i2c_del_driver(i2c_driver);
 578}
 579EXPORT_SYMBOL(mlxsw_i2c_driver_unregister);
 580
 581MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
 582MODULE_DESCRIPTION("Mellanox switch I2C interface driver");
 583MODULE_LICENSE("Dual BSD/GPL");
 584