Skip to content

Commit

Permalink
mfd/rtc: s5m: fix register updating by adding regmap for RTC
Browse files Browse the repository at this point in the history
Rename old regmap field of "struct sec_pmic_dev" to "regmap_pmic" and
add new regmap for RTC.

On S5M8767A registers were not properly updated and read due to usage of
the same regmap as the PMIC.  This could be observed in various hangs,
e.g.  in infinite loop during waiting for UDR field change.

On this chip family the RTC has different I2C address than PMIC so
additional regmap is needed.

Signed-off-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
Reviewed-by: Mark Brown <[email protected]>
Acked-by: Sangbeom Kim <[email protected]>
Cc: Samuel Ortiz <[email protected]>
Cc: Lee Jones <[email protected]>
Cc: Liam Girdwood <[email protected]>
Cc: Alessandro Zummo <[email protected]>
Cc: Marek Szyprowski <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Kyungmin Park <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
krzk authored and torvalds committed Dec 13, 2013
1 parent 222ead7 commit 3e1e4a5
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 14 deletions.
30 changes: 22 additions & 8 deletions drivers/mfd/sec-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,31 +81,31 @@ static struct of_device_id sec_dt_match[] = {

int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest)
{
return regmap_read(sec_pmic->regmap, reg, dest);
return regmap_read(sec_pmic->regmap_pmic, reg, dest);
}
EXPORT_SYMBOL_GPL(sec_reg_read);

int sec_bulk_read(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
{
return regmap_bulk_read(sec_pmic->regmap, reg, buf, count);
return regmap_bulk_read(sec_pmic->regmap_pmic, reg, buf, count);
}
EXPORT_SYMBOL_GPL(sec_bulk_read);

int sec_reg_write(struct sec_pmic_dev *sec_pmic, u8 reg, u8 value)
{
return regmap_write(sec_pmic->regmap, reg, value);
return regmap_write(sec_pmic->regmap_pmic, reg, value);
}
EXPORT_SYMBOL_GPL(sec_reg_write);

int sec_bulk_write(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
{
return regmap_raw_write(sec_pmic->regmap, reg, buf, count);
return regmap_raw_write(sec_pmic->regmap_pmic, reg, buf, count);
}
EXPORT_SYMBOL_GPL(sec_bulk_write);

int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask)
{
return regmap_update_bits(sec_pmic->regmap, reg, mask, val);
return regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, val);
}
EXPORT_SYMBOL_GPL(sec_reg_update);

Expand Down Expand Up @@ -166,6 +166,11 @@ static struct regmap_config s5m8767_regmap_config = {
.cache_type = REGCACHE_FLAT,
};

static const struct regmap_config sec_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};

#ifdef CONFIG_OF
/*
* Only the common platform data elements for s5m8767 are parsed here from the
Expand Down Expand Up @@ -266,9 +271,9 @@ static int sec_pmic_probe(struct i2c_client *i2c,
break;
}

sec_pmic->regmap = devm_regmap_init_i2c(i2c, regmap);
if (IS_ERR(sec_pmic->regmap)) {
ret = PTR_ERR(sec_pmic->regmap);
sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
if (IS_ERR(sec_pmic->regmap_pmic)) {
ret = PTR_ERR(sec_pmic->regmap_pmic);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
Expand All @@ -277,6 +282,15 @@ static int sec_pmic_probe(struct i2c_client *i2c,
sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
i2c_set_clientdata(sec_pmic->rtc, sec_pmic);

sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc,
&sec_rtc_regmap_config);
if (IS_ERR(sec_pmic->regmap_rtc)) {
ret = PTR_ERR(sec_pmic->regmap_rtc);
dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
ret);
return ret;
}

if (pdata && pdata->cfg_pmic_irq)
pdata->cfg_pmic_irq();

Expand Down
6 changes: 3 additions & 3 deletions drivers/mfd/sec-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,19 +280,19 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)

switch (type) {
case S5M8763X:
ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
sec_pmic->irq_base, &s5m8763_irq_chip,
&sec_pmic->irq_data);
break;
case S5M8767X:
ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
sec_pmic->irq_base, &s5m8767_irq_chip,
&sec_pmic->irq_data);
break;
case S2MPS11X:
ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
sec_pmic->irq_base, &s2mps11_irq_chip,
&sec_pmic->irq_data);
Expand Down
2 changes: 1 addition & 1 deletion drivers/regulator/s5m8767.c
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
config.dev = s5m8767->dev;
config.init_data = pdata->regulators[i].initdata;
config.driver_data = s5m8767;
config.regmap = iodev->regmap;
config.regmap = iodev->regmap_pmic;
config.of_node = pdata->regulators[i].reg_node;

rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id],
Expand Down
2 changes: 1 addition & 1 deletion drivers/rtc/rtc-s5m.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)

info->dev = &pdev->dev;
info->s5m87xx = s5m87xx;
info->regmap = s5m87xx->regmap;
info->regmap = s5m87xx->regmap_rtc;
info->device_type = s5m87xx->device_type;
info->wtsr_smpl = s5m87xx->wtsr_smpl;

Expand Down
3 changes: 2 additions & 1 deletion include/linux/mfd/samsung/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ enum sec_device_type {
struct sec_pmic_dev {
struct device *dev;
struct sec_platform_data *pdata;
struct regmap *regmap;
struct regmap *regmap_pmic;
struct regmap *regmap_rtc;
struct i2c_client *i2c;
struct i2c_client *rtc;

Expand Down

0 comments on commit 3e1e4a5

Please sign in to comment.