Blame view

drivers/rtc/nvmem.c 2.31 KB
cdf7545ae   Alexandre Belloni   rtc: convert core...
1
  // SPDX-License-Identifier: GPL-2.0
697e5a47a   Alexandre Belloni   rtc: add generic ...
2
3
4
5
  /*
   * RTC subsystem, nvmem interface
   *
   * Copyright (C) 2017 Alexandre Belloni
697e5a47a   Alexandre Belloni   rtc: add generic ...
6
7
8
9
10
11
   */
  
  #include <linux/err.h>
  #include <linux/types.h>
  #include <linux/nvmem-consumer.h>
  #include <linux/rtc.h>
bba3d2daa   Alexandre Belloni   rtc: nvmem: fix p...
12
  #include <linux/slab.h>
697e5a47a   Alexandre Belloni   rtc: add generic ...
13
  #include <linux/sysfs.h>
697e5a47a   Alexandre Belloni   rtc: add generic ...
14
15
16
17
18
19
20
21
22
23
24
  /*
   * Deprecated ABI compatibility, this should be removed at some point
   */
  
  static const char nvram_warning[] = "Deprecated ABI, please use nvmem";
  
  static ssize_t
  rtc_nvram_read(struct file *filp, struct kobject *kobj,
  	       struct bin_attribute *attr,
  	       char *buf, loff_t off, size_t count)
  {
697e5a47a   Alexandre Belloni   rtc: add generic ...
25
  	dev_warn_once(kobj_to_dev(kobj), nvram_warning);
41c9e132c   Alexandre Belloni   rtc: nvmem: remov...
26
  	return nvmem_device_read(attr->private, off, count, buf);
697e5a47a   Alexandre Belloni   rtc: add generic ...
27
28
29
30
31
32
33
  }
  
  static ssize_t
  rtc_nvram_write(struct file *filp, struct kobject *kobj,
  		struct bin_attribute *attr,
  		char *buf, loff_t off, size_t count)
  {
697e5a47a   Alexandre Belloni   rtc: add generic ...
34
  	dev_warn_once(kobj_to_dev(kobj), nvram_warning);
41c9e132c   Alexandre Belloni   rtc: nvmem: remov...
35
  	return nvmem_device_write(attr->private, off, count, buf);
697e5a47a   Alexandre Belloni   rtc: add generic ...
36
  }
41c9e132c   Alexandre Belloni   rtc: nvmem: remov...
37
38
  static int rtc_nvram_register(struct rtc_device *rtc,
  			      struct nvmem_device *nvmem, size_t size)
697e5a47a   Alexandre Belloni   rtc: add generic ...
39
40
  {
  	int err;
606cc43c7   Alexandre Belloni   rtc: core: correc...
41
  	rtc->nvram = kzalloc(sizeof(*rtc->nvram), GFP_KERNEL);
697e5a47a   Alexandre Belloni   rtc: add generic ...
42
43
44
45
46
  	if (!rtc->nvram)
  		return -ENOMEM;
  
  	rtc->nvram->attr.name = "nvram";
  	rtc->nvram->attr.mode = 0644;
41c9e132c   Alexandre Belloni   rtc: nvmem: remov...
47
  	rtc->nvram->private = nvmem;
697e5a47a   Alexandre Belloni   rtc: add generic ...
48
49
50
51
52
  
  	sysfs_bin_attr_init(rtc->nvram);
  
  	rtc->nvram->read = rtc_nvram_read;
  	rtc->nvram->write = rtc_nvram_write;
4cce9d398   Alexandre Belloni   rtc: nvmem: pass ...
53
  	rtc->nvram->size = size;
697e5a47a   Alexandre Belloni   rtc: add generic ...
54
55
56
57
  
  	err = sysfs_create_bin_file(&rtc->dev.parent->kobj,
  				    rtc->nvram);
  	if (err) {
bba3d2daa   Alexandre Belloni   rtc: nvmem: fix p...
58
  		kfree(rtc->nvram);
697e5a47a   Alexandre Belloni   rtc: add generic ...
59
60
61
62
63
64
65
66
67
  		rtc->nvram = NULL;
  	}
  
  	return err;
  }
  
  static void rtc_nvram_unregister(struct rtc_device *rtc)
  {
  	sysfs_remove_bin_file(&rtc->dev.parent->kobj, rtc->nvram);
bba3d2daa   Alexandre Belloni   rtc: nvmem: fix p...
68
69
  	kfree(rtc->nvram);
  	rtc->nvram = NULL;
697e5a47a   Alexandre Belloni   rtc: add generic ...
70
71
72
73
74
  }
  
  /*
   * New ABI, uses nvmem
   */
2cc821219   Alexandre Belloni   rtc: nvmem: retur...
75
76
  int rtc_nvmem_register(struct rtc_device *rtc,
  		       struct nvmem_config *nvmem_config)
697e5a47a   Alexandre Belloni   rtc: add generic ...
77
  {
41c9e132c   Alexandre Belloni   rtc: nvmem: remov...
78
  	struct nvmem_device *nvmem;
ab3ea36ed   Alexandre Belloni   rtc: nvmem: disal...
79

4cce9d398   Alexandre Belloni   rtc: nvmem: pass ...
80
  	if (!nvmem_config)
2cc821219   Alexandre Belloni   rtc: nvmem: retur...
81
  		return -ENODEV;
697e5a47a   Alexandre Belloni   rtc: add generic ...
82

ac75779b7   Alexandre Belloni   rtc: nvmem: allow...
83
  	nvmem_config->dev = rtc->dev.parent;
4cce9d398   Alexandre Belloni   rtc: nvmem: pass ...
84
  	nvmem_config->owner = rtc->owner;
41c9e132c   Alexandre Belloni   rtc: nvmem: remov...
85
86
87
  	nvmem = devm_nvmem_register(rtc->dev.parent, nvmem_config);
  	if (IS_ERR(nvmem))
  		return PTR_ERR(nvmem);
697e5a47a   Alexandre Belloni   rtc: add generic ...
88
89
90
  
  	/* Register the old ABI */
  	if (rtc->nvram_old_abi)
41c9e132c   Alexandre Belloni   rtc: nvmem: remov...
91
  		rtc_nvram_register(rtc, nvmem, nvmem_config->size);
2cc821219   Alexandre Belloni   rtc: nvmem: retur...
92
93
  
  	return 0;
697e5a47a   Alexandre Belloni   rtc: add generic ...
94
  }
fd5cd21d9   Alexandre Belloni   rtc: export rtc_n...
95
  EXPORT_SYMBOL_GPL(rtc_nvmem_register);
697e5a47a   Alexandre Belloni   rtc: add generic ...
96
97
98
  
  void rtc_nvmem_unregister(struct rtc_device *rtc)
  {
697e5a47a   Alexandre Belloni   rtc: add generic ...
99
100
101
  	/* unregister the old ABI */
  	if (rtc->nvram)
  		rtc_nvram_unregister(rtc);
697e5a47a   Alexandre Belloni   rtc: add generic ...
102
  }