aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>2014-04-14 03:40:45 -0400
committerLee Jones <lee.jones@linaro.org>2014-06-03 03:11:16 -0400
commite349c910e2398cbff59d7c58851503191a8e9157 (patch)
tree0d54685f5ea382b6b99e6a7d9e2d536e2b6d06db /drivers/rtc
parenta865a589144da6dbf26750b7193a9748da159305 (diff)
mfd/rtc: s5m: Do not allocate RTC I2C dummy and regmap for unsupported chipsets
The rtc-s5m driver does not support all of S2M and S5M chipsets supported by main MFD sec-core driver. For such chipsets unsupported by rtc-s5m, the MFD sec-core driver initialized regmap with default config. This config in such cases wouldn't work at all. The main MFD sec-core driver shouldn't initialize regmap for child drivers which is not used by them and even not valid. Move the allocation of RTC I2C dummy device and initialization of RTC regmap from main MFD sec-core driver to the rtc-s5m driver. The rtc-s5m driver will use proper regmap config for supported devices. Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-s5m.c75
1 files changed, 70 insertions, 5 deletions
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index 476af93543f6..8ec2d6a1dbe1 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -40,6 +40,7 @@
40 40
41struct s5m_rtc_info { 41struct s5m_rtc_info {
42 struct device *dev; 42 struct device *dev;
43 struct i2c_client *i2c;
43 struct sec_pmic_dev *s5m87xx; 44 struct sec_pmic_dev *s5m87xx;
44 struct regmap *regmap; 45 struct regmap *regmap;
45 struct rtc_device *rtc_dev; 46 struct rtc_device *rtc_dev;
@@ -49,6 +50,20 @@ struct s5m_rtc_info {
49 bool wtsr_smpl; 50 bool wtsr_smpl;
50}; 51};
51 52
53static const struct regmap_config s5m_rtc_regmap_config = {
54 .reg_bits = 8,
55 .val_bits = 8,
56
57 .max_register = SEC_RTC_REG_MAX,
58};
59
60static const struct regmap_config s2mps14_rtc_regmap_config = {
61 .reg_bits = 8,
62 .val_bits = 8,
63
64 .max_register = S2MPS_RTC_REG_MAX,
65};
66
52static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm, 67static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm,
53 int rtc_24hr_mode) 68 int rtc_24hr_mode)
54{ 69{
@@ -554,6 +569,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
554 struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent); 569 struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
555 struct sec_platform_data *pdata = s5m87xx->pdata; 570 struct sec_platform_data *pdata = s5m87xx->pdata;
556 struct s5m_rtc_info *info; 571 struct s5m_rtc_info *info;
572 const struct regmap_config *regmap_cfg;
557 int ret; 573 int ret;
558 574
559 if (!pdata) { 575 if (!pdata) {
@@ -565,9 +581,37 @@ static int s5m_rtc_probe(struct platform_device *pdev)
565 if (!info) 581 if (!info)
566 return -ENOMEM; 582 return -ENOMEM;
567 583
584 switch (pdata->device_type) {
585 case S2MPS14X:
586 regmap_cfg = &s2mps14_rtc_regmap_config;
587 break;
588 case S5M8763X:
589 regmap_cfg = &s5m_rtc_regmap_config;
590 break;
591 case S5M8767X:
592 regmap_cfg = &s5m_rtc_regmap_config;
593 break;
594 default:
595 dev_err(&pdev->dev, "Device type is not supported by RTC driver\n");
596 return -ENODEV;
597 }
598
599 info->i2c = i2c_new_dummy(s5m87xx->i2c->adapter, RTC_I2C_ADDR);
600 if (!info->i2c) {
601 dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
602 return -ENODEV;
603 }
604
605 info->regmap = devm_regmap_init_i2c(info->i2c, regmap_cfg);
606 if (IS_ERR(info->regmap)) {
607 ret = PTR_ERR(info->regmap);
608 dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n",
609 ret);
610 goto err;
611 }
612
568 info->dev = &pdev->dev; 613 info->dev = &pdev->dev;
569 info->s5m87xx = s5m87xx; 614 info->s5m87xx = s5m87xx;
570 info->regmap = s5m87xx->regmap_rtc;
571 info->device_type = s5m87xx->device_type; 615 info->device_type = s5m87xx->device_type;
572 info->wtsr_smpl = s5m87xx->wtsr_smpl; 616 info->wtsr_smpl = s5m87xx->wtsr_smpl;
573 617
@@ -585,7 +629,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
585 default: 629 default:
586 ret = -EINVAL; 630 ret = -EINVAL;
587 dev_err(&pdev->dev, "Unsupported device type: %d\n", ret); 631 dev_err(&pdev->dev, "Unsupported device type: %d\n", ret);
588 return ret; 632 goto err;
589 } 633 }
590 634
591 platform_set_drvdata(pdev, info); 635 platform_set_drvdata(pdev, info);
@@ -602,15 +646,24 @@ static int s5m_rtc_probe(struct platform_device *pdev)
602 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc", 646 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
603 &s5m_rtc_ops, THIS_MODULE); 647 &s5m_rtc_ops, THIS_MODULE);
604 648
605 if (IS_ERR(info->rtc_dev)) 649 if (IS_ERR(info->rtc_dev)) {
606 return PTR_ERR(info->rtc_dev); 650 ret = PTR_ERR(info->rtc_dev);
651 goto err;
652 }
607 653
608 ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, 654 ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
609 s5m_rtc_alarm_irq, 0, "rtc-alarm0", 655 s5m_rtc_alarm_irq, 0, "rtc-alarm0",
610 info); 656 info);
611 if (ret < 0) 657 if (ret < 0) {
612 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", 658 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
613 info->irq, ret); 659 info->irq, ret);
660 goto err;
661 }
662
663 return 0;
664
665err:
666 i2c_unregister_device(info->i2c);
614 667
615 return ret; 668 return ret;
616} 669}
@@ -639,6 +692,17 @@ static void s5m_rtc_shutdown(struct platform_device *pdev)
639 s5m_rtc_enable_smpl(info, false); 692 s5m_rtc_enable_smpl(info, false);
640} 693}
641 694
695static int s5m_rtc_remove(struct platform_device *pdev)
696{
697 struct s5m_rtc_info *info = platform_get_drvdata(pdev);
698
699 /* Perform also all shutdown steps when removing */
700 s5m_rtc_shutdown(pdev);
701 i2c_unregister_device(info->i2c);
702
703 return 0;
704}
705
642#ifdef CONFIG_PM_SLEEP 706#ifdef CONFIG_PM_SLEEP
643static int s5m_rtc_resume(struct device *dev) 707static int s5m_rtc_resume(struct device *dev)
644{ 708{
@@ -676,6 +740,7 @@ static struct platform_driver s5m_rtc_driver = {
676 .pm = &s5m_rtc_pm_ops, 740 .pm = &s5m_rtc_pm_ops,
677 }, 741 },
678 .probe = s5m_rtc_probe, 742 .probe = s5m_rtc_probe,
743 .remove = s5m_rtc_remove,
679 .shutdown = s5m_rtc_shutdown, 744 .shutdown = s5m_rtc_shutdown,
680 .id_table = s5m_rtc_id, 745 .id_table = s5m_rtc_id,
681}; 746};