diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-02-12 17:47:40 -0500 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-03-01 04:49:26 -0500 |
commit | 0ff3565d88cde06c4ce20c55e7ce23050e1d6a0d (patch) | |
tree | 44c2b7d9907aede924fbb2871abb041221582017 | |
parent | affb842b84a27d12ab7fd0a86cefda0a343f0941 (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.c | 56 |
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 | ||
337 | static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, | 337 | static 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 | ||
358 | static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, | 358 | static 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 | ||
379 | static 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 | |||
388 | static int m48t59_rtc_probe(struct platform_device *pdev) | 379 | static 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 | ||
502 | static 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 */ |
509 | MODULE_ALIAS("platform:rtc-m48t59"); | 502 | MODULE_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 | ||
519 | module_platform_driver(m48t59_rtc_driver); | 511 | module_platform_driver(m48t59_rtc_driver); |