summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@bootlin.com>2018-09-15 07:29:56 -0400
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2018-09-28 08:14:38 -0400
commit1b4c794fda583edabe864ac466e9cd43c707be80 (patch)
treec3c6ae9359c4d245d3b70c84d34bcb25eecbe0d2
parentf1c8bc332e6dacac221d0d6304f4a3e99b756e2f (diff)
rtc: isl1208: avoid possible sysfs race
Use rtc_add_group to add the common sysfs group to avoid a possible race condition. [Denis.Osterland@diehl.com: use to_i2c_client(dev->parent)] Signed-off-by: Denis Osterland <Denis.Osterland@diehl.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> The move of atrim, dtrim usr sysfs properties from i2c device to rtc device require to access them via dev->parent. This patch also aligns timestamp0.
-rw-r--r--drivers/rtc/rtc-isl1208.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index ea18a8f4bce0..033f65aef578 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -518,7 +518,7 @@ static ssize_t timestamp0_store(struct device *dev,
518 struct device_attribute *attr, 518 struct device_attribute *attr,
519 const char *buf, size_t count) 519 const char *buf, size_t count)
520{ 520{
521 struct i2c_client *client = dev_get_drvdata(dev); 521 struct i2c_client *client = to_i2c_client(dev->parent);
522 int sr; 522 int sr;
523 523
524 sr = isl1208_i2c_get_sr(client); 524 sr = isl1208_i2c_get_sr(client);
@@ -540,7 +540,7 @@ static ssize_t timestamp0_store(struct device *dev,
540static ssize_t timestamp0_show(struct device *dev, 540static ssize_t timestamp0_show(struct device *dev,
541 struct device_attribute *attr, char *buf) 541 struct device_attribute *attr, char *buf)
542{ 542{
543 struct i2c_client *client = dev_get_drvdata(dev); 543 struct i2c_client *client = to_i2c_client(dev->parent);
544 u8 regs[ISL1219_EVT_SECTION_LEN] = { 0, }; 544 u8 regs[ISL1219_EVT_SECTION_LEN] = { 0, };
545 struct rtc_time tm; 545 struct rtc_time tm;
546 int sr; 546 int sr;
@@ -650,7 +650,7 @@ static ssize_t
650isl1208_sysfs_show_atrim(struct device *dev, 650isl1208_sysfs_show_atrim(struct device *dev,
651 struct device_attribute *attr, char *buf) 651 struct device_attribute *attr, char *buf)
652{ 652{
653 int atr = isl1208_i2c_get_atr(to_i2c_client(dev)); 653 int atr = isl1208_i2c_get_atr(to_i2c_client(dev->parent));
654 if (atr < 0) 654 if (atr < 0)
655 return atr; 655 return atr;
656 656
@@ -663,7 +663,7 @@ static ssize_t
663isl1208_sysfs_show_dtrim(struct device *dev, 663isl1208_sysfs_show_dtrim(struct device *dev,
664 struct device_attribute *attr, char *buf) 664 struct device_attribute *attr, char *buf)
665{ 665{
666 int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev)); 666 int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev->parent));
667 if (dtr < 0) 667 if (dtr < 0)
668 return dtr; 668 return dtr;
669 669
@@ -676,7 +676,7 @@ static ssize_t
676isl1208_sysfs_show_usr(struct device *dev, 676isl1208_sysfs_show_usr(struct device *dev,
677 struct device_attribute *attr, char *buf) 677 struct device_attribute *attr, char *buf)
678{ 678{
679 int usr = isl1208_i2c_get_usr(to_i2c_client(dev)); 679 int usr = isl1208_i2c_get_usr(to_i2c_client(dev->parent));
680 if (usr < 0) 680 if (usr < 0)
681 return usr; 681 return usr;
682 682
@@ -701,7 +701,10 @@ isl1208_sysfs_store_usr(struct device *dev,
701 if (usr < 0 || usr > 0xffff) 701 if (usr < 0 || usr > 0xffff)
702 return -EINVAL; 702 return -EINVAL;
703 703
704 return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count; 704 if (isl1208_i2c_set_usr(to_i2c_client(dev->parent), usr))
705 return -EIO;
706
707 return count;
705} 708}
706 709
707static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, 710static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
@@ -765,7 +768,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
765 rtc->ops = &isl1208_rtc_ops; 768 rtc->ops = &isl1208_rtc_ops;
766 769
767 i2c_set_clientdata(client, rtc); 770 i2c_set_clientdata(client, rtc);
768 dev_set_drvdata(&rtc->dev, client);
769 771
770 rc = isl1208_i2c_get_sr(client); 772 rc = isl1208_i2c_get_sr(client);
771 if (rc < 0) { 773 if (rc < 0) {
@@ -804,7 +806,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
804 evdet_irq = of_irq_get_byname(np, "evdet"); 806 evdet_irq = of_irq_get_byname(np, "evdet");
805 } 807 }
806 808
807 rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); 809 rc = rtc_add_group(rtc, &isl1208_rtc_sysfs_files);
808 if (rc) 810 if (rc)
809 return rc; 811 return rc;
810 812
@@ -821,14 +823,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
821 return rtc_register_device(rtc); 823 return rtc_register_device(rtc);
822} 824}
823 825
824static int
825isl1208_remove(struct i2c_client *client)
826{
827 sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files);
828
829 return 0;
830}
831
832static const struct i2c_device_id isl1208_id[] = { 826static const struct i2c_device_id isl1208_id[] = {
833 { "isl1208", TYPE_ISL1208 }, 827 { "isl1208", TYPE_ISL1208 },
834 { "isl1218", TYPE_ISL1218 }, 828 { "isl1218", TYPE_ISL1218 },
@@ -851,7 +845,6 @@ static struct i2c_driver isl1208_driver = {
851 .of_match_table = of_match_ptr(isl1208_of_match), 845 .of_match_table = of_match_ptr(isl1208_of_match),
852 }, 846 },
853 .probe = isl1208_probe, 847 .probe = isl1208_probe,
854 .remove = isl1208_remove,
855 .id_table = isl1208_id, 848 .id_table = isl1208_id,
856}; 849};
857 850