Blame view
drivers/platform/chrome/cros_ec_vbc.c
3.65 KB
27755cf70 platform/chrome: ... |
1 2 3 4 5 |
// SPDX-License-Identifier: GPL-2.0+ // Expose the vboot context nvram to userspace // // Copyright (C) 2012 Google, Inc. // Copyright (C) 2015 Collabora Ltd. |
18800fc7a platform/chrome: ... |
6 7 8 |
#include <linux/of.h> #include <linux/platform_device.h> |
acb9900f9 mfd / platform: c... |
9 |
#include <linux/module.h> |
840d9f131 mfd / platform: c... |
10 11 |
#include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_proto.h> |
18800fc7a platform/chrome: ... |
12 |
#include <linux/slab.h> |
acb9900f9 mfd / platform: c... |
13 |
#define DRV_NAME "cros-ec-vbc" |
18800fc7a platform/chrome: ... |
14 15 16 17 18 |
static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj, struct bin_attribute *att, char *buf, loff_t pos, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); |
79a3d6030 platform/chrome: ... |
19 |
struct cros_ec_dev *ec = to_cros_ec_dev(dev); |
18800fc7a platform/chrome: ... |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
struct cros_ec_device *ecdev = ec->ec_dev; struct ec_params_vbnvcontext *params; struct cros_ec_command *msg; int err; const size_t para_sz = sizeof(params->op); const size_t resp_sz = sizeof(struct ec_response_vbnvcontext); const size_t payload = max(para_sz, resp_sz); msg = kmalloc(sizeof(*msg) + payload, GFP_KERNEL); if (!msg) return -ENOMEM; /* NB: we only kmalloc()ated enough space for the op field */ params = (struct ec_params_vbnvcontext *)msg->data; params->op = EC_VBNV_CONTEXT_OP_READ; msg->version = EC_VER_VBNV_CONTEXT; msg->command = EC_CMD_VBNV_CONTEXT; msg->outsize = para_sz; msg->insize = resp_sz; err = cros_ec_cmd_xfer(ecdev, msg); if (err < 0) { dev_err(dev, "Error sending read request: %d ", err); kfree(msg); return err; } memcpy(buf, msg->data, resp_sz); kfree(msg); return resp_sz; } static ssize_t vboot_context_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); |
79a3d6030 platform/chrome: ... |
60 |
struct cros_ec_dev *ec = to_cros_ec_dev(dev); |
18800fc7a platform/chrome: ... |
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
struct cros_ec_device *ecdev = ec->ec_dev; struct ec_params_vbnvcontext *params; struct cros_ec_command *msg; int err; const size_t para_sz = sizeof(*params); const size_t data_sz = sizeof(params->block); /* Only write full values */ if (count != data_sz) return -EINVAL; msg = kmalloc(sizeof(*msg) + para_sz, GFP_KERNEL); if (!msg) return -ENOMEM; params = (struct ec_params_vbnvcontext *)msg->data; params->op = EC_VBNV_CONTEXT_OP_WRITE; memcpy(params->block, buf, data_sz); msg->version = EC_VER_VBNV_CONTEXT; msg->command = EC_CMD_VBNV_CONTEXT; msg->outsize = para_sz; msg->insize = 0; err = cros_ec_cmd_xfer(ecdev, msg); if (err < 0) { dev_err(dev, "Error sending write request: %d ", err); kfree(msg); return err; } kfree(msg); return data_sz; } |
18800fc7a platform/chrome: ... |
96 97 98 99 100 101 |
static BIN_ATTR_RW(vboot_context, 16); static struct bin_attribute *cros_ec_vbc_bin_attrs[] = { &bin_attr_vboot_context, NULL }; |
81bc8c03e platform/chrome: ... |
102 |
static struct attribute_group cros_ec_vbc_attr_group = { |
18800fc7a platform/chrome: ... |
103 104 |
.name = "vbc", .bin_attrs = cros_ec_vbc_bin_attrs, |
18800fc7a platform/chrome: ... |
105 |
}; |
acb9900f9 mfd / platform: c... |
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
static int cros_ec_vbc_probe(struct platform_device *pd) { struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); struct device *dev = &pd->dev; int ret; ret = sysfs_create_group(&ec_dev->class_dev.kobj, &cros_ec_vbc_attr_group); if (ret < 0) dev_err(dev, "failed to create %s attributes. err=%d ", cros_ec_vbc_attr_group.name, ret); return ret; } static int cros_ec_vbc_remove(struct platform_device *pd) { struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); sysfs_remove_group(&ec_dev->class_dev.kobj, &cros_ec_vbc_attr_group); return 0; } static struct platform_driver cros_ec_vbc_driver = { .driver = { .name = DRV_NAME, }, .probe = cros_ec_vbc_probe, .remove = cros_ec_vbc_remove, }; module_platform_driver(cros_ec_vbc_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Expose the vboot context nvram to userspace"); MODULE_ALIAS("platform:" DRV_NAME); |