2 * cros_ec_vbc - Expose the vboot context nvram to userspace
4 * Copyright (C) 2015 Collabora Ltd.
6 * based on vendor driver,
8 * Copyright (C) 2012 The Chromium OS Authors
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
22 #include <linux/platform_device.h>
23 #include <linux/mfd/cros_ec.h>
24 #include <linux/mfd/cros_ec_commands.h>
25 #include <linux/slab.h>
27 static ssize_t
vboot_context_read(struct file
*filp
, struct kobject
*kobj
,
28 struct bin_attribute
*att
, char *buf
,
29 loff_t pos
, size_t count
)
31 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
32 struct cros_ec_dev
*ec
= to_cros_ec_dev(dev
);
33 struct cros_ec_device
*ecdev
= ec
->ec_dev
;
34 struct ec_params_vbnvcontext
*params
;
35 struct cros_ec_command
*msg
;
37 const size_t para_sz
= sizeof(params
->op
);
38 const size_t resp_sz
= sizeof(struct ec_response_vbnvcontext
);
39 const size_t payload
= max(para_sz
, resp_sz
);
41 msg
= kmalloc(sizeof(*msg
) + payload
, GFP_KERNEL
);
45 /* NB: we only kmalloc()ated enough space for the op field */
46 params
= (struct ec_params_vbnvcontext
*)msg
->data
;
47 params
->op
= EC_VBNV_CONTEXT_OP_READ
;
49 msg
->version
= EC_VER_VBNV_CONTEXT
;
50 msg
->command
= EC_CMD_VBNV_CONTEXT
;
51 msg
->outsize
= para_sz
;
52 msg
->insize
= resp_sz
;
54 err
= cros_ec_cmd_xfer(ecdev
, msg
);
56 dev_err(dev
, "Error sending read request: %d\n", err
);
61 memcpy(buf
, msg
->data
, resp_sz
);
67 static ssize_t
vboot_context_write(struct file
*filp
, struct kobject
*kobj
,
68 struct bin_attribute
*attr
, char *buf
,
69 loff_t pos
, size_t count
)
71 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
72 struct cros_ec_dev
*ec
= to_cros_ec_dev(dev
);
73 struct cros_ec_device
*ecdev
= ec
->ec_dev
;
74 struct ec_params_vbnvcontext
*params
;
75 struct cros_ec_command
*msg
;
77 const size_t para_sz
= sizeof(*params
);
78 const size_t data_sz
= sizeof(params
->block
);
80 /* Only write full values */
84 msg
= kmalloc(sizeof(*msg
) + para_sz
, GFP_KERNEL
);
88 params
= (struct ec_params_vbnvcontext
*)msg
->data
;
89 params
->op
= EC_VBNV_CONTEXT_OP_WRITE
;
90 memcpy(params
->block
, buf
, data_sz
);
92 msg
->version
= EC_VER_VBNV_CONTEXT
;
93 msg
->command
= EC_CMD_VBNV_CONTEXT
;
94 msg
->outsize
= para_sz
;
97 err
= cros_ec_cmd_xfer(ecdev
, msg
);
99 dev_err(dev
, "Error sending write request: %d\n", err
);
108 static umode_t
cros_ec_vbc_is_visible(struct kobject
*kobj
,
109 struct bin_attribute
*a
, int n
)
111 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
112 struct cros_ec_dev
*ec
= to_cros_ec_dev(dev
);
113 struct device_node
*np
= ec
->ec_dev
->dev
->of_node
;
115 if (IS_ENABLED(CONFIG_OF
) && np
) {
116 if (of_property_read_bool(np
, "google,has-vbc-nvram"))
123 static BIN_ATTR_RW(vboot_context
, 16);
125 static struct bin_attribute
*cros_ec_vbc_bin_attrs
[] = {
126 &bin_attr_vboot_context
,
130 struct attribute_group cros_ec_vbc_attr_group
= {
132 .bin_attrs
= cros_ec_vbc_bin_attrs
,
133 .is_bin_visible
= cros_ec_vbc_is_visible
,
135 EXPORT_SYMBOL(cros_ec_vbc_attr_group
);