diff options
Diffstat (limited to 'drivers/i2c')
24 files changed, 288 insertions, 304 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 25eb4e8fd22f..87600b4aacb3 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -566,9 +566,12 @@ config I2C_DESIGNWARE_PLATFORM  config I2C_DESIGNWARE_AMDPSP  	bool "AMD PSP I2C semaphore support" -	depends on X86_MSR  	depends on ACPI +	depends on CRYPTO_DEV_SP_PSP +	depends on PCI  	depends on I2C_DESIGNWARE_PLATFORM +	depends on (I2C_DESIGNWARE_PLATFORM=y && CRYPTO_DEV_CCP_DD=y) || \ +		   (I2C_DESIGNWARE_PLATFORM=m && CRYPTO_DEV_CCP_DD)  	help  	  This driver enables managed host access to the selected I2C bus shared  	  between AMD CPU and AMD PSP. @@ -804,7 +807,7 @@ config I2C_MESON  config I2C_MICROCHIP_CORE  	tristate "Microchip FPGA I2C controller" -	depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST +	depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST  	depends on OF  	help  	  If you say yes to this option, support will be included for the diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c index 69383be47905..ef942714642a 100644 --- a/drivers/i2c/busses/i2c-brcmstb.c +++ b/drivers/i2c/busses/i2c-brcmstb.c @@ -575,12 +575,10 @@ static void brcmstb_i2c_set_bsc_reg_defaults(struct brcmstb_i2c_dev *dev)  static int bcm2711_release_bsc(struct brcmstb_i2c_dev *dev)  {  	struct platform_device *pdev = to_platform_device(dev->device); -	struct resource *iomem;  	void __iomem *autoi2c;  	/* Map hardware registers */ -	iomem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "auto-i2c"); -	autoi2c = devm_ioremap_resource(&pdev->dev, iomem); +	autoi2c = devm_platform_ioremap_resource_byname(pdev, "auto-i2c");  	if (IS_ERR(autoi2c))  		return PTR_ERR(autoi2c); diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index b5d22e7282c2..3a4edf7e75f9 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -16,6 +16,7 @@  #include <linux/of.h>  #include <linux/pm_runtime.h>  #include <linux/pinctrl/consumer.h> +#include <linux/reset.h>  /* Register offsets for the I2C device. */  #define CDNS_I2C_CR_OFFSET		0x00 /* Control Register, RW */ @@ -114,10 +115,10 @@  /* timeout for pm runtime autosuspend */  #define CNDS_I2C_PM_TIMEOUT		1000	/* ms */ -#define CDNS_I2C_FIFO_DEPTH		16 +#define CDNS_I2C_FIFO_DEPTH_DEFAULT	16  #define CDNS_I2C_MAX_TRANSFER_SIZE	255  /* Transfer size in multiples of data interrupt depth */ -#define CDNS_I2C_TRANSFER_SIZE	(CDNS_I2C_MAX_TRANSFER_SIZE - 3) +#define CDNS_I2C_TRANSFER_SIZE(max)	((max) - 3)  #define DRIVER_NAME		"cdns-i2c" @@ -178,12 +179,15 @@ enum cdns_i2c_slave_state {   * @bus_hold_flag:	Flag used in repeated start for clearing HOLD bit   * @clk:		Pointer to struct clk   * @clk_rate_change_nb:	Notifier block for clock rate changes + * @reset:		Reset control for the device   * @quirks:		flag for broken hold bit usage in r1p10   * @ctrl_reg:		Cached value of the control register.   * @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register   * @slave:		Registered slave instance.   * @dev_mode:		I2C operating role(master/slave).   * @slave_state:	I2C Slave state(idle/read/write). + * @fifo_depth:		The depth of the transfer FIFO + * @transfer_size:	The maximum number of bytes in one transfer   */  struct cdns_i2c {  	struct device		*dev; @@ -202,6 +206,7 @@ struct cdns_i2c {  	unsigned int bus_hold_flag;  	struct clk *clk;  	struct notifier_block clk_rate_change_nb; +	struct reset_control *reset;  	u32 quirks;  	u32 ctrl_reg;  	struct i2c_bus_recovery_info rinfo; @@ -211,6 +216,8 @@ struct cdns_i2c {  	enum cdns_i2c_mode dev_mode;  	enum cdns_i2c_slave_state slave_state;  #endif +	u32 fifo_depth; +	unsigned int transfer_size;  };  struct cdns_platform_data { @@ -236,7 +243,7 @@ static void cdns_i2c_clear_bus_hold(struct cdns_i2c *id)  static inline bool cdns_is_holdquirk(struct cdns_i2c *id, bool hold_wrkaround)  {  	return (hold_wrkaround && -		(id->curr_recv_count == CDNS_I2C_FIFO_DEPTH + 1)); +		(id->curr_recv_count == id->fifo_depth + 1));  }  #if IS_ENABLED(CONFIG_I2C_SLAVE) @@ -431,7 +438,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)  				 * if RX data left is less than or equal to  				 * FIFO DEPTH unless repeated start is selected  				 */ -				if (id->recv_count <= CDNS_I2C_FIFO_DEPTH && +				if (id->recv_count <= id->fifo_depth &&  				    !id->bus_hold_flag)  					cdns_i2c_clear_bus_hold(id); @@ -456,22 +463,22 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)  		if (cdns_is_holdquirk(id, updatetx)) {  			/* wait while fifo is full */  			while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) != -			       (id->curr_recv_count - CDNS_I2C_FIFO_DEPTH)) +			       (id->curr_recv_count - id->fifo_depth))  				;  			/*  			 * Check number of bytes to be received against maximum  			 * transfer size and update register accordingly.  			 */ -			if (((int)(id->recv_count) - CDNS_I2C_FIFO_DEPTH) > -			    CDNS_I2C_TRANSFER_SIZE) { -				cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, +			if (((int)(id->recv_count) - id->fifo_depth) > +			    id->transfer_size) { +				cdns_i2c_writereg(id->transfer_size,  						  CDNS_I2C_XFER_SIZE_OFFSET); -				id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE + -						      CDNS_I2C_FIFO_DEPTH; +				id->curr_recv_count = id->transfer_size + +						      id->fifo_depth;  			} else {  				cdns_i2c_writereg(id->recv_count - -						  CDNS_I2C_FIFO_DEPTH, +						  id->fifo_depth,  						  CDNS_I2C_XFER_SIZE_OFFSET);  				id->curr_recv_count = id->recv_count;  			} @@ -494,7 +501,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)  		 * space available in FIFO and fill with that many bytes.  		 */  		if (id->send_count) { -			avail_bytes = CDNS_I2C_FIFO_DEPTH - +			avail_bytes = id->fifo_depth -  			    cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET);  			if (id->send_count > avail_bytes)  				bytes_to_send = avail_bytes; @@ -588,7 +595,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)  	 * Check for the message size against FIFO depth and set the  	 * 'hold bus' bit if it is greater than FIFO depth.  	 */ -	if (id->recv_count > CDNS_I2C_FIFO_DEPTH) +	if (id->recv_count > id->fifo_depth)  		ctrl_reg |= CDNS_I2C_CR_HOLD;  	cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); @@ -603,17 +610,17 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)  	 * receive if it is less than transfer size and transfer size if  	 * it is more. Enable the interrupts.  	 */ -	if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) { -		cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, +	if (id->recv_count > id->transfer_size) { +		cdns_i2c_writereg(id->transfer_size,  				  CDNS_I2C_XFER_SIZE_OFFSET); -		id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE; +		id->curr_recv_count = id->transfer_size;  	} else {  		cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET);  	}  	/* Determine hold_clear based on number of bytes to receive and hold flag */ -	if (!id->bus_hold_flag && id->recv_count <= CDNS_I2C_FIFO_DEPTH) { -		if (cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & CDNS_I2C_CR_HOLD) { +	if (!id->bus_hold_flag && id->recv_count <= id->fifo_depth) { +		if (ctrl_reg & CDNS_I2C_CR_HOLD) {  			hold_clear = true;  			if (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT)  				irq_save = true; @@ -624,7 +631,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)  	addr &= CDNS_I2C_ADDR_MASK;  	if (hold_clear) { -		ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & ~CDNS_I2C_CR_HOLD; +		ctrl_reg &= ~CDNS_I2C_CR_HOLD;  		/*  		 * In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size  		 * register reaches '0'. This is an IP bug which causes transfer size @@ -673,7 +680,7 @@ static void cdns_i2c_msend(struct cdns_i2c *id)  	 * Check for the message size against FIFO depth and set the  	 * 'hold bus' bit if it is greater than FIFO depth.  	 */ -	if (id->send_count > CDNS_I2C_FIFO_DEPTH) +	if (id->send_count > id->fifo_depth)  		ctrl_reg |= CDNS_I2C_CR_HOLD;  	cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); @@ -686,7 +693,7 @@ static void cdns_i2c_msend(struct cdns_i2c *id)  	 * against the space available, and fill the FIFO accordingly.  	 * Enable the interrupts.  	 */ -	avail_bytes = CDNS_I2C_FIFO_DEPTH - +	avail_bytes = id->fifo_depth -  				cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET);  	if (id->send_count > avail_bytes) @@ -827,8 +834,10 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,  #if IS_ENABLED(CONFIG_I2C_SLAVE)  	/* Check i2c operating mode and switch if possible */  	if (id->dev_mode == CDNS_I2C_MODE_SLAVE) { -		if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) -			return -EAGAIN; +		if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) { +			ret = -EAGAIN; +			goto out; +		}  		/* Set mode to master */  		cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id); @@ -1030,8 +1039,7 @@ static int cdns_i2c_calc_divs(unsigned long *f, unsigned long input_clk,  		if (actual_fscl > fscl)  			continue; -		current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) : -							(fscl - actual_fscl)); +		current_error = fscl - actual_fscl;  		if (last_error > current_error) {  			calc_div_a = div_a; @@ -1227,6 +1235,37 @@ static const struct of_device_id cdns_i2c_of_match[] = {  MODULE_DEVICE_TABLE(of, cdns_i2c_of_match);  /** + * cdns_i2c_detect_transfer_size - Detect the maximum transfer size supported + * @id: Device private data structure + * + * Detect the maximum transfer size that is supported by this instance of the + * Cadence I2C controller. + */ +static void cdns_i2c_detect_transfer_size(struct cdns_i2c *id) +{ +	u32 val; + +	/* +	 * Writing to the transfer size register is only possible if these two bits +	 * are set in the control register. +	 */ +	cdns_i2c_writereg(CDNS_I2C_CR_MS | CDNS_I2C_CR_RW, CDNS_I2C_CR_OFFSET); + +	/* +	 * The number of writable bits of the transfer size register can be between +	 * 4 and 8. This is a controlled through a synthesis parameter of the IP +	 * core and can vary from instance to instance. The unused MSBs always read +	 * back as 0. Writing 0xff and then reading the value back will report the +	 * maximum supported transfer size. +	 */ +	cdns_i2c_writereg(CDNS_I2C_MAX_TRANSFER_SIZE, CDNS_I2C_XFER_SIZE_OFFSET); +	val = cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET); +	id->transfer_size = CDNS_I2C_TRANSFER_SIZE(val); +	cdns_i2c_writereg(0, CDNS_I2C_XFER_SIZE_OFFSET); +	cdns_i2c_writereg(0, CDNS_I2C_CR_OFFSET); +} + +/**   * cdns_i2c_probe - Platform registration call   * @pdev:	Handle to the platform device structure   * @@ -1291,10 +1330,22 @@ static int cdns_i2c_probe(struct platform_device *pdev)  		return dev_err_probe(&pdev->dev, PTR_ERR(id->clk),  				     "input clock not found.\n"); +	id->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL); +	if (IS_ERR(id->reset)) +		return dev_err_probe(&pdev->dev, PTR_ERR(id->reset), +				     "Failed to request reset.\n"); +  	ret = clk_prepare_enable(id->clk);  	if (ret)  		dev_err(&pdev->dev, "Unable to enable clock.\n"); +	ret = reset_control_deassert(id->reset); +	if (ret) { +		dev_err_probe(&pdev->dev, ret, +			      "Failed to de-assert reset.\n"); +		goto err_clk_dis; +	} +  	pm_runtime_set_autosuspend_delay(id->dev, CNDS_I2C_PM_TIMEOUT);  	pm_runtime_use_autosuspend(id->dev);  	pm_runtime_set_active(id->dev); @@ -1317,32 +1368,39 @@ static int cdns_i2c_probe(struct platform_device *pdev)  #endif  	id->ctrl_reg = CDNS_I2C_CR_ACK_EN | CDNS_I2C_CR_NEA | CDNS_I2C_CR_MS; +	id->fifo_depth = CDNS_I2C_FIFO_DEPTH_DEFAULT; +	of_property_read_u32(pdev->dev.of_node, "fifo-depth", &id->fifo_depth); + +	cdns_i2c_detect_transfer_size(id); +  	ret = cdns_i2c_setclk(id->input_clk, id);  	if (ret) {  		dev_err(&pdev->dev, "invalid SCL clock: %u Hz\n", id->i2c_clk);  		ret = -EINVAL; -		goto err_clk_dis; +		goto err_clk_notifier_unregister;  	}  	ret = devm_request_irq(&pdev->dev, irq, cdns_i2c_isr, 0,  				 DRIVER_NAME, id);  	if (ret) {  		dev_err(&pdev->dev, "cannot get irq %d\n", irq); -		goto err_clk_dis; +		goto err_clk_notifier_unregister;  	}  	cdns_i2c_init(id);  	ret = i2c_add_adapter(&id->adap);  	if (ret < 0) -		goto err_clk_dis; +		goto err_clk_notifier_unregister;  	dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n",  		 id->i2c_clk / 1000, (unsigned long)r_mem->start, irq);  	return 0; -err_clk_dis: +err_clk_notifier_unregister:  	clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); +	reset_control_assert(id->reset); +err_clk_dis:  	clk_disable_unprepare(id->clk);  	pm_runtime_disable(&pdev->dev);  	pm_runtime_set_suspended(&pdev->dev); @@ -1367,6 +1425,7 @@ static int cdns_i2c_remove(struct platform_device *pdev)  	i2c_del_adapter(&id->adap);  	clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); +	reset_control_assert(id->reset);  	clk_disable_unprepare(id->clk);  	return 0; diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c index 4e787dc709f9..8b3ff5bb14d8 100644 --- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c @@ -292,13 +292,13 @@ static int ec_i2c_remove(struct platform_device *dev)  	return 0;  } -static const struct of_device_id cros_ec_i2c_of_match[] = { +static const struct of_device_id cros_ec_i2c_of_match[] __maybe_unused = {  	{ .compatible = "google,cros-ec-i2c-tunnel" },  	{},  };  MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match); -static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] = { +static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] __maybe_unused = {  	{ "GOOG0012", 0 },  	{ }  }; diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index c836cf884185..9750310f2c96 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -764,11 +764,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)  	int r, irq;  	irq = platform_get_irq(pdev, 0); -	if (irq <= 0) { -		if (!irq) -			irq = -ENXIO; +	if (irq < 0)  		return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n"); -	}  	dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev),  			GFP_KERNEL); diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c index 8f36167bce62..63454b06e5da 100644 --- a/drivers/i2c/busses/i2c-designware-amdpsp.c +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -1,41 +1,21 @@  // SPDX-License-Identifier: GPL-2.0 -#include <linux/bitfield.h> -#include <linux/bits.h>  #include <linux/i2c.h> -#include <linux/io-64-nonatomic-lo-hi.h> -#include <linux/psp-sev.h> -#include <linux/types.h> +#include <linux/pci.h> +#include <linux/psp-platform-access.h> +#include <linux/psp.h>  #include <linux/workqueue.h> -#include <asm/msr.h> -  #include "i2c-designware-core.h" -#define MSR_AMD_PSP_ADDR	0xc00110a2 -#define PSP_MBOX_OFFSET		0x10570 -#define PSP_CMD_TIMEOUT_US	(500 * USEC_PER_MSEC) -  #define PSP_I2C_RESERVATION_TIME_MS 100 -#define PSP_I2C_REQ_BUS_CMD		0x64  #define PSP_I2C_REQ_RETRY_CNT		400  #define PSP_I2C_REQ_RETRY_DELAY_US	(25 * USEC_PER_MSEC)  #define PSP_I2C_REQ_STS_OK		0x0  #define PSP_I2C_REQ_STS_BUS_BUSY	0x1  #define PSP_I2C_REQ_STS_INV_PARAM	0x3 -#define PSP_MBOX_FIELDS_STS		GENMASK(15, 0) -#define PSP_MBOX_FIELDS_CMD		GENMASK(23, 16) -#define PSP_MBOX_FIELDS_RESERVED	GENMASK(29, 24) -#define PSP_MBOX_FIELDS_RECOVERY	BIT(30) -#define PSP_MBOX_FIELDS_READY		BIT(31) - -struct psp_req_buffer_hdr { -	u32 total_size; -	u32 status; -}; -  enum psp_i2c_req_type {  	PSP_I2C_REQ_ACQUIRE,  	PSP_I2C_REQ_RELEASE, @@ -47,118 +27,13 @@ struct psp_i2c_req {  	enum psp_i2c_req_type type;  }; -struct psp_mbox { -	u32 cmd_fields; -	u64 i2c_req_addr; -} __packed; -  static DEFINE_MUTEX(psp_i2c_access_mutex);  static unsigned long psp_i2c_sem_acquired; -static void __iomem *mbox_iomem;  static u32 psp_i2c_access_count;  static bool psp_i2c_mbox_fail;  static struct device *psp_i2c_dev; -/* - * Implementation of PSP-x86 i2c-arbitration mailbox introduced for AMD Cezanne - * family of SoCs. - */ - -static int psp_get_mbox_addr(unsigned long *mbox_addr) -{ -	unsigned long long psp_mmio; - -	if (rdmsrl_safe(MSR_AMD_PSP_ADDR, &psp_mmio)) -		return -EIO; - -	*mbox_addr = (unsigned long)(psp_mmio + PSP_MBOX_OFFSET); - -	return 0; -} - -static int psp_mbox_probe(void) -{ -	unsigned long mbox_addr; -	int ret; - -	ret = psp_get_mbox_addr(&mbox_addr); -	if (ret) -		return ret; - -	mbox_iomem = ioremap(mbox_addr, sizeof(struct psp_mbox)); -	if (!mbox_iomem) -		return -ENOMEM; - -	return 0; -} - -/* Recovery field should be equal 0 to start sending commands */ -static int psp_check_mbox_recovery(struct psp_mbox __iomem *mbox) -{ -	u32 tmp; - -	tmp = readl(&mbox->cmd_fields); - -	return FIELD_GET(PSP_MBOX_FIELDS_RECOVERY, tmp); -} - -static int psp_wait_cmd(struct psp_mbox __iomem *mbox) -{ -	u32 tmp, expected; - -	/* Expect mbox_cmd to be cleared and ready bit to be set by PSP */ -	expected = FIELD_PREP(PSP_MBOX_FIELDS_READY, 1); - -	/* -	 * Check for readiness of PSP mailbox in a tight loop in order to -	 * process further as soon as command was consumed. -	 */ -	return readl_poll_timeout(&mbox->cmd_fields, tmp, (tmp == expected), -				  0, PSP_CMD_TIMEOUT_US); -} - -/* Status equal to 0 means that PSP succeed processing command */ -static u32 psp_check_mbox_sts(struct psp_mbox __iomem *mbox) -{ -	u32 cmd_reg; - -	cmd_reg = readl(&mbox->cmd_fields); - -	return FIELD_GET(PSP_MBOX_FIELDS_STS, cmd_reg); -} - -static int psp_send_cmd(struct psp_i2c_req *req) -{ -	struct psp_mbox __iomem *mbox = mbox_iomem; -	phys_addr_t req_addr; -	u32 cmd_reg; - -	if (psp_check_mbox_recovery(mbox)) -		return -EIO; - -	if (psp_wait_cmd(mbox)) -		return -EBUSY; - -	/* -	 * Fill mailbox with address of command-response buffer, which will be -	 * used for sending i2c requests as well as reading status returned by -	 * PSP. Use physical address of buffer, since PSP will map this region. -	 */ -	req_addr = __psp_pa((void *)req); -	writeq(req_addr, &mbox->i2c_req_addr); - -	/* Write command register to trigger processing */ -	cmd_reg = FIELD_PREP(PSP_MBOX_FIELDS_CMD, PSP_I2C_REQ_BUS_CMD); -	writel(cmd_reg, &mbox->cmd_fields); - -	if (psp_wait_cmd(mbox)) -		return -ETIMEDOUT; - -	if (psp_check_mbox_sts(mbox)) -		return -EIO; - -	return 0; -} +static int (*_psp_send_i2c_req)(struct psp_i2c_req *req);  /* Helper to verify status returned by PSP */  static int check_i2c_req_sts(struct psp_i2c_req *req) @@ -179,22 +54,36 @@ static int check_i2c_req_sts(struct psp_i2c_req *req)  	}  } -static int psp_send_check_i2c_req(struct psp_i2c_req *req) +/* + * Errors in x86-PSP i2c-arbitration protocol may occur at two levels: + * 1. mailbox communication - PSP is not operational or some IO errors with + *    basic communication had happened. + * 2. i2c-requests - PSP refuses to grant i2c arbitration to x86 for too long. + * + * In order to distinguish between these in error handling code all mailbox + * communication errors on the first level (from CCP symbols) will be passed + * up and if -EIO is returned the second level will be checked. + */ +static int psp_send_i2c_req_cezanne(struct psp_i2c_req *req)  { -	/* -	 * Errors in x86-PSP i2c-arbitration protocol may occur at two levels: -	 * 1. mailbox communication - PSP is not operational or some IO errors -	 * with basic communication had happened; -	 * 2. i2c-requests - PSP refuses to grant i2c arbitration to x86 for too -	 * long. -	 * In order to distinguish between these two in error handling code, all -	 * errors on the first level (returned by psp_send_cmd) are shadowed by -	 * -EIO. -	 */ -	if (psp_send_cmd(req)) -		return -EIO; +	int ret; + +	ret = psp_send_platform_access_msg(PSP_I2C_REQ_BUS_CMD, (struct psp_request *)req); +	if (ret == -EIO) +		return check_i2c_req_sts(req); -	return check_i2c_req_sts(req); +	return ret; +} + +static int psp_send_i2c_req_doorbell(struct psp_i2c_req *req) +{ +	int ret; + +	ret = psp_ring_platform_doorbell(req->type, &req->hdr.status); +	if (ret == -EIO) +		return check_i2c_req_sts(req); + +	return ret;  }  static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) @@ -208,11 +97,11 @@ static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type)  	if (!req)  		return -ENOMEM; -	req->hdr.total_size = sizeof(*req); +	req->hdr.payload_size = sizeof(*req);  	req->type = i2c_req_type;  	start = jiffies; -	ret = read_poll_timeout(psp_send_check_i2c_req, status, +	ret = read_poll_timeout(_psp_send_i2c_req, status,  				(status != -EBUSY),  				PSP_I2C_REQ_RETRY_DELAY_US,  				PSP_I2C_REQ_RETRY_CNT * PSP_I2C_REQ_RETRY_DELAY_US, @@ -387,7 +276,10 @@ static const struct i2c_lock_operations i2c_dw_psp_lock_ops = {  int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev)  { -	int ret; +	struct pci_dev *rdev; + +	if (!IS_REACHABLE(CONFIG_CRYPTO_DEV_CCP_DD)) +		return -ENODEV;  	if (!dev)  		return -ENODEV; @@ -399,11 +291,18 @@ int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev)  	if (psp_i2c_dev)  		return -EEXIST; -	psp_i2c_dev = dev->dev; +	/* Cezanne uses platform mailbox, Mendocino and later use doorbell */ +	rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); +	if (rdev->device == 0x1630) +		_psp_send_i2c_req = psp_send_i2c_req_cezanne; +	else +		_psp_send_i2c_req = psp_send_i2c_req_doorbell; +	pci_dev_put(rdev); -	ret = psp_mbox_probe(); -	if (ret) -		return ret; +	if (psp_check_platform_access_status()) +		return -EPROBE_DEFER; + +	psp_i2c_dev = dev->dev;  	dev_info(psp_i2c_dev, "I2C bus managed by AMD PSP\n"); @@ -417,9 +316,3 @@ int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev)  	return 0;  } - -/* Unmap area used as a mailbox with PSP */ -void i2c_dw_amdpsp_remove_lock_support(struct dw_i2c_dev *dev) -{ -	iounmap(mbox_iomem); -} diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 050d8c63ad3c..c5d87aae39c6 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -383,7 +383,6 @@ int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev);  #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_AMDPSP)  int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev); -void i2c_dw_amdpsp_remove_lock_support(struct dw_i2c_dev *dev);  #endif  int i2c_dw_validate_speed(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 74182db03a88..89ad88c54754 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -214,7 +214,6 @@ static const struct i2c_dw_semaphore_callbacks i2c_dw_semaphore_cb_table[] = {  #ifdef CONFIG_I2C_DESIGNWARE_AMDPSP  	{  		.probe = i2c_dw_amdpsp_probe_lock_support, -		.remove = i2c_dw_amdpsp_remove_lock_support,  	},  #endif  	{} diff --git a/drivers/i2c/busses/i2c-gxp.c b/drivers/i2c/busses/i2c-gxp.c index d4b55d989a26..8ea3fb5e4c7f 100644 --- a/drivers/i2c/busses/i2c-gxp.c +++ b/drivers/i2c/busses/i2c-gxp.c @@ -353,7 +353,6 @@ static void gxp_i2c_chk_data_ack(struct gxp_i2c_drvdata *drvdata)  	writew(value, drvdata->base + GXP_I2CMCMD);  } -#if IS_ENABLED(CONFIG_I2C_SLAVE)  static bool gxp_i2c_slave_irq_handler(struct gxp_i2c_drvdata *drvdata)  {  	u8 value; @@ -437,7 +436,6 @@ static bool gxp_i2c_slave_irq_handler(struct gxp_i2c_drvdata *drvdata)  	return true;  } -#endif  static irqreturn_t gxp_i2c_irq_handler(int irq, void *_drvdata)  { diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index a49b14d52a98..1af0a637d7f1 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -639,7 +639,7 @@ static int __maybe_unused lpi2c_runtime_suspend(struct device *dev)  {  	struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); -	clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks); +	clk_bulk_disable(lpi2c_imx->num_clks, lpi2c_imx->clks);  	pinctrl_pm_select_sleep_state(dev);  	return 0; @@ -651,7 +651,7 @@ static int __maybe_unused lpi2c_runtime_resume(struct device *dev)  	int ret;  	pinctrl_pm_select_default_state(dev); -	ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks); +	ret = clk_bulk_enable(lpi2c_imx->num_clks, lpi2c_imx->clks);  	if (ret) {  		dev_err(dev, "failed to enable I2C clock, ret=%d\n", ret);  		return ret; diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index cf5bacf3a488..42189a5f2905 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1482,17 +1482,11 @@ static int i2c_imx_probe(struct platform_device *pdev)  	ACPI_COMPANION_SET(&i2c_imx->adapter.dev, ACPI_COMPANION(&pdev->dev));  	/* Get I2C clock */ -	i2c_imx->clk = devm_clk_get(&pdev->dev, NULL); +	i2c_imx->clk = devm_clk_get_enabled(&pdev->dev, NULL);  	if (IS_ERR(i2c_imx->clk))  		return dev_err_probe(&pdev->dev, PTR_ERR(i2c_imx->clk),  				     "can't get I2C clock\n"); -	ret = clk_prepare_enable(i2c_imx->clk); -	if (ret) { -		dev_err(&pdev->dev, "can't enable I2C clock, ret=%d\n", ret); -		return ret; -	} -  	/* Init queue */  	init_waitqueue_head(&i2c_imx->queue); @@ -1564,7 +1558,6 @@ rpm_disable:  	pm_runtime_disable(&pdev->dev);  	pm_runtime_set_suspended(&pdev->dev);  	pm_runtime_dont_use_autosuspend(&pdev->dev); -	clk_disable_unprepare(i2c_imx->clk);  	return ret;  } @@ -1590,7 +1583,6 @@ static int i2c_imx_remove(struct platform_device *pdev)  		imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR);  		imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR);  		imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR); -		clk_disable(i2c_imx->clk);  	}  	clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb); @@ -1598,8 +1590,6 @@ static int i2c_imx_remove(struct platform_device *pdev)  	if (irq >= 0)  		free_irq(irq, i2c_imx); -	clk_unprepare(i2c_imx->clk); -  	pm_runtime_put_noidle(&pdev->dev);  	pm_runtime_disable(&pdev->dev); diff --git a/drivers/i2c/busses/i2c-mchp-pci1xxxx.c b/drivers/i2c/busses/i2c-mchp-pci1xxxx.c index 09af75921147..b21ffd6df927 100644 --- a/drivers/i2c/busses/i2c-mchp-pci1xxxx.c +++ b/drivers/i2c/busses/i2c-mchp-pci1xxxx.c @@ -48,9 +48,9 @@   * SR_HOLD_TIME_XK_TICKS field will indicate the number of ticks of the   * baud clock required to program 'Hold Time' at X KHz.   */ -#define SR_HOLD_TIME_100K_TICKS	133 -#define SR_HOLD_TIME_400K_TICKS	20 -#define SR_HOLD_TIME_1000K_TICKS	11 +#define SR_HOLD_TIME_100K_TICKS		150 +#define SR_HOLD_TIME_400K_TICKS		20 +#define SR_HOLD_TIME_1000K_TICKS	12  #define SMB_CORE_COMPLETION_REG_OFF3	(SMBUS_MAST_CORE_ADDR_BASE + 0x23) @@ -65,17 +65,17 @@   * the baud clock required to program 'fair idle delay' at X KHz. Fair idle   * delay establishes the MCTP T(IDLE_DELAY) period.   */ -#define FAIR_BUS_IDLE_MIN_100K_TICKS		969 -#define FAIR_BUS_IDLE_MIN_400K_TICKS		157 -#define FAIR_BUS_IDLE_MIN_1000K_TICKS		157 +#define FAIR_BUS_IDLE_MIN_100K_TICKS		992 +#define FAIR_BUS_IDLE_MIN_400K_TICKS		500 +#define FAIR_BUS_IDLE_MIN_1000K_TICKS		500  /*   * FAIR_IDLE_DELAY_XK_TICKS field will indicate the number of ticks of the   * baud clock required to satisfy the fairness protocol at X KHz.   */ -#define FAIR_IDLE_DELAY_100K_TICKS	1000 -#define FAIR_IDLE_DELAY_400K_TICKS	500 -#define FAIR_IDLE_DELAY_1000K_TICKS	500 +#define FAIR_IDLE_DELAY_100K_TICKS	963 +#define FAIR_IDLE_DELAY_400K_TICKS	156 +#define FAIR_IDLE_DELAY_1000K_TICKS	156  #define SMB_IDLE_SCALING_100K		\  	((FAIR_IDLE_DELAY_100K_TICKS << 16) | FAIR_BUS_IDLE_MIN_100K_TICKS) @@ -105,7 +105,7 @@   */  #define BUS_CLK_100K_LOW_PERIOD_TICKS		156  #define BUS_CLK_400K_LOW_PERIOD_TICKS		41 -#define BUS_CLK_1000K_LOW_PERIOD_TICKS	15 +#define BUS_CLK_1000K_LOW_PERIOD_TICKS		15  /*   * BUS_CLK_XK_HIGH_PERIOD_TICKS field defines the number of I2C Baud Clock @@ -131,7 +131,7 @@   */  #define CLK_SYNC_100K			4  #define CLK_SYNC_400K			4 -#define CLK_SYNC_1000K		4 +#define CLK_SYNC_1000K			4  #define SMB_CORE_DATA_TIMING_REG_OFF	(SMBUS_MAST_CORE_ADDR_BASE + 0x40) @@ -142,25 +142,25 @@   * determines the SCLK hold time following SDAT driven low during the first   * START bit in a transfer.   */ -#define FIRST_START_HOLD_100K_TICKS	22 -#define FIRST_START_HOLD_400K_TICKS	16 -#define FIRST_START_HOLD_1000K_TICKS	6 +#define FIRST_START_HOLD_100K_TICKS	23 +#define FIRST_START_HOLD_400K_TICKS	8 +#define FIRST_START_HOLD_1000K_TICKS	12  /*   * STOP_SETUP_XK_TICKS will indicate the number of ticks of the baud clock   * required to program 'STOP_SETUP' timer at X KHz. This timer determines the   * SDAT setup time from the rising edge of SCLK for a STOP condition.   */ -#define STOP_SETUP_100K_TICKS		157 +#define STOP_SETUP_100K_TICKS		150  #define STOP_SETUP_400K_TICKS		20 -#define STOP_SETUP_1000K_TICKS	12 +#define STOP_SETUP_1000K_TICKS		12  /*   * RESTART_SETUP_XK_TICKS will indicate the number of ticks of the baud clock   * required to program 'RESTART_SETUP' timer at X KHz. This timer determines the   * SDAT setup time from the rising edge of SCLK for a repeated START condition.   */ -#define RESTART_SETUP_100K_TICKS	157 +#define RESTART_SETUP_100K_TICKS	156  #define RESTART_SETUP_400K_TICKS	20  #define RESTART_SETUP_1000K_TICKS	12 @@ -169,7 +169,7 @@   * required to program 'DATA_HOLD' timer at X KHz. This timer determines the   * SDAT hold time following SCLK driven low.   */ -#define DATA_HOLD_100K_TICKS		2 +#define DATA_HOLD_100K_TICKS		12  #define DATA_HOLD_400K_TICKS		2  #define DATA_HOLD_1000K_TICKS		2 @@ -190,35 +190,35 @@   * Bus Idle Minimum time = BUS_IDLE_MIN[7:0] x Baud_Clock_Period x   * (BUS_IDLE_MIN_XK_TICKS[7] ? 4,1)   */ -#define BUS_IDLE_MIN_100K_TICKS		167UL -#define BUS_IDLE_MIN_400K_TICKS		139UL -#define BUS_IDLE_MIN_1000K_TICKS		133UL +#define BUS_IDLE_MIN_100K_TICKS		36UL +#define BUS_IDLE_MIN_400K_TICKS		10UL +#define BUS_IDLE_MIN_1000K_TICKS	4UL  /*   * CTRL_CUM_TIME_OUT_XK_TICKS defines SMBus Controller Cumulative Time-Out.   * SMBus Controller Cumulative Time-Out duration =   * CTRL_CUM_TIME_OUT_XK_TICKS[7:0] x Baud_Clock_Period x 2048   */ -#define CTRL_CUM_TIME_OUT_100K_TICKS		159 -#define CTRL_CUM_TIME_OUT_400K_TICKS		159 -#define CTRL_CUM_TIME_OUT_1000K_TICKS		159 +#define CTRL_CUM_TIME_OUT_100K_TICKS		76 +#define CTRL_CUM_TIME_OUT_400K_TICKS		76 +#define CTRL_CUM_TIME_OUT_1000K_TICKS		76  /*   * TARGET_CUM_TIME_OUT_XK_TICKS defines SMBus Target Cumulative Time-Out duration.   * SMBus Target Cumulative Time-Out duration = TARGET_CUM_TIME_OUT_XK_TICKS[7:0] x   * Baud_Clock_Period x 4096   */ -#define TARGET_CUM_TIME_OUT_100K_TICKS	199 -#define TARGET_CUM_TIME_OUT_400K_TICKS	199 -#define TARGET_CUM_TIME_OUT_1000K_TICKS	199 +#define TARGET_CUM_TIME_OUT_100K_TICKS	95 +#define TARGET_CUM_TIME_OUT_400K_TICKS	95 +#define TARGET_CUM_TIME_OUT_1000K_TICKS	95  /*   * CLOCK_HIGH_TIME_OUT_XK defines Clock High time out period.   * Clock High time out period = CLOCK_HIGH_TIME_OUT_XK[7:0] x Baud_Clock_Period x 8   */ -#define CLOCK_HIGH_TIME_OUT_100K_TICKS	204 -#define CLOCK_HIGH_TIME_OUT_400K_TICKS	204 -#define CLOCK_HIGH_TIME_OUT_1000K_TICKS	204 +#define CLOCK_HIGH_TIME_OUT_100K_TICKS	97 +#define CLOCK_HIGH_TIME_OUT_400K_TICKS	97 +#define CLOCK_HIGH_TIME_OUT_1000K_TICKS	97  #define TO_SCALING_100K		\  	((BUS_IDLE_MIN_100K_TICKS << 24) | (CTRL_CUM_TIME_OUT_100K_TICKS << 16) | \ diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 81ac92bb4f6f..cfd074ee6d54 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -770,7 +770,6 @@ static const struct i2c_algorithm mpc_algo = {  static struct i2c_adapter mpc_ops = {  	.owner = THIS_MODULE,  	.algo = &mpc_algo, -	.timeout = HZ,  };  static struct i2c_bus_recovery_info fsl_i2c_recovery_info = { @@ -781,11 +780,9 @@ static int fsl_i2c_probe(struct platform_device *op)  {  	const struct mpc_i2c_data *data;  	struct mpc_i2c *i2c; -	const u32 *prop; -	u32 clock = MPC_I2C_CLOCK_LEGACY; -	int result = 0; -	int plen;  	struct clk *clk; +	int result; +	u32 clock;  	int err;  	i2c = devm_kzalloc(&op->dev, sizeof(*i2c), GFP_KERNEL); @@ -831,10 +828,10 @@ static int fsl_i2c_probe(struct platform_device *op)  	if (of_property_read_bool(op->dev.of_node, "fsl,preserve-clocking")) {  		clock = MPC_I2C_CLOCK_PRESERVE;  	} else { -		prop = of_get_property(op->dev.of_node, "clock-frequency", -					&plen); -		if (prop && plen == sizeof(u32)) -			clock = *prop; +		result = of_property_read_u32(op->dev.of_node, +					      "clock-frequency", &clock); +		if (result) +			clock = MPC_I2C_CLOCK_LEGACY;  	}  	data = device_get_match_data(&op->dev); @@ -842,16 +839,30 @@ static int fsl_i2c_probe(struct platform_device *op)  		data->setup(op->dev.of_node, i2c, clock);  	} else {  		/* Backwards compatibility */ -		if (of_get_property(op->dev.of_node, "dfsrr", NULL)) +		if (of_property_read_bool(op->dev.of_node, "dfsrr"))  			mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock);  	} -	prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen); -	if (prop && plen == sizeof(u32)) { -		mpc_ops.timeout = *prop * HZ / 1000000; +	/* +	 * "fsl,timeout" has been marked as deprecated and, to maintain +	 * backward compatibility, we will only look for it if +	 * "i2c-scl-clk-low-timeout-us" is not present. +	 */ +	result = of_property_read_u32(op->dev.of_node, +				      "i2c-scl-clk-low-timeout-us", +				      &mpc_ops.timeout); +	if (result == -EINVAL) +		result = of_property_read_u32(op->dev.of_node, +					      "fsl,timeout", &mpc_ops.timeout); + +	if (!result) { +		mpc_ops.timeout *= HZ / 1000000;  		if (mpc_ops.timeout < 5)  			mpc_ops.timeout = 5; +	} else { +		mpc_ops.timeout = HZ;  	} +  	dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);  	if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447")) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 43dd966d5ef5..a43c4d77739a 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -431,6 +431,18 @@ static const struct mtk_i2c_compatible mt8168_compat = {  	.max_dma_support = 33,  }; +static const struct mtk_i2c_compatible mt7981_compat = { +	.regs = mt_i2c_regs_v3, +	.pmic_i2c = 0, +	.dcm = 0, +	.auto_restart = 1, +	.aux_len_reg = 1, +	.timing_adjust = 1, +	.dma_sync = 1, +	.ltiming_adjust = 1, +	.max_dma_support = 33 +}; +  static const struct mtk_i2c_compatible mt7986_compat = {  	.quirks = &mt7622_i2c_quirks,  	.regs = mt_i2c_regs_v1, @@ -516,6 +528,7 @@ static const struct of_device_id mtk_i2c_of_match[] = {  	{ .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },  	{ .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },  	{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat }, +	{ .compatible = "mediatek,mt7981-i2c", .data = &mt7981_compat },  	{ .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },  	{ .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },  	{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat }, @@ -1546,7 +1559,7 @@ static struct platform_driver mtk_i2c_driver = {  	.driver = {  		.name = I2C_DRV_NAME,  		.pm = &mtk_i2c_pm, -		.of_match_table = of_match_ptr(mtk_i2c_of_match), +		.of_match_table = mtk_i2c_of_match,  	},  }; diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index a0af027db04c..2e575856c5cd 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -342,18 +342,18 @@ static int ocores_poll_wait(struct ocores_i2c *i2c)   * ocores_isr(), we just add our polling code around it.   *   * It can run in atomic context + * + * Return: 0 on success, -ETIMEDOUT on timeout   */ -static void ocores_process_polling(struct ocores_i2c *i2c) +static int ocores_process_polling(struct ocores_i2c *i2c)  { -	while (1) { -		irqreturn_t ret; -		int err; +	irqreturn_t ret; +	int err = 0; +	while (1) {  		err = ocores_poll_wait(i2c); -		if (err) { -			i2c->state = STATE_ERROR; +		if (err)  			break; /* timeout */ -		}  		ret = ocores_isr(-1, i2c);  		if (ret == IRQ_NONE) @@ -364,13 +364,15 @@ static void ocores_process_polling(struct ocores_i2c *i2c)  					break;  		}  	} + +	return err;  }  static int ocores_xfer_core(struct ocores_i2c *i2c,  			    struct i2c_msg *msgs, int num,  			    bool polling)  { -	int ret; +	int ret = 0;  	u8 ctrl;  	ctrl = oc_getreg(i2c, OCI2C_CONTROL); @@ -388,15 +390,16 @@ static int ocores_xfer_core(struct ocores_i2c *i2c,  	oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);  	if (polling) { -		ocores_process_polling(i2c); +		ret = ocores_process_polling(i2c);  	} else { -		ret = wait_event_timeout(i2c->wait, -					 (i2c->state == STATE_ERROR) || -					 (i2c->state == STATE_DONE), HZ); -		if (ret == 0) { -			ocores_process_timeout(i2c); -			return -ETIMEDOUT; -		} +		if (wait_event_timeout(i2c->wait, +				       (i2c->state == STATE_ERROR) || +				       (i2c->state == STATE_DONE), HZ) == 0) +			ret = -ETIMEDOUT; +	} +	if (ret) { +		ocores_process_timeout(i2c); +		return ret;  	}  	return (i2c->state == STATE_DONE) ? num : -EIO; diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index f9ae520aed22..4199f57a6bf2 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1058,7 +1058,7 @@ omap_i2c_isr(int irq, void *dev_id)  	u16 stat;  	stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG); -	mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG); +	mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK;  	if (stat & mask)  		ret = IRQ_WAKE_THREAD; @@ -1525,14 +1525,17 @@ static int omap_i2c_remove(struct platform_device *pdev)  	int ret;  	i2c_del_adapter(&omap->adapter); -	ret = pm_runtime_resume_and_get(&pdev->dev); + +	ret = pm_runtime_get_sync(&pdev->dev);  	if (ret < 0) -		return ret; +		dev_err(omap->dev, "Failed to resume hardware, skip disable\n"); +	else +		omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0); -	omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);  	pm_runtime_dont_use_autosuspend(&pdev->dev);  	pm_runtime_put_sync(&pdev->dev);  	pm_runtime_disable(&pdev->dev); +  	return 0;  } diff --git a/drivers/i2c/busses/i2c-owl.c b/drivers/i2c/busses/i2c-owl.c index 98882fe4e965..99ddd8894964 100644 --- a/drivers/i2c/busses/i2c-owl.c +++ b/drivers/i2c/busses/i2c-owl.c @@ -519,7 +519,7 @@ static struct platform_driver owl_i2c_driver = {  	.probe		= owl_i2c_probe,  	.driver		= {  		.name	= "owl-i2c", -		.of_match_table = of_match_ptr(owl_i2c_of_match), +		.of_match_table = owl_i2c_of_match,  		.probe_type = PROBE_PREFER_ASYNCHRONOUS,  	},  }; diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 2e74747eec9c..ec706a3aba26 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -284,7 +284,7 @@ static bool i2c_powermac_get_type(struct i2c_adapter *adap,  	 */  	/* First try proper modalias */ -	if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { +	if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) {  		snprintf(type, type_size, "MAC,%s", tmp);  		return true;  	} diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index b605b6e43cb9..f9fa5308556b 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1261,10 +1261,8 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,  	/* For device tree we always use the dynamic or alias-assigned ID */  	i2c->adap.nr = -1; -	if (of_get_property(np, "mrvl,i2c-polling", NULL)) -		i2c->use_pio = 1; -	if (of_get_property(np, "mrvl,i2c-fast-mode", NULL)) -		i2c->fast_mode = 1; +	i2c->use_pio = of_property_read_bool(np, "mrvl,i2c-polling"); +	i2c->fast_mode = of_property_read_bool(np, "mrvl,i2c-fast-mode");  	*i2c_types = (enum pxa_i2c_types)(of_id->data); diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c index e4026c5416b1..50d19cf99a03 100644 --- a/drivers/i2c/busses/i2c-synquacer.c +++ b/drivers/i2c/busses/i2c-synquacer.c @@ -629,7 +629,7 @@ static int synquacer_i2c_remove(struct platform_device *pdev)  	return 0;  }; -static const struct of_device_id synquacer_i2c_dt_ids[] = { +static const struct of_device_id synquacer_i2c_dt_ids[] __maybe_unused = {  	{ .compatible = "socionext,synquacer-i2c" },  	{ /* sentinel */ }  }; diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 6aab84c8d22b..157066f06a32 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -242,9 +242,10 @@ struct tegra_i2c_hw_feature {   * @is_dvc: identifies the DVC I2C controller, has a different register layout   * @is_vi: identifies the VI I2C controller, has a different register layout   * @msg_complete: transfer completion notifier + * @msg_buf_remaining: size of unsent data in the message buffer + * @msg_len: length of message in current transfer   * @msg_err: error code for completed message   * @msg_buf: pointer to current message data - * @msg_buf_remaining: size of unsent data in the message buffer   * @msg_read: indicates that the transfer is a read access   * @timings: i2c timings information like bus frequency   * @multimaster_mode: indicates that I2C controller is in multi-master mode @@ -277,6 +278,7 @@ struct tegra_i2c_dev {  	struct completion msg_complete;  	size_t msg_buf_remaining; +	unsigned int msg_len;  	int msg_err;  	u8 *msg_buf; @@ -1169,7 +1171,7 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,  	else  		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); -	packet_header = msg->len - 1; +	packet_header = i2c_dev->msg_len - 1;  	if (i2c_dev->dma_mode && !i2c_dev->msg_read)  		*dma_buf++ = packet_header; @@ -1242,20 +1244,32 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,  		return err;  	i2c_dev->msg_buf = msg->buf; +	i2c_dev->msg_len = msg->len; -	/* The condition true implies smbus block read and len is already read */ -	if (msg->flags & I2C_M_RECV_LEN && end_state != MSG_END_CONTINUE) -		i2c_dev->msg_buf = msg->buf + 1; - -	i2c_dev->msg_buf_remaining = msg->len;  	i2c_dev->msg_err = I2C_ERR_NONE;  	i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);  	reinit_completion(&i2c_dev->msg_complete); +	/* +	 * For SMBUS block read command, read only 1 byte in the first transfer. +	 * Adjust that 1 byte for the next transfer in the msg buffer and msg +	 * length. +	 */ +	if (msg->flags & I2C_M_RECV_LEN) { +		if (end_state == MSG_END_CONTINUE) { +			i2c_dev->msg_len = 1; +		} else { +			i2c_dev->msg_buf += 1; +			i2c_dev->msg_len -= 1; +		} +	} + +	i2c_dev->msg_buf_remaining = i2c_dev->msg_len; +  	if (i2c_dev->msg_read) -		xfer_size = msg->len; +		xfer_size = i2c_dev->msg_len;  	else -		xfer_size = msg->len + I2C_PACKET_HEADER_SIZE; +		xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;  	xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD); @@ -1295,7 +1309,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,  	if (!i2c_dev->msg_read) {  		if (i2c_dev->dma_mode) {  			memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE, -			       msg->buf, msg->len); +			       msg->buf, i2c_dev->msg_len);  			dma_sync_single_for_device(i2c_dev->dma_dev,  						   i2c_dev->dma_phys, @@ -1352,7 +1366,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,  						i2c_dev->dma_phys,  						xfer_size, DMA_FROM_DEVICE); -			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, msg->len); +			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);  		}  	} @@ -1408,8 +1422,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],  			ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);  			if (ret)  				break; -			/* Set the read byte as msg len */ -			msgs[i].len = msgs[i].buf[0]; +			/* Set the msg length from first byte */ +			msgs[i].len += msgs[i].buf[0];  			dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);  		}  		ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type); diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index dbb792fc197e..8a3d9817cb41 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -1164,7 +1164,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	err = xiic_start_xfer(i2c, msgs, num);  	if (err < 0) {  		dev_err(adap->dev.parent, "Error xiic_start_xfer\n"); -		return err; +		goto out;  	}  	err = wait_for_completion_timeout(&i2c->completion, XIIC_XFER_TIMEOUT); @@ -1178,6 +1178,8 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  		err = (i2c->state == STATE_DONE) ? num : -EIO;  	}  	mutex_unlock(&i2c->lock); + +out:  	pm_runtime_mark_last_busy(i2c->dev);  	pm_runtime_put_autosuspend(i2c->dev);  	return err; @@ -1199,11 +1201,11 @@ static const struct i2c_adapter xiic_adapter = {  	.algo = &xiic_algorithm,  }; +#if defined(CONFIG_OF)  static const struct xiic_version_data xiic_2_00 = {  	.quirks = DYNAMIC_MODE_READ_BROKEN_BIT,  }; -#if defined(CONFIG_OF)  static const struct of_device_id xiic_of_match[] = {  	{ .compatible = "xlnx,xps-iic-2.00.a", .data = &xiic_2_00 },  	{ .compatible = "xlnx,axi-iic-2.1", }, @@ -1233,8 +1235,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)  		i2c->quirks = data->quirks;  	} -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	i2c->base = devm_ioremap_resource(&pdev->dev, res); +	i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);  	if (IS_ERR(i2c->base))  		return PTR_ERR(i2c->base); diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index bce6b796e04c..a6c407d36800 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device *dev, struct device_node *node,  	memset(info, 0, sizeof(*info)); -	if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { +	if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) {  		dev_err(dev, "of_i2c: modalias failure on %pOF\n", node);  		return -EINVAL;  	} @@ -55,7 +55,7 @@ int of_i2c_get_board_info(struct device *dev, struct device_node *node,  	if (of_property_read_bool(node, "host-notify"))  		info->flags |= I2C_CLIENT_HOST_NOTIFY; -	if (of_get_property(node, "wakeup-source", NULL)) +	if (of_property_read_bool(node, "wakeup-source"))  		info->flags |= I2C_CLIENT_WAKE;  	return 0; @@ -178,6 +178,11 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,  			return NOTIFY_OK;  		} +		/* +		 * Clear the flag before adding the device so that fw_devlink +		 * doesn't skip adding consumers to this device. +		 */ +		rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;  		client = of_i2c_register_device(adap, rd->dn);  		if (IS_ERR(client)) {  			dev_err(&adap->dev, "failed to create client for '%pOF'\n", diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 95a0b63ac560..a01b59e3599b 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -751,7 +751,7 @@ static int __init i2c_dev_init(void)  	if (res)  		goto out; -	i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); +	i2c_dev_class = class_create("i2c-dev");  	if (IS_ERR(i2c_dev_class)) {  		res = PTR_ERR(i2c_dev_class);  		goto out_unreg_chrdev;  |