diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 24 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-aspeed.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-at91-core.c | 38 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-at91-master.c | 53 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-at91.h | 13 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-bcm-iproc.c | 63 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-cros-ec-tunnel.c | 15 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 8 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-icy.c | 9 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 75 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-qup.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-rcar.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32.c | 16 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32f7.c | 32 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-xiic.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core-base.c | 86 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core-of.c | 1 | ||||
| -rw-r--r-- | drivers/i2c/i2c-smbus.c | 7 | ||||
| -rw-r--r-- | drivers/i2c/muxes/Kconfig | 18 | 
21 files changed, 322 insertions, 154 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 146ce40d8e0a..6a0aa76859f3 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -145,6 +145,7 @@ config I2C_I801  	    Comet Lake (PCH)  	    Elkhart Lake (PCH)  	    Tiger Lake (PCH) +	    Jasper Lake (SOC)  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-i801. @@ -292,7 +293,7 @@ config I2C_VIA  	select I2C_ALGOBIT  	help  	  If you say yes to this option, support will be included for the VIA -          82C586B I2C interface +	  82C586B I2C interface  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-via. @@ -677,11 +678,11 @@ config I2C_IMX_LPI2C  	tristate "IMX Low Power I2C interface"  	depends on ARCH_MXC || COMPILE_TEST  	help -          Say Y here if you want to use the Low Power IIC bus controller -          on the Freescale i.MX processors. +	  Say Y here if you want to use the Low Power IIC bus controller +	  on the Freescale i.MX processors. -          This driver can also be built as a module. If so, the module -          will be called i2c-imx-lpi2c. +	  This driver can also be built as a module. If so, the module +	  will be called i2c-imx-lpi2c.  config I2C_IOP3XX  	tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" @@ -874,6 +875,7 @@ config I2C_PXA_PCI  config I2C_PXA_SLAVE  	bool "Intel PXA2XX I2C Slave comms support"  	depends on I2C_PXA && !X86_32 +	select I2C_SLAVE  	help  	  Support I2C slave mode communications on the PXA I2C bus.  This  	  is necessary for systems where the PXA may be a target on the @@ -1182,9 +1184,9 @@ config I2C_DIOLAN_U2C  	  will be called i2c-diolan-u2c.  config I2C_DLN2 -       tristate "Diolan DLN-2 USB I2C adapter" -       depends on MFD_DLN2 -       help +	tristate "Diolan DLN-2 USB I2C adapter" +	depends on MFD_DLN2 +	help  	 If you say yes to this option, support will be included for Diolan  	 DLN2, a USB to I2C interface. @@ -1283,9 +1285,9 @@ config I2C_VIPERBOARD  	help  	  Say yes here to access the I2C part of the Nano River  	  Technologies Viperboard as I2C master. -          See viperboard API specification and Nano -          River Tech's viperboard.h for detailed meaning -          of the module parameters. +	  See viperboard API specification and Nano +	  River Tech's viperboard.h for detailed meaning +	  of the module parameters.  comment "Other I2C/SMBus bus drivers" diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index 7b098ff5f5dd..a7be6f24450b 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -952,6 +952,10 @@ static const struct of_device_id aspeed_i2c_bus_of_table[] = {  		.compatible = "aspeed,ast2500-i2c-bus",  		.data = aspeed_i2c_25xx_get_clk_reg_val,  	}, +	{ +		.compatible = "aspeed,ast2600-i2c-bus", +		.data = aspeed_i2c_25xx_get_clk_reg_val, +	},  	{ },  };  MODULE_DEVICE_TABLE(of, aspeed_i2c_bus_of_table); diff --git a/drivers/i2c/busses/i2c-at91-core.c b/drivers/i2c/busses/i2c-at91-core.c index 435c7d7377a3..e13af4874976 100644 --- a/drivers/i2c/busses/i2c-at91-core.c +++ b/drivers/i2c/busses/i2c-at91-core.c @@ -68,6 +68,9 @@ static struct at91_twi_pdata at91rm9200_config = {  	.has_unre_flag = true,  	.has_alt_cmd = false,  	.has_hold_field = false, +	.has_dig_filtr = false, +	.has_adv_dig_filtr = false, +	.has_ana_filtr = false,  };  static struct at91_twi_pdata at91sam9261_config = { @@ -76,6 +79,9 @@ static struct at91_twi_pdata at91sam9261_config = {  	.has_unre_flag = false,  	.has_alt_cmd = false,  	.has_hold_field = false, +	.has_dig_filtr = false, +	.has_adv_dig_filtr = false, +	.has_ana_filtr = false,  };  static struct at91_twi_pdata at91sam9260_config = { @@ -84,6 +90,9 @@ static struct at91_twi_pdata at91sam9260_config = {  	.has_unre_flag = false,  	.has_alt_cmd = false,  	.has_hold_field = false, +	.has_dig_filtr = false, +	.has_adv_dig_filtr = false, +	.has_ana_filtr = false,  };  static struct at91_twi_pdata at91sam9g20_config = { @@ -92,6 +101,9 @@ static struct at91_twi_pdata at91sam9g20_config = {  	.has_unre_flag = false,  	.has_alt_cmd = false,  	.has_hold_field = false, +	.has_dig_filtr = false, +	.has_adv_dig_filtr = false, +	.has_ana_filtr = false,  };  static struct at91_twi_pdata at91sam9g10_config = { @@ -100,6 +112,9 @@ static struct at91_twi_pdata at91sam9g10_config = {  	.has_unre_flag = false,  	.has_alt_cmd = false,  	.has_hold_field = false, +	.has_dig_filtr = false, +	.has_adv_dig_filtr = false, +	.has_ana_filtr = false,  };  static const struct platform_device_id at91_twi_devtypes[] = { @@ -130,6 +145,9 @@ static struct at91_twi_pdata at91sam9x5_config = {  	.has_unre_flag = false,  	.has_alt_cmd = false,  	.has_hold_field = false, +	.has_dig_filtr = false, +	.has_adv_dig_filtr = false, +	.has_ana_filtr = false,  };  static struct at91_twi_pdata sama5d4_config = { @@ -138,6 +156,9 @@ static struct at91_twi_pdata sama5d4_config = {  	.has_unre_flag = false,  	.has_alt_cmd = false,  	.has_hold_field = true, +	.has_dig_filtr = true, +	.has_adv_dig_filtr = false, +	.has_ana_filtr = false,  };  static struct at91_twi_pdata sama5d2_config = { @@ -146,6 +167,20 @@ static struct at91_twi_pdata sama5d2_config = {  	.has_unre_flag = true,  	.has_alt_cmd = true,  	.has_hold_field = true, +	.has_dig_filtr = true, +	.has_adv_dig_filtr = true, +	.has_ana_filtr = true, +}; + +static struct at91_twi_pdata sam9x60_config = { +	.clk_max_div = 7, +	.clk_offset = 4, +	.has_unre_flag = true, +	.has_alt_cmd = true, +	.has_hold_field = true, +	.has_dig_filtr = true, +	.has_adv_dig_filtr = true, +	.has_ana_filtr = true,  };  static const struct of_device_id atmel_twi_dt_ids[] = { @@ -174,6 +209,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = {  		.compatible = "atmel,sama5d2-i2c",  		.data = &sama5d2_config,  	}, { +		.compatible = "microchip,sam9x60-i2c", +		.data = &sam9x60_config, +	}, {  		/* sentinel */  	}  }; diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c index a3fcc35ffd3b..7a862e00b475 100644 --- a/drivers/i2c/busses/i2c-at91-master.c +++ b/drivers/i2c/busses/i2c-at91-master.c @@ -31,12 +31,32 @@  void at91_init_twi_bus_master(struct at91_twi_dev *dev)  { +	struct at91_twi_pdata *pdata = dev->pdata; +	u32 filtr = 0; +  	/* FIFO should be enabled immediately after the software reset */  	if (dev->fifo_size)  		at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN);  	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);  	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS);  	at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg); + +	/* enable digital filter */ +	if (pdata->has_dig_filtr && dev->enable_dig_filt) +		filtr |= AT91_TWI_FILTR_FILT; + +	/* enable advanced digital filter */ +	if (pdata->has_adv_dig_filtr && dev->enable_dig_filt) +		filtr |= AT91_TWI_FILTR_FILT | +			 (AT91_TWI_FILTR_THRES(dev->filter_width) & +			 AT91_TWI_FILTR_THRES_MASK); + +	/* enable analog filter */ +	if (pdata->has_ana_filtr && dev->enable_ana_filt) +		filtr |= AT91_TWI_FILTR_PADFEN; + +	if (filtr) +		at91_twi_write(dev, AT91_TWI_FILTR, filtr);  }  /* @@ -45,7 +65,7 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev)   */  static void at91_calc_twi_clock(struct at91_twi_dev *dev)  { -	int ckdiv, cdiv, div, hold = 0; +	int ckdiv, cdiv, div, hold = 0, filter_width = 0;  	struct at91_twi_pdata *pdata = dev->pdata;  	int offset = pdata->clk_offset;  	int max_ckdiv = pdata->clk_max_div; @@ -84,11 +104,29 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev)  		}  	} +	if (pdata->has_adv_dig_filtr) { +		/* +		 * filter width = 0 to AT91_TWI_FILTR_THRES_MAX +		 * peripheral clocks +		 */ +		filter_width = DIV_ROUND_UP(t->digital_filter_width_ns +				* (clk_get_rate(dev->clk) / 1000), 1000000); +		if (filter_width > AT91_TWI_FILTR_THRES_MAX) { +			dev_warn(dev->dev, +				"Filter threshold set to its maximum value (%d instead of %d)\n", +				AT91_TWI_FILTR_THRES_MAX, filter_width); +			filter_width = AT91_TWI_FILTR_THRES_MAX; +		} +	} +  	dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv  			    | AT91_TWI_CWGR_HOLD(hold); -	dev_dbg(dev->dev, "cdiv %d ckdiv %d hold %d (%d ns)\n", -		cdiv, ckdiv, hold, t->sda_hold_ns); +	dev->filter_width = filter_width; + +	dev_dbg(dev->dev, "cdiv %d ckdiv %d hold %d (%d ns), filter_width %d (%d ns)\n", +		cdiv, ckdiv, hold, t->sda_hold_ns, filter_width, +		t->digital_filter_width_ns);  }  static void at91_twi_dma_cleanup(struct at91_twi_dev *dev) @@ -720,14 +758,14 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)  	slave_config.dst_maxburst = 1;  	slave_config.device_fc = false; -	dma->chan_tx = dma_request_slave_channel_reason(dev->dev, "tx"); +	dma->chan_tx = dma_request_chan(dev->dev, "tx");  	if (IS_ERR(dma->chan_tx)) {  		ret = PTR_ERR(dma->chan_tx);  		dma->chan_tx = NULL;  		goto error;  	} -	dma->chan_rx = dma_request_slave_channel_reason(dev->dev, "rx"); +	dma->chan_rx = dma_request_chan(dev->dev, "rx");  	if (IS_ERR(dma->chan_rx)) {  		ret = PTR_ERR(dma->chan_rx);  		dma->chan_rx = NULL; @@ -793,6 +831,11 @@ int at91_twi_probe_master(struct platform_device *pdev,  		dev_info(dev->dev, "Using FIFO (%u data)\n", dev->fifo_size);  	} +	dev->enable_dig_filt = of_property_read_bool(pdev->dev.of_node, +						     "i2c-digital-filter"); + +	dev->enable_ana_filt = of_property_read_bool(pdev->dev.of_node, +						     "i2c-analog-filter");  	at91_calc_twi_clock(dev);  	dev->adapter.algo = &at91_twi_algorithm; diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h index 499b506f6128..977a67bc0f88 100644 --- a/drivers/i2c/busses/i2c-at91.h +++ b/drivers/i2c/busses/i2c-at91.h @@ -84,6 +84,13 @@  #define	AT91_TWI_ACR_DATAL(len)	((len) & 0xff)  #define	AT91_TWI_ACR_DIR	BIT(8) +#define AT91_TWI_FILTR		0x0044 +#define AT91_TWI_FILTR_FILT	BIT(0) +#define AT91_TWI_FILTR_PADFEN	BIT(1) +#define AT91_TWI_FILTR_THRES(v)		((v) << 8) +#define AT91_TWI_FILTR_THRES_MAX	7 +#define AT91_TWI_FILTR_THRES_MASK	GENMASK(10, 8) +  #define	AT91_TWI_FMR		0x0050	/* FIFO Mode Register */  #define	AT91_TWI_FMR_TXRDYM(mode)	(((mode) & 0x3) << 0)  #define	AT91_TWI_FMR_TXRDYM_MASK	(0x3 << 0) @@ -108,6 +115,9 @@ struct at91_twi_pdata {  	bool has_unre_flag;  	bool has_alt_cmd;  	bool has_hold_field; +	bool has_dig_filtr; +	bool has_adv_dig_filtr; +	bool has_ana_filtr;  	struct at_dma_slave dma_slave;  }; @@ -145,6 +155,9 @@ struct at91_twi_dev {  	unsigned smr;  	struct i2c_client *slave;  #endif +	bool enable_dig_filt; +	bool enable_ana_filt; +	u32 filter_width;  };  unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg); diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c index 9ffdffaf6141..30efb7913b2e 100644 --- a/drivers/i2c/busses/i2c-bcm-iproc.c +++ b/drivers/i2c/busses/i2c-bcm-iproc.c @@ -81,6 +81,7 @@  #define M_CMD_PROTOCOL_MASK          0xf  #define M_CMD_PROTOCOL_BLK_WR        0x7  #define M_CMD_PROTOCOL_BLK_RD        0x8 +#define M_CMD_PROTOCOL_PROCESS       0xa  #define M_CMD_PEC_SHIFT              8  #define M_CMD_RD_CNT_SHIFT           0  #define M_CMD_RD_CNT_MASK            0xff @@ -675,13 +676,20 @@ static int bcm_iproc_i2c_xfer_wait(struct bcm_iproc_i2c_dev *iproc_i2c,  	return 0;  } -static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, -					 struct i2c_msg *msg) +/* + * If 'process_call' is true, then this is a multi-msg transfer that requires + * a repeated start between the messages. + * More specifically, it must be a write (reg) followed by a read (data). + * The i2c quirks are set to enforce this rule. + */ +static int bcm_iproc_i2c_xfer_internal(struct bcm_iproc_i2c_dev *iproc_i2c, +					struct i2c_msg *msgs, bool process_call)  {  	int i;  	u8 addr;  	u32 val, tmp, val_intr_en;  	unsigned int tx_bytes; +	struct i2c_msg *msg = &msgs[0];  	/* check if bus is busy */  	if (!!(iproc_i2c_rd_reg(iproc_i2c, @@ -707,14 +715,29 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,  			val = msg->buf[i];  			/* mark the last byte */ -			if (i == msg->len - 1) -				val |= BIT(M_TX_WR_STATUS_SHIFT); +			if (!process_call && (i == msg->len - 1)) +				val |= 1 << M_TX_WR_STATUS_SHIFT;  			iproc_i2c_wr_reg(iproc_i2c, M_TX_OFFSET, val);  		}  		iproc_i2c->tx_bytes = tx_bytes;  	} +	/* Process the read message if this is process call */ +	if (process_call) { +		msg++; +		iproc_i2c->msg = msg;  /* point to second msg */ + +		/* +		 * The last byte to be sent out should be a slave +		 * address with read operation +		 */ +		addr = i2c_8bit_addr_from_msg(msg); +		/* mark it the last byte out */ +		val = addr | (1 << M_TX_WR_STATUS_SHIFT); +		iproc_i2c_wr_reg(iproc_i2c, M_TX_OFFSET, val); +	} +  	/* mark as incomplete before starting the transaction */  	if (iproc_i2c->irq)  		reinit_completion(&iproc_i2c->done); @@ -733,7 +756,7 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,  	 * underrun interrupt, which will be triggerred when the TX FIFO is  	 * empty. When that happens we can then pump more data into the FIFO  	 */ -	if (!(msg->flags & I2C_M_RD) && +	if (!process_call && !(msg->flags & I2C_M_RD) &&  	    msg->len > iproc_i2c->tx_bytes)  		val_intr_en |= BIT(IE_M_TX_UNDERRUN_SHIFT); @@ -743,6 +766,8 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,  	 */  	val = BIT(M_CMD_START_BUSY_SHIFT);  	if (msg->flags & I2C_M_RD) { +		u32 protocol; +  		iproc_i2c->rx_bytes = 0;  		if (msg->len > M_RX_FIFO_MAX_THLD_VALUE)  			iproc_i2c->thld_bytes = M_RX_FIFO_THLD_VALUE; @@ -758,7 +783,10 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,  		/* enable the RX threshold interrupt */  		val_intr_en |= BIT(IE_M_RX_THLD_SHIFT); -		val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | +		protocol = process_call ? +				M_CMD_PROTOCOL_PROCESS : M_CMD_PROTOCOL_BLK_RD; + +		val |= (protocol << M_CMD_PROTOCOL_SHIFT) |  		       (msg->len << M_CMD_RD_CNT_SHIFT);  	} else {  		val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT); @@ -774,17 +802,24 @@ static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter,  			      struct i2c_msg msgs[], int num)  {  	struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter); -	int ret, i; +	bool process_call = false; +	int ret; -	/* go through all messages */ -	for (i = 0; i < num; i++) { -		ret = bcm_iproc_i2c_xfer_single_msg(iproc_i2c, &msgs[i]); -		if (ret) { -			dev_dbg(iproc_i2c->device, "xfer failed\n"); -			return ret; +	if (num == 2) { +		/* Repeated start, use process call */ +		process_call = true; +		if (msgs[1].flags & I2C_M_NOSTART) { +			dev_err(iproc_i2c->device, "Invalid repeated start\n"); +			return -EOPNOTSUPP;  		}  	} +	ret = bcm_iproc_i2c_xfer_internal(iproc_i2c, msgs, process_call); +	if (ret) { +		dev_dbg(iproc_i2c->device, "xfer failed\n"); +		return ret; +	} +  	return num;  } @@ -809,6 +844,8 @@ static struct i2c_algorithm bcm_iproc_algo = {  };  static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { +	.flags = I2C_AQ_COMB_WRITE_THEN_READ, +	.max_comb_1st_msg_len = M_TX_RX_FIFO_SIZE,  	.max_read_len = M_RX_MAX_READ_LEN,  }; diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c index c551aa96a2e3..958161c71985 100644 --- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c @@ -3,6 +3,7 @@  //  // Copyright (C) 2013 Google, Inc. +#include <linux/acpi.h>  #include <linux/module.h>  #include <linux/i2c.h>  #include <linux/platform_data/cros_ec_commands.h> @@ -240,7 +241,6 @@ static const struct i2c_algorithm ec_i2c_algorithm = {  static int ec_i2c_probe(struct platform_device *pdev)  { -	struct device_node *np = pdev->dev.of_node;  	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);  	struct device *dev = &pdev->dev;  	struct ec_i2c_device *bus = NULL; @@ -256,7 +256,7 @@ static int ec_i2c_probe(struct platform_device *pdev)  	if (bus == NULL)  		return -ENOMEM; -	err = of_property_read_u32(np, "google,remote-bus", &remote_bus); +	err = device_property_read_u32(dev, "google,remote-bus", &remote_bus);  	if (err) {  		dev_err(dev, "Couldn't read remote-bus property\n");  		return err; @@ -271,7 +271,7 @@ static int ec_i2c_probe(struct platform_device *pdev)  	bus->adap.algo = &ec_i2c_algorithm;  	bus->adap.algo_data = bus;  	bus->adap.dev.parent = &pdev->dev; -	bus->adap.dev.of_node = np; +	bus->adap.dev.of_node = pdev->dev.of_node;  	bus->adap.retries = I2C_MAX_RETRIES;  	err = i2c_add_adapter(&bus->adap); @@ -291,19 +291,24 @@ static int ec_i2c_remove(struct platform_device *dev)  	return 0;  } -#ifdef CONFIG_OF  static const struct of_device_id cros_ec_i2c_of_match[] = {  	{ .compatible = "google,cros-ec-i2c-tunnel" },  	{},  };  MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match); -#endif + +static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] = { +	{ "GOOG001A", 0 }, +	{ } +}; +MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_tunnel_acpi_id);  static struct platform_driver ec_i2c_tunnel_driver = {  	.probe = ec_i2c_probe,  	.remove = ec_i2c_remove,  	.driver = {  		.name = "cros-ec-i2c-tunnel", +		.acpi_match_table = ACPI_PTR(cros_ec_i2c_tunnel_acpi_id),  		.of_match_table = of_match_ptr(cros_ec_i2c_of_match),  	},  }; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index f1c714acc280..f5e69fe56532 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -64,8 +64,10 @@   * Cedar Fork (PCH)		0x18df	32	hard	yes	yes	yes   * Ice Lake-LP (PCH)		0x34a3	32	hard	yes	yes	yes   * Comet Lake (PCH)		0x02a3	32	hard	yes	yes	yes + * Comet Lake-H (PCH)		0x06a3	32	hard	yes	yes	yes   * Elkhart Lake (PCH)		0x4b23	32	hard	yes	yes	yes   * Tiger Lake-LP (PCH)		0xa0a3	32	hard	yes	yes	yes + * Jasper Lake (SOC)		0x4da3	32	hard	yes	yes	yes   *   * Features supported by this driver:   * Software PEC				no @@ -205,6 +207,7 @@  /* Older devices have their ID defined in <linux/pci_ids.h> */  #define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS		0x02a3 +#define PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS		0x06a3  #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS		0x0f12  #define PCI_DEVICE_ID_INTEL_CDF_SMBUS			0x18df  #define PCI_DEVICE_ID_INTEL_DNV_SMBUS			0x19df @@ -223,6 +226,7 @@  #define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS		0x34a3  #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS		0x3b30  #define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS		0x4b23 +#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS		0x4da3  #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS		0x5ad4  #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS		0x8c22  #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS		0x8ca2 @@ -1069,8 +1073,10 @@ static const struct pci_device_id i801_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS) },  	{ 0, }  }; @@ -1750,8 +1756,10 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)  	case PCI_DEVICE_ID_INTEL_CDF_SMBUS:  	case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS:  	case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: +	case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS:  	case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS:  	case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS: +	case PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS:  		priv->features |= FEATURE_BLOCK_PROC;  		priv->features |= FEATURE_I2C_BLOCK_READ;  		priv->features |= FEATURE_IRQ; diff --git a/drivers/i2c/busses/i2c-icy.c b/drivers/i2c/busses/i2c-icy.c index 8382eb64b424..271470f4d8a9 100644 --- a/drivers/i2c/busses/i2c-icy.c +++ b/drivers/i2c/busses/i2c-icy.c @@ -122,7 +122,6 @@ static int icy_probe(struct zorro_dev *z,  	struct fwnode_handle *new_fwnode;  	struct i2c_board_info ltc2990_info = {  		.type		= "ltc2990", -		.addr		= 0x4c,  	};  	i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL); @@ -188,10 +187,10 @@ static int icy_probe(struct zorro_dev *z,  		ltc2990_info.fwnode = new_fwnode;  		i2c->ltc2990_client = -			i2c_new_probed_device(&i2c->adapter, -					      <c2990_info, -					      icy_ltc2990_addresses, -					      NULL); +			i2c_new_scanned_device(&i2c->adapter, +					       <c2990_info, +					       icy_ltc2990_addresses, +					       NULL);  	}  	return 0; diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 2c3c3d6935c0..466e4f681d7a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -25,7 +25,6 @@  #include <linux/delay.h>  #include <linux/errno.h>  #include <linux/interrupt.h> -#include <linux/i2c-pxa.h>  #include <linux/of.h>  #include <linux/of_device.h>  #include <linux/platform_device.h> @@ -180,7 +179,7 @@ struct pxa_i2c {  	struct i2c_adapter	adap;  	struct clk		*clk;  #ifdef CONFIG_I2C_PXA_SLAVE -	struct i2c_slave_client *slave; +	struct i2c_client	*slave;  #endif  	unsigned int		irqlogidx; @@ -544,22 +543,23 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)  	if (isr & ISR_BED) {  		/* what should we do here? */  	} else { -		int ret = 0; +		u8 byte = 0;  		if (i2c->slave != NULL) -			ret = i2c->slave->read(i2c->slave->data); +			i2c_slave_event(i2c->slave, I2C_SLAVE_READ_PROCESSED, +					&byte); -		writel(ret, _IDBR(i2c)); +		writel(byte, _IDBR(i2c));  		writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));   /* allow next byte */  	}  }  static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)  { -	unsigned int byte = readl(_IDBR(i2c)); +	u8 byte = readl(_IDBR(i2c));  	if (i2c->slave != NULL) -		i2c->slave->write(i2c->slave->data, byte); +		i2c_slave_event(i2c->slave, I2C_SLAVE_WRITE_RECEIVED, &byte);  	writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));  } @@ -572,9 +572,18 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)  		dev_dbg(&i2c->adap.dev, "SAD, mode is slave-%cx\n",  		       (isr & ISR_RWM) ? 'r' : 't'); -	if (i2c->slave != NULL) -		i2c->slave->event(i2c->slave->data, -				 (isr & ISR_RWM) ? I2C_SLAVE_EVENT_START_READ : I2C_SLAVE_EVENT_START_WRITE); +	if (i2c->slave != NULL) { +		if (isr & ISR_RWM) { +			u8 byte = 0; + +			i2c_slave_event(i2c->slave, I2C_SLAVE_READ_REQUESTED, +					&byte); +			writel(byte, _IDBR(i2c)); +		} else { +			i2c_slave_event(i2c->slave, I2C_SLAVE_WRITE_REQUESTED, +					NULL); +		} +	}  	/*  	 * slave could interrupt in the middle of us generating a @@ -607,7 +616,7 @@ static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)  		dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop)\n");  	if (i2c->slave != NULL) -		i2c->slave->event(i2c->slave->data, I2C_SLAVE_EVENT_STOP); +		i2c_slave_event(i2c->slave, I2C_SLAVE_STOP, NULL);  	if (i2c_debug > 2)  		dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop) acked\n"); @@ -619,6 +628,38 @@ static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)  	if (i2c->msg)  		i2c_pxa_master_complete(i2c, I2C_RETRY);  } + +static int i2c_pxa_slave_reg(struct i2c_client *slave) +{ +	struct pxa_i2c *i2c = slave->adapter->algo_data; + +	if (i2c->slave) +		return -EBUSY; + +	if (!i2c->reg_isar) +		return -EAFNOSUPPORT; + +	i2c->slave = slave; +	i2c->slave_addr = slave->addr; + +	writel(i2c->slave_addr, _ISAR(i2c)); + +	return 0; +} + +static int i2c_pxa_slave_unreg(struct i2c_client *slave) +{ +	struct pxa_i2c *i2c = slave->adapter->algo_data; + +	WARN_ON(!i2c->slave); + +	i2c->slave_addr = I2C_PXA_SLAVE_ADDR; +	writel(i2c->slave_addr, _ISAR(i2c)); + +	i2c->slave = NULL; + +	return 0; +}  #else  static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)  { @@ -1141,11 +1182,19 @@ static u32 i2c_pxa_functionality(struct i2c_adapter *adap)  static const struct i2c_algorithm i2c_pxa_algorithm = {  	.master_xfer	= i2c_pxa_xfer,  	.functionality	= i2c_pxa_functionality, +#ifdef CONFIG_I2C_PXA_SLAVE +	.reg_slave	= i2c_pxa_slave_reg, +	.unreg_slave	= i2c_pxa_slave_unreg, +#endif  };  static const struct i2c_algorithm i2c_pxa_pio_algorithm = {  	.master_xfer	= i2c_pxa_pio_xfer,  	.functionality	= i2c_pxa_functionality, +#ifdef CONFIG_I2C_PXA_SLAVE +	.reg_slave	= i2c_pxa_slave_reg, +	.unreg_slave	= i2c_pxa_slave_unreg, +#endif  };  static const struct of_device_id i2c_pxa_dt_ids[] = { @@ -1270,10 +1319,6 @@ static int i2c_pxa_probe(struct platform_device *dev)  	i2c->highmode_enter = false;  	if (plat) { -#ifdef CONFIG_I2C_PXA_SLAVE -		i2c->slave_addr = plat->slave_addr; -		i2c->slave = plat->slave; -#endif  		i2c->adap.class = plat->class;  	} diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index e09cd0775ae9..2d7dabe12723 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -628,7 +628,7 @@ static int qup_i2c_req_dma(struct qup_i2c_dev *qup)  	int err;  	if (!qup->btx.dma) { -		qup->btx.dma = dma_request_slave_channel_reason(qup->dev, "tx"); +		qup->btx.dma = dma_request_chan(qup->dev, "tx");  		if (IS_ERR(qup->btx.dma)) {  			err = PTR_ERR(qup->btx.dma);  			qup->btx.dma = NULL; @@ -638,7 +638,7 @@ static int qup_i2c_req_dma(struct qup_i2c_dev *qup)  	}  	if (!qup->brx.dma) { -		qup->brx.dma = dma_request_slave_channel_reason(qup->dev, "rx"); +		qup->brx.dma = dma_request_chan(qup->dev, "rx");  		if (IS_ERR(qup->brx.dma)) {  			dev_err(qup->dev, "\n rx channel not available");  			err = PTR_ERR(qup->brx.dma); diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 531c01100b56..879f0e61a496 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -317,7 +317,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timin  scgd_find:  	dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n", -		scl, t->bus_freq_hz, clk_get_rate(priv->clk), round, cdf, scgd); +		scl, t->bus_freq_hz, rate, round, cdf, scgd);  	/* keep icccr value */  	priv->icccr = scgd << cdf_width | cdf; diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 8777af4c695e..82b3b795e0bd 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -486,7 +486,7 @@ static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev,  	char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx";  	int ret; -	chan = dma_request_slave_channel_reason(dev, chan_name); +	chan = dma_request_chan(dev, chan_name);  	if (IS_ERR(chan)) {  		dev_dbg(dev, "request_channel failed for %s (%ld)\n", chan_name,  			PTR_ERR(chan)); diff --git a/drivers/i2c/busses/i2c-stm32.c b/drivers/i2c/busses/i2c-stm32.c index 07d5dfce68d4..1da347e6a358 100644 --- a/drivers/i2c/busses/i2c-stm32.c +++ b/drivers/i2c/busses/i2c-stm32.c @@ -20,13 +20,13 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,  	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);  	if (!dma) -		return NULL; +		return ERR_PTR(-ENOMEM);  	/* Request and configure I2C TX dma channel */ -	dma->chan_tx = dma_request_slave_channel(dev, "tx"); -	if (!dma->chan_tx) { +	dma->chan_tx = dma_request_chan(dev, "tx"); +	if (IS_ERR(dma->chan_tx)) {  		dev_dbg(dev, "can't request DMA tx channel\n"); -		ret = -EINVAL; +		ret = PTR_ERR(dma->chan_tx);  		goto fail_al;  	} @@ -42,10 +42,10 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,  	}  	/* Request and configure I2C RX dma channel */ -	dma->chan_rx = dma_request_slave_channel(dev, "rx"); -	if (!dma->chan_rx) { +	dma->chan_rx = dma_request_chan(dev, "rx"); +	if (IS_ERR(dma->chan_rx)) {  		dev_err(dev, "can't request DMA rx channel\n"); -		ret = -EINVAL; +		ret = PTR_ERR(dma->chan_rx);  		goto fail_tx;  	} @@ -75,7 +75,7 @@ fail_al:  	devm_kfree(dev, dma);  	dev_info(dev, "can't use DMA\n"); -	return NULL; +	return ERR_PTR(ret);  }  void stm32_i2c_dma_free(struct stm32_i2c_dma *dma) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index b24e7b937f21..b2634afe066d 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -1267,8 +1267,8 @@ static int stm32f7_i2c_get_free_slave_id(struct stm32f7_i2c_dev *i2c_dev,  	 * slave[0] supports 7-bit and 10-bit slave address  	 * slave[1] supports 7-bit slave address only  	 */ -	for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) { -		if (i == 1 && (slave->flags & I2C_CLIENT_PEC)) +	for (i = STM32F7_I2C_MAX_SLAVE - 1; i >= 0; i--) { +		if (i == 1 && (slave->flags & I2C_CLIENT_TEN))  			continue;  		if (!i2c_dev->slave[i]) {  			*id = i; @@ -1955,6 +1955,15 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)  	i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr,  					     STM32F7_I2C_TXDR,  					     STM32F7_I2C_RXDR); +	if (PTR_ERR(i2c_dev->dma) == -ENODEV) +		i2c_dev->dma = NULL; +	else if (IS_ERR(i2c_dev->dma)) { +		ret = PTR_ERR(i2c_dev->dma); +		if (ret != -EPROBE_DEFER) +			dev_err(&pdev->dev, +				"Failed to request dma error %i\n", ret); +		goto clk_free; +	}  	platform_set_drvdata(pdev, i2c_dev); @@ -1985,6 +1994,11 @@ pm_disable:  	pm_runtime_set_suspended(i2c_dev->dev);  	pm_runtime_dont_use_autosuspend(i2c_dev->dev); +	if (i2c_dev->dma) { +		stm32_i2c_dma_free(i2c_dev->dma); +		i2c_dev->dma = NULL; +	} +  clk_free:  	clk_disable_unprepare(i2c_dev->clk); @@ -1995,21 +2009,21 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)  {  	struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); -	if (i2c_dev->dma) { -		stm32_i2c_dma_free(i2c_dev->dma); -		i2c_dev->dma = NULL; -	} -  	i2c_del_adapter(&i2c_dev->adap);  	pm_runtime_get_sync(i2c_dev->dev); -	clk_disable_unprepare(i2c_dev->clk); -  	pm_runtime_put_noidle(i2c_dev->dev);  	pm_runtime_disable(i2c_dev->dev);  	pm_runtime_set_suspended(i2c_dev->dev);  	pm_runtime_dont_use_autosuspend(i2c_dev->dev); +	if (i2c_dev->dma) { +		stm32_i2c_dma_free(i2c_dev->dma); +		i2c_dev->dma = NULL; +	} + +	clk_disable_unprepare(i2c_dev->clk); +  	return 0;  } diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index c1683f9338b4..a98bf31d0e5c 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -413,7 +413,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)  		return 0;  	} -	chan = dma_request_slave_channel_reason(i2c_dev->dev, "rx"); +	chan = dma_request_chan(i2c_dev->dev, "rx");  	if (IS_ERR(chan)) {  		err = PTR_ERR(chan);  		goto err_out; @@ -421,7 +421,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)  	i2c_dev->rx_dma_chan = chan; -	chan = dma_request_slave_channel_reason(i2c_dev->dev, "tx"); +	chan = dma_request_chan(i2c_dev->dev, "tx");  	if (IS_ERR(chan)) {  		err = PTR_ERR(chan);  		goto err_out; diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 37b3b9307d07..d8d49f1814c7 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -46,6 +46,7 @@ enum xiic_endian {  /**   * struct xiic_i2c - Internal representation of the XIIC I2C bus + * @dev:	Pointer to device structure   * @base:	Memory base of the HW registers   * @wait:	Wait queue for callers   * @adap:	Kernel adapter representation @@ -57,6 +58,7 @@ enum xiic_endian {   * @rx_msg:	Current RX message   * @rx_pos:	Position within current RX message   * @endianness: big/little-endian byte order + * @clk:	Pointer to AXI4-lite input clock   */  struct xiic_i2c {  	struct device		*dev; diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 5f6a4985f2bc..9f8dcd3f8385 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -896,29 +896,6 @@ struct i2c_client *i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address  }  EXPORT_SYMBOL_GPL(i2c_new_dummy_device); -/** - * i2c_new_dummy - return a new i2c device bound to a dummy driver - * @adapter: the adapter managing the device - * @address: seven bit address to be used - * Context: can sleep - * - * This deprecated function has the same functionality as @i2c_new_dummy_device, - * it just returns NULL instead of an ERR_PTR in case of an error for - * compatibility with current I2C API. It will be removed once all users are - * converted. - * - * This returns the new i2c client, which should be saved for later use with - * i2c_unregister_device(); or NULL to indicate an error. - */ -struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) -{ -	struct i2c_client *ret; - -	ret = i2c_new_dummy_device(adapter, address); -	return IS_ERR(ret) ? NULL : ret; -} -EXPORT_SYMBOL_GPL(i2c_new_dummy); -  struct i2c_dummy_devres {  	struct i2c_client *client;  }; @@ -1656,6 +1633,12 @@ void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_de  		t->sda_fall_ns = t->scl_fall_ns;  	device_property_read_u32(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns); + +	device_property_read_u32(dev, "i2c-digital-filter-width-ns", +				 &t->digital_filter_width_ns); + +	device_property_read_u32(dev, "i2c-analog-filter-cutoff-frequency", +				 &t->analog_filter_cutoff_freq_hz);  }  EXPORT_SYMBOL_GPL(i2c_parse_fw_timings); @@ -1737,38 +1720,6 @@ EXPORT_SYMBOL(i2c_del_driver);  /* ------------------------------------------------------------------------- */ -/** - * i2c_use_client - increments the reference count of the i2c client structure - * @client: the client being referenced - * - * Each live reference to a client should be refcounted. The driver model does - * that automatically as part of driver binding, so that most drivers don't - * need to do this explicitly: they hold a reference until they're unbound - * from the device. - * - * A pointer to the client with the incremented reference counter is returned. - */ -struct i2c_client *i2c_use_client(struct i2c_client *client) -{ -	if (client && get_device(&client->dev)) -		return client; -	return NULL; -} -EXPORT_SYMBOL(i2c_use_client); - -/** - * i2c_release_client - release a use of the i2c client structure - * @client: the client being no longer referenced - * - * Must be called when a user of a client is finished with it. - */ -void i2c_release_client(struct i2c_client *client) -{ -	if (client) -		put_device(&client->dev); -} -EXPORT_SYMBOL(i2c_release_client); -  struct i2c_cmd_arg {  	unsigned	cmd;  	void		*arg; @@ -2271,10 +2222,10 @@ int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr)  EXPORT_SYMBOL_GPL(i2c_probe_func_quick_read);  struct i2c_client * -i2c_new_probed_device(struct i2c_adapter *adap, -		      struct i2c_board_info *info, -		      unsigned short const *addr_list, -		      int (*probe)(struct i2c_adapter *adap, unsigned short addr)) +i2c_new_scanned_device(struct i2c_adapter *adap, +		       struct i2c_board_info *info, +		       unsigned short const *addr_list, +		       int (*probe)(struct i2c_adapter *adap, unsigned short addr))  {  	int i; @@ -2304,11 +2255,24 @@ i2c_new_probed_device(struct i2c_adapter *adap,  	if (addr_list[i] == I2C_CLIENT_END) {  		dev_dbg(&adap->dev, "Probing failed, no device found\n"); -		return NULL; +		return ERR_PTR(-ENODEV);  	}  	info->addr = addr_list[i]; -	return i2c_new_device(adap, info); +	return i2c_new_client_device(adap, info); +} +EXPORT_SYMBOL_GPL(i2c_new_scanned_device); + +struct i2c_client * +i2c_new_probed_device(struct i2c_adapter *adap, +		      struct i2c_board_info *info, +		      unsigned short const *addr_list, +		      int (*probe)(struct i2c_adapter *adap, unsigned short addr)) +{ +	struct i2c_client *client; + +	client = i2c_new_scanned_device(adap, info, addr_list, probe); +	return IS_ERR(client) ? NULL : client;  }  EXPORT_SYMBOL_GPL(i2c_new_probed_device); diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index 7eb41990bd6d..e4d296b40baa 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -50,6 +50,7 @@ int of_i2c_get_board_info(struct device *dev, struct device_node *node,  	info->addr = addr;  	info->of_node = node; +	info->fwnode = of_fwnode_handle(node);  	if (of_property_read_bool(node, "host-notify"))  		info->flags |= I2C_CLIENT_HOST_NOTIFY; diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 03096f47e6ab..7e2f5d0eacdb 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -66,7 +66,6 @@ static irqreturn_t smbus_alert(int irq, void *d)  {  	struct i2c_smbus_alert *alert = d;  	struct i2c_client *ara; -	unsigned short prev_addr = 0;	/* Not a valid address */  	ara = alert->ara; @@ -90,18 +89,12 @@ static irqreturn_t smbus_alert(int irq, void *d)  		data.addr = status >> 1;  		data.type = I2C_PROTOCOL_SMBUS_ALERT; -		if (data.addr == prev_addr) { -			dev_warn(&ara->dev, "Duplicate SMBALERT# from dev " -				"0x%02x, skipping\n", data.addr); -			break; -		}  		dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n",  			data.addr, data.data);  		/* Notify driver for the device which issued the alert */  		device_for_each_child(&ara->adapter->dev, &data,  				      smbus_do_alert); -		prev_addr = data.addr;  	}  	return IRQ_HANDLED; diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index c6040aa839ac..1708b1a82da2 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -109,14 +109,14 @@ config I2C_DEMUX_PINCTRL  	  want to change the I2C master at run-time depending on features.  config I2C_MUX_MLXCPLD -        tristate "Mellanox CPLD based I2C multiplexer" -        help -          If you say yes to this option, support will be included for a -          CPLD based I2C multiplexer. This driver provides access to -          I2C busses connected through a MUX, which is controlled -          by a CPLD register. - -          This driver can also be built as a module.  If so, the module -          will be called i2c-mux-mlxcpld. +	tristate "Mellanox CPLD based I2C multiplexer" +	help +	  If you say yes to this option, support will be included for a +	  CPLD based I2C multiplexer. This driver provides access to +	  I2C busses connected through a MUX, which is controlled +	  by a CPLD register. + +	  This driver can also be built as a module.  If so, the module +	  will be called i2c-mux-mlxcpld.  endmenu  |