summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@bootlin.com>2018-02-12 17:47:40 -0500
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2018-03-01 04:49:26 -0500
commit0ff3565d88cde06c4ce20c55e7ce23050e1d6a0d (patch)
tree44c2b7d9907aede924fbb2871abb041221582017
parentaffb842b84a27d12ab7fd0a86cefda0a343f0941 (diff)
rtc: m48t59: use generic nvmem
Instead of adding a binary sysfs attribute from the driver (which suffers from a race condition as the attribute appears after the device), use the core to register an nvmem device. Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r--drivers/rtc/rtc-m48t59.c56
1 files changed, 24 insertions, 32 deletions
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index e248e56ff8a1..d2ba7d76dbb9 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -334,16 +334,16 @@ static const struct rtc_class_ops m48t02_rtc_ops = {
334 .set_time = m48t59_rtc_set_time, 334 .set_time = m48t59_rtc_set_time,
335}; 335};
336 336
337static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, 337static int m48t59_nvram_read(void *priv, unsigned int offset, void *val,
338 struct bin_attribute *bin_attr, 338 size_t size)
339 char *buf, loff_t pos, size_t size)
340{ 339{
341 struct device *dev = container_of(kobj, struct device, kobj); 340 struct platform_device *pdev = priv;
342 struct platform_device *pdev = to_platform_device(dev); 341 struct device *dev = &pdev->dev;
343 struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); 342 struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
344 struct m48t59_private *m48t59 = platform_get_drvdata(pdev); 343 struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
345 ssize_t cnt = 0; 344 ssize_t cnt = 0;
346 unsigned long flags; 345 unsigned long flags;
346 u8 *buf = val;
347 347
348 spin_lock_irqsave(&m48t59->lock, flags); 348 spin_lock_irqsave(&m48t59->lock, flags);
349 349
@@ -352,19 +352,19 @@ static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj,
352 352
353 spin_unlock_irqrestore(&m48t59->lock, flags); 353 spin_unlock_irqrestore(&m48t59->lock, flags);
354 354
355 return cnt; 355 return 0;
356} 356}
357 357
358static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, 358static int m48t59_nvram_write(void *priv, unsigned int offset, void *val,
359 struct bin_attribute *bin_attr, 359 size_t size)
360 char *buf, loff_t pos, size_t size)
361{ 360{
362 struct device *dev = container_of(kobj, struct device, kobj); 361 struct platform_device *pdev = priv;
363 struct platform_device *pdev = to_platform_device(dev); 362 struct device *dev = &pdev->dev;
364 struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); 363 struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
365 struct m48t59_private *m48t59 = platform_get_drvdata(pdev); 364 struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
366 ssize_t cnt = 0; 365 ssize_t cnt = 0;
367 unsigned long flags; 366 unsigned long flags;
367 u8 *buf = val;
368 368
369 spin_lock_irqsave(&m48t59->lock, flags); 369 spin_lock_irqsave(&m48t59->lock, flags);
370 370
@@ -373,18 +373,9 @@ static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj,
373 373
374 spin_unlock_irqrestore(&m48t59->lock, flags); 374 spin_unlock_irqrestore(&m48t59->lock, flags);
375 375
376 return cnt; 376 return 0;
377} 377}
378 378
379static struct bin_attribute m48t59_nvram_attr = {
380 .attr = {
381 .name = "nvram",
382 .mode = S_IRUGO | S_IWUSR,
383 },
384 .read = m48t59_nvram_read,
385 .write = m48t59_nvram_write,
386};
387
388static int m48t59_rtc_probe(struct platform_device *pdev) 379static int m48t59_rtc_probe(struct platform_device *pdev)
389{ 380{
390 struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); 381 struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
@@ -393,6 +384,14 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
393 int ret = -ENOMEM; 384 int ret = -ENOMEM;
394 char *name; 385 char *name;
395 const struct rtc_class_ops *ops; 386 const struct rtc_class_ops *ops;
387 struct nvmem_config nvmem_cfg = {
388 .name = "m48t59-",
389 .word_size = 1,
390 .stride = 1,
391 .reg_read = m48t59_nvram_read,
392 .reg_write = m48t59_nvram_write,
393 .priv = pdev,
394 };
396 395
397 /* This chip could be memory-mapped or I/O-mapped */ 396 /* This chip could be memory-mapped or I/O-mapped */
398 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 397 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -484,27 +483,21 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
484 if (IS_ERR(m48t59->rtc)) 483 if (IS_ERR(m48t59->rtc))
485 return PTR_ERR(m48t59->rtc); 484 return PTR_ERR(m48t59->rtc);
486 485
486 m48t59->rtc->nvram_old_abi = true;
487 m48t59->rtc->ops = ops; 487 m48t59->rtc->ops = ops;
488 488
489 ret = rtc_register_device(m48t59->rtc); 489 nvmem_cfg.size = pdata->offset;
490 ret = rtc_nvmem_register(m48t59->rtc, &nvmem_cfg);
490 if (ret) 491 if (ret)
491 return ret; 492 return ret;
492 493
493 m48t59_nvram_attr.size = pdata->offset; 494 ret = rtc_register_device(m48t59->rtc);
494
495 ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
496 if (ret) 495 if (ret)
497 return ret; 496 return ret;
498 497
499 return 0; 498 return 0;
500} 499}
501 500
502static int m48t59_rtc_remove(struct platform_device *pdev)
503{
504 sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
505 return 0;
506}
507
508/* work with hotplug and coldplug */ 501/* work with hotplug and coldplug */
509MODULE_ALIAS("platform:rtc-m48t59"); 502MODULE_ALIAS("platform:rtc-m48t59");
510 503
@@ -513,7 +506,6 @@ static struct platform_driver m48t59_rtc_driver = {
513 .name = "rtc-m48t59", 506 .name = "rtc-m48t59",
514 }, 507 },
515 .probe = m48t59_rtc_probe, 508 .probe = m48t59_rtc_probe,
516 .remove = m48t59_rtc_remove,
517}; 509};
518 510
519module_platform_driver(m48t59_rtc_driver); 511module_platform_driver(m48t59_rtc_driver);