brintos

brintos / linux-shallow public Read only

0
0
Text · 21.1 KiB · 1e150ce Raw
768 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */3 4#include <linux/err.h>5#include <linux/i2c.h>6#include <linux/init.h>7#include <linux/jiffies.h>8#include <linux/kernel.h>9#include <linux/mutex.h>10#include <linux/module.h>11#include <linux/mod_devicetable.h>12#include <linux/platform_data/mlxreg.h>13#include <linux/slab.h>14 15#include "cmd.h"16#include "core.h"17#include "i2c.h"18#include "resources.h"19 20#define MLXSW_I2C_CIR2_BASE		0x7200021#define MLXSW_I2C_CIR_STATUS_OFF	0x1822#define MLXSW_I2C_CIR2_OFF_STATUS	(MLXSW_I2C_CIR2_BASE + \23					 MLXSW_I2C_CIR_STATUS_OFF)24#define MLXSW_I2C_OPMOD_SHIFT		1225#define MLXSW_I2C_EVENT_BIT_SHIFT	2226#define MLXSW_I2C_GO_BIT_SHIFT		2327#define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT	2428#define MLXSW_I2C_EVENT_BIT		BIT(MLXSW_I2C_EVENT_BIT_SHIFT)29#define MLXSW_I2C_GO_BIT		BIT(MLXSW_I2C_GO_BIT_SHIFT)30#define MLXSW_I2C_GO_OPMODE		BIT(MLXSW_I2C_OPMOD_SHIFT)31#define MLXSW_I2C_SET_IMM_CMD		(MLXSW_I2C_GO_OPMODE | \32					 MLXSW_CMD_OPCODE_QUERY_FW)33#define MLXSW_I2C_PUSH_IMM_CMD		(MLXSW_I2C_GO_BIT | \34					 MLXSW_I2C_SET_IMM_CMD)35#define MLXSW_I2C_SET_CMD		(MLXSW_CMD_OPCODE_ACCESS_REG)36#define MLXSW_I2C_PUSH_CMD		(MLXSW_I2C_GO_BIT | MLXSW_I2C_SET_CMD)37#define MLXSW_I2C_TLV_HDR_SIZE		0x1038#define MLXSW_I2C_ADDR_WIDTH		439#define MLXSW_I2C_PUSH_CMD_SIZE		(MLXSW_I2C_ADDR_WIDTH + 4)40#define MLXSW_I2C_SET_EVENT_CMD		(MLXSW_I2C_EVENT_BIT)41#define MLXSW_I2C_PUSH_EVENT_CMD	(MLXSW_I2C_GO_BIT | \42					 MLXSW_I2C_SET_EVENT_CMD)43#define MLXSW_I2C_READ_SEMA_SIZE	444#define MLXSW_I2C_PREP_SIZE		(MLXSW_I2C_ADDR_WIDTH + 28)45#define MLXSW_I2C_MBOX_SIZE		2046#define MLXSW_I2C_MBOX_OUT_PARAM_OFF	1247#define MLXSW_I2C_MBOX_OFFSET_BITS	2048#define MLXSW_I2C_MBOX_SIZE_BITS	1249#define MLXSW_I2C_ADDR_BUF_SIZE		450#define MLXSW_I2C_BLK_DEF		3251#define MLXSW_I2C_BLK_MAX		10052#define MLXSW_I2C_RETRY			553#define MLXSW_I2C_TIMEOUT_MSECS		500054#define MLXSW_I2C_MAX_DATA_SIZE		25655 56/* Driver can be initialized by kernel platform driver or from the user57 * space. In the first case IRQ line number is passed through the platform58 * data, otherwise default IRQ line is to be used. Default IRQ is relevant59 * only for specific I2C slave address, allowing 3.4 MHz I2C path to the chip60 * (special hardware feature for I2C acceleration).61 */62#define MLXSW_I2C_DEFAULT_IRQ		1763#define MLXSW_FAST_I2C_SLAVE		0x3764 65/**66 * struct mlxsw_i2c - device private data:67 * @cmd: command attributes;68 * @cmd.mb_size_in: input mailbox size;69 * @cmd.mb_off_in: input mailbox offset in register space;70 * @cmd.mb_size_out: output mailbox size;71 * @cmd.mb_off_out: output mailbox offset in register space;72 * @cmd.lock: command execution lock;73 * @dev: I2C device;74 * @core: switch core pointer;75 * @bus_info: bus info block;76 * @block_size: maximum block size allowed to pass to under layer;77 * @pdata: device platform data;78 * @irq_work: interrupts work item;79 * @irq: IRQ line number;80 */81struct mlxsw_i2c {82	struct {83		u32 mb_size_in;84		u32 mb_off_in;85		u32 mb_size_out;86		u32 mb_off_out;87		struct mutex lock;88	} cmd;89	struct device *dev;90	struct mlxsw_core *core;91	struct mlxsw_bus_info bus_info;92	u16 block_size;93	struct mlxreg_core_hotplug_platform_data *pdata;94	struct work_struct irq_work;95	int irq;96};97 98#define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) {	\99	{ .addr = (_client)->addr,				\100	  .buf = (_addr_buf),					\101	  .len = MLXSW_I2C_ADDR_BUF_SIZE,			\102	  .flags = 0 },						\103	{ .addr = (_client)->addr,				\104	  .buf = (_buf),					\105	  .len = (_len),					\106	  .flags = I2C_M_RD } }107 108#define MLXSW_I2C_WRITE_MSG(_client, _buf, _len)		\109	{ .addr = (_client)->addr,				\110	  .buf = (u8 *)(_buf),					\111	  .len = (_len),					\112	  .flags = 0 }113 114/* Routine converts in and out mail boxes offset and size. */115static inline void116mlxsw_i2c_convert_mbox(struct mlxsw_i2c *mlxsw_i2c, u8 *buf)117{118	u32 tmp;119 120	/* Local in/out mailboxes: 20 bits for offset, 12 for size */121	tmp = be32_to_cpup((__be32 *) buf);122	mlxsw_i2c->cmd.mb_off_in = tmp &123				   GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);124	mlxsw_i2c->cmd.mb_size_in = (tmp & GENMASK(31,125					MLXSW_I2C_MBOX_OFFSET_BITS)) >>126					MLXSW_I2C_MBOX_OFFSET_BITS;127 128	tmp = be32_to_cpup((__be32 *) (buf + MLXSW_I2C_ADDR_WIDTH));129	mlxsw_i2c->cmd.mb_off_out = tmp &130				    GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);131	mlxsw_i2c->cmd.mb_size_out = (tmp & GENMASK(31,132					MLXSW_I2C_MBOX_OFFSET_BITS)) >>133					MLXSW_I2C_MBOX_OFFSET_BITS;134}135 136/* Routine obtains register size from mail box buffer. */137static inline int mlxsw_i2c_get_reg_size(u8 *in_mbox)138{139	u16  tmp = be16_to_cpup((__be16 *) (in_mbox + MLXSW_I2C_TLV_HDR_SIZE));140 141	return (tmp & 0x7ff) * 4 + MLXSW_I2C_TLV_HDR_SIZE;142}143 144/* Routine sets I2C device internal offset in the transaction buffer. */145static inline void mlxsw_i2c_set_slave_addr(u8 *buf, u32 off)146{147	__be32 *val = (__be32 *) buf;148 149	*val = htonl(off);150}151 152/* Routine waits until go bit is cleared. */153static int mlxsw_i2c_wait_go_bit(struct i2c_client *client,154				 struct mlxsw_i2c *mlxsw_i2c, u8 *p_status)155{156	u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];157	u8 buf[MLXSW_I2C_READ_SEMA_SIZE];158	int len = MLXSW_I2C_READ_SEMA_SIZE;159	struct i2c_msg read_sema[] =160		MLXSW_I2C_READ_MSG(client, addr_buf, buf, len);161	bool wait_done = false;162	unsigned long end;163	int i = 0, err;164 165	mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_OFF_STATUS);166 167	end = jiffies + msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);168	do {169		u32 ctrl;170 171		err = i2c_transfer(client->adapter, read_sema,172				   ARRAY_SIZE(read_sema));173 174		ctrl = be32_to_cpu(*(__be32 *) buf);175		if (err == ARRAY_SIZE(read_sema)) {176			if (!(ctrl & MLXSW_I2C_GO_BIT)) {177				wait_done = true;178				*p_status = ctrl >>179					    MLXSW_I2C_CIR_CTRL_STATUS_SHIFT;180				break;181			}182		}183		cond_resched();184	} while ((time_before(jiffies, end)) || (i++ < MLXSW_I2C_RETRY));185 186	if (wait_done) {187		if (*p_status)188			err = -EIO;189	} else {190		return -ETIMEDOUT;191	}192 193	return err > 0 ? 0 : err;194}195 196/* Routine posts a command to ASIC through mail box. */197static int mlxsw_i2c_write_cmd(struct i2c_client *client,198			       struct mlxsw_i2c *mlxsw_i2c,199			       int immediate)200{201	__be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {202		0, cpu_to_be32(MLXSW_I2C_PUSH_IMM_CMD)203	};204	__be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {205		0, 0, 0, 0, 0, 0,206		cpu_to_be32(client->adapter->nr & 0xffff),207		cpu_to_be32(MLXSW_I2C_SET_IMM_CMD)208	};209	struct i2c_msg push_cmd =210		MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,211				    MLXSW_I2C_PUSH_CMD_SIZE);212	struct i2c_msg prep_cmd =213		MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);214	int err;215 216	if (!immediate) {217		push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_CMD);218		prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_SET_CMD);219	}220	mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,221				 MLXSW_I2C_CIR2_BASE);222	mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,223				 MLXSW_I2C_CIR2_OFF_STATUS);224 225	/* Prepare Command Interface Register for transaction */226	err = i2c_transfer(client->adapter, &prep_cmd, 1);227	if (err < 0)228		return err;229	else if (err != 1)230		return -EIO;231 232	/* Write out Command Interface Register GO bit to push transaction */233	err = i2c_transfer(client->adapter, &push_cmd, 1);234	if (err < 0)235		return err;236	else if (err != 1)237		return -EIO;238 239	return 0;240}241 242/* Routine posts initialization command to ASIC through mail box. */243static int244mlxsw_i2c_write_init_cmd(struct i2c_client *client,245			 struct mlxsw_i2c *mlxsw_i2c, u16 opcode, u32 in_mod)246{247	__be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {248		0, cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD)249	};250	__be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {251		0, 0, 0, 0, 0, 0,252		cpu_to_be32(client->adapter->nr & 0xffff),253		cpu_to_be32(MLXSW_I2C_SET_EVENT_CMD)254	};255	struct i2c_msg push_cmd =256		MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,257				    MLXSW_I2C_PUSH_CMD_SIZE);258	struct i2c_msg prep_cmd =259		MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);260	u8 status;261	int err;262 263	push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD | opcode);264	prep_cmd_buf[3] = cpu_to_be32(in_mod);265	prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_GO_BIT | opcode);266	mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,267				 MLXSW_I2C_CIR2_BASE);268	mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,269				 MLXSW_I2C_CIR2_OFF_STATUS);270 271	/* Prepare Command Interface Register for transaction */272	err = i2c_transfer(client->adapter, &prep_cmd, 1);273	if (err < 0)274		return err;275	else if (err != 1)276		return -EIO;277 278	/* Write out Command Interface Register GO bit to push transaction */279	err = i2c_transfer(client->adapter, &push_cmd, 1);280	if (err < 0)281		return err;282	else if (err != 1)283		return -EIO;284 285	/* Wait until go bit is cleared. */286	err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);287	if (err) {288		dev_err(&client->dev, "HW semaphore is not released");289		return err;290	}291 292	/* Validate transaction completion status. */293	if (status) {294		dev_err(&client->dev, "Bad transaction completion status %x\n",295			status);296		return -EIO;297	}298 299	return 0;300}301 302/* Routine obtains mail box offsets from ASIC register space. */303static int mlxsw_i2c_get_mbox(struct i2c_client *client,304			      struct mlxsw_i2c *mlxsw_i2c)305{306	u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];307	u8 buf[MLXSW_I2C_MBOX_SIZE];308	struct i2c_msg mbox_cmd[] =309		MLXSW_I2C_READ_MSG(client, addr_buf, buf, MLXSW_I2C_MBOX_SIZE);310	int err;311 312	/* Read mail boxes offsets. */313	mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_BASE);314	err = i2c_transfer(client->adapter, mbox_cmd, 2);315	if (err != 2) {316		dev_err(&client->dev, "Could not obtain mail boxes\n");317		if (!err)318			return -EIO;319		else320			return err;321	}322 323	/* Convert mail boxes. */324	mlxsw_i2c_convert_mbox(mlxsw_i2c, &buf[MLXSW_I2C_MBOX_OUT_PARAM_OFF]);325 326	return err;327}328 329/* Routine sends I2C write transaction to ASIC device. */330static int331mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,332		u8 *p_status)333{334	struct i2c_client *client = to_i2c_client(dev);335	struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);336	unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);337	int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;338	unsigned long end;339	u8 *tran_buf;340	struct i2c_msg write_tran =341		MLXSW_I2C_WRITE_MSG(client, NULL, MLXSW_I2C_PUSH_CMD_SIZE);342	int err;343 344	tran_buf = kmalloc(mlxsw_i2c->block_size + MLXSW_I2C_ADDR_BUF_SIZE,345			   GFP_KERNEL);346	if (!tran_buf)347		return -ENOMEM;348 349	write_tran.buf = tran_buf;350	for (i = 0; i < num; i++) {351		chunk_size = (in_mbox_size > mlxsw_i2c->block_size) ?352			     mlxsw_i2c->block_size : in_mbox_size;353		write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;354		mlxsw_i2c_set_slave_addr(tran_buf, off);355		memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +356		       mlxsw_i2c->block_size * i, chunk_size);357 358		j = 0;359		end = jiffies + timeout;360		do {361			err = i2c_transfer(client->adapter, &write_tran, 1);362			if (err == 1)363				break;364 365			cond_resched();366		} while ((time_before(jiffies, end)) ||367			 (j++ < MLXSW_I2C_RETRY));368 369		if (err != 1) {370			if (!err) {371				err = -EIO;372				goto mlxsw_i2c_write_exit;373			}374		}375 376		off += chunk_size;377		in_mbox_size -= chunk_size;378	}379 380	/* Prepare and write out Command Interface Register for transaction. */381	err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);382	if (err) {383		dev_err(&client->dev, "Could not start transaction");384		err = -EIO;385		goto mlxsw_i2c_write_exit;386	}387 388	/* Wait until go bit is cleared. */389	err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);390	if (err) {391		dev_err(&client->dev, "HW semaphore is not released");392		goto mlxsw_i2c_write_exit;393	}394 395	/* Validate transaction completion status. */396	if (*p_status) {397		dev_err(&client->dev, "Bad transaction completion status %x\n",398			*p_status);399		err = -EIO;400	}401 402mlxsw_i2c_write_exit:403	kfree(tran_buf);404	return err;405}406 407/* Routine executes I2C command. */408static int409mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,410	      u8 *in_mbox, size_t out_mbox_size, u8 *out_mbox, u8 *status)411{412	struct i2c_client *client = to_i2c_client(dev);413	struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);414	unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);415	u8 tran_buf[MLXSW_I2C_ADDR_BUF_SIZE];416	int num, chunk_size, reg_size, i, j;417	int off = mlxsw_i2c->cmd.mb_off_out;418	unsigned long end;419	struct i2c_msg read_tran[] =420		MLXSW_I2C_READ_MSG(client, tran_buf, NULL, 0);421	int err;422 423	WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));424 425	if (in_mbox) {426		reg_size = mlxsw_i2c_get_reg_size(in_mbox);427		num = DIV_ROUND_UP(reg_size, mlxsw_i2c->block_size);428 429		if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {430			dev_err(&client->dev, "Could not acquire lock");431			return -EINVAL;432		}433 434		err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);435		if (err)436			goto cmd_fail;437 438		/* No out mailbox is case of write transaction. */439		if (!out_mbox) {440			mutex_unlock(&mlxsw_i2c->cmd.lock);441			return 0;442		}443	} else {444		/* No input mailbox is case of initialization query command. */445		reg_size = MLXSW_I2C_MAX_DATA_SIZE;446		num = DIV_ROUND_UP(reg_size, mlxsw_i2c->block_size);447 448		if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {449			dev_err(&client->dev, "Could not acquire lock");450			return -EINVAL;451		}452 453		err = mlxsw_i2c_write_init_cmd(client, mlxsw_i2c, opcode,454					       in_mod);455		if (err)456			goto cmd_fail;457	}458 459	/* Send read transaction to get output mailbox content. */460	read_tran[1].buf = out_mbox;461	for (i = 0; i < num; i++) {462		chunk_size = (reg_size > mlxsw_i2c->block_size) ?463			     mlxsw_i2c->block_size : reg_size;464		read_tran[1].len = chunk_size;465		mlxsw_i2c_set_slave_addr(tran_buf, off);466 467		j = 0;468		end = jiffies + timeout;469		do {470			err = i2c_transfer(client->adapter, read_tran,471					   ARRAY_SIZE(read_tran));472			if (err == ARRAY_SIZE(read_tran))473				break;474 475			cond_resched();476		} while ((time_before(jiffies, end)) ||477			 (j++ < MLXSW_I2C_RETRY));478 479		if (err != ARRAY_SIZE(read_tran)) {480			if (!err)481				err = -EIO;482 483			goto cmd_fail;484		}485 486		off += chunk_size;487		reg_size -= chunk_size;488		read_tran[1].buf += chunk_size;489	}490 491	mutex_unlock(&mlxsw_i2c->cmd.lock);492 493	return 0;494 495cmd_fail:496	mutex_unlock(&mlxsw_i2c->cmd.lock);497	return err;498}499 500static int mlxsw_i2c_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,501			      u32 in_mod, bool out_mbox_direct,502			      char *in_mbox, size_t in_mbox_size,503			      char *out_mbox, size_t out_mbox_size,504			      u8 *status)505{506	struct mlxsw_i2c *mlxsw_i2c = bus_priv;507 508	return mlxsw_i2c_cmd(mlxsw_i2c->dev, opcode, in_mod, in_mbox_size,509			     in_mbox, out_mbox_size, out_mbox, status);510}511 512static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv,513					const struct mlxsw_tx_info *tx_info)514{515	return false;516}517 518static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb,519				  const struct mlxsw_tx_info *tx_info)520{521	return 0;522}523 524static int525mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,526	       const struct mlxsw_config_profile *profile,527	       struct mlxsw_res *res)528{529	struct mlxsw_i2c *mlxsw_i2c = bus_priv;530	char *mbox;531	int err;532 533	mlxsw_i2c->core = mlxsw_core;534 535	mbox = mlxsw_cmd_mbox_alloc();536	if (!mbox)537		return -ENOMEM;538 539	err = mlxsw_cmd_query_fw(mlxsw_core, mbox);540	if (err)541		goto mbox_put;542 543	mlxsw_i2c->bus_info.fw_rev.major =544		mlxsw_cmd_mbox_query_fw_fw_rev_major_get(mbox);545	mlxsw_i2c->bus_info.fw_rev.minor =546		mlxsw_cmd_mbox_query_fw_fw_rev_minor_get(mbox);547	mlxsw_i2c->bus_info.fw_rev.subminor =548		mlxsw_cmd_mbox_query_fw_fw_rev_subminor_get(mbox);549 550	err = mlxsw_core_resources_query(mlxsw_core, mbox, res);551 552mbox_put:553	mlxsw_cmd_mbox_free(mbox);554	return err;555}556 557static void mlxsw_i2c_fini(void *bus_priv)558{559	struct mlxsw_i2c *mlxsw_i2c = bus_priv;560 561	mlxsw_i2c->core = NULL;562}563 564static void mlxsw_i2c_work_handler(struct work_struct *work)565{566	struct mlxsw_i2c *mlxsw_i2c;567 568	mlxsw_i2c = container_of(work, struct mlxsw_i2c, irq_work);569	mlxsw_core_irq_event_handlers_call(mlxsw_i2c->core);570}571 572static irqreturn_t mlxsw_i2c_irq_handler(int irq, void *dev)573{574	struct mlxsw_i2c *mlxsw_i2c = dev;575 576	mlxsw_core_schedule_work(&mlxsw_i2c->irq_work);577 578	/* Interrupt handler shares IRQ line with 'main' interrupt handler.579	 * Return here IRQ_NONE, while main handler will return IRQ_HANDLED.580	 */581	return IRQ_NONE;582}583 584static int mlxsw_i2c_irq_init(struct mlxsw_i2c *mlxsw_i2c, u8 addr)585{586	int err;587 588	/* Initialize interrupt handler if system hotplug driver is reachable,589	 * otherwise interrupt line is not enabled and interrupts will not be590	 * raised to CPU. Also request_irq() call will be not valid.591	 */592	if (!IS_REACHABLE(CONFIG_MLXREG_HOTPLUG))593		return 0;594 595	/* Set default interrupt line. */596	if (mlxsw_i2c->pdata && mlxsw_i2c->pdata->irq)597		mlxsw_i2c->irq = mlxsw_i2c->pdata->irq;598	else if (addr == MLXSW_FAST_I2C_SLAVE)599		mlxsw_i2c->irq = MLXSW_I2C_DEFAULT_IRQ;600 601	if (!mlxsw_i2c->irq)602		return 0;603 604	INIT_WORK(&mlxsw_i2c->irq_work, mlxsw_i2c_work_handler);605	err = request_irq(mlxsw_i2c->irq, mlxsw_i2c_irq_handler,606			  IRQF_TRIGGER_FALLING | IRQF_SHARED, "mlxsw-i2c",607			  mlxsw_i2c);608	if (err) {609		dev_err(mlxsw_i2c->bus_info.dev, "Failed to request irq: %d\n",610			err);611		return err;612	}613 614	return 0;615}616 617static void mlxsw_i2c_irq_fini(struct mlxsw_i2c *mlxsw_i2c)618{619	if (!IS_REACHABLE(CONFIG_MLXREG_HOTPLUG) || !mlxsw_i2c->irq)620		return;621	cancel_work_sync(&mlxsw_i2c->irq_work);622	free_irq(mlxsw_i2c->irq, mlxsw_i2c);623}624 625static const struct mlxsw_bus mlxsw_i2c_bus = {626	.kind			= "i2c",627	.init			= mlxsw_i2c_init,628	.fini			= mlxsw_i2c_fini,629	.skb_transmit_busy	= mlxsw_i2c_skb_transmit_busy,630	.skb_transmit		= mlxsw_i2c_skb_transmit,631	.cmd_exec		= mlxsw_i2c_cmd_exec,632};633 634static int mlxsw_i2c_probe(struct i2c_client *client)635{636	const struct i2c_device_id *id = i2c_client_get_device_id(client);637	const struct i2c_adapter_quirks *quirks = client->adapter->quirks;638	struct mlxsw_i2c *mlxsw_i2c;639	u8 status;640	int err;641 642	mlxsw_i2c = devm_kzalloc(&client->dev, sizeof(*mlxsw_i2c), GFP_KERNEL);643	if (!mlxsw_i2c)644		return -ENOMEM;645 646	if (quirks) {647		if ((quirks->max_read_len &&648		     quirks->max_read_len < MLXSW_I2C_BLK_DEF) ||649		    (quirks->max_write_len &&650		     quirks->max_write_len < MLXSW_I2C_BLK_DEF)) {651			dev_err(&client->dev, "Insufficient transaction buffer length\n");652			return -EOPNOTSUPP;653		}654 655		mlxsw_i2c->block_size = min_t(u16, MLXSW_I2C_BLK_MAX,656					      min_t(u16, quirks->max_read_len,657						    quirks->max_write_len));658	} else {659		mlxsw_i2c->block_size = MLXSW_I2C_BLK_DEF;660	}661 662	i2c_set_clientdata(client, mlxsw_i2c);663	mutex_init(&mlxsw_i2c->cmd.lock);664 665	/* In order to use mailboxes through the i2c, special area is reserved666	 * on the i2c address space that can be used for input and output667	 * mailboxes. Such mailboxes are called local mailboxes. When using a668	 * local mailbox, software should specify 0 as the Input/Output669	 * parameters. The location of the Local Mailbox addresses on the i2c670	 * space can be retrieved through the QUERY_FW command.671	 * For this purpose QUERY_FW is to be issued with opcode modifier equal672	 * 0x01. For such command the output parameter is an immediate value.673	 * Here QUERY_FW command is invoked for ASIC probing and for getting674	 * local mailboxes addresses from immedate output parameters.675	 */676 677	/* Prepare and write out Command Interface Register for transaction */678	err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 1);679	if (err) {680		dev_err(&client->dev, "Could not start transaction");681		goto errout;682	}683 684	/* Wait until go bit is cleared. */685	err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);686	if (err) {687		dev_err(&client->dev, "HW semaphore is not released");688		goto errout;689	}690 691	/* Validate transaction completion status. */692	if (status) {693		dev_err(&client->dev, "Bad transaction completion status %x\n",694			status);695		err = -EIO;696		goto errout;697	}698 699	/* Get mailbox offsets. */700	err = mlxsw_i2c_get_mbox(client, mlxsw_i2c);701	if (err < 0) {702		dev_err(&client->dev, "Fail to get mailboxes\n");703		goto errout;704	}705 706	dev_info(&client->dev, "%s mb size=%x off=0x%08x out mb size=%x off=0x%08x\n",707		 id->name, mlxsw_i2c->cmd.mb_size_in,708		 mlxsw_i2c->cmd.mb_off_in, mlxsw_i2c->cmd.mb_size_out,709		 mlxsw_i2c->cmd.mb_off_out);710 711	/* Register device bus. */712	mlxsw_i2c->bus_info.device_kind = id->name;713	mlxsw_i2c->bus_info.device_name = client->name;714	mlxsw_i2c->bus_info.dev = &client->dev;715	mlxsw_i2c->bus_info.low_frequency = true;716	mlxsw_i2c->dev = &client->dev;717	mlxsw_i2c->pdata = client->dev.platform_data;718 719	err = mlxsw_i2c_irq_init(mlxsw_i2c, client->addr);720	if (err)721		goto errout;722 723	err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,724					     &mlxsw_i2c_bus, mlxsw_i2c, false,725					     NULL, NULL);726	if (err) {727		dev_err(&client->dev, "Fail to register core bus\n");728		goto err_bus_device_register;729	}730 731	return 0;732 733err_bus_device_register:734	mlxsw_i2c_irq_fini(mlxsw_i2c);735errout:736	mutex_destroy(&mlxsw_i2c->cmd.lock);737	i2c_set_clientdata(client, NULL);738 739	return err;740}741 742static void mlxsw_i2c_remove(struct i2c_client *client)743{744	struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);745 746	mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);747	mlxsw_i2c_irq_fini(mlxsw_i2c);748	mutex_destroy(&mlxsw_i2c->cmd.lock);749}750 751int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)752{753	i2c_driver->probe = mlxsw_i2c_probe;754	i2c_driver->remove = mlxsw_i2c_remove;755	return i2c_add_driver(i2c_driver);756}757EXPORT_SYMBOL(mlxsw_i2c_driver_register);758 759void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)760{761	i2c_del_driver(i2c_driver);762}763EXPORT_SYMBOL(mlxsw_i2c_driver_unregister);764 765MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");766MODULE_DESCRIPTION("Mellanox switch I2C interface driver");767MODULE_LICENSE("Dual BSD/GPL");768