The last resume result exposing logic in cros_ec_sleep_event()
incorrectly requires S0ix support, which doesn't work on ARM based
systems where S0ix doesn't exist. That's because cros_ec_sleep_event()
only reports the last resume result when the EC indicates the last sleep
event was an S0ix resume. On ARM systems, the last sleep event is always
S3 resume, but the EC can still detect sleep hang events in case some
other part of the AP is blocking sleep.
Always expose the last resume result if the EC supports it so that this
works on all devices regardless of S0ix support. This fixes sleep hang
detection on ARM based chromebooks like Trogdor.
Cc: Rajat Jain <rajatja@chromium.org>
Cc: Matthias Kaehlcke <mka@chromium.org>
Cc: Hsin-Yi Wang <hsinyi@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Reviewed-by: Evan Green <evgreen@chromium.org>
Fixes: 7235560ac7 ("platform/chrome: Add support for v1 of host sleep event")
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220614075726.2729987-1-swboyd@chromium.org
cros_ec_get_host_event_wake_mask() expects to receive
sizeof(struct ec_response_host_event_mask) from send_command(). The
payload is valid only if the return value is positive.
Return -EPROTO if send_command() returns 0 in
cros_ec_get_host_event_wake_mask().
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-22-tzungbi@kernel.org
cros_ec_get_host_event_wake_mask() expects to receive
sizeof(struct ec_response_host_event_mask) from send_command().
The payload is valid only if the return value is positive.
Add Kunit tests for returning 0 from send_command() in
cros_ec_get_host_event_wake_mask().
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-21-tzungbi@kernel.org
cros_ec_get_host_event_wake_mask() used to return value from
send_command() which is number of bytes for input payload on success
(i.e. sizeof(struct ec_response_host_event_mask)).
However, the callers don't need to know how many bytes are available.
Don't return number of available bytes. Instead, return 0 on success;
otherwise, negative integers on error.
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-20-tzungbi@kernel.org
cros_ec_get_host_command_version_mask() expects to receive
sizeof(struct ec_response_get_cmd_versions) from send_command(). The
payload is valid only if the return value is positive.
Return -EPROTO if send_command() returns 0 in
cros_ec_get_host_command_version_mask().
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-19-tzungbi@kernel.org
cros_ec_get_host_command_version_mask() expects to receive
sizeof(struct ec_response_get_cmd_versions) from send_command().
The payload is valid only if the return value is positive.
Add Kunit tests for returning 0 from send_command() in
cros_ec_get_host_command_version_mask().
Note that because the 2 cros_ec_get_host_command_version_mask() use the
same `ver_mask`. cros_ec_proto_test_query_all_no_host_sleep_return0()
polluates the `ver_mask` and returns 0 on the second send_command() to
make sure the second cros_ec_get_host_command_version_mask() doesn't
take the garbage from the previous call.
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-18-tzungbi@kernel.org
cros_ec_query_all() uses cros_ec_get_host_command_version_mask() to
query the supported MKBP version; cros_ec_get_host_command_version_mask()
uses send_command() for transferring the host command.
Returning >=0 from send_command() only denotes the transfer was success.
cros_ec_get_host_command_version_mask() should check if EC wasn't happy
by checking `msg->result`.
Add a Kunit test for returning error in `msg->result` in
cros_ec_get_host_command_version_mask(). For the case,
cros_ec_query_all() should find the EC device doesn't support MKBP.
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-16-tzungbi@kernel.org
cros_ec_get_host_command_version_mask() used to return value from
send_command() which is number of available bytes for input payload on
success (i.e. sizeof(struct ec_response_get_cmd_versions)).
However, the callers don't need to know how many bytes are available.
Don't return number of available bytes. Instead, return 0 on success;
otherwise, negative integers on error.
Also remove the unneeded `ver_mask` initialization as the callers should
take it only if cros_ec_get_host_command_version_mask() returns 0.
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-15-tzungbi@kernel.org
cros_ec_get_proto_info_legacy() expects to receive
sizeof(struct ec_response_hello) from send_command(). The payload is
valid only if the return value is positive.
Add a Kunit test for returning 0 from send_command() in
cros_ec_get_proto_info_legacy().
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-12-tzungbi@kernel.org
cros_ec_get_proto_info() expects to receive
sizeof(struct ec_response_get_protocol_info) from send_command(). The
payload is valid only if the return value is positive.
Add Kunit tests for returning 0 from send_command() in
cros_ec_get_proto_info().
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-9-tzungbi@kernel.org
Rename cros_ec_host_command_proto_query() to cros_ec_get_proto_info()
and make it responsible for setting `ec_dev` fields according to the
response protocol info.
Also make cros_ec_get_host_event_wake_mask() allocate its own message
buffer. It was lucky that size of `struct ec_response_host_event_mask`
is less than `struct ec_response_get_protocol_info`. Thus, the buffer
wasn't overflow.
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-8-tzungbi@kernel.org
Use cros_ec_map_error() in cros_ec_get_host_event_wake_mask().
The behavior of cros_ec_get_host_event_wake_mask() slightly changed. It
is acceptable because the caller only needs it returns negative integers
for indicating errors. Especially, the EC_RES_INVALID_COMMAND still
maps to -EOPNOTSUPP.
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220609084957.3684698-7-tzungbi@kernel.org
cros_ec_prepare_tx() mixed the code for both versions. To be neat and to
make it clear, factor the legacy part out as a separate function, rename
the function, and update the comments.
Specifically,
- prepare_tx(), for current protocol version (i.e. 3).
- prepare_tx_legacy(), for protocol version <= 2.
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Link: https://lore.kernel.org/r/20220518091814.2028579-3-tzungbi@kernel.org
In the context, the following conditions are always false:
- `todo` < 0
Suppose that EC_SPI_FRAME_START is found at the last byte of transfer.
In the case, `ptr` == `end` - 1. As a result, `todo` must be 0.
- `todo` > `ec_dev->din_size`
Suppose that there is no preamble bytes. EC_SPI_FRAME_START is found at
the first byte of transfer.
In the case, `end` == `ptr` + EC_MSG_PREAMBLE_COUNT.
As a result, `todo` == EC_MSG_PREAMBLE_COUNT - 1.
However, it already checked `ec_dev->din_size` < EC_MSG_PREAMBLE_COUNT at
the beginning of function.
Drop the unneeded BUG_ON().
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Link: https://lore.kernel.org/r/20220513044143.1045728-7-tzungbi@kernel.org
The x86 Chromebooks have the ChromeOS ACPI device. This driver attaches
to the ChromeOS ACPI device and exports the values reported by ACPI in a
sysfs directory. This data isn't present in ACPI tables when read
through ACPI tools, hence a driver is needed to do it. The driver gets
data from firmware using the ACPI component of the kernel. The ACPI values
are presented in string form (numbers as decimal values) or binary
blobs, and can be accessed as the contents of the appropriate read only
files in the standard ACPI device's sysfs directory tree. This data is
consumed by the ChromeOS user space.
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Co-developed-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
Signed-off-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/Yn4OKYrtV35Dv+nd@debian-BULLSEYE-live-builder-AMD64
Some ChromeOS EC devices (such as the Framework Laptop) only map I/O
ports 0x800-0x807. Making the larger reservation required by the non-MEC
LPC (the 0xFF ports for the memory map, and the 0xFF ports for the
parameter region) is non-viable on these devices.
Since we probe the MEC EC first, we can get away with a smaller
reservation that covers the MEC EC ports. If we fall back to classic
LPC, we can grow the reservation to cover the memory map and the
parameter region.
cros_ec_lpc_probe also interacted with I/O ports 0x800-0x807 without a
reservation. Restructuring the code to request the MEC LPC region first
obviates the need to do so.
Signed-off-by: Dustin L. Howett <dustin@howett.net>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220217165930.15081-3-dustin@howett.net
Commit 413dda8f2c ("platform/chrome: cros_ec_chardev: Use
cros_ec_cmd_xfer_status helper") inadvertendly changed the userspace ABI.
Previously, cros_ec ioctls would only report errors if the EC communication
failed, and otherwise return success and the result of the EC
communication. An EC command execution failure was reported in the EC
response field. The above mentioned commit changed this behavior, and the
ioctl itself would fail. This breaks userspace commands trying to analyze
the EC command execution error since the actual EC command response is no
longer reported to userspace.
Fix the problem by re-introducing the cros_ec_cmd_xfer() helper, and use it
to handle ioctl messages.
Fixes: 413dda8f2c ("platform/chrome: cros_ec_chardev: Use cros_ec_cmd_xfer_status helper")
Cc: Daisuke Nojiri <dnojiri@chromium.org>
Cc: Rob Barnes <robbarnes@google.com>
Cc: Rajat Jain <rajatja@google.com>
Cc: Brian Norris <briannorris@chromium.org>
Cc: Parth Malkan <parthmalkan@google.com>
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
`wake_enabled` indicates cros_ec_resume() needs to call
disable_irq_wake() to undo enable_irq_wake() in cros_ec_suspend().
Determine `wake_enabled` in cros_ec_suspend() instead of
reset-after-used in cros_ec_resume().
Reviewed-by: Prashant Malani <pmalani@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Fix cros_ec_register() to unregister platform devices if
blocking_notifier_chain_register() fails.
Also use the single exit path to handle the platform device
unregistration.
Fixes: 42cd0ab476 ("platform/chrome: cros_ec: Query EC protocol version if EC transitions between RO/RW")
Reviewed-by: Prashant Malani <pmalani@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>