Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tag-chrome-platform-for-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform updates from Benson Leung:
"cros_ec_typec:
- Add notifier for update, and register port partner

Sensors/iio:
- Fixes to cros_ec_sensorhub around allocation of resources, and
send_sample

Wilco EC:
- Fix to output format of h1_gpio

Misc:
- Misc fixes to appease kernel-doc and other warnings
- Set user space log size in chromeos_pstore"

* tag 'tag-chrome-platform-for-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
platform/chrome: cros_usbpd_logger: Add __printf annotation to append_str()
platform/chrome: cros_ec_i2c: Appease the kernel-doc deity
platform/chrome: typec: Fix ret value check error
platform/chrome: cros_ec_typec: Register port partner
platform/chrome: cros_ec_typec: Add struct for port data
platform/chrome: cros_ec_typec: Use notifier for updates
platform/chrome: cros_ec_ishtp: free ishtp buffer before sending event
platform/chrome: cros_ec_ishtp: skip old cros_ec responses
platform/chrome: wilco_ec: Provide correct output format to 'h1_gpio' file
platform/chrome: chromeos_pstore: set user space log size

+145 -31
+1
drivers/platform/chrome/Kconfig
··· 217 217 config CROS_EC_TYPEC 218 218 tristate "ChromeOS EC Type-C Connector Control" 219 219 depends on MFD_CROS_EC_DEV && TYPEC 220 + depends on CROS_USBPD_NOTIFY 220 221 default MFD_CROS_EC_DEV 221 222 help 222 223 If you say Y here, you get support for accessing Type C connector
+1
drivers/platform/chrome/chromeos_pstore.c
··· 57 57 .record_size = 0x40000, 58 58 .console_size = 0x20000, 59 59 .ftrace_size = 0x20000, 60 + .pmsg_size = 0x20000, 60 61 .max_reason = KMSG_DUMP_OOPS, 61 62 }; 62 63
+1 -1
drivers/platform/chrome/cros_ec_i2c.c
··· 16 16 17 17 #include "cros_ec.h" 18 18 19 - /** 19 + /* 20 20 * Request format for protocol v3 21 21 * byte 0 0xda (EC_COMMAND_PROTOCOL_3) 22 22 * byte 1-8 struct ec_host_request
+33 -12
drivers/platform/chrome/cros_ec_ishtp.c
··· 48 48 struct header { 49 49 u8 channel; 50 50 u8 status; 51 - u8 reserved[2]; 51 + u8 token; 52 + u8 reserved; 52 53 } __packed; 53 54 54 55 struct cros_ish_out_msg { ··· 91 90 * data exceeds this value, we log an error. 92 91 * @size: Actual size of data received from firmware. 93 92 * @error: 0 for success, negative error code for a failure in process_recv(). 93 + * @token: Expected token for response that we are waiting on. 94 94 * @received: Set to true on receiving a valid firmware response to host command 95 95 * @wait_queue: Wait queue for host to wait for firmware response. 96 96 */ ··· 100 98 size_t max_size; 101 99 size_t size; 102 100 int error; 101 + u8 token; 103 102 bool received; 104 103 wait_queue_head_t wait_queue; 105 104 }; ··· 165 162 u8 *out_msg, size_t out_size, 166 163 u8 *in_msg, size_t in_size) 167 164 { 165 + static u8 next_token; 168 166 int rv; 169 167 struct header *out_hdr = (struct header *)out_msg; 170 168 struct ishtp_cl *cros_ish_cl = client_data->cros_ish_cl; ··· 178 174 client_data->response.data = in_msg; 179 175 client_data->response.max_size = in_size; 180 176 client_data->response.error = 0; 177 + client_data->response.token = next_token++; 181 178 client_data->response.received = false; 179 + 180 + out_hdr->token = client_data->response.token; 182 181 183 182 rv = ishtp_cl_send(cros_ish_cl, out_msg, out_size); 184 183 if (rv) { ··· 256 249 257 250 switch (in_msg->hdr.channel) { 258 251 case CROS_EC_COMMAND: 252 + if (client_data->response.received) { 253 + dev_err(dev, 254 + "Previous firmware message not yet processed\n"); 255 + goto end_error; 256 + } 257 + 258 + if (client_data->response.token != in_msg->hdr.token) { 259 + dev_err_ratelimited(dev, 260 + "Dropping old response token %d\n", 261 + in_msg->hdr.token); 262 + goto end_error; 263 + } 264 + 259 265 /* Sanity check */ 260 266 if (!client_data->response.data) { 261 267 dev_err(dev, 262 268 "Receiving buffer is null. Should be allocated by calling function\n"); 263 - client_data->response.error = -EINVAL; 264 - goto error_wake_up; 265 - } 266 - 267 - if (client_data->response.received) { 268 - dev_err(dev, 269 - "Previous firmware message not yet processed\n"); 270 269 client_data->response.error = -EINVAL; 271 270 goto error_wake_up; 272 271 } ··· 302 289 memcpy(client_data->response.data, 303 290 rb_in_proc->buffer.data, data_len); 304 291 292 + error_wake_up: 293 + /* Free the buffer since we copied data or didn't need it */ 294 + ishtp_cl_io_rb_recycle(rb_in_proc); 295 + rb_in_proc = NULL; 296 + 305 297 /* Set flag before waking up the caller */ 306 298 client_data->response.received = true; 307 - error_wake_up: 299 + 308 300 /* Wake the calling thread */ 309 301 wake_up_interruptible(&client_data->response.wait_queue); 310 302 311 303 break; 312 304 313 305 case CROS_MKBP_EVENT: 306 + /* Free the buffer. This is just an event without data */ 307 + ishtp_cl_io_rb_recycle(rb_in_proc); 308 + rb_in_proc = NULL; 314 309 /* 315 310 * Set timestamp from beginning of function since we actually 316 311 * got an incoming MKBP event 317 312 */ 318 313 client_data->ec_dev->last_event_time = timestamp; 319 - /* The event system doesn't send any data in buffer */ 320 314 schedule_work(&client_data->work_ec_evt); 321 315 322 316 break; ··· 333 313 } 334 314 335 315 end_error: 336 - /* Free the buffer */ 337 - ishtp_cl_io_rb_recycle(rb_in_proc); 316 + /* Free the buffer if we already haven't */ 317 + if (rb_in_proc) 318 + ishtp_cl_io_rb_recycle(rb_in_proc); 338 319 339 320 up_read(&init_lock); 340 321 }
+102 -17
drivers/platform/chrome/cros_ec_typec.c
··· 11 11 #include <linux/of.h> 12 12 #include <linux/platform_data/cros_ec_commands.h> 13 13 #include <linux/platform_data/cros_ec_proto.h> 14 + #include <linux/platform_data/cros_usbpd_notify.h> 14 15 #include <linux/platform_device.h> 15 16 #include <linux/usb/typec.h> 16 17 17 18 #define DRV_NAME "cros-ec-typec" 19 + 20 + /* Per port data. */ 21 + struct cros_typec_port { 22 + struct typec_port *port; 23 + /* Initial capabilities for the port. */ 24 + struct typec_capability caps; 25 + struct typec_partner *partner; 26 + /* Port partner PD identity info. */ 27 + struct usb_pd_identity p_identity; 28 + }; 18 29 19 30 /* Platform-specific data for the Chrome OS EC Type C controller. */ 20 31 struct cros_typec_data { ··· 34 23 int num_ports; 35 24 unsigned int cmd_ver; 36 25 /* Array of ports, indexed by port number. */ 37 - struct typec_port *ports[EC_USB_PD_MAX_PORTS]; 38 - /* Initial capabilities for each port. */ 39 - struct typec_capability *caps[EC_USB_PD_MAX_PORTS]; 26 + struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS]; 27 + struct notifier_block nb; 40 28 }; 41 29 42 30 static int cros_typec_parse_port_props(struct typec_capability *cap, ··· 84 74 return 0; 85 75 } 86 76 77 + static void cros_unregister_ports(struct cros_typec_data *typec) 78 + { 79 + int i; 80 + 81 + for (i = 0; i < typec->num_ports; i++) { 82 + if (!typec->ports[i]) 83 + continue; 84 + typec_unregister_port(typec->ports[i]->port); 85 + } 86 + } 87 + 87 88 static int cros_typec_init_ports(struct cros_typec_data *typec) 88 89 { 89 90 struct device *dev = typec->dev; 90 91 struct typec_capability *cap; 91 92 struct fwnode_handle *fwnode; 93 + struct cros_typec_port *cros_port; 92 94 const char *port_prop; 93 95 int ret; 94 - int i; 95 96 int nports; 96 97 u32 port_num = 0; 97 98 ··· 134 113 135 114 dev_dbg(dev, "Registering port %d\n", port_num); 136 115 137 - cap = devm_kzalloc(dev, sizeof(*cap), GFP_KERNEL); 138 - if (!cap) { 116 + cros_port = devm_kzalloc(dev, sizeof(*cros_port), GFP_KERNEL); 117 + if (!cros_port) { 139 118 ret = -ENOMEM; 140 119 goto unregister_ports; 141 120 } 142 121 143 - typec->caps[port_num] = cap; 122 + typec->ports[port_num] = cros_port; 123 + cap = &cros_port->caps; 144 124 145 125 ret = cros_typec_parse_port_props(cap, fwnode, dev); 146 126 if (ret < 0) 147 127 goto unregister_ports; 148 128 149 - typec->ports[port_num] = typec_register_port(dev, cap); 150 - if (IS_ERR(typec->ports[port_num])) { 129 + cros_port->port = typec_register_port(dev, cap); 130 + if (IS_ERR(cros_port->port)) { 151 131 dev_err(dev, "Failed to register port %d\n", port_num); 152 - ret = PTR_ERR(typec->ports[port_num]); 132 + ret = PTR_ERR(cros_port->port); 153 133 goto unregister_ports; 154 134 } 155 135 } ··· 158 136 return 0; 159 137 160 138 unregister_ports: 161 - for (i = 0; i < typec->num_ports; i++) 162 - typec_unregister_port(typec->ports[i]); 139 + cros_unregister_ports(typec); 163 140 return ret; 164 141 } 165 142 ··· 193 172 return ret; 194 173 } 195 174 175 + static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num, 176 + bool pd_en) 177 + { 178 + struct cros_typec_port *port = typec->ports[port_num]; 179 + struct typec_partner_desc p_desc = { 180 + .usb_pd = pd_en, 181 + }; 182 + int ret = 0; 183 + 184 + /* 185 + * Fill an initial PD identity, which will then be updated with info 186 + * from the EC. 187 + */ 188 + p_desc.identity = &port->p_identity; 189 + 190 + port->partner = typec_register_partner(port->port, &p_desc); 191 + if (IS_ERR(port->partner)) { 192 + ret = PTR_ERR(port->partner); 193 + port->partner = NULL; 194 + } 195 + 196 + return ret; 197 + } 198 + 196 199 static void cros_typec_set_port_params_v0(struct cros_typec_data *typec, 197 200 int port_num, struct ec_response_usb_pd_control *resp) 198 201 { 199 - struct typec_port *port = typec->ports[port_num]; 202 + struct typec_port *port = typec->ports[port_num]->port; 200 203 enum typec_orientation polarity; 201 204 202 205 if (!resp->enabled) ··· 237 192 static void cros_typec_set_port_params_v1(struct cros_typec_data *typec, 238 193 int port_num, struct ec_response_usb_pd_control_v1 *resp) 239 194 { 240 - struct typec_port *port = typec->ports[port_num]; 195 + struct typec_port *port = typec->ports[port_num]->port; 241 196 enum typec_orientation polarity; 197 + bool pd_en; 198 + int ret; 242 199 243 200 if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED)) 244 201 polarity = TYPEC_ORIENTATION_NONE; ··· 255 208 TYPEC_SOURCE : TYPEC_SINK); 256 209 typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ? 257 210 TYPEC_SOURCE : TYPEC_SINK); 211 + 212 + /* Register/remove partners when a connect/disconnect occurs. */ 213 + if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) { 214 + if (typec->ports[port_num]->partner) 215 + return; 216 + 217 + pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE; 218 + ret = cros_typec_add_partner(typec, port_num, pd_en); 219 + if (ret) 220 + dev_warn(typec->dev, 221 + "Failed to register partner on port: %d\n", 222 + port_num); 223 + } else { 224 + if (!typec->ports[port_num]->partner) 225 + return; 226 + 227 + typec_unregister_partner(typec->ports[port_num]->partner); 228 + typec->ports[port_num]->partner = NULL; 229 + } 258 230 } 259 231 260 232 static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) ··· 338 272 return 0; 339 273 } 340 274 275 + static int cros_ec_typec_event(struct notifier_block *nb, 276 + unsigned long host_event, void *_notify) 277 + { 278 + struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, 279 + nb); 280 + int ret, i; 281 + 282 + for (i = 0; i < typec->num_ports; i++) { 283 + ret = cros_typec_port_update(typec, i); 284 + if (ret < 0) 285 + dev_warn(typec->dev, "Update failed for port: %d\n", i); 286 + } 287 + 288 + return NOTIFY_OK; 289 + } 290 + 341 291 #ifdef CONFIG_ACPI 342 292 static const struct acpi_device_id cros_typec_acpi_id[] = { 343 293 { "GOOG0014", 0 }, ··· 414 332 goto unregister_ports; 415 333 } 416 334 335 + typec->nb.notifier_call = cros_ec_typec_event; 336 + ret = cros_usbpd_register_notify(&typec->nb); 337 + if (ret < 0) 338 + goto unregister_ports; 339 + 417 340 return 0; 418 341 419 342 unregister_ports: 420 - for (i = 0; i < typec->num_ports; i++) 421 - if (typec->ports[i]) 422 - typec_unregister_port(typec->ports[i]); 343 + cros_unregister_ports(typec); 423 344 return ret; 424 345 } 425 346
+1
drivers/platform/chrome/cros_usbpd_logger.c
··· 46 46 "---", "OCP", "fast OCP", "OVP", "Discharge" 47 47 }; 48 48 49 + __printf(3, 4) 49 50 static int append_str(char *buf, int pos, const char *fmt, ...) 50 51 { 51 52 va_list args;
+6 -1
drivers/platform/chrome/wilco_ec/debugfs.c
··· 208 208 */ 209 209 static int h1_gpio_get(void *arg, u64 *val) 210 210 { 211 - return send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val); 211 + int ret; 212 + 213 + ret = send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val); 214 + if (ret == 0) 215 + *val &= 0xFF; 216 + return ret; 212 217 } 213 218 214 219 DEFINE_DEBUGFS_ATTRIBUTE(fops_h1_gpio, h1_gpio_get, NULL, "0x%02llx\n");