From 36821b3f55adc26c593520d8c207eea36c5c264a Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Thu, 28 Mar 2019 21:11:48 +0100 Subject: i2c: designware: fix reset handling on socfpga gen5 Using this driver on socfpga gen5 with DM_I2C enabled leads to a data abort as the 'i2c' reset property cannot be found (the gen5 dtsi does not provide reset-names). The actual bug was to check 'if (&priv->reset_ctl)', which is never false. While at it, convert the driver to use 'reset_get_bulk' instead of looking at a specific named reset and also make it release the reset on driver remove before starting the OS. Fixes: 622597dee4f6 ("i2c: designware: add reset ctrl to driver") Signed-off-by: Simon Goldschmidt Reviewed-by: Heiko Schocher --- drivers/i2c/designware_i2c.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 63e40823f1..9ccc2411a6 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -34,7 +34,7 @@ static struct dw_scl_sda_cfg byt_config = { struct dw_i2c { struct i2c_regs *regs; struct dw_scl_sda_cfg *scl_sda_cfg; - struct reset_ctl reset_ctl; + struct reset_ctl_bulk resets; }; #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED @@ -562,16 +562,22 @@ static int designware_i2c_probe(struct udevice *bus) priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus); } - ret = reset_get_by_name(bus, "i2c", &priv->reset_ctl); + ret = reset_get_bulk(bus, &priv->resets); if (ret) - pr_info("reset_get_by_name() failed: %d\n", ret); - - if (&priv->reset_ctl) - reset_deassert(&priv->reset_ctl); + dev_warn(bus, "Can't get reset: %d\n", ret); + else + reset_deassert_bulk(&priv->resets); return __dw_i2c_init(priv->regs, 0, 0); } +static int designware_i2c_remove(struct udevice *dev) +{ + struct dw_i2c *priv = dev_get_priv(dev); + + return reset_release_bulk(&priv->resets); +} + static int designware_i2c_bind(struct udevice *dev) { static int num_cards; @@ -613,6 +619,8 @@ U_BOOT_DRIVER(i2c_designware) = { .bind = designware_i2c_bind, .probe = designware_i2c_probe, .priv_auto_alloc_size = sizeof(struct dw_i2c), + .remove = designware_i2c_remove, + .flags = DM_FLAG_OS_PREPARE, .ops = &designware_i2c_ops, }; -- cgit v1.2.3 From 4e829e9841f80c540150a14b4d12169139a0b7b9 Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Thu, 28 Mar 2019 21:11:49 +0100 Subject: rtc: m41t62: add compatible for m41t82 This adds a compatible string for m41t82. This ensures that this driver can be used for m41t82 in DM mode, too (asit was usable for this model in non-DM mode before). In addition, the HT bit has to be reset during probe, since the m41t82 chip sets it when entering battery standby mode. This patch ensures this driver works on socfpga_socrates. Signed-off-by: Simon Goldschmidt Reviewed-by: Stefan Roese --- drivers/rtc/m41t62.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/m41t62.c b/drivers/rtc/m41t62.c index 2ee7e00b02..6161b76712 100644 --- a/drivers/rtc/m41t62.c +++ b/drivers/rtc/m41t62.c @@ -155,6 +155,15 @@ static int m41t62_rtc_reset(struct udevice *dev) return ret; } +/* + * Make sure HT bit is cleared. This bit is set on entering battery backup + * mode, so do this before the first read access. + */ +static int m41t62_rtc_probe(struct udevice *dev) +{ + return m41t62_rtc_reset(dev); +} + static const struct rtc_ops m41t62_rtc_ops = { .get = m41t62_rtc_get, .set = m41t62_rtc_set, @@ -163,6 +172,7 @@ static const struct rtc_ops m41t62_rtc_ops = { static const struct udevice_id m41t62_rtc_ids[] = { { .compatible = "st,m41t62" }, + { .compatible = "st,m41t82" }, { .compatible = "microcrystal,rv4162" }, { } }; @@ -172,6 +182,7 @@ U_BOOT_DRIVER(rtc_m41t62) = { .id = UCLASS_RTC, .of_match = m41t62_rtc_ids, .ops = &m41t62_rtc_ops, + .probe = &m41t62_rtc_probe, }; #else /* NON DM RTC code - will be removed */ -- cgit v1.2.3