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
= container_of(dev
, struct cros_ec_dev
,
34 struct cros_ec_device
*ecdev
= ec
->ec_dev
;
35 struct ec_params_vbnvcontext
*params
;
36 struct cros_ec_command
*msg
;
38 const size_t para_sz
= sizeof(params
->op
);
39 const size_t resp_sz
= sizeof(struct ec_response_vbnvcontext
);
40 const size_t payload
= max(para_sz
, resp_sz
);
42 msg
= kmalloc(sizeof(*msg
) + payload
, GFP_KERNEL
);
46 /* NB: we only kmalloc()ated enough space for the op field */
47 params
= (struct ec_params_vbnvcontext
*)msg
->data
;
48 params
->op
= EC_VBNV_CONTEXT_OP_READ
;
50 msg
->version
= EC_VER_VBNV_CONTEXT
;
51 msg
->command
= EC_CMD_VBNV_CONTEXT
;
52 msg
->outsize
= para_sz
;
53 msg
->insize
= resp_sz
;
55 err
= cros_ec_cmd_xfer(ecdev
, msg
);
57 dev_err(dev
, "Error sending read request: %d\n", err
);
62 memcpy(buf
, msg
->data
, resp_sz
);
68 static ssize_t
vboot_context_write(struct file
*filp
, struct kobject
*kobj
,
69 struct bin_attribute
*attr
, char *buf
,
70 loff_t pos
, size_t count
)
72 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
73 struct cros_ec_dev
*ec
= container_of(dev
, struct cros_ec_dev
,
75 struct cros_ec_device
*ecdev
= ec
->ec_dev
;
76 struct ec_params_vbnvcontext
*params
;
77 struct cros_ec_command
*msg
;
79 const size_t para_sz
= sizeof(*params
);
80 const size_t data_sz
= sizeof(params
->block
);
82 /* Only write full values */
86 msg
= kmalloc(sizeof(*msg
) + para_sz
, GFP_KERNEL
);
90 params
= (struct ec_params_vbnvcontext
*)msg
->data
;
91 params
->op
= EC_VBNV_CONTEXT_OP_WRITE
;
92 memcpy(params
->block
, buf
, data_sz
);
94 msg
->version
= EC_VER_VBNV_CONTEXT
;
95 msg
->command
= EC_CMD_VBNV_CONTEXT
;
96 msg
->outsize
= para_sz
;
99 err
= cros_ec_cmd_xfer(ecdev
, msg
);
101 dev_err(dev
, "Error sending write request: %d\n", err
);
110 static umode_t
cros_ec_vbc_is_visible(struct kobject
*kobj
,
111 struct bin_attribute
*a
, int n
)
113 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
114 struct cros_ec_dev
*ec
= container_of(dev
, struct cros_ec_dev
,
116 struct device_node
*np
= ec
->ec_dev
->dev
->of_node
;
118 if (IS_ENABLED(CONFIG_OF
) && np
) {
119 if (of_property_read_bool(np
, "google,has-vbc-nvram"))
126 static BIN_ATTR_RW(vboot_context
, 16);
128 static struct bin_attribute
*cros_ec_vbc_bin_attrs
[] = {
129 &bin_attr_vboot_context
,
133 struct attribute_group cros_ec_vbc_attr_group
= {
135 .bin_attrs
= cros_ec_vbc_bin_attrs
,
136 .is_bin_visible
= cros_ec_vbc_is_visible
,