1 // SPDX-License-Identifier: GPL-2.0-only
5 * Driver for exporting cbmem entries in sysfs.
7 * Copyright 2022 Google LLC
10 #include <linux/device.h>
11 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/kobject.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
18 #include <linux/sysfs.h>
20 #include "coreboot_table.h"
27 static struct cbmem_entry
*to_cbmem_entry(struct kobject
*kobj
)
29 return dev_get_drvdata(kobj_to_dev(kobj
));
32 static ssize_t
mem_read(struct file
*filp
, struct kobject
*kobj
,
33 struct bin_attribute
*bin_attr
, char *buf
, loff_t pos
,
36 struct cbmem_entry
*entry
= to_cbmem_entry(kobj
);
38 return memory_read_from_buffer(buf
, count
, &pos
, entry
->mem_file_buf
,
42 static ssize_t
mem_write(struct file
*filp
, struct kobject
*kobj
,
43 struct bin_attribute
*bin_attr
, char *buf
, loff_t pos
,
46 struct cbmem_entry
*entry
= to_cbmem_entry(kobj
);
48 if (pos
< 0 || pos
>= entry
->size
)
50 if (count
> entry
->size
- pos
)
51 count
= entry
->size
- pos
;
53 memcpy(entry
->mem_file_buf
+ pos
, buf
, count
);
56 static BIN_ATTR_ADMIN_RW(mem
, 0);
58 static ssize_t
address_show(struct device
*dev
, struct device_attribute
*attr
,
61 struct coreboot_device
*cbdev
= dev_to_coreboot_device(dev
);
63 return sysfs_emit(buf
, "0x%llx\n", cbdev
->cbmem_entry
.address
);
65 static DEVICE_ATTR_RO(address
);
67 static ssize_t
size_show(struct device
*dev
, struct device_attribute
*attr
,
70 struct coreboot_device
*cbdev
= dev_to_coreboot_device(dev
);
72 return sysfs_emit(buf
, "0x%x\n", cbdev
->cbmem_entry
.entry_size
);
74 static DEVICE_ATTR_RO(size
);
76 static struct attribute
*attrs
[] = {
77 &dev_attr_address
.attr
,
82 static struct bin_attribute
*bin_attrs
[] = {
87 static const struct attribute_group cbmem_entry_group
= {
89 .bin_attrs
= bin_attrs
,
92 static const struct attribute_group
*dev_groups
[] = {
97 static int cbmem_entry_probe(struct coreboot_device
*dev
)
99 struct cbmem_entry
*entry
;
101 entry
= devm_kzalloc(&dev
->dev
, sizeof(*entry
), GFP_KERNEL
);
105 dev_set_drvdata(&dev
->dev
, entry
);
106 entry
->mem_file_buf
= devm_memremap(&dev
->dev
, dev
->cbmem_entry
.address
,
107 dev
->cbmem_entry
.entry_size
,
109 if (IS_ERR(entry
->mem_file_buf
))
110 return PTR_ERR(entry
->mem_file_buf
);
112 entry
->size
= dev
->cbmem_entry
.entry_size
;
117 static const struct coreboot_device_id cbmem_ids
[] = {
118 { .tag
= LB_TAG_CBMEM_ENTRY
},
121 MODULE_DEVICE_TABLE(coreboot
, cbmem_ids
);
123 static struct coreboot_driver cbmem_entry_driver
= {
124 .probe
= cbmem_entry_probe
,
127 .dev_groups
= dev_groups
,
129 .id_table
= cbmem_ids
,
131 module_coreboot_driver(cbmem_entry_driver
);
133 MODULE_AUTHOR("Jack Rosenthal <jrosenth@chromium.org>");
134 MODULE_DESCRIPTION("Driver for exporting CBMEM entries in sysfs");
135 MODULE_LICENSE("GPL");