Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 370136bc authored by Maxime Ripard's avatar Maxime Ripard Committed by Wolfram Sang
Browse files

i2c: mv64xxx: Add reset deassert call



The Allwinner A31 SoC using that IP has a reset controller maintaining
it reset unless told otherwise.

Add some optional reset support to the driver.

Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Reviewed-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
Tested-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 96c4b6bb
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@ Optional properties :


 - clock-frequency : Desired I2C bus clock frequency in Hz. If not set the
 - clock-frequency : Desired I2C bus clock frequency in Hz. If not set the
default frequency is 100kHz
default frequency is 100kHz
 - resets          : phandle to the parent reset controller


Examples:
Examples:


+1 −0
Original line number Original line Diff line number Diff line
@@ -528,6 +528,7 @@ config I2C_MPC
config I2C_MV64XXX
config I2C_MV64XXX
	tristate "Marvell mv64xxx I2C Controller"
	tristate "Marvell mv64xxx I2C Controller"
	depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI)
	depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI)
	select RESET_CONTROLLER
	help
	help
	  If you say yes to this option, support will be included for the
	  If you say yes to this option, support will be included for the
	  built-in I2C interface on the Marvell 64xxx line of host bridges.
	  built-in I2C interface on the Marvell 64xxx line of host bridges.
+19 −2
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/mv643xx_i2c.h>
#include <linux/mv643xx_i2c.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_device.h>
@@ -148,6 +149,7 @@ struct mv64xxx_i2c_data {
	bool			offload_enabled;
	bool			offload_enabled;
/* 5us delay in order to avoid repeated start timing violation */
/* 5us delay in order to avoid repeated start timing violation */
	bool			errata_delay;
	bool			errata_delay;
	struct reset_control	*rstc;
};
};


static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -759,6 +761,16 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
	}
	}
	drv_data->irq = irq_of_parse_and_map(np, 0);
	drv_data->irq = irq_of_parse_and_map(np, 0);


	drv_data->rstc = devm_reset_control_get(dev, NULL);
	if (IS_ERR(drv_data->rstc)) {
		if (PTR_ERR(drv_data->rstc) == -EPROBE_DEFER) {
			rc = -EPROBE_DEFER;
			goto out;
		}
	} else {
		reset_control_deassert(drv_data->rstc);
	}

	/* Its not yet defined how timeouts will be specified in device tree.
	/* Its not yet defined how timeouts will be specified in device tree.
	 * So hard code the value to 1 second.
	 * So hard code the value to 1 second.
	 */
	 */
@@ -845,7 +857,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
	}
	}
	if (drv_data->irq < 0) {
	if (drv_data->irq < 0) {
		rc = -ENXIO;
		rc = -ENXIO;
		goto exit_clk;
		goto exit_reset;
	}
	}


	drv_data->adapter.dev.parent = &pd->dev;
	drv_data->adapter.dev.parent = &pd->dev;
@@ -865,7 +877,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
		dev_err(&drv_data->adapter.dev,
		dev_err(&drv_data->adapter.dev,
			"mv64xxx: Can't register intr handler irq%d: %d\n",
			"mv64xxx: Can't register intr handler irq%d: %d\n",
			drv_data->irq, rc);
			drv_data->irq, rc);
		goto exit_clk;
		goto exit_reset;
	} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
	} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
		dev_err(&drv_data->adapter.dev,
		dev_err(&drv_data->adapter.dev,
			"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
			"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
@@ -876,6 +888,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)


exit_free_irq:
exit_free_irq:
	free_irq(drv_data->irq, drv_data);
	free_irq(drv_data->irq, drv_data);
exit_reset:
	if (pd->dev.of_node && !IS_ERR(drv_data->rstc))
		reset_control_assert(drv_data->rstc);
exit_clk:
exit_clk:
#if defined(CONFIG_HAVE_CLK)
#if defined(CONFIG_HAVE_CLK)
	/* Not all platforms have a clk */
	/* Not all platforms have a clk */
@@ -894,6 +909,8 @@ mv64xxx_i2c_remove(struct platform_device *dev)


	i2c_del_adapter(&drv_data->adapter);
	i2c_del_adapter(&drv_data->adapter);
	free_irq(drv_data->irq, drv_data);
	free_irq(drv_data->irq, drv_data);
	if (dev->dev.of_node && !IS_ERR(drv_data->rstc))
		reset_control_assert(drv_data->rstc);
#if defined(CONFIG_HAVE_CLK)
#if defined(CONFIG_HAVE_CLK)
	/* Not all platforms have a clk */
	/* Not all platforms have a clk */
	if (!IS_ERR(drv_data->clk)) {
	if (!IS_ERR(drv_data->clk)) {