[PATCH v3 5/7] i2c: aspeed: Add aspeed_set_slave_busy()

Ryan Chen ryan_chen at aspeedtech.com
Thu May 20 21:06:36 AEST 2021


> -----Original Message-----
> From: openbmc
> <openbmc-bounces+ryan_chen=aspeedtech.com at lists.ozlabs.org> On Behalf
> Of Quan Nguyen
> Sent: Wednesday, May 19, 2021 3:50 PM
> To: Corey Minyard <minyard at acm.org>; Rob Herring <robh+dt at kernel.org>;
> Joel Stanley <joel at jms.id.au>; Andrew Jeffery <andrew at aj.id.au>; Brendan
> Higgins <brendanhiggins at google.com>; Benjamin Herrenschmidt
> <benh at kernel.crashing.org>; Wolfram Sang <wsa at kernel.org>; Philipp Zabel
> <p.zabel at pengutronix.de>; openipmi-developer at lists.sourceforge.net;
> devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-aspeed at lists.ozlabs.org; linux-kernel at vger.kernel.org;
> linux-i2c at vger.kernel.org
> Cc: Open Source Submission <patches at amperecomputing.com>; Thang Q .
> Nguyen <thang at os.amperecomputing.com>; Phong Vo
> <phong at os.amperecomputing.com>; openbmc at lists.ozlabs.org
> Subject: [PATCH v3 5/7] i2c: aspeed: Add aspeed_set_slave_busy()
> 
> Slave i2c device on AST2500 received a lot of slave irq while it is busy
> processing the response. To handle this case, adds and exports
> aspeed_set_slave_busy() for controller to temporary stop slave irq while slave
> is handling the response, and re-enable them again when the response is ready.
> 
> Signed-off-by: Quan Nguyen <quan at os.amperecomputing.com>
> ---
> v3:
>   + First introduce in v3 [Quan]
> 
>  drivers/i2c/busses/i2c-aspeed.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> index b2e9c8f0ddf7..9926d04831a2 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -944,6 +944,26 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus
> *bus,
>  	return 0;
>  }
> 
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> +void aspeed_set_slave_busy(struct i2c_adapter *adap, bool busy) {
> +	struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
> +	unsigned long current_mask, flags;
> +
> +	spin_lock_irqsave(&bus->lock, flags);
> +
> +	current_mask = readl(bus->base + ASPEED_I2C_INTR_CTRL_REG);
> +	if (busy)
> +		current_mask &= ~(ASPEED_I2CD_INTR_RX_DONE |
> ASPEED_I2CD_INTR_SLAVE_MATCH);
> +	else
> +		current_mask |= ASPEED_I2CD_INTR_RX_DONE |
> ASPEED_I2CD_INTR_SLAVE_MATCH;
> +	writel(current_mask, bus->base + ASPEED_I2C_INTR_CTRL_REG);
> +
> +	spin_unlock_irqrestore(&bus->lock, flags); }
> +EXPORT_SYMBOL_GPL(aspeed_set_slave_busy);
> +#endif
> +
>  static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus)  {
>  	struct platform_device *pdev = to_platform_device(bus->dev);
> --
> 2.28.0

Hello,
	The better idea is use disable i2c slave mode. 
	Due to if i2c controller running in slave will get slave match, and latch the SCL.
	Until cpu clear interrupt status. 
Ryan



More information about the Linux-aspeed mailing list