From: <Mario.Limonciello@dell.com>
To: <andy.shevchenko@gmail.com>, <srinivas.pandruvada@linux.intel.com>
Cc: <alex.hung@canonical.com>, <dvhart@infradead.org>,
<andy@infradead.org>, <platform-driver-x86@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <rjw@rjwysocki.net>
Subject: RE: [PATCH v2] platform/x86: intel-hid: Add support for Device Specific Methods
Date: Mon, 2 Jul 2018 13:51:14 +0000 [thread overview]
Message-ID: <cc4bc804434a40d9bdd2fa03bbb875aa@ausx13mpc120.AMER.DELL.COM> (raw)
In-Reply-To: <CAHp75VdX+i_N_GttiL3QZrpivpUeJa0ofGfeJR1FkfuiBWocqA@mail.gmail.com>
> -----Original Message-----
> From: Andy Shevchenko [mailto:andy.shevchenko@gmail.com]
> Sent: Monday, July 2, 2018 7:41 AM
> To: Srinivas Pandruvada
> Cc: Limonciello, Mario; Alex Hung; Darren Hart; Andy Shevchenko; Platform Driver;
> Linux Kernel Mailing List; Rafael J. Wysocki
> Subject: Re: [PATCH v2] platform/x86: intel-hid: Add support for Device Specific
> Methods
>
> On Fri, Jun 29, 2018 at 9:41 PM, Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com> wrote:
> > On Fri, 2018-06-29 at 16:44 +0000, Mario.Limonciello@dell.com wrote:
> >> >
> >
> > [...]
> >
> >> I verified this on XPS 9370 FW 1.3.2 (which contains this alternate
> >> HEBC interface).
> >> Power button works again for wakeup from s2idle.
> >>
> >> Tested-by: Mario Limonciello <mario.limonciello@dell.com>
> >>
> > So there are some customers who will have issue with power button
> > without this patch, so it should be also marked for stable also.
> > Also this may be a candidate for 4.18-rcX.
> >
>
> I'm not sure Greg will take this selling point for rather big patch.
> From changelog, honestly, I don't see any regression description,
> looks like "it wasn't working before change anyway".
>
Just for adding some context.
Some platforms have moved to different interface in ASL in FW upgrade
due to deficiencies/bugs present with old interface. So yes it's platform FW
change in behavior that leads to Linux kernel regression. Windows driver has supported
both interfaces for a long time. Linux kernel however doesn't support this interface until now.
> For now, I pushed this to my review and testing queue as is, thanks!
If not stable I think it would at least be ideal to try to bring this to 4.18-rcX if possible for
compatibility with more platforms that will come with this other interface instead.
>
> > Thanks,
> > Srinivas
> >
> >> > ---
> >> > Accidently sent the patch without change of version, so please
> >> > ignore
> >> > the previous one sent today.
> >> > v2:
> >> > Minor changes suggested by Andy
> >> >
> >> > drivers/platform/x86/intel-hid.c | 178
> >> > ++++++++++++++++++++++++++++++++++----
> >> > -
> >> > 1 file changed, 157 insertions(+), 21 deletions(-)
> >> >
> >> > diff --git a/drivers/platform/x86/intel-hid.c
> >> > b/drivers/platform/x86/intel-hid.c
> >> > index b5adba227783..6cf9b7fa5bf0 100644
> >> > --- a/drivers/platform/x86/intel-hid.c
> >> > +++ b/drivers/platform/x86/intel-hid.c
> >> > @@ -96,13 +96,140 @@ struct intel_hid_priv {
> >> > bool wakeup_mode;
> >> > };
> >> >
> >> > -static int intel_hid_set_enable(struct device *device, bool
> >> > enable)
> >> > +#define HID_EVENT_FILTER_UUID "eeec56b3-4442-408f-a792-
> >> > 4edd4d758054"
> >> > +
> >> > +enum intel_hid_dsm_fn_codes {
> >> > + INTEL_HID_DSM_FN_INVALID,
> >> > + INTEL_HID_DSM_BTNL_FN,
> >> > + INTEL_HID_DSM_HDMM_FN,
> >> > + INTEL_HID_DSM_HDSM_FN,
> >> > + INTEL_HID_DSM_HDEM_FN,
> >> > + INTEL_HID_DSM_BTNS_FN,
> >> > + INTEL_HID_DSM_BTNE_FN,
> >> > + INTEL_HID_DSM_HEBC_V1_FN,
> >> > + INTEL_HID_DSM_VGBS_FN,
> >> > + INTEL_HID_DSM_HEBC_V2_FN,
> >> > + INTEL_HID_DSM_FN_MAX
> >> > +};
> >> > +
> >> > +static const char
> >> > *intel_hid_dsm_fn_to_method[INTEL_HID_DSM_FN_MAX] = {
> >> > + NULL,
> >> > + "BTNL",
> >> > + "HDMM",
> >> > + "HDSM",
> >> > + "HDEM",
> >> > + "BTNS",
> >> > + "BTNE",
> >> > + "HEBC",
> >> > + "VGBS",
> >> > + "HEBC"
> >> > +};
> >> > +
> >> > +static unsigned long long intel_hid_dsm_fn_mask;
> >> > +static guid_t intel_dsm_guid;
> >> > +
> >> > +static bool intel_hid_execute_method(acpi_handle handle,
> >> > + enum intel_hid_dsm_fn_codes
> >> > fn_index,
> >> > + unsigned long long arg)
> >> > {
> >> > + union acpi_object *obj, argv4, req;
> >> > acpi_status status;
> >> > + char *method_name;
> >> >
> >> > - status = acpi_execute_simple_method(ACPI_HANDLE(device),
> >> > "HDSM",
> >> > - enable);
> >> > - if (ACPI_FAILURE(status)) {
> >> > + if (fn_index <= INTEL_HID_DSM_FN_INVALID ||
> >> > + fn_index >= INTEL_HID_DSM_FN_MAX)
> >> > + return false;
> >> > +
> >> > + method_name = (char
> >> > *)intel_hid_dsm_fn_to_method[fn_index];
> >> > +
> >> > + if (!(intel_hid_dsm_fn_mask & fn_index))
> >> > + goto skip_dsm_exec;
> >> > +
> >> > + /* All methods expects a package with one integer element
> >> > */
> >> > + req.type = ACPI_TYPE_INTEGER;
> >> > + req.integer.value = arg;
> >> > +
> >> > + argv4.type = ACPI_TYPE_PACKAGE;
> >> > + argv4.package.count = 1;
> >> > + argv4.package.elements = &req;
> >> > +
> >> > + obj = acpi_evaluate_dsm(handle, &intel_dsm_guid, 1,
> >> > fn_index, &argv4);
> >> > + if (obj) {
> >> > + acpi_handle_debug(handle, "Exec DSM Fn code:
> >> > %d[%s]
> >> > success\n",
> >> > + fn_index, method_name);
> >> > + ACPI_FREE(obj);
> >> > + return true;
> >> > + }
> >> > +
> >> > +skip_dsm_exec:
> >> > + status = acpi_execute_simple_method(handle, method_name,
> >> > arg);
> >> > + if (ACPI_SUCCESS(status))
> >> > + return true;
> >> > +
> >> > + return false;
> >> > +}
> >> > +
> >> > +static bool intel_hid_evaluate_method(acpi_handle handle,
> >> > + enum intel_hid_dsm_fn_codes
> >> > fn_index,
> >> > + unsigned long long *result)
> >> > +{
> >> > + union acpi_object *obj;
> >> > + acpi_status status;
> >> > + char *method_name;
> >> > +
> >> > + if (fn_index <= INTEL_HID_DSM_FN_INVALID ||
> >> > + fn_index >= INTEL_HID_DSM_FN_MAX)
> >> > + return false;
> >> > +
> >> > + method_name = (char
> >> > *)intel_hid_dsm_fn_to_method[fn_index];
> >> > +
> >> > + if (!(intel_hid_dsm_fn_mask & fn_index))
> >> > + goto skip_dsm_eval;
> >> > +
> >> > + obj = acpi_evaluate_dsm_typed(handle, &intel_dsm_guid,
> >> > + 1, fn_index,
> >> > + NULL, ACPI_TYPE_INTEGER);
> >> > + if (obj) {
> >> > + *result = obj->integer.value;
> >> > + acpi_handle_debug(handle,
> >> > + "Eval DSM Fn code: %d[%s]
> >> > results: 0x%llx\n",
> >> > + fn_index, method_name, *result);
> >> > + ACPI_FREE(obj);
> >> > + return true;
> >> > + }
> >> > +
> >> > +skip_dsm_eval:
> >> > + status = acpi_evaluate_integer(handle, method_name, NULL,
> >> > result);
> >> > + if (ACPI_SUCCESS(status))
> >> > + return true;
> >> > +
> >> > + return false;
> >> > +}
> >> > +
> >> > +static void intel_hid_init_dsm(acpi_handle handle)
> >> > +{
> >> > + union acpi_object *obj;
> >> > +
> >> > + guid_parse(HID_EVENT_FILTER_UUID, &intel_dsm_guid);
> >> > +
> >> > + obj = acpi_evaluate_dsm_typed(handle, &intel_dsm_guid, 1,
> >> > 0, NULL,
> >> > + ACPI_TYPE_BUFFER);
> >> > + if (obj) {
> >> > + intel_hid_dsm_fn_mask = *obj->buffer.pointer;
> >> > + ACPI_FREE(obj);
> >> > + }
> >> > +
> >> > + acpi_handle_debug(handle, "intel_hid_dsm_fn_mask =
> >> > %llx\n",
> >> > + intel_hid_dsm_fn_mask);
> >> > +}
> >> > +
> >> > +static int intel_hid_set_enable(struct device *device, bool
> >> > enable)
> >> > +{
> >> > + acpi_handle handle = ACPI_HANDLE(device);
> >> > +
> >> > + /* Enable|disable features - power button is always
> >> > enabled */
> >> > + if (!intel_hid_execute_method(handle,
> >> > INTEL_HID_DSM_HDSM_FN,
> >> > + enable)) {
> >> > dev_warn(device, "failed to %sable hotkeys\n",
> >> > enable ? "en" : "dis");
> >> > return -EIO;
> >> > @@ -129,9 +256,8 @@ static void intel_button_array_enable(struct
> >> > device
> >> > *device, bool enable)
> >> > }
> >> >
> >> > /* Enable|disable features - power button is always
> >> > enabled */
> >> > - status = acpi_execute_simple_method(handle, "BTNE",
> >> > - enable ? button_cap :
> >> > 1);
> >> > - if (ACPI_FAILURE(status))
> >> > + if (!intel_hid_execute_method(handle,
> >> > INTEL_HID_DSM_BTNE_FN,
> >> > + enable ? button_cap : 1))
> >> > dev_warn(device, "failed to set button
> >> > capability\n");
> >> > }
> >> >
> >> > @@ -217,7 +343,6 @@ static void notify_handler(acpi_handle handle,
> >> > u32 event,
> >> > void *context)
> >> > struct platform_device *device = context;
> >> > struct intel_hid_priv *priv = dev_get_drvdata(&device-
> >> > >dev);
> >> > unsigned long long ev_index;
> >> > - acpi_status status;
> >> >
> >> > if (priv->wakeup_mode) {
> >> > /*
> >> > @@ -269,8 +394,8 @@ static void notify_handler(acpi_handle handle,
> >> > u32 event,
> >> > void *context)
> >> > return;
> >> > }
> >> >
> >> > - status = acpi_evaluate_integer(handle, "HDEM", NULL,
> >> > &ev_index);
> >> > - if (ACPI_FAILURE(status)) {
> >> > + if (!intel_hid_evaluate_method(handle,
> >> > INTEL_HID_DSM_HDEM_FN,
> >> > + &ev_index)) {
> >> > dev_warn(&device->dev, "failed to get event
> >> > index\n");
> >> > return;
> >> > }
> >> > @@ -284,17 +409,24 @@ static bool button_array_present(struct
> >> > platform_device
> >> > *device)
> >> > {
> >> > acpi_handle handle = ACPI_HANDLE(&device->dev);
> >> > unsigned long long event_cap;
> >> > - acpi_status status;
> >> > - bool supported = false;
> >> >
> >> > - status = acpi_evaluate_integer(handle, "HEBC", NULL,
> >> > &event_cap);
> >> > - if (ACPI_SUCCESS(status) && (event_cap & 0x20000))
> >> > - supported = true;
> >> > + if (intel_hid_evaluate_method(handle,
> >> > INTEL_HID_DSM_HEBC_V2_FN,
> >> > + &event_cap)) {
> >> > + /* Check presence of 5 button array or v2 power
> >> > button */
> >> > + if (event_cap & 0x60000)
> >> > + return true;
> >> > + }
> >> > +
> >> > + if (intel_hid_evaluate_method(handle,
> >> > INTEL_HID_DSM_HEBC_V1_FN,
> >> > + &event_cap)) {
> >> > + if (event_cap & 0x20000)
> >> > + return true;
> >> > + }
> >> >
> >> > if (dmi_check_system(button_array_table))
> >> > - supported = true;
> >> > + return true;
> >> >
> >> > - return supported;
> >> > + return false;
> >> > }
> >> >
> >> > static int intel_hid_probe(struct platform_device *device)
> >> > @@ -305,8 +437,9 @@ static int intel_hid_probe(struct
> >> > platform_device *device)
> >> > acpi_status status;
> >> > int err;
> >> >
> >> > - status = acpi_evaluate_integer(handle, "HDMM", NULL,
> >> > &mode);
> >> > - if (ACPI_FAILURE(status)) {
> >> > + intel_hid_init_dsm(handle);
> >> > +
> >> > + if (!intel_hid_evaluate_method(handle,
> >> > INTEL_HID_DSM_HDMM_FN,
> >> > &mode)) {
> >> > dev_warn(&device->dev, "failed to read mode\n");
> >> > return -ENODEV;
> >> > }
> >> > @@ -352,13 +485,16 @@ static int intel_hid_probe(struct
> >> > platform_device
> >> > *device)
> >> > goto err_remove_notify;
> >> >
> >> > if (priv->array) {
> >> > + unsigned long long dummy;
> >> > +
> >> > intel_button_array_enable(&device->dev, true);
> >> >
> >> > /* Call button load method to enable HID power
> >> > button */
> >> > - status = acpi_evaluate_object(handle, "BTNL",
> >> > NULL, NULL);
> >> > - if (ACPI_FAILURE(status))
> >> > + if (!intel_hid_evaluate_method(handle,
> >> > INTEL_HID_DSM_BTNL_FN,
> >> > + &dummy)) {
> >> > dev_warn(&device->dev,
> >> > "failed to enable HID power
> >> > button\n");
> >> > + }
> >> > }
> >> >
> >> > device_init_wakeup(&device->dev, true);
> >> > --
> >> > 2.14.1
> >>
> >>
>
>
>
> --
> With Best Regards,
> Andy Shevchenko
next prev parent reply other threads:[~2018-07-02 13:51 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-28 18:19 Srinivas Pandruvada
2018-06-29 16:44 ` Mario.Limonciello
2018-06-29 18:41 ` Srinivas Pandruvada
2018-07-02 12:41 ` Andy Shevchenko
2018-07-02 13:51 ` Mario.Limonciello [this message]
2018-07-02 14:06 ` Andy Shevchenko
2018-07-06 23:59 ` Darren Hart
2018-07-07 3:48 ` Mario.Limonciello
2018-07-07 16:24 ` Andy Shevchenko
2018-07-07 23:37 ` Srinivas Pandruvada
2018-07-08 17:53 ` Andy Shevchenko
2018-07-07 13:43 ` Srinivas Pandruvada
2018-07-09 4:38 ` Mario.Limonciello
2018-07-09 21:06 ` Darren Hart
2018-07-09 21:08 ` Mario.Limonciello
2018-07-09 23:17 ` Darren Hart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cc4bc804434a40d9bdd2fa03bbb875aa@ausx13mpc120.AMER.DELL.COM \
--to=mario.limonciello@dell.com \
--cc=alex.hung@canonical.com \
--cc=andy.shevchenko@gmail.com \
--cc=andy@infradead.org \
--cc=dvhart@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rjw@rjwysocki.net \
--cc=srinivas.pandruvada@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®