Commit b996c10e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tag-chrome-platform-for-v5.12' of...

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

Pull chrome platform updates from Benson Leung:
 "Lots of changes to the cros_ec_typec driver for 5.12.

  A portion of this this set of cros_ec_typec driver's changes was
  merged through GregKH's USB tree in order to satisfy cros_ec_typec
  driver and typec connector class subsystem dependencies of subsequent
  changes.

  Summary:

  cros_ec_typec:
   - Registration of cable plug information
   - Support for SOP' plug registration and altmodes
   - Support for reporting number of altmodes supported by partners and
     plugs
   - Send mux configuration ack to EC via a new host command
   - Support mux control with no port partner present
   - Decouple cable removal from partner removal

  cros_ec misc:
   - Fix some event masking in cros_ec_proto.
   - Gwendal reworked cros_ec's top and bottom half for consistency in
     ishtp and rpmsg
   - Constify static attribute_group structs"

* tag 'tag-chrome-platform-for-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
  platform/chrome: cros_ec_typec: Flush pending work
  platform/chrome: cros_ec_types: Support disconnect events without partners
  platform/chrome: cros_ec_typec: Skip port partner check in configure_mux()
  platform/chrome: cros_ec_typec: Decouple partner removal
  platform/chrome: cros_ec: Call interrupt bottom half at probe time
  platform/chrome: cros_ec: Call interrupt bottom half in ISH or RPMSG mode
  platform/chrome: cros_ec_sysfs: Add cold-ap-off to sysfs reboot.
  platform/chrome: cros_ec_commands: Add host command to keep AP off after EC reset.
  platform/chrome: Constify static attribute_group structs
  platform/chrome: cros_ec_proto: Add LID and BATTERY to default mask
  platform/chrome: cros_ec_proto: Use EC_HOST_EVENT_MASK not BIT
parents f158bbee a59e1221
...@@ -32,7 +32,14 @@ static struct cros_ec_platform pd_p = { ...@@ -32,7 +32,14 @@ static struct cros_ec_platform pd_p = {
.cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX), .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX),
}; };
static irqreturn_t ec_irq_handler(int irq, void *data) /**
* cros_ec_irq_handler() - top half part of the interrupt handler
* @irq: IRQ id
* @data: (ec_dev) Device with events to process.
*
* Return: Wakeup the bottom half
*/
static irqreturn_t cros_ec_irq_handler(int irq, void *data)
{ {
struct cros_ec_device *ec_dev = data; struct cros_ec_device *ec_dev = data;
...@@ -51,7 +58,7 @@ static irqreturn_t ec_irq_handler(int irq, void *data) ...@@ -51,7 +58,7 @@ static irqreturn_t ec_irq_handler(int irq, void *data)
* Return: true if more events are still pending and this function should be * Return: true if more events are still pending and this function should be
* called again. * called again.
*/ */
bool cros_ec_handle_event(struct cros_ec_device *ec_dev) static bool cros_ec_handle_event(struct cros_ec_device *ec_dev)
{ {
bool wake_event; bool wake_event;
bool ec_has_more_events; bool ec_has_more_events;
...@@ -73,9 +80,15 @@ bool cros_ec_handle_event(struct cros_ec_device *ec_dev) ...@@ -73,9 +80,15 @@ bool cros_ec_handle_event(struct cros_ec_device *ec_dev)
return ec_has_more_events; return ec_has_more_events;
} }
EXPORT_SYMBOL(cros_ec_handle_event);
static irqreturn_t ec_irq_thread(int irq, void *data) /**
* cros_ec_irq_thread() - bottom half part of the interrupt handler
* @irq: IRQ id
* @data: (ec_dev) Device with events to process.
*
* Return: Interrupt handled.
*/
irqreturn_t cros_ec_irq_thread(int irq, void *data)
{ {
struct cros_ec_device *ec_dev = data; struct cros_ec_device *ec_dev = data;
bool ec_has_more_events; bool ec_has_more_events;
...@@ -86,6 +99,7 @@ static irqreturn_t ec_irq_thread(int irq, void *data) ...@@ -86,6 +99,7 @@ static irqreturn_t ec_irq_thread(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
EXPORT_SYMBOL(cros_ec_irq_thread);
static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event)
{ {
...@@ -194,8 +208,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev) ...@@ -194,8 +208,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
if (ec_dev->irq > 0) { if (ec_dev->irq > 0) {
err = devm_request_threaded_irq(dev, ec_dev->irq, err = devm_request_threaded_irq(dev, ec_dev->irq,
ec_irq_handler, cros_ec_irq_handler,
ec_irq_thread, cros_ec_irq_thread,
IRQF_TRIGGER_LOW | IRQF_ONESHOT, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"chromeos-ec", ec_dev); "chromeos-ec", ec_dev);
if (err) { if (err) {
...@@ -269,6 +283,13 @@ int cros_ec_register(struct cros_ec_device *ec_dev) ...@@ -269,6 +283,13 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
dev_info(dev, "Chrome EC device registered\n"); dev_info(dev, "Chrome EC device registered\n");
/*
* Unlock EC that may be waiting for AP to process MKBP events.
* If the AP takes to long to answer, the EC would stop sending events.
*/
if (ec_dev->mkbp_event_supported)
cros_ec_irq_thread(0, ec_dev);
return 0; return 0;
} }
EXPORT_SYMBOL(cros_ec_register); EXPORT_SYMBOL(cros_ec_register);
......
...@@ -8,12 +8,14 @@ ...@@ -8,12 +8,14 @@
#ifndef __CROS_EC_H #ifndef __CROS_EC_H
#define __CROS_EC_H #define __CROS_EC_H
#include <linux/interrupt.h>
int cros_ec_register(struct cros_ec_device *ec_dev); int cros_ec_register(struct cros_ec_device *ec_dev);
int cros_ec_unregister(struct cros_ec_device *ec_dev); int cros_ec_unregister(struct cros_ec_device *ec_dev);
int cros_ec_suspend(struct cros_ec_device *ec_dev); int cros_ec_suspend(struct cros_ec_device *ec_dev);
int cros_ec_resume(struct cros_ec_device *ec_dev); int cros_ec_resume(struct cros_ec_device *ec_dev);
bool cros_ec_handle_event(struct cros_ec_device *ec_dev); irqreturn_t cros_ec_irq_thread(int irq, void *data);
#endif /* __CROS_EC_H */ #endif /* __CROS_EC_H */
...@@ -140,12 +140,8 @@ static void ish_evt_handler(struct work_struct *work) ...@@ -140,12 +140,8 @@ static void ish_evt_handler(struct work_struct *work)
{ {
struct ishtp_cl_data *client_data = struct ishtp_cl_data *client_data =
container_of(work, struct ishtp_cl_data, work_ec_evt); container_of(work, struct ishtp_cl_data, work_ec_evt);
struct cros_ec_device *ec_dev = client_data->ec_dev;
bool ec_has_more_events;
do { cros_ec_irq_thread(0, client_data->ec_dev);
ec_has_more_events = cros_ec_handle_event(ec_dev);
} while (ec_has_more_events);
} }
/** /**
......
...@@ -523,7 +523,7 @@ static struct attribute *__lb_cmds_attrs[] = { ...@@ -523,7 +523,7 @@ static struct attribute *__lb_cmds_attrs[] = {
NULL, NULL,
}; };
static struct attribute_group cros_ec_lightbar_attr_group = { static const struct attribute_group cros_ec_lightbar_attr_group = {
.name = "lightbar", .name = "lightbar",
.attrs = __lb_cmds_attrs, .attrs = __lb_cmds_attrs,
}; };
......
...@@ -526,11 +526,13 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) ...@@ -526,11 +526,13 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev)
* power), not wake up. * power), not wake up.
*/ */
ec_dev->host_event_wake_mask = U32_MAX & ec_dev->host_event_wake_mask = U32_MAX &
~(BIT(EC_HOST_EVENT_AC_DISCONNECTED) | ~(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED) |
BIT(EC_HOST_EVENT_BATTERY_LOW) | EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) |
BIT(EC_HOST_EVENT_BATTERY_CRITICAL) | EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW) |
BIT(EC_HOST_EVENT_PD_MCU) | EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL) |
BIT(EC_HOST_EVENT_BATTERY_STATUS)); EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY) |
EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU) |
EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS));
/* /*
* Old ECs may not support this command. Complain about all * Old ECs may not support this command. Complain about all
* other errors. * other errors.
......
...@@ -149,12 +149,8 @@ cros_ec_rpmsg_host_event_function(struct work_struct *host_event_work) ...@@ -149,12 +149,8 @@ cros_ec_rpmsg_host_event_function(struct work_struct *host_event_work)
struct cros_ec_rpmsg *ec_rpmsg = container_of(host_event_work, struct cros_ec_rpmsg *ec_rpmsg = container_of(host_event_work,
struct cros_ec_rpmsg, struct cros_ec_rpmsg,
host_event_work); host_event_work);
struct cros_ec_device *ec_dev = dev_get_drvdata(&ec_rpmsg->rpdev->dev);
bool ec_has_more_events;
do { cros_ec_irq_thread(0, dev_get_drvdata(&ec_rpmsg->rpdev->dev));
ec_has_more_events = cros_ec_handle_event(ec_dev);
} while (ec_has_more_events);
} }
static int cros_ec_rpmsg_callback(struct rpmsg_device *rpdev, void *data, static int cros_ec_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
......
...@@ -28,7 +28,7 @@ static ssize_t reboot_show(struct device *dev, ...@@ -28,7 +28,7 @@ static ssize_t reboot_show(struct device *dev,
int count = 0; int count = 0;
count += scnprintf(buf + count, PAGE_SIZE - count, count += scnprintf(buf + count, PAGE_SIZE - count,
"ro|rw|cancel|cold|disable-jump|hibernate"); "ro|rw|cancel|cold|disable-jump|hibernate|cold-ap-off");
count += scnprintf(buf + count, PAGE_SIZE - count, count += scnprintf(buf + count, PAGE_SIZE - count,
" [at-shutdown]\n"); " [at-shutdown]\n");
return count; return count;
...@@ -46,6 +46,7 @@ static ssize_t reboot_store(struct device *dev, ...@@ -46,6 +46,7 @@ static ssize_t reboot_store(struct device *dev,
{"cancel", EC_REBOOT_CANCEL, 0}, {"cancel", EC_REBOOT_CANCEL, 0},
{"ro", EC_REBOOT_JUMP_RO, 0}, {"ro", EC_REBOOT_JUMP_RO, 0},
{"rw", EC_REBOOT_JUMP_RW, 0}, {"rw", EC_REBOOT_JUMP_RW, 0},
{"cold-ap-off", EC_REBOOT_COLD_AP_OFF, 0},
{"cold", EC_REBOOT_COLD, 0}, {"cold", EC_REBOOT_COLD, 0},
{"disable-jump", EC_REBOOT_DISABLE_JUMP, 0}, {"disable-jump", EC_REBOOT_DISABLE_JUMP, 0},
{"hibernate", EC_REBOOT_HIBERNATE, 0}, {"hibernate", EC_REBOOT_HIBERNATE, 0},
...@@ -329,7 +330,7 @@ static umode_t cros_ec_ctrl_visible(struct kobject *kobj, ...@@ -329,7 +330,7 @@ static umode_t cros_ec_ctrl_visible(struct kobject *kobj,
return a->mode; return a->mode;
} }
static struct attribute_group cros_ec_attr_group = { static const struct attribute_group cros_ec_attr_group = {
.attrs = __ec_attrs, .attrs = __ec_attrs,
.is_visible = cros_ec_ctrl_visible, .is_visible = cros_ec_ctrl_visible,
}; };
......
...@@ -203,20 +203,26 @@ static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int po ...@@ -203,20 +203,26 @@ static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int po
} }
} }
static void cros_typec_remove_partner(struct cros_typec_data *typec, static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
int port_num)
{ {
struct cros_typec_port *port = typec->ports[port_num];
cros_typec_unregister_altmodes(typec, port_num, true);
port->state.alt = NULL; port->state.alt = NULL;
port->state.mode = TYPEC_STATE_USB; port->state.mode = TYPEC_STATE_USB;
port->state.data = NULL; port->state.data = NULL;
usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE); usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE); typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
typec_mux_set(port->mux, &port->state);
return typec_mux_set(port->mux, &port->state);
}
static void cros_typec_remove_partner(struct cros_typec_data *typec,
int port_num)
{
struct cros_typec_port *port = typec->ports[port_num];
cros_typec_unregister_altmodes(typec, port_num, true);
cros_typec_usb_disconnect_state(port);
typec_unregister_partner(port->partner); typec_unregister_partner(port->partner);
port->partner = NULL; port->partner = NULL;
...@@ -536,8 +542,10 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, ...@@ -536,8 +542,10 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
enum typec_orientation orientation; enum typec_orientation orientation;
int ret; int ret;
if (!port->partner) if (mux_flags == USB_PD_MUX_NONE) {
return 0; ret = cros_typec_usb_disconnect_state(port);
goto mux_ack;
}
if (mux_flags & USB_PD_MUX_POLARITY_INVERTED) if (mux_flags & USB_PD_MUX_POLARITY_INVERTED)
orientation = TYPEC_ORIENTATION_REVERSE; orientation = TYPEC_ORIENTATION_REVERSE;
...@@ -572,6 +580,7 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, ...@@ -572,6 +580,7 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
mux_flags); mux_flags);
} }
mux_ack:
if (!typec->needs_mux_ack) if (!typec->needs_mux_ack)
return ret; return ret;
...@@ -638,9 +647,8 @@ static void cros_typec_set_port_params_v1(struct cros_typec_data *typec, ...@@ -638,9 +647,8 @@ static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
"Failed to register partner on port: %d\n", "Failed to register partner on port: %d\n",
port_num); port_num);
} else { } else {
if (!typec->ports[port_num]->partner) if (typec->ports[port_num]->partner)
return; cros_typec_remove_partner(typec, port_num);
cros_typec_remove_partner(typec, port_num);
if (typec->ports[port_num]->cable) if (typec->ports[port_num]->cable)
cros_typec_remove_cable(typec, port_num); cros_typec_remove_cable(typec, port_num);
...@@ -1060,6 +1068,7 @@ static int cros_ec_typec_event(struct notifier_block *nb, ...@@ -1060,6 +1068,7 @@ static int cros_ec_typec_event(struct notifier_block *nb,
{ {
struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb); struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb);
flush_work(&typec->port_work);
schedule_work(&typec->port_work); schedule_work(&typec->port_work);
return NOTIFY_OK; return NOTIFY_OK;
......
...@@ -101,7 +101,7 @@ static struct bin_attribute *cros_ec_vbc_bin_attrs[] = { ...@@ -101,7 +101,7 @@ static struct bin_attribute *cros_ec_vbc_bin_attrs[] = {
NULL NULL
}; };
static struct attribute_group cros_ec_vbc_attr_group = { static const struct attribute_group cros_ec_vbc_attr_group = {
.name = "vbc", .name = "vbc",
.bin_attrs = cros_ec_vbc_bin_attrs, .bin_attrs = cros_ec_vbc_bin_attrs,
}; };
......
...@@ -236,7 +236,7 @@ static struct attribute *wilco_dev_attrs[] = { ...@@ -236,7 +236,7 @@ static struct attribute *wilco_dev_attrs[] = {
NULL, NULL,
}; };
static struct attribute_group wilco_dev_attr_group = { static const struct attribute_group wilco_dev_attr_group = {
.attrs = wilco_dev_attrs, .attrs = wilco_dev_attrs,
}; };
......
...@@ -4742,6 +4742,7 @@ enum ec_reboot_cmd { ...@@ -4742,6 +4742,7 @@ enum ec_reboot_cmd {
EC_REBOOT_DISABLE_JUMP = 5, /* Disable jump until next reboot */ EC_REBOOT_DISABLE_JUMP = 5, /* Disable jump until next reboot */
EC_REBOOT_HIBERNATE = 6, /* Hibernate EC */ EC_REBOOT_HIBERNATE = 6, /* Hibernate EC */
EC_REBOOT_HIBERNATE_CLEAR_AP_OFF = 7, /* and clears AP_OFF flag */ EC_REBOOT_HIBERNATE_CLEAR_AP_OFF = 7, /* and clears AP_OFF flag */
EC_REBOOT_COLD_AP_OFF = 8, /* Cold-reboot and don't boot AP */
}; };
/* Flags for ec_params_reboot_ec.reboot_flags */ /* Flags for ec_params_reboot_ec.reboot_flags */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment