Re: [PATCH v4] wilco_ec: Add Dell's USB PowerShare Policy control

2019-10-11 Thread Nick Crews
Many thanks Enric!

On Fri, Oct 11, 2019 at 9:08 AM Enric Balletbo i Serra
 wrote:
>
> Hi Daniel, Nick
>
> On 9/10/19 17:00, Nick Crews wrote:
> > On Tue, Oct 8, 2019 at 4:18 PM Daniel Campello  
> > wrote:
> >>
> >> USB PowerShare is a policy which affects charging via the special
> >> USB PowerShare port (marked with a small lightning bolt or battery icon)
> >> when in low power states:
> >> - In S0, the port will always provide power.
> >> - In S0ix, if usb_charge is enabled, then power will be supplied to
> >>   the port when on AC or if battery is > 50%. Else no power is supplied.
> >> - In S5, if usb_charge is enabled, then power will be supplied to
> >>   the port when on AC. Else no power is supplied.
> >>
> >> Signed-off-by: Daniel Campello 
> >> Signed-off-by: Nick Crews 
> >> ---
> >>
> >> v4 changes:
> >> - Renamed from usb_power_share to usb_charge to match existing feature
> >> in other platforms in the kernel (i.e., sony-laptop, samsung-laptop,
> >> lg-laptop)
> >
> > Daniel and I put in considerable effort trying to get this integrated
> > with the USB subsystem. However, it was becoming much too
> > complicated, so we hoped that if we made this more consistent
> > with the three existing examples it would be acceptable.
> >
>
> Agree, let's land as is for now. Prefixed the patch subject with
> "platform/chrome: ", replaced tabs for space in the documentation (to be
> coherent with the rest of the file) and queued for autobuilders to play with. 
> If
> all goes well will be applied for 5.5.
>
> Thanks,
>  Enric
>
>
> > Thanks for the thoughts,
> > Nick
> >
> >> v3 changes:
> >> - Drop a silly blank line
> >> - Use val > 1 instead of val != 0 && val != 1
> >> v2 changes:
> >> - Move documentation to Documentation/ABI/testing/sysfs-platform-wilco-ec
> >> - Zero out reserved bytes in requests.
> >>
> >>  .../ABI/testing/sysfs-platform-wilco-ec   | 17 
> >>  drivers/platform/chrome/wilco_ec/sysfs.c  | 91 +++
> >>  2 files changed, 108 insertions(+)
> >>
> >> diff --git a/Documentation/ABI/testing/sysfs-platform-wilco-ec 
> >> b/Documentation/ABI/testing/sysfs-platform-wilco-ec
> >> index 8827a734f933..bb7ba67cae97 100644
> >> --- a/Documentation/ABI/testing/sysfs-platform-wilco-ec
> >> +++ b/Documentation/ABI/testing/sysfs-platform-wilco-ec
> >> @@ -31,6 +31,23 @@ Description:
> >> Output will a version string be similar to the example 
> >> below:
> >> 08B6
> >>
> >> +What:  /sys/bus/platform/devices/GOOG000C\:00/usb_charge
> >> +Date:  October 2019
> >> +KernelVersion: 5.5
> >> +Description:
> >> +   Control the USB PowerShare Policy. USB PowerShare is a 
> >> policy
> >> +   which affects charging via the special USB PowerShare port
> >> +   (marked with a small lightning bolt or battery icon) when 
> >> in
> >> +   low power states:
> >> +   - In S0, the port will always provide power.
> >> +   - In S0ix, if usb_charge is enabled, then power will be
> >> + supplied to the port when on AC or if battery is > 50%.
> >> + Else no power is supplied.
> >> +   - In S5, if usb_charge is enabled, then power will be 
> >> supplied
> >> + to the port when on AC. Else no power is supplied.
> >> +
> >> +   Input should be either "0" or "1".
> >> +
> >>  What:  /sys/bus/platform/devices/GOOG000C\:00/version
> >>  Date:  May 2019
> >>  KernelVersion: 5.3
> >> diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
> >> b/drivers/platform/chrome/wilco_ec/sysfs.c
> >> index 3b86a21005d3..f0d174b6bb21 100644
> >> --- a/drivers/platform/chrome/wilco_ec/sysfs.c
> >> +++ b/drivers/platform/chrome/wilco_ec/sysfs.c
> >> @@ -23,6 +23,26 @@ struct boot_on_ac_request {
> >> u8 reserved7;
> >>  } __packed;
> >>
> >> +#define CMD_USB_CHARGE 0x39
> >> +
> >> +enum usb_charge_op {
> >> +   USB_CHARGE_GET = 0,
> >> +   USB_CHARGE_SET = 1,
> >> +};
> >> +
> >> +struct usb_charge_reques

Re: [PATCH v4] wilco_ec: Add Dell's USB PowerShare Policy control

2019-10-09 Thread Nick Crews
On Tue, Oct 8, 2019 at 4:18 PM Daniel Campello  wrote:
>
> USB PowerShare is a policy which affects charging via the special
> USB PowerShare port (marked with a small lightning bolt or battery icon)
> when in low power states:
> - In S0, the port will always provide power.
> - In S0ix, if usb_charge is enabled, then power will be supplied to
>   the port when on AC or if battery is > 50%. Else no power is supplied.
> - In S5, if usb_charge is enabled, then power will be supplied to
>   the port when on AC. Else no power is supplied.
>
> Signed-off-by: Daniel Campello 
> Signed-off-by: Nick Crews 
> ---
>
> v4 changes:
> - Renamed from usb_power_share to usb_charge to match existing feature
> in other platforms in the kernel (i.e., sony-laptop, samsung-laptop,
> lg-laptop)

Daniel and I put in considerable effort trying to get this integrated
with the USB subsystem. However, it was becoming much too
complicated, so we hoped that if we made this more consistent
with the three existing examples it would be acceptable.

Thanks for the thoughts,
Nick

> v3 changes:
> - Drop a silly blank line
> - Use val > 1 instead of val != 0 && val != 1
> v2 changes:
> - Move documentation to Documentation/ABI/testing/sysfs-platform-wilco-ec
> - Zero out reserved bytes in requests.
>
>  .../ABI/testing/sysfs-platform-wilco-ec   | 17 
>  drivers/platform/chrome/wilco_ec/sysfs.c  | 91 +++
>  2 files changed, 108 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-platform-wilco-ec 
> b/Documentation/ABI/testing/sysfs-platform-wilco-ec
> index 8827a734f933..bb7ba67cae97 100644
> --- a/Documentation/ABI/testing/sysfs-platform-wilco-ec
> +++ b/Documentation/ABI/testing/sysfs-platform-wilco-ec
> @@ -31,6 +31,23 @@ Description:
> Output will a version string be similar to the example below:
> 08B6
>
> +What:  /sys/bus/platform/devices/GOOG000C\:00/usb_charge
> +Date:  October 2019
> +KernelVersion: 5.5
> +Description:
> +   Control the USB PowerShare Policy. USB PowerShare is a policy
> +   which affects charging via the special USB PowerShare port
> +   (marked with a small lightning bolt or battery icon) when in
> +   low power states:
> +   - In S0, the port will always provide power.
> +   - In S0ix, if usb_charge is enabled, then power will be
> + supplied to the port when on AC or if battery is > 50%.
> + Else no power is supplied.
> +   - In S5, if usb_charge is enabled, then power will be supplied
> + to the port when on AC. Else no power is supplied.
> +
> +   Input should be either "0" or "1".
> +
>  What:  /sys/bus/platform/devices/GOOG000C\:00/version
>  Date:  May 2019
>  KernelVersion: 5.3
> diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
> b/drivers/platform/chrome/wilco_ec/sysfs.c
> index 3b86a21005d3..f0d174b6bb21 100644
> --- a/drivers/platform/chrome/wilco_ec/sysfs.c
> +++ b/drivers/platform/chrome/wilco_ec/sysfs.c
> @@ -23,6 +23,26 @@ struct boot_on_ac_request {
> u8 reserved7;
>  } __packed;
>
> +#define CMD_USB_CHARGE 0x39
> +
> +enum usb_charge_op {
> +   USB_CHARGE_GET = 0,
> +   USB_CHARGE_SET = 1,
> +};
> +
> +struct usb_charge_request {
> +   u8 cmd; /* Always CMD_USB_CHARGE */
> +   u8 reserved;
> +   u8 op;  /* One of enum usb_charge_op */
> +   u8 val; /* When setting, either 0 or 1 */
> +} __packed;
> +
> +struct usb_charge_response {
> +   u8 reserved;
> +   u8 status;  /* Set by EC to 0 on success, other value on failure 
> */
> +   u8 val; /* When getting, set by EC to either 0 or 1 */
> +} __packed;
> +
>  #define CMD_EC_INFO0x38
>  enum get_ec_info_op {
> CMD_GET_EC_LABEL= 0,
> @@ -131,12 +151,83 @@ static ssize_t model_number_show(struct device *dev,
>
>  static DEVICE_ATTR_RO(model_number);
>
> +static int send_usb_charge(struct wilco_ec_device *ec,
> +   struct usb_charge_request *rq,
> +   struct usb_charge_response *rs)
> +{
> +   struct wilco_ec_message msg;
> +   int ret;
> +
> +   memset(, 0, sizeof(msg));
> +   msg.type = WILCO_EC_MSG_LEGACY;
> +   msg.request_data = rq;
> +   msg.request_size = sizeof(*rq);
> +   msg.response_data = rs;
> +   msg.response_size = sizeof(*rs);
> +   ret = wilco_ec_mailbox(ec, );
> +   if (ret < 0)
> +   return r

[PATCH v4] rtc: wilco-ec: Handle reading invalid times

2019-10-04 Thread Nick Crews
If the RTC HW returns an invalid time, the rtc_year_days()
call would crash. This patch adds error logging in this
situation, and removes the tm_yday and tm_wday calculations.
These fields should not be relied upon by userspace
according to man rtc, and thus we don't need to calculate
them.

Signed-off-by: Nick Crews 
---
 drivers/rtc/rtc-wilco-ec.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
index 8ad4c4e6d557..ff46066a68a4 100644
--- a/drivers/rtc/rtc-wilco-ec.c
+++ b/drivers/rtc/rtc-wilco-ec.c
@@ -110,10 +110,12 @@ static int wilco_ec_rtc_read(struct device *dev, struct 
rtc_time *tm)
tm->tm_mday = rtc.day;
tm->tm_mon  = rtc.month - 1;
tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
-   tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+   /* Ignore other tm fields, man rtc says userspace shouldn't use them. */
 
-   /* Don't compute day of week, we don't need it. */
-   tm->tm_wday = -1;
+   if (rtc_valid_tm(tm)) {
+   dev_err(dev, "Time from RTC is invalid: %ptRr\n", tm);
+   return -EIO;
+   }
 
return 0;
 }
-- 
2.21.0



Re: [PATCH v3] rtc: wilco-ec: Handle reading invalid times

2019-10-03 Thread Nick Crews
On Wed, Oct 2, 2019 at 9:20 AM Dmitry Torokhov  wrote:
>
> On Wed, Oct 2, 2019 at 3:32 AM Alexandre Belloni
>  wrote:
> >
> > On 01/10/2019 13:42:24-0700, Dmitry Torokhov wrote:
> > > On Tue, Oct 1, 2019 at 12:53 PM Alexandre Belloni
> > >  wrote:
> > > >
> > > > Hi Nick,
> > > >
> > > > On 25/09/2019 14:32:09-0600, Nick Crews wrote:
> > > > > If the RTC HW returns an invalid time, the rtc_year_days()
> > > > > call would crash. This patch adds error logging in this
> > > > > situation, and removes the tm_yday and tm_wday calculations.
> > > > > These fields should not be relied upon by userspace
> > > > > according to man rtc, and thus we don't need to calculate
> > > > > them.
> > > > >
> > > > > Signed-off-by: Nick Crews 
> > > > > ---
> > > > >  drivers/rtc/rtc-wilco-ec.c | 13 +
> > > > >  1 file changed, 9 insertions(+), 4 deletions(-)
> > > > >
> > > > > diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
> > > > > index 8ad4c4e6d557..53da355d996a 100644
> > > > > --- a/drivers/rtc/rtc-wilco-ec.c
> > > > > +++ b/drivers/rtc/rtc-wilco-ec.c
> > > > > @@ -110,10 +110,15 @@ static int wilco_ec_rtc_read(struct device 
> > > > > *dev, struct rtc_time *tm)
> > > > >   tm->tm_mday = rtc.day;
> > > > >   tm->tm_mon  = rtc.month - 1;
> > > > >   tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
> > > > > - tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, 
> > > > > tm->tm_year);
> > > > > -
> > > > > - /* Don't compute day of week, we don't need it. */
> > > > > - tm->tm_wday = -1;
> > > > > + /* Ignore other tm fields, man rtc says userspace shouldn't use 
> > > > > them. */
> > > > > +
> > > > > + if (rtc_valid_tm(tm)) {
> > > > > + dev_err(dev,
> > > > > +  "Time from RTC is invalid: second=%u, 
> > > > > minute=%u, hour=%u, day=%u, month=%u, year=%u, century=%u",
> > > > > +  rtc.second, rtc.minute, rtc.hour, rtc.day, 
> > > > > rtc.month,
> > > > > +  rtc.year, rtc.century);
> > > >
> > > > Do you mind using %ptR? At this point you already filled the tm struct
> > > > anyway and if you print century separately, you can infer tm_year.
> > >
> > > I do not think this is a good idea: we have just established that tm
> > > does not contain valid data. Does %ptR guarantee that it handles junk
> > > better than, let's say, rtc_year_days(), and does not crash when
> > > presented with garbage?
> > >
> >
> > It is safe to use. You can also use %ptRr if you want to ensure no
> > extra operations are done on the value before printing them out.
>
> OK, I'll keeo this in mind then.

I will resend this using %ptRr, chromium is using 4.19 so I didn't see
that this was added.

>
> >
> > I'm still not convinced it is useful to have an error in dmesg when the
> > time is invalid, as long as userspace knows it is invalid. What is the
> > course of action for the end user when that happens?
>
> Report it, or, in our case, we will see it in the feedback logs.
> However I do agree that it is not the best option, even if we report
> error to userspace I am not sure if it will handle it properly. What
> userspace is supposed to do when presented with -EIO or similar?

Yes, we will be able to see this in feedback logs, which would be valuable.

>
> Nick, do we know the root cause of the EC/RTC reporting invalid time?

No, I haven't really looked into it deeply. It's not limited to the RTC
interface though, it's a problem with the EC or EC communication
in general, as I've noticed similar occasional errors with the other EC
drivers.

>
> Thanks,
> Dmitry


Re: [PATCH -next] platform/chrome: wilco_ec: Use kmemdup in enqueue_events()

2019-09-27 Thread Nick Crews
On Thu, Sep 26, 2019 at 4:43 PM Benson Leung  wrote:
>
> Hey Nick,
> On Fri, Jun 21, 2019 at 7:51 AM Nick Crews  wrote:
> >
> > Thanks Yue, looks good to me.
> >
> > Nick
> >
> > On Fri, Jun 21, 2019 at 7:59 AM YueHaibing  wrote:
> > >
> > > Use kmemdup rather than duplicating its implementation
> > >
> > > Signed-off-by: YueHaibing 
> > > ---
> > >  drivers/platform/chrome/wilco_ec/event.c | 3 +--
> > >  1 file changed, 1 insertion(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/platform/chrome/wilco_ec/event.c 
> > > b/drivers/platform/chrome/wilco_ec/event.c
> > > index c975b76e6255..70156e75047e 100644
> > > --- a/drivers/platform/chrome/wilco_ec/event.c
> > > +++ b/drivers/platform/chrome/wilco_ec/event.c
> > > @@ -248,10 +248,9 @@ static int enqueue_events(struct acpi_device *adev, 
> > > const u8 *buf, u32 length)
> > > offset += event_size;
> > >
> > > /* Copy event into the queue */
> > > -   queue_event = kzalloc(event_size, GFP_KERNEL);
> > > +   queue_event = kmemdup(event, event_size, GFP_KERNEL);
> > > if (!queue_event)
> > > return -ENOMEM;
> > > -   memcpy(queue_event, event, event_size);
> > > event_queue_push(dev_data->events, queue_event);
> > > }
> > >
> > >
> > >
>
> Looks like this was already incorporated into your commit,
> platform/chrome: wilco_ec: Use kmemdup in enqueue_events().

Thanks for the note Benson, but I think that must have
been a copy pasta error, it was actually included in
"platform/chrome: wilco_ec: Add circular buffer as event queue"
just so there isn't any confusion later :)

Nick

>
> Thanks!
> Benson
>
> --
> Benson Leung
> Staff Software Engineer
> Chrome OS Kernel
> Google Inc.
> ble...@google.com
> Chromium OS Project
> ble...@chromium.org


[PATCH v3] rtc: wilco-ec: Handle reading invalid times

2019-09-25 Thread Nick Crews
If the RTC HW returns an invalid time, the rtc_year_days()
call would crash. This patch adds error logging in this
situation, and removes the tm_yday and tm_wday calculations.
These fields should not be relied upon by userspace
according to man rtc, and thus we don't need to calculate
them.

Signed-off-by: Nick Crews 
---
 drivers/rtc/rtc-wilco-ec.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
index 8ad4c4e6d557..53da355d996a 100644
--- a/drivers/rtc/rtc-wilco-ec.c
+++ b/drivers/rtc/rtc-wilco-ec.c
@@ -110,10 +110,15 @@ static int wilco_ec_rtc_read(struct device *dev, struct 
rtc_time *tm)
tm->tm_mday = rtc.day;
tm->tm_mon  = rtc.month - 1;
tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
-   tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
-
-   /* Don't compute day of week, we don't need it. */
-   tm->tm_wday = -1;
+   /* Ignore other tm fields, man rtc says userspace shouldn't use them. */
+
+   if (rtc_valid_tm(tm)) {
+   dev_err(dev,
+"Time from RTC is invalid: second=%u, minute=%u, 
hour=%u, day=%u, month=%u, year=%u, century=%u",
+rtc.second, rtc.minute, rtc.hour, rtc.day, rtc.month,
+rtc.year, rtc.century);
+   return -EIO;
+   }
 
return 0;
 }
-- 
2.21.0



Re: [PATCH v2 1/2] rtc: wilco-ec: Remove yday and wday calculations

2019-09-25 Thread Nick Crews
Hi Alexandre,

Sorry to be a pain, but I passed this by some other Chrome OS
kernel engineers, and when the HW gives a bogus time we
want logging at a more severe level than the dev_dbg() call
in the core, so I'm going to send another revision. It's going to
require duplicated calls to rtc_valid_tm(), but we feel that it is
required.

Thanks,
Nick

On Mon, Sep 23, 2019 at 2:19 PM Alexandre Belloni
 wrote:
>
> On 23/09/2019 11:20:42-0600, Nick Crews wrote:
> > > This is coming from struct tm, it is part of C89 but I think I was not
> > > born when this decision was made. man rtc properly reports that those
> > > fields are unused and no userspace tools are actually making use of
> > > them. Nobody cares about the broken down representation of the time.
> > > What is done is use the ioctl then mktime to have a UNIX timestamp.
> > >
> > > "The mktime function ignores the specified contents of the tm_wday,
> > > tm_yday, tm_gmtoff, and tm_zone members of the broken-down time
> > > structure. It uses the values of the other components to determine the
> > > calendar time; it’s permissible for these components to have
> > > unnormalized values outside their normal ranges. The last thing that
> > > mktime does is adjust the components of the brokentime structure,
> > > including the members that were initially ignored."
> >
> > This is very non-obvious and I only knew this from talking to you,
> > Alexandre. Perhaps we should add this note to the RTC core,
> > such as in the description for rtc_class_ops?
> >
>
> I'm planning to add documentation on what should be done in an RTC
> driver, I'll ensure to add something on this topic.
>
> > For this patch, do you want me to make any further changes?
> >
>
> No need for any changes, however, I can't apply it right now because we
> are in the middle of the merge window.
>
>
> --
> Alexandre Belloni, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


Re: [PATCH v5] platform/chrome: wilco_ec: Add debugfs test_event file

2019-09-24 Thread Nick Crews
Thanks Daniel, looks even better.

On Tue, Sep 24, 2019 at 2:37 PM Daniel Campello  wrote:
>
> This change introduces a new debugfs file 'test_event' that when written
> to causes the EC to generate a test event.
> This adds a second sub cmd for the test event, and pulls out send_ec_cmd
> to be a common helper between h1_gpio_get and test_event_set.
>
> Signed-off-by: Daniel Campello 

Reviewed-by: Nick Crews 

> ---
> Changes for v2:
>   - Cleaned up and added comments.
>   - Renamed and updated function signature from write_to_mailbox to
> send_ec_cmd.
> Changes for v3:
>   - Switched NULL format string to empty format string
>   - Renamed val parameter on send_ec_cmd to out_val
> Changes for v4:
>   - Provided a format string to avoid -Wformat-zero-length warning
> Changes for v5:
>   - Updated commit message to include more implementation details
>   - Restored removed empty line between functions
>
>  drivers/platform/chrome/wilco_ec/debugfs.c | 47 +-
>  1 file changed, 37 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
> b/drivers/platform/chrome/wilco_ec/debugfs.c
> index 8d65a1e2f1a3..df5a5f6c3ec6 100644
> --- a/drivers/platform/chrome/wilco_ec/debugfs.c
> +++ b/drivers/platform/chrome/wilco_ec/debugfs.c
> @@ -160,29 +160,29 @@ static const struct file_operations fops_raw = {
>
>  #define CMD_KB_CHROME  0x88
>  #define SUB_CMD_H1_GPIO0x0A
> +#define SUB_CMD_TEST_EVENT 0x0B
>
> -struct h1_gpio_status_request {
> +struct ec_request {
> u8 cmd; /* Always CMD_KB_CHROME */
> u8 reserved;
> -   u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */
> +   u8 sub_cmd;
>  } __packed;
>
> -struct hi_gpio_status_response {
> +struct ec_response {
> u8 status;  /* 0 if allowed */
> -   u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL */
> +   u8 val;
>  } __packed;
>
> -static int h1_gpio_get(void *arg, u64 *val)
> +static int send_ec_cmd(struct wilco_ec_device *ec, u8 sub_cmd, u8 *out_val)
>  {
> -   struct wilco_ec_device *ec = arg;
> -   struct h1_gpio_status_request rq;
> -   struct hi_gpio_status_response rs;
> +   struct ec_request rq;
> +   struct ec_response rs;
> struct wilco_ec_message msg;
> int ret;
>
> memset(, 0, sizeof(rq));
> rq.cmd = CMD_KB_CHROME;
> -   rq.sub_cmd = SUB_CMD_H1_GPIO;
> +   rq.sub_cmd = sub_cmd;
>
> memset(, 0, sizeof(msg));
> msg.type = WILCO_EC_MSG_LEGACY;
> @@ -196,13 +196,38 @@ static int h1_gpio_get(void *arg, u64 *val)
> if (rs.status)
> return -EIO;
>
> -   *val = rs.val;
> +   *out_val = rs.val;
>
> return 0;
>  }
>
> +/**
> + * h1_gpio_get() - Gets h1 gpio status.
> + * @arg: The wilco EC device.
> + * @val: BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL
> + */
> +static int h1_gpio_get(void *arg, u64 *val)
> +{
> +   return send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val);
> +}
> +
>  DEFINE_DEBUGFS_ATTRIBUTE(fops_h1_gpio, h1_gpio_get, NULL, "0x%02llx\n");
>
> +/**
> + * test_event_set() - Sends command to EC to cause an EC test event.
> + * @arg: The wilco EC device.
> + * @val: unused.
> + */
> +static int test_event_set(void *arg, u64 val)
> +{
> +   u8 ret;
> +
> +   return send_ec_cmd(arg, SUB_CMD_TEST_EVENT, );
> +}
> +
> +/* Format is unused since it is only required for get method which is NULL */
> +DEFINE_DEBUGFS_ATTRIBUTE(fops_test_event, NULL, test_event_set, "%llu\n");
> +
>  /**
>   * wilco_ec_debugfs_probe() - Create the debugfs node
>   * @pdev: The platform device, probably created in core.c
> @@ -226,6 +251,8 @@ static int wilco_ec_debugfs_probe(struct platform_device 
> *pdev)
> debugfs_create_file("raw", 0644, debug_info->dir, NULL, _raw);
> debugfs_create_file("h1_gpio", 0444, debug_info->dir, ec,
> _h1_gpio);
> +   debugfs_create_file("test_event", 0200, debug_info->dir, ec,
> +   _test_event);
>
> return 0;
>  }
> --
> 2.23.0.351.gc4317032e6-goog
>


Re: [PATCH v2 2/2] rtc: wilco-ec: Fix license to GPL from GPLv2

2019-09-24 Thread Nick Crews
On Tue, Sep 24, 2019 at 1:55 AM Pavel Machek  wrote:
>
> On Sun 2019-09-22 22:43:53, Alexandre Belloni wrote:
> > On 22/09/2019 22:29:48+0200, Pavel Machek wrote:
> > > On Mon 2019-09-16 12:12:17, Nick Crews wrote:
> > > > Signed-off-by: Nick Crews 
> > > > ---
> > > >  drivers/rtc/rtc-wilco-ec.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
> > > > index e84faa268caf..951268f5e690 100644
> > > > --- a/drivers/rtc/rtc-wilco-ec.c
> > > > +++ b/drivers/rtc/rtc-wilco-ec.c
> > > > @@ -184,5 +184,5 @@ module_platform_driver(wilco_ec_rtc_driver);
> > > >
> > > >  MODULE_ALIAS("platform:rtc-wilco-ec");
> > > >  MODULE_AUTHOR("Nick Crews ");
> > > > -MODULE_LICENSE("GPL v2");
> > > > +MODULE_LICENSE("GPL");
> > > >  MODULE_DESCRIPTION("Wilco EC RTC driver");
> > >
> > > File spdx header says GPL-2.0, this change would make it inconsistent 
> > > with that...
> >
> > Commit bf7fbeeae6db ("module: Cure the MODULE_LICENSE "GPL" vs. "GPL v2"
> > bogosity") doesn't agree with you (but I was surprised too).
>
> Still don't get it. bf7fbeeae6db makes MODULE_LICENSE less useful, and
> declares "GPL" == "GPL v2" in MODULE_LICENSE. So.. this change is no
> longer wrong, it is just unneccessary...? Why do it? It is not a fix
> as a subject line says...

All new modules should have the plain "GPL", or at least that's what I
was told when I submitted a patch adding a "GPL v2" license. Therefore
I assumed that if the distinction was worthwhile there, I should try to make
existing code consistent too. Sounds fine to me to drop this though,
unless anyone else has strong opinions,

>
> Pavel
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) 
> http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


Re: [PATCH v2 1/2] rtc: wilco-ec: Remove yday and wday calculations

2019-09-23 Thread Nick Crews
On Sun, Sep 22, 2019 at 1:05 PM Alexandre Belloni
 wrote:
>
> On 22/09/2019 18:13:06+0200, Pavel Machek wrote:
> > On Mon 2019-09-16 12:12:15, Nick Crews wrote:
> > > The tm_yday and tm_wday fields are not used by userspace,
> > > so since they aren't needed within the driver, don't
> > > bother calculating them. This is especially needed since
> > > the rtc_year_days() call was crashing if the HW returned
> > > an invalid time.
> > >
> > > Signed-off-by: Nick Crews 
> > > ---
> > >  drivers/rtc/rtc-wilco-ec.c | 4 
> > >  1 file changed, 4 deletions(-)
> > >
> > > diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
> > > index 8ad4c4e6d557..e84faa268caf 100644
> > > --- a/drivers/rtc/rtc-wilco-ec.c
> > > +++ b/drivers/rtc/rtc-wilco-ec.c
> > > @@ -110,10 +110,6 @@ static int wilco_ec_rtc_read(struct device *dev, 
> > > struct rtc_time *tm)
> > > tm->tm_mday = rtc.day;
> > > tm->tm_mon  = rtc.month - 1;
> > > tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
> > > -   tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
> > > -
> > > -   /* Don't compute day of week, we don't need it. */
> > > -   tm->tm_wday = -1;
> > >
> > > return 0;
> >
> > Are you sure? It would be bad to pass unititialized memory to userspace...
> >
>
> This problem doesn't exist because userspace is passing the memory, not
> the other way around.
>
> > If userspace does not need those fields, why are they there?
> >
>
> This is coming from struct tm, it is part of C89 but I think I was not
> born when this decision was made. man rtc properly reports that those
> fields are unused and no userspace tools are actually making use of
> them. Nobody cares about the broken down representation of the time.
> What is done is use the ioctl then mktime to have a UNIX timestamp.
>
> "The mktime function ignores the specified contents of the tm_wday,
> tm_yday, tm_gmtoff, and tm_zone members of the broken-down time
> structure. It uses the values of the other components to determine the
> calendar time; it’s permissible for these components to have
> unnormalized values outside their normal ranges. The last thing that
> mktime does is adjust the components of the brokentime structure,
> including the members that were initially ignored."

This is very non-obvious and I only knew this from talking to you,
Alexandre. Perhaps we should add this note to the RTC core,
such as in the description for rtc_class_ops?

For this patch, do you want me to make any further changes?

Thanks,
Nick

>
>
> --
> Alexandre Belloni, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


Re: [PATCH v2 2/2] rtc: wilco-ec: Fix license to GPL from GPLv2

2019-09-23 Thread Nick Crews
Would you like me to change this patch at all? Perhaps reference
bf7fbeeae6db in the commit description? I probably should have
done that since the beginning, I just couldn't find bf7fbeeae6db at first.

Thanks,
Nick

On Sun, Sep 22, 2019 at 2:43 PM Alexandre Belloni
 wrote:
>
> On 22/09/2019 22:29:48+0200, Pavel Machek wrote:
> > On Mon 2019-09-16 12:12:17, Nick Crews wrote:
> > > Signed-off-by: Nick Crews 
> > > ---
> > >  drivers/rtc/rtc-wilco-ec.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
> > > index e84faa268caf..951268f5e690 100644
> > > --- a/drivers/rtc/rtc-wilco-ec.c
> > > +++ b/drivers/rtc/rtc-wilco-ec.c
> > > @@ -184,5 +184,5 @@ module_platform_driver(wilco_ec_rtc_driver);
> > >
> > >  MODULE_ALIAS("platform:rtc-wilco-ec");
> > >  MODULE_AUTHOR("Nick Crews ");
> > > -MODULE_LICENSE("GPL v2");
> > > +MODULE_LICENSE("GPL");
> > >  MODULE_DESCRIPTION("Wilco EC RTC driver");
> >
> > File spdx header says GPL-2.0, this change would make it inconsistent with 
> > that...
> >
>
> Commit bf7fbeeae6db ("module: Cure the MODULE_LICENSE "GPL" vs. "GPL v2"
> bogosity") doesn't agree with you (but I was surprised too).
>
>
> --
> Alexandre Belloni, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


Re: [PATCH v4] platform/chrome: wilco_ec: Add debugfs test_event file

2019-09-18 Thread Nick Crews
Assuming that the Kbuild bot doesn't get mad about the format string
now, LGTM. Thanks Daniel!

Reviewed-by: Nick Crews 

On Wed, Sep 18, 2019 at 2:43 PM Daniel Campello  wrote:
>
> This change introduces a new debugfs file 'test_event' that when written
> to causes the EC to generate a test event.
>
> Signed-off-by: Daniel Campello 
> ---
> Changes for v2:
>   - Cleaned up and added comments.
>   - Renamed and updated function signature from write_to_mailbox to
> send_ec_cmd.
> Changes for v3:
>   - Switched NULL format string to empty format string
>   - Renamed val parameter on send_ec_cmd to out_val
> Changes for v4:
>   - Provided a format string to avoid -Wformat-zero-length warning
>
>  drivers/platform/chrome/wilco_ec/debugfs.c | 46 +-
>  1 file changed, 36 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
> b/drivers/platform/chrome/wilco_ec/debugfs.c
> index 8d65a1e2f1a3..ba86c38421ff 100644
> --- a/drivers/platform/chrome/wilco_ec/debugfs.c
> +++ b/drivers/platform/chrome/wilco_ec/debugfs.c
> @@ -160,29 +160,29 @@ static const struct file_operations fops_raw = {
>
>  #define CMD_KB_CHROME  0x88
>  #define SUB_CMD_H1_GPIO0x0A
> +#define SUB_CMD_TEST_EVENT 0x0B
>
> -struct h1_gpio_status_request {
> +struct ec_request {
> u8 cmd; /* Always CMD_KB_CHROME */
> u8 reserved;
> -   u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */
> +   u8 sub_cmd;
>  } __packed;
>
> -struct hi_gpio_status_response {
> +struct ec_response {
> u8 status;  /* 0 if allowed */
> -   u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL */
> +   u8 val;
>  } __packed;
>
> -static int h1_gpio_get(void *arg, u64 *val)
> +static int send_ec_cmd(struct wilco_ec_device *ec, u8 sub_cmd, u8 *out_val)
>  {
> -   struct wilco_ec_device *ec = arg;
> -   struct h1_gpio_status_request rq;
> -   struct hi_gpio_status_response rs;
> +   struct ec_request rq;
> +   struct ec_response rs;
> struct wilco_ec_message msg;
> int ret;
>
> memset(, 0, sizeof(rq));
> rq.cmd = CMD_KB_CHROME;
> -   rq.sub_cmd = SUB_CMD_H1_GPIO;
> +   rq.sub_cmd = sub_cmd;
>
> memset(, 0, sizeof(msg));
> msg.type = WILCO_EC_MSG_LEGACY;
> @@ -196,13 +196,37 @@ static int h1_gpio_get(void *arg, u64 *val)
> if (rs.status)
> return -EIO;
>
> -   *val = rs.val;
> +   *out_val = rs.val;
>
> return 0;
>  }
> +/**
> + * h1_gpio_get() - Gets h1 gpio status.
> + * @arg: The wilco EC device.
> + * @val: BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL
> + */
> +static int h1_gpio_get(void *arg, u64 *val)
> +{
> +   return send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val);
> +}
>
>  DEFINE_DEBUGFS_ATTRIBUTE(fops_h1_gpio, h1_gpio_get, NULL, "0x%02llx\n");
>
> +/**
> + * test_event_set() - Sends command to EC to cause an EC test event.
> + * @arg: The wilco EC device.
> + * @val: unused.
> + */
> +static int test_event_set(void *arg, u64 val)
> +{
> +   u8 ret;
> +
> +   return send_ec_cmd(arg, SUB_CMD_TEST_EVENT, );
> +}
> +
> +/* Format is unused since it is only required for get method which is NULL */
> +DEFINE_DEBUGFS_ATTRIBUTE(fops_test_event, NULL, test_event_set, "%llu\n");
> +
>  /**
>   * wilco_ec_debugfs_probe() - Create the debugfs node
>   * @pdev: The platform device, probably created in core.c
> @@ -226,6 +250,8 @@ static int wilco_ec_debugfs_probe(struct platform_device 
> *pdev)
> debugfs_create_file("raw", 0644, debug_info->dir, NULL, _raw);
> debugfs_create_file("h1_gpio", 0444, debug_info->dir, ec,
> _h1_gpio);
> +   debugfs_create_file("test_event", 0200, debug_info->dir, ec,
> +   _test_event);
>
> return 0;
>  }
> --
> 2.23.0.237.gc6a4ce50a0-goog
>


[PATCH v2 1/2] rtc: wilco-ec: Remove yday and wday calculations

2019-09-16 Thread Nick Crews
The tm_yday and tm_wday fields are not used by userspace,
so since they aren't needed within the driver, don't
bother calculating them. This is especially needed since
the rtc_year_days() call was crashing if the HW returned
an invalid time.

Signed-off-by: Nick Crews 
---
 drivers/rtc/rtc-wilco-ec.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
index 8ad4c4e6d557..e84faa268caf 100644
--- a/drivers/rtc/rtc-wilco-ec.c
+++ b/drivers/rtc/rtc-wilco-ec.c
@@ -110,10 +110,6 @@ static int wilco_ec_rtc_read(struct device *dev, struct 
rtc_time *tm)
tm->tm_mday = rtc.day;
tm->tm_mon  = rtc.month - 1;
tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
-   tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
-
-   /* Don't compute day of week, we don't need it. */
-   tm->tm_wday = -1;
 
return 0;
 }
-- 
2.21.0



[PATCH v2 2/2] rtc: wilco-ec: Fix license to GPL from GPLv2

2019-09-16 Thread Nick Crews
Signed-off-by: Nick Crews 
---
 drivers/rtc/rtc-wilco-ec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
index e84faa268caf..951268f5e690 100644
--- a/drivers/rtc/rtc-wilco-ec.c
+++ b/drivers/rtc/rtc-wilco-ec.c
@@ -184,5 +184,5 @@ module_platform_driver(wilco_ec_rtc_driver);
 
 MODULE_ALIAS("platform:rtc-wilco-ec");
 MODULE_AUTHOR("Nick Crews ");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Wilco EC RTC driver");
-- 
2.21.0



Re: [PATCH] rtc: wilco-ec: Sanitize values received from RTC

2019-09-16 Thread Nick Crews
On Mon, Sep 16, 2019 at 2:02 AM Alexandre Belloni
 wrote:
>
> On 15/09/2019 23:44:03+0100, Nick Crews wrote:
> > Hi Alexandre, thanks for the thoughts.
> >
> > On Thu, Sep 12, 2019 at 9:09 AM Alexandre Belloni
> >  wrote:
> > >
> > > Hi Nick,
> > >
> > > On 10/09/2019 16:19:29+0100, Nick Crews wrote:
> > > > Check that the time received from the RTC HW is valid,
> > > > otherwise the computation of rtc_year_days() in the next
> > > > line could, and sometimes does, crash the kernel.
> > > >
> > > > While we're at it, fix the license to plain "GPL".
> > > >
> > > > Signed-off-by: Nick Crews 
> > > > ---
> > > >  drivers/rtc/rtc-wilco-ec.c | 12 ++--
> > > >  1 file changed, 10 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
> > > > index 8ad4c4e6d557..0ccbf2dce832 100644
> > > > --- a/drivers/rtc/rtc-wilco-ec.c
> > > > +++ b/drivers/rtc/rtc-wilco-ec.c
> > > > @@ -110,8 +110,16 @@ static int wilco_ec_rtc_read(struct device *dev, 
> > > > struct rtc_time *tm)
> > > >   tm->tm_mday = rtc.day;
> > > >   tm->tm_mon  = rtc.month - 1;
> > > >   tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
> > > > - tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, 
> > > > tm->tm_year);
> > >
> > > If your driver doesn't care about yday, userspace doesn't either. You
> > > can simply not set it.
> >
> > This driver indeed does not care about yday, so it sounds good to me
> > to simply not set it. However, I do still want to worry about the HW
> > returning some bogus time. It could be indicative of some other problem,
> > and I don't want to pass on this illegal time further up the stack. I can't
> > think of a reason why an illegal time should exist at all, we should just
> > deal with it as soon as possible. How about I remove setting yday as
> > you suggest, but still keep the rtc_valid_tm() check?
> >
>
> As rtc_valid_tm would be the last thing the driver does in the callback
> and the first thing the core does after returning from the callback,
> you'd get two calls back to back which is not useful.

Ah, I see now where the core checks that the time is valid
in interface.c. Sounds good, I'll skip the check then.

>
> > >
> > > >
> > > > + if (rtc_valid_tm(tm)) {
> > > > + dev_warn(dev,
> > > > +  "Time computed from EC RTC is invalid: sec=%d, 
> > > > min=%d, hour=%d, mday=%d, mon=%d, year=%d",
> > > > +  tm->tm_sec, tm->tm_min, tm->tm_hour, tm->mday,
> > > > +  tm->mon, tm->year);
> > > > + return -EIO;
> > > > + }
> > > > +
> > > > + tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
> > > >   /* Don't compute day of week, we don't need it. */
> > > >   tm->tm_wday = -1;
> >
> > Following our discussion, perhaps I'll just remove this too since the
> > RTC core inits this to -1 already?
> >
>
> You can remove it.

Will do!

>
>
> --
> Alexandre Belloni, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


Re: [PATCH] rtc: wilco-ec: Sanitize values received from RTC

2019-09-15 Thread Nick Crews
Hi Alexandre, thanks for the thoughts.

On Thu, Sep 12, 2019 at 9:09 AM Alexandre Belloni
 wrote:
>
> Hi Nick,
>
> On 10/09/2019 16:19:29+0100, Nick Crews wrote:
> > Check that the time received from the RTC HW is valid,
> > otherwise the computation of rtc_year_days() in the next
> > line could, and sometimes does, crash the kernel.
> >
> > While we're at it, fix the license to plain "GPL".
> >
> > Signed-off-by: Nick Crews 
> > ---
> >  drivers/rtc/rtc-wilco-ec.c | 12 ++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
> > index 8ad4c4e6d557..0ccbf2dce832 100644
> > --- a/drivers/rtc/rtc-wilco-ec.c
> > +++ b/drivers/rtc/rtc-wilco-ec.c
> > @@ -110,8 +110,16 @@ static int wilco_ec_rtc_read(struct device *dev, 
> > struct rtc_time *tm)
> >   tm->tm_mday = rtc.day;
> >   tm->tm_mon  = rtc.month - 1;
> >   tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
> > - tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
>
> If your driver doesn't care about yday, userspace doesn't either. You
> can simply not set it.

This driver indeed does not care about yday, so it sounds good to me
to simply not set it. However, I do still want to worry about the HW
returning some bogus time. It could be indicative of some other problem,
and I don't want to pass on this illegal time further up the stack. I can't
think of a reason why an illegal time should exist at all, we should just
deal with it as soon as possible. How about I remove setting yday as
you suggest, but still keep the rtc_valid_tm() check?

>
> >
> > + if (rtc_valid_tm(tm)) {
> > + dev_warn(dev,
> > +  "Time computed from EC RTC is invalid: sec=%d, 
> > min=%d, hour=%d, mday=%d, mon=%d, year=%d",
> > +  tm->tm_sec, tm->tm_min, tm->tm_hour, tm->mday,
> > +  tm->mon, tm->year);
> > + return -EIO;
> > + }
> > +
> > + tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
> >   /* Don't compute day of week, we don't need it. */
> >   tm->tm_wday = -1;

Following our discussion, perhaps I'll just remove this too since the
RTC core inits this to -1 already?

> >
> > @@ -188,5 +196,5 @@ module_platform_driver(wilco_ec_rtc_driver);
> >
> >  MODULE_ALIAS("platform:rtc-wilco-ec");
> >  MODULE_AUTHOR("Nick Crews ");
> > -MODULE_LICENSE("GPL v2");
> > +MODULE_LICENSE("GPL");
>
> This should be in a separate patch.

OK, I'll separate this out :)

>
> >  MODULE_DESCRIPTION("Wilco EC RTC driver");
> > --
> > 2.11.0
> >
>
> --
> Alexandre Belloni, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


[PATCH] rtc: wilco-ec: Sanitize values received from RTC

2019-09-10 Thread Nick Crews
Check that the time received from the RTC HW is valid,
otherwise the computation of rtc_year_days() in the next
line could, and sometimes does, crash the kernel.

While we're at it, fix the license to plain "GPL".

Signed-off-by: Nick Crews 
---
 drivers/rtc/rtc-wilco-ec.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
index 8ad4c4e6d557..0ccbf2dce832 100644
--- a/drivers/rtc/rtc-wilco-ec.c
+++ b/drivers/rtc/rtc-wilco-ec.c
@@ -110,8 +110,16 @@ static int wilco_ec_rtc_read(struct device *dev, struct 
rtc_time *tm)
tm->tm_mday = rtc.day;
tm->tm_mon  = rtc.month - 1;
tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
-   tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
 
+   if (rtc_valid_tm(tm)) {
+   dev_warn(dev,
+"Time computed from EC RTC is invalid: sec=%d, min=%d, 
hour=%d, mday=%d, mon=%d, year=%d",
+tm->tm_sec, tm->tm_min, tm->tm_hour, tm->mday,
+tm->mon, tm->year);
+   return -EIO;
+   }
+
+   tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
/* Don't compute day of week, we don't need it. */
tm->tm_wday = -1;
 
@@ -188,5 +196,5 @@ module_platform_driver(wilco_ec_rtc_driver);
 
 MODULE_ALIAS("platform:rtc-wilco-ec");
 MODULE_AUTHOR("Nick Crews ");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Wilco EC RTC driver");
-- 
2.11.0



Re: [PATCH] platform/chrome: wilco_ec: Add debugfs test_event file

2019-09-06 Thread Nick Crews
Thanks for the patch Daniel! A few thoughts that I didn't
have on the review on Gerrit, sorry :) After those changes,

Reviewed-by: Nick Crews 

On Fri, Sep 6, 2019 at 4:42 PM Daniel Campello  wrote:
>
> This change introduces a new debugfs file 'test_event' that when written
> to causes the EC to generate a test event.
>
> Signed-off-by: Daniel Campello 
> ---
>
>  drivers/platform/chrome/wilco_ec/debugfs.c | 33 +-
>  1 file changed, 26 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
> b/drivers/platform/chrome/wilco_ec/debugfs.c
> index 8d65a1e2f1a3..2103c3ed8385 100644
> --- a/drivers/platform/chrome/wilco_ec/debugfs.c
> +++ b/drivers/platform/chrome/wilco_ec/debugfs.c
> @@ -160,29 +160,29 @@ static const struct file_operations fops_raw = {
>
>  #define CMD_KB_CHROME  0x88
>  #define SUB_CMD_H1_GPIO0x0A
> +#define SUB_CMD_TEST_EVENT 0x0B
>
> -struct h1_gpio_status_request {
> +struct ec_request {
> u8 cmd; /* Always CMD_KB_CHROME */
> u8 reserved;
> u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */

This comment should be removed.

>  } __packed;
>
> -struct hi_gpio_status_response {
> +struct ec_response {
> u8 status;  /* 0 if allowed */
> u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL */

This comment should be moved to h1_gpio_get().

>  } __packed;
>
> -static int h1_gpio_get(void *arg, u64 *val)
> +static int write_to_mailbox(struct wilco_ec_device *ec, u8 sub_cmd, u64 *val)

What about send_ec_cmd() or similar? Something that communicates that
we are sometimes telling the EC to do something, and sometimes reading something
back. Also, since we are adding in another layer in here, we can fix
the signature from
the one required by a debugfs attribute. Use "ret" instead of "val"
and make it a u8*.

>  {
> -   struct wilco_ec_device *ec = arg;
> -   struct h1_gpio_status_request rq;
> -   struct hi_gpio_status_response rs;
> +   struct ec_request rq;
> +   struct ec_response rs;
> struct wilco_ec_message msg;
> int ret;
>
> memset(, 0, sizeof(rq));
> rq.cmd = CMD_KB_CHROME;
> -   rq.sub_cmd = SUB_CMD_H1_GPIO;
> +   rq.sub_cmd = sub_cmd;
>
> memset(, 0, sizeof(msg));
> msg.type = WILCO_EC_MSG_LEGACY;
> @@ -201,8 +201,25 @@ static int h1_gpio_get(void *arg, u64 *val)
> return 0;
>  }
>
> +static int h1_gpio_get(void *arg, u64 *val)
> +{
> +   return write_to_mailbox(arg, SUB_CMD_H1_GPIO, val);
> +}
> +
>  DEFINE_DEBUGFS_ATTRIBUTE(fops_h1_gpio, h1_gpio_get, NULL, "0x%02llx\n");
>

A one line comment as to what test_event does?

> +static int test_event_set(void *arg, u64 val)
> +{
> +   u64 ret;
> +
> +   return write_to_mailbox(arg, SUB_CMD_TEST_EVENT, );
> +}
> +
> +/* Format set to NULL since it is only used on read operations which are
> + * forbidden by file permissions.
> + */
> +DEFINE_DEBUGFS_ATTRIBUTE(fops_test_event, NULL, test_event_set, NULL);
> +
>  /**
>   * wilco_ec_debugfs_probe() - Create the debugfs node
>   * @pdev: The platform device, probably created in core.c
> @@ -226,6 +243,8 @@ static int wilco_ec_debugfs_probe(struct platform_device 
> *pdev)
> debugfs_create_file("raw", 0644, debug_info->dir, NULL, _raw);
> debugfs_create_file("h1_gpio", 0444, debug_info->dir, ec,
> _h1_gpio);
> +   debugfs_create_file("test_event", 0200, debug_info->dir, ec,
> +   _test_event);
>
> return 0;
>  }
> --
> 2.23.0.162.g0b9fbb3734-goog
>


Re: Policy to keep USB ports powered in low-power states

2019-08-29 Thread Nick Crews
On Tue, Aug 27, 2019 at 8:29 AM Enric Balletbo i Serra
 wrote:
>
> Hi,
>
> On 16/8/19 19:02, Duncan Laurie wrote:
> > On Fri, Aug 16, 2019 at 2:12 AM Greg Kroah-Hartman
> >  wrote:
> >>
> >> On Thu, Aug 15, 2019 at 05:42:05PM -0600, Duncan Laurie wrote:
> >>> On Wed, Aug 14, 2019 at 6:08 PM Nick Crews  wrote:
> >>>>
> >>>> Adding Duncan Laurie who I think has some more intimate knowledge
> >>>> of how this is implemented in HW. Duncan, could you correct or elaborate
> >>>> on my answers below as you see fit? Also, sorry if I make some beginner
> >>>> mistakes here, I'm just getting familiar with the USB subsystem, and 
> >>>> thanks for
> >>>> your patience.
> >>>>
> >>>> On Wed, Aug 14, 2019 at 3:20 PM Greg Kroah-Hartman
> >>>>  wrote:
> >>>>>
> >>>>> On Wed, Aug 14, 2019 at 02:12:07PM -0600, Nick Crews wrote:
> >>>>>> Thanks for the fast response!
> >>>>>>
> >>>>>> On Tue, Aug 13, 2019 at 12:02 AM Greg Kroah-Hartman
> >>>>>>  wrote:
> >>>>>>>
> >>>>>>> On Mon, Aug 12, 2019 at 06:08:43PM -0600, Nick Crews wrote:
> >>>>>>>> Hi Greg!
> >>>>>>>
> >>>>>>> Hi!
> >>>>>>>
> >>>>>>> First off, please fix your email client to not send html so that vger
> >>>>>>> does not reject your messages :)
> >>>>>>
> >>>>>> Thanks, should be good now.
> >>>>>>
> >>>>>>>
> >>>>>>>> I am working on a Chrome OS device that supports a policy called 
> >>>>>>>> "USB Power
> >>>>>>>> Share," which allows users to turn the laptop into a charge pack for 
> >>>>>>>> their
> >>>>>>>> phone. When the policy is enabled, power will be supplied to the USB 
> >>>>>>>> ports
> >>>>>>>> even when the system is in low power states such as S3 and S5. When
> >>>>>>>> disabled, then no power will be supplied in S3 and S5. I wrote a 
> >>>>>>>> driver
> >>>>>>>> <https://lore.kernel.org/patchwork/patch/1062995/> for this already 
> >>>>>>>> as part
> >>>>>>>> of drivers/platform/chrome/, but Enric Balletbo i Serra, the 
> >>>>>>>> maintainer,
> >>>>>>>> had the reasonable suggestion of trying to move this into the USB 
> >>>>>>>> subsystem.
> >>>>>>>
> >>>>>>> Correct suggestion.
> >>>>>>>
> >>>>>>>> Has anything like this been done before? Do you have any preliminary
> >>>>>>>> thoughts on this before I start writing code? A few things that I 
> >>>>>>>> haven't
> >>>>>>>> figured out yet:
> >>>>>>>> - How to make this feature only available on certain devices. Using 
> >>>>>>>> device
> >>>>>>>> tree? Kconfig? Making a separate driver just for this device that 
> >>>>>>>> plugs
> >>>>>>>> into the USB core?
> >>>>>>>> - The feature is only supported on some USB ports, so we need a way 
> >>>>>>>> of
> >>>>>>>> filtering on a per-port basis.
> >>>>>>>
> >>>>>>> Look at the drivers/usb/typec/ code, I think that should do everything
> >>>>>>> you need here as this is a typec standard functionality, right?
> >>>>>>
> >>>>>> Unfortunately this is for USB 2.0 ports, so it's not type-C.
> >>>>>> Is the type-C code still worth looking at?
> >>>>>
> >>>>> If this is for USB 2, does it use the "non-standard" hub commands to
> >>>>> turn on and off power?  If so, why not just use the usbreset userspace
> >>>>> program for that?
> >>>>
> >>>> It does not use the standard hub commands. The USB ports are controlled
> >>>> by an Embedded Controller (EC), so to control this policy we send a 
> >>&g

Re: [PATCH] platform/chrome: wilco_ec: Add batt_ppid_info command to telemetry driver

2019-08-22 Thread Nick Crews
Friendly bump on this :)

On Mon, Aug 5, 2019 at 2:22 PM Nick Crews  wrote:
>
> Add the GET_BATT_PPID_INFO=0x8A command to the allowlist of accepted
> telemetry commands. In addition, since this new command requires
> verifying the contents of some of the arguments, I also restructure
> the request to use a union of the argument structs. Also, zero out the
> request buffer before each request, and change "whitelist" to
> "allowlist".
>
> Signed-off-by: Nick Crews 
> ---
>  drivers/platform/chrome/wilco_ec/telemetry.c | 64 +---
>  1 file changed, 43 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c 
> b/drivers/platform/chrome/wilco_ec/telemetry.c
> index 94cdc166c840..b9d03c33d8dc 100644
> --- a/drivers/platform/chrome/wilco_ec/telemetry.c
> +++ b/drivers/platform/chrome/wilco_ec/telemetry.c
> @@ -9,7 +9,7 @@
>   * the OS sends a command to the EC via a write() to a char device,
>   * and can read the response with a read(). The write() request is
>   * verified by the driver to ensure that it is performing only one
> - * of the whitelisted commands, and that no extraneous data is
> + * of the allowlisted commands, and that no extraneous data is
>   * being transmitted to the EC. The response is passed directly
>   * back to the reader with no modification.
>   *
> @@ -59,21 +59,10 @@ static DEFINE_IDA(telem_ida);
>  #define WILCO_EC_TELEM_GET_TEMP_INFO   0x95
>  #define WILCO_EC_TELEM_GET_TEMP_READ   0x2C
>  #define WILCO_EC_TELEM_GET_BATT_EXT_INFO   0x07
> +#define WILCO_EC_TELEM_GET_BATT_PPID_INFO  0x8A
>
>  #define TELEM_ARGS_SIZE_MAX30
>
> -/**
> - * struct wilco_ec_telem_request - Telemetry command and arguments sent to 
> EC.
> - * @command: One of WILCO_EC_TELEM_GET_* command codes.
> - * @reserved: Must be 0.
> - * @args: The first N bytes are one of telem_args_get_* structs, the rest is 
> 0.
> - */
> -struct wilco_ec_telem_request {
> -   u8 command;
> -   u8 reserved;
> -   u8 args[TELEM_ARGS_SIZE_MAX];
> -} __packed;
> -
>  /*
>   * The following telem_args_get_* structs are embedded within the |args| 
> field
>   * of wilco_ec_telem_request.
> @@ -122,6 +111,32 @@ struct telem_args_get_batt_ext_info {
> u8 var_args[5];
>  } __packed;
>
> +struct telem_args_get_batt_ppid_info {
> +   u8 always1; /* Should always be 1 */
> +} __packed;
> +
> +/**
> + * struct wilco_ec_telem_request - Telemetry command and arguments sent to 
> EC.
> + * @command: One of WILCO_EC_TELEM_GET_* command codes.
> + * @reserved: Must be 0.
> + * @args: The first N bytes are one of telem_args_get_* structs, the rest is 
> 0.
> + */
> +struct wilco_ec_telem_request {
> +   u8 command;
> +   u8 reserved;
> +   union {
> +   u8 buf[TELEM_ARGS_SIZE_MAX];
> +   struct telem_args_get_log   get_log;
> +   struct telem_args_get_version   get_version;
> +   struct telem_args_get_fan_info  get_fan_info;
> +   struct telem_args_get_diag_info get_diag_info;
> +   struct telem_args_get_temp_info get_temp_info;
> +   struct telem_args_get_temp_read get_temp_read;
> +   struct telem_args_get_batt_ext_info get_batt_ext_info;
> +   struct telem_args_get_batt_ppid_infoget_batt_ppid_info;
> +   } args;
> +} __packed;
> +
>  /**
>   * check_telem_request() - Ensure that a request from userspace is valid.
>   * @rq: Request buffer copied from userspace.
> @@ -133,7 +148,7 @@ struct telem_args_get_batt_ext_info {
>   * We do not want to allow userspace to send arbitrary telemetry commands to
>   * the EC. Therefore we check to ensure that
>   * 1. The request follows the format of struct wilco_ec_telem_request.
> - * 2. The supplied command code is one of the whitelisted commands.
> + * 2. The supplied command code is one of the allowlisted commands.
>   * 3. The request only contains the necessary data for the header and 
> arguments.
>   */
>  static int check_telem_request(struct wilco_ec_telem_request *rq,
> @@ -146,25 +161,31 @@ static int check_telem_request(struct 
> wilco_ec_telem_request *rq,
>
> switch (rq->command) {
> case WILCO_EC_TELEM_GET_LOG:
> -   max_size += sizeof(struct telem_args_get_log);
> +   max_size += sizeof(rq->args.get_log);
> break;
> case WILCO_EC_TELEM_GET_VERSION:
> -   max_size += sizeof(struct telem_args_get_version);
> +   max_size += sizeof(rq->args.get_version);
>   

[PATCH] platform/chrome: wilco_ec: Add batt_ppid_info command to telemetry driver

2019-08-05 Thread Nick Crews
Add the GET_BATT_PPID_INFO=0x8A command to the allowlist of accepted
telemetry commands. In addition, since this new command requires
verifying the contents of some of the arguments, I also restructure
the request to use a union of the argument structs. Also, zero out the
request buffer before each request, and change "whitelist" to
"allowlist".

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/telemetry.c | 64 +---
 1 file changed, 43 insertions(+), 21 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c 
b/drivers/platform/chrome/wilco_ec/telemetry.c
index 94cdc166c840..b9d03c33d8dc 100644
--- a/drivers/platform/chrome/wilco_ec/telemetry.c
+++ b/drivers/platform/chrome/wilco_ec/telemetry.c
@@ -9,7 +9,7 @@
  * the OS sends a command to the EC via a write() to a char device,
  * and can read the response with a read(). The write() request is
  * verified by the driver to ensure that it is performing only one
- * of the whitelisted commands, and that no extraneous data is
+ * of the allowlisted commands, and that no extraneous data is
  * being transmitted to the EC. The response is passed directly
  * back to the reader with no modification.
  *
@@ -59,21 +59,10 @@ static DEFINE_IDA(telem_ida);
 #define WILCO_EC_TELEM_GET_TEMP_INFO   0x95
 #define WILCO_EC_TELEM_GET_TEMP_READ   0x2C
 #define WILCO_EC_TELEM_GET_BATT_EXT_INFO   0x07
+#define WILCO_EC_TELEM_GET_BATT_PPID_INFO  0x8A
 
 #define TELEM_ARGS_SIZE_MAX30
 
-/**
- * struct wilco_ec_telem_request - Telemetry command and arguments sent to EC.
- * @command: One of WILCO_EC_TELEM_GET_* command codes.
- * @reserved: Must be 0.
- * @args: The first N bytes are one of telem_args_get_* structs, the rest is 0.
- */
-struct wilco_ec_telem_request {
-   u8 command;
-   u8 reserved;
-   u8 args[TELEM_ARGS_SIZE_MAX];
-} __packed;
-
 /*
  * The following telem_args_get_* structs are embedded within the |args| field
  * of wilco_ec_telem_request.
@@ -122,6 +111,32 @@ struct telem_args_get_batt_ext_info {
u8 var_args[5];
 } __packed;
 
+struct telem_args_get_batt_ppid_info {
+   u8 always1; /* Should always be 1 */
+} __packed;
+
+/**
+ * struct wilco_ec_telem_request - Telemetry command and arguments sent to EC.
+ * @command: One of WILCO_EC_TELEM_GET_* command codes.
+ * @reserved: Must be 0.
+ * @args: The first N bytes are one of telem_args_get_* structs, the rest is 0.
+ */
+struct wilco_ec_telem_request {
+   u8 command;
+   u8 reserved;
+   union {
+   u8 buf[TELEM_ARGS_SIZE_MAX];
+   struct telem_args_get_log   get_log;
+   struct telem_args_get_version   get_version;
+   struct telem_args_get_fan_info  get_fan_info;
+   struct telem_args_get_diag_info get_diag_info;
+   struct telem_args_get_temp_info get_temp_info;
+   struct telem_args_get_temp_read get_temp_read;
+   struct telem_args_get_batt_ext_info get_batt_ext_info;
+   struct telem_args_get_batt_ppid_infoget_batt_ppid_info;
+   } args;
+} __packed;
+
 /**
  * check_telem_request() - Ensure that a request from userspace is valid.
  * @rq: Request buffer copied from userspace.
@@ -133,7 +148,7 @@ struct telem_args_get_batt_ext_info {
  * We do not want to allow userspace to send arbitrary telemetry commands to
  * the EC. Therefore we check to ensure that
  * 1. The request follows the format of struct wilco_ec_telem_request.
- * 2. The supplied command code is one of the whitelisted commands.
+ * 2. The supplied command code is one of the allowlisted commands.
  * 3. The request only contains the necessary data for the header and 
arguments.
  */
 static int check_telem_request(struct wilco_ec_telem_request *rq,
@@ -146,25 +161,31 @@ static int check_telem_request(struct 
wilco_ec_telem_request *rq,
 
switch (rq->command) {
case WILCO_EC_TELEM_GET_LOG:
-   max_size += sizeof(struct telem_args_get_log);
+   max_size += sizeof(rq->args.get_log);
break;
case WILCO_EC_TELEM_GET_VERSION:
-   max_size += sizeof(struct telem_args_get_version);
+   max_size += sizeof(rq->args.get_version);
break;
case WILCO_EC_TELEM_GET_FAN_INFO:
-   max_size += sizeof(struct telem_args_get_fan_info);
+   max_size += sizeof(rq->args.get_fan_info);
break;
case WILCO_EC_TELEM_GET_DIAG_INFO:
-   max_size += sizeof(struct telem_args_get_diag_info);
+   max_size += sizeof(rq->args.get_diag_info);
break;
case WILCO_EC_TELEM_GET_TEMP_INFO:
-   max_size += sizeof(struct telem_args_get_temp_info);
+   max_size += sizeof(rq->args.get_temp_info);
break;
   

Re: [PATCH v4 1/1] power/supply/sbs-battery: Fix confusing battery status when idle or empty

2019-08-01 Thread Nick Crews
Thanks Richard, I still would like some more opinions
on this changing the userspace experience, but LGTM
otherwise.

Reviewed-by: Nick Crews 

On Mon, Jul 29, 2019 at 8:00 PM Richard Tresidder
 wrote:
>
> When a battery or batteries in a system are in parallel then one or more
> may not be providing any current to the system.
> This fixes an incorrect status indication of FULL for the battery simply
> because it wasn't discharging at that point in time.
> The battery will now be flagged as NOT CHARGING.
> Have also added the additional check for the battery FULL DISCHARGED flag
> which will now flag a status of EMPTY.
>
> Signed-off-by: Richard Tresidder 
> ---
>
> Notes:
> power/supply/sbs-battery: Fix confusing battery status when idle or empty
>
> When a battery or batteries in a system are in parallel then one or more
> may not be providing any current to the system.
> This fixes an incorrect status indication of FULL for the battery simply
> because it wasn't discharging at that point in time.
> The battery will now be flagged as NOT CHARGING.
> Have also added the additional check for the battery FULL DISCHARGED flag
> which will now flag a status of EMPTY.
>
> v2: Missed a later merge that should have been included in original patch
> v3: Refactor the sbs_status_correct function to capture all the states for
> normal operation rather than being spread across multile functions.
> v4: Remove unnecessary brackets, rename sbs_status_correct to
> sbs_correct_battery_status
>
>  drivers/power/supply/power_supply_sysfs.c |  2 +-
>  drivers/power/supply/sbs-battery.c| 46 
> ---
>  include/linux/power_supply.h  |  1 +
>  3 files changed, 19 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/power/supply/power_supply_sysfs.c 
> b/drivers/power/supply/power_supply_sysfs.c
> index f37ad4e..305e833 100644
> --- a/drivers/power/supply/power_supply_sysfs.c
> +++ b/drivers/power/supply/power_supply_sysfs.c
> @@ -51,7 +51,7 @@
>  };
>
>  static const char * const power_supply_status_text[] = {
> -   "Unknown", "Charging", "Discharging", "Not charging", "Full"
> +   "Unknown", "Charging", "Discharging", "Not charging", "Full", "Empty"
>  };
>
>  static const char * const power_supply_charge_type_text[] = {
> diff --git a/drivers/power/supply/sbs-battery.c 
> b/drivers/power/supply/sbs-battery.c
> index 048d205..3ed70d4 100644
> --- a/drivers/power/supply/sbs-battery.c
> +++ b/drivers/power/supply/sbs-battery.c
> @@ -283,7 +283,7 @@ static int sbs_write_word_data(struct i2c_client *client, 
> u8 address,
> return 0;
>  }
>
> -static int sbs_status_correct(struct i2c_client *client, int *intval)
> +static int sbs_correct_battery_status(struct i2c_client *client, int *status)
>  {
> int ret;
>
> @@ -293,16 +293,18 @@ static int sbs_status_correct(struct i2c_client 
> *client, int *intval)
>
> ret = (s16)ret;
>
> -   /* Not drawing current means full (cannot be not charging) */
> -   if (ret == 0)
> -   *intval = POWER_SUPPLY_STATUS_FULL;
> -
> -   if (*intval == POWER_SUPPLY_STATUS_FULL) {
> -   /* Drawing or providing current when full */
> -   if (ret > 0)
> -   *intval = POWER_SUPPLY_STATUS_CHARGING;
> -   else if (ret < 0)
> -   *intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +   if (ret > 0)
> +   *status = POWER_SUPPLY_STATUS_CHARGING;
> +   else if (ret < 0)
> +   *status = POWER_SUPPLY_STATUS_DISCHARGING;
> +   else {
> +   /* Current is 0, so how full is the battery? */
> +   if (*status & BATTERY_FULL_CHARGED)
> +   *status = POWER_SUPPLY_STATUS_FULL;
> +   else if (*status & BATTERY_FULL_DISCHARGED)
> +   *status = POWER_SUPPLY_STATUS_EMPTY;
> +   else
> +   *status = POWER_SUPPLY_STATUS_NOT_CHARGING;
> }
>
> return 0;
> @@ -421,14 +423,9 @@ static int sbs_get_battery_property(struct i2c_client 
> *client,
> return 0;
> }
>
> -   if (ret & BATTERY_FULL_CHARGED)
> -   val->intval = POWER_SUPPLY_STATUS_FULL;
> -   else if (ret & BATTERY_DISCHARGING)
> -   val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> -   else
> -   val-&g

Re: [PATCH v3 1/1] power/supply/sbs-battery: Fix confusing battery status when idle or empty

2019-07-29 Thread Nick Crews
On Mon, Jul 29, 2019 at 2:07 AM Richard Tresidder
 wrote:
>
> When a battery or batteries in a system are in parallel then one or more
> may not be providing any current to the system.
> This fixes an incorrect status indication of FULL for the battery simply
> because it wasn't discharging at that point in time.
> The battery will now be flagged as NOT CHARGING.
> Have also added the additional check for the battery FULL DISCHARGED flag
> which will now flag a status of EMPTY.
>
> Signed-off-by: Richard Tresidder 
> ---
>
> Notes:
> power/supply/sbs-battery: Fix confusing battery status when idle or empty
>
> When a battery or batteries in a system are in parallel then one or more
> may not be providing any current to the system.
> This fixes an incorrect status indication of FULL for the battery simply
> because it wasn't discharging at that point in time.
> The battery will now be flagged as NOT CHARGING.
> Have also added the additional check for the battery FULL DISCHARGED flag
> which will now flag a status of EMPTY.
>
> v2: Missed a later merge that should have been included in original patch
> v3: Refactor the sbs_status_correct function to capture all the states for
> normal operation rather than being spread across multile functions.
>
>  drivers/power/supply/power_supply_sysfs.c |  2 +-
>  drivers/power/supply/sbs-battery.c| 44 
> +++
>  include/linux/power_supply.h  |  1 +
>  3 files changed, 18 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/power/supply/power_supply_sysfs.c 
> b/drivers/power/supply/power_supply_sysfs.c
> index f37ad4e..305e833 100644
> --- a/drivers/power/supply/power_supply_sysfs.c
> +++ b/drivers/power/supply/power_supply_sysfs.c
> @@ -51,7 +51,7 @@
>  };
>
>  static const char * const power_supply_status_text[] = {
> -   "Unknown", "Charging", "Discharging", "Not charging", "Full"
> +   "Unknown", "Charging", "Discharging", "Not charging", "Full", "Empty"
>  };
>
>  static const char * const power_supply_charge_type_text[] = {
> diff --git a/drivers/power/supply/sbs-battery.c 
> b/drivers/power/supply/sbs-battery.c
> index 048d205..b28402d 100644
> --- a/drivers/power/supply/sbs-battery.c
> +++ b/drivers/power/supply/sbs-battery.c
> @@ -293,16 +293,18 @@ static int sbs_status_correct(struct i2c_client 
> *client, int *intval)

sbs_status_correct() sounds like it is checking for a condition. Change
to sbs_correct_status() or sbs_correct_battery_status() to imply that it
is performing an action. Also, change "intval" to "status"?

>
> ret = (s16)ret;
>
> -   /* Not drawing current means full (cannot be not charging) */
> -   if (ret == 0)
> -   *intval = POWER_SUPPLY_STATUS_FULL;
> -
> -   if (*intval == POWER_SUPPLY_STATUS_FULL) {
> -   /* Drawing or providing current when full */
> -   if (ret > 0)
> -   *intval = POWER_SUPPLY_STATUS_CHARGING;
> -   else if (ret < 0)
> -   *intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +   if (ret > 0)
> +   *intval = POWER_SUPPLY_STATUS_CHARGING;
> +   else if (ret < 0)
> +   *intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +   else {
> +   /* Current is 0, so how full is the battery? */
> +   if (*intval & BATTERY_FULL_CHARGED)
> +   *intval = POWER_SUPPLY_STATUS_FULL;
> +   else if (*intval & BATTERY_FULL_DISCHARGED)
> +   *intval = POWER_SUPPLY_STATUS_EMPTY;
> +   else
> +   *intval = POWER_SUPPLY_STATUS_NOT_CHARGING;

This will cause some behavior changes for users. Can we get the opinion
of someone familiar with the users of this driver as to whether this is OK?

> }
>
> return 0;
> @@ -421,14 +423,9 @@ static int sbs_get_battery_property(struct i2c_client 
> *client,
> return 0;
> }
>
> -   if (ret & BATTERY_FULL_CHARGED)
> -   val->intval = POWER_SUPPLY_STATUS_FULL;
> -   else if (ret & BATTERY_DISCHARGING)
> -   val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> -   else
> -   val->intval = POWER_SUPPLY_STATUS_CHARGING;
> -
> -   sbs_status_correct(client, >intval);
> +   ret = sbs_status_correct(client, >intval);
> +   if (ret < 0)
> +   return ret;
>
> if (chip->poll_time == 0)
> chip->last_state = val->intval;
> @@ -773,20 +770,11 @@ static void sbs_delayed_work(struct work_struct *work)
>
> ret = sbs_read_word_data(chip->client, sbs_data[REG_STATUS].addr);
> /* if the read failed, give up on this work */
> -   if (ret < 0) {
> +   if ((ret < 0) || (sbs_status_correct(chip->client, ) < 0)) {
> 

Re: [RESEND v2 1/1] power/supply/sbs-battery: Fix confusing battery status when idle or empty

2019-07-26 Thread Nick Crews
Hi Richard!

Thanks for the patch. I'm not familiar with these batteries, but I have
a few thoughts. For others, the SBS battery spec is at
http://sbs-forum.org/specs/sbdat110.pdf, and section 5.1.21 at page 28
is useful.

On Thu, Jul 25, 2019 at 2:55 AM Richard Tresidder
 wrote:
>
> When a battery or batteries in a system are in parallel then one or more
> may not be providing any current to the system.
> This fixes an incorrect status indication of FULL for the battery simply
> because it wasn't discharging at that point in time.
> The battery will now be flagged as IDLE.
> Have also added the additional check for the battery FULL DISCHARGED flag
> which will now flag a status of EMPTY.
>
> Signed-off-by: Richard Tresidder 
> ---
>
> Notes:
> power/supply/sbs-battery: Fix confusing battery status when idle or empty
>
> When a battery or batteries in a system are in parallel then one or more
> may not be providing any current to the system.
> This fixes an incorrect
> status indication of FULL for the battery simply because it wasn't
> discharging at that point in time.
> The battery will now be flagged as IDLE.
> Have also added the additional check for the battery FULL DISCHARGED flag
> which will now flag a status of EMPTY.
>
> v2: missed a later merge that should have been included in original patch
>
>  drivers/power/supply/power_supply_sysfs.c |  3 ++-
>  drivers/power/supply/sbs-battery.c| 32 
> +++
>  include/linux/power_supply.h  |  2 ++
>  3 files changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/power/supply/power_supply_sysfs.c 
> b/drivers/power/supply/power_supply_sysfs.c
> index ce6671c..68ec49d 100644
> --- a/drivers/power/supply/power_supply_sysfs.c
> +++ b/drivers/power/supply/power_supply_sysfs.c
> @@ -51,7 +51,8 @@
>  };
>
>  static const char * const power_supply_status_text[] = {
> -   "Unknown", "Charging", "Discharging", "Not charging", "Full"
> +   "Unknown", "Charging", "Discharging", "Not charging", "Full",
> +   "Empty", "Idle"

How is "Idle" different" from "Not charging"? To me they both mean that the
battery is at an intermediate state of charge and that there is no significant
current going into or out of the battery. Can you just use "Not
charging" instead
of adding a new status type? Idle seems like a better name to me, but
unfortunately we can't change that at this point.

Adding "Empty" seems quite reasonable.

>  };
>
>  static const char * const power_supply_charge_type_text[] = {
> diff --git a/drivers/power/supply/sbs-battery.c 
> b/drivers/power/supply/sbs-battery.c
> index ea8ba3e..664c317 100644
> --- a/drivers/power/supply/sbs-battery.c
> +++ b/drivers/power/supply/sbs-battery.c
> @@ -294,16 +294,12 @@ static int sbs_status_correct(struct i2c_client 
> *client, int *intval)
>
> ret = (s16)ret;
>
> -   /* Not drawing current means full (cannot be not charging) */
> -   if (ret == 0)
> -   *intval = POWER_SUPPLY_STATUS_FULL;
> -
> -   if (*intval == POWER_SUPPLY_STATUS_FULL) {
> -   /* Drawing or providing current when full */
> -   if (ret > 0)
> -   *intval = POWER_SUPPLY_STATUS_CHARGING;
> -   else if (ret < 0)
> -   *intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +   if ((*intval == POWER_SUPPLY_STATUS_DISCHARGING && (ret == 0)) {
> +   /* Charging indicator not set in battery */
> +   *intval = POWER_SUPPLY_STATUS_IDLE;
> +   } else if ((*intval == POWER_SUPPLY_STATUS_FULL) && (ret < 0)) {
> +   /* Full Flag set but we are discharging */
> +   *intval = POWER_SUPPLY_STATUS_DISCHARGING;

In any of these cases do we really care about intval? Wouldn't the
current be the
ultimate ground truth of what is happening? e.g.
-(ret == 0) means "Idle"/"Not charging"
-(ret > 0) mean charging
-(ret < 0) means discharging

At the least, how about a check for
else if ((*intval == POWER_SUPPLY_STATUS_EMPTY) && (ret > 0)) {
   /* Empty flag set but current is positive. */
   *intval = POWER_SUPPLY_STATUS_CHARGING;
}

> }
>
> return 0;
> @@ -424,10 +420,12 @@ static int sbs_get_battery_property(struct i2c_client 
> *client,
>
> if (ret & BATTERY_FULL_CHARGED)
> val->intval = POWER_SUPPLY_STATUS_FULL;
> -   else if (ret & BATTERY_DISCHARGING)
> -   val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> -   else
> +   else if (ret & BATTERY_FULL_DISCHARGED)
> +   val->intval = POWER_SUPPLY_STATUS_EMPTY;
> +   else if (!(ret & BATTERY_DISCHARGING))
> val->intval = POWER_SUPPLY_STATUS_CHARGING;
> +   else
> +   val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
>
> 

[PATCH v2 2/2] platform/chrome: wilco_ec: Add circular buffer as event queue

2019-06-24 Thread Nick Crews
The current implementation of the event queue both
wastes space using a doubly linked list and isn't super
obvious in how it behaves. This converts the queue to an
actual circular buffer. The size of the queue is a
tunable module parameter. This also fixes a few other things:

- A memory leak that occurred when the ACPI device was
  removed, but the events were not freed from the queue.
- Now kfree() the oldest event from outside all locks.
- Add newline to logging messages.
- Add helper macros to calculate size of events.
- Remove unneeded lock around a check for dev_data->exist
  in hangup_device().
- Remove an unneeded null event pointer check in enqueue_events().
- Correct some comments.

Signed-off-by: Nick Crews 
Reported-by: kbuild test robot 
---

A v1 of this was applied to the chrome-platform-5.3 branch, but then
several errors were found, so Enric and Benson reverted the two commits.

v2 changes:
- Check if kmalloc() of queue fails (Colin Ian King)
- Use struct_size() macro when allocating the queue (Dan Carpenter)
- Remove unneeded semicolon after "if" in enqueue_events() (kbuild bot)
- Change nonseekable_open() to stream_open() (kbuild bot)
- Use kmemdup() for copying events to queue (YueHaibing)
- Wake up threads in enqueue_events() after every event, not
  event_device_notify(), so listeners are guaranteed to be woken
  (Dmitry Torokhov and Daniel Kurtz)
- Move lock back outside the queue, remove "full" boolean,
  streamline pop() and push(), fix race condition where an queue
  of size 1 could get doubly popped, move kfree() of oldest event
  to outside the lock (Daniel Kurtz)

 drivers/platform/chrome/wilco_ec/event.c | 258 +--
 1 file changed, 149 insertions(+), 109 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/event.c 
b/drivers/platform/chrome/wilco_ec/event.c
index 1eed55681598..dba3d445623f 100644
--- a/drivers/platform/chrome/wilco_ec/event.c
+++ b/drivers/platform/chrome/wilco_ec/event.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -69,12 +70,110 @@ static DEFINE_IDA(event_ida);
 /* Size of circular queue of events. */
 #define MAX_NUM_EVENTS 64
 
+/**
+ * struct ec_event - Extended event returned by the EC.
+ * @size: Number of 16bit words in structure after the size word.
+ * @type: Extended event type, meaningless for us.
+ * @event: Event data words.  Max count is %EC_ACPI_MAX_EVENT_WORDS.
+ */
+struct ec_event {
+   u16 size;
+   u16 type;
+   u16 event[0];
+} __packed;
+
+#define ec_event_num_words(ev) (ev->size - 1)
+#define ec_event_size(ev) (sizeof(*ev) + (ec_event_num_words(ev) * 
sizeof(u16)))
+
+/**
+ * struct ec_event_queue - Circular queue for events.
+ * @capacity: Number of elements the queue can hold.
+ * @head: Next index to write to.
+ * @tail: Next index to read from.
+ * @entries: Array of events.
+ */
+struct ec_event_queue {
+   int capacity;
+   int head;
+   int tail;
+   struct ec_event *entries[0];
+};
+
+/* Maximum number of events to store in ec_event_queue */
+static int queue_size = 64;
+module_param(queue_size, int, 0644);
+
+static struct ec_event_queue *event_queue_new(int capacity)
+{
+   struct ec_event_queue *q;
+
+   q = kzalloc(struct_size(q, entries, capacity), GFP_KERNEL);
+   if (!q)
+   return NULL;
+
+   q->capacity = capacity;
+
+   return q;
+}
+
+static inline bool event_queue_empty(struct ec_event_queue *q)
+{
+   /* head==tail when both full and empty, but head==NULL when empty */
+   return q->head == q->tail && !q->entries[q->head];
+}
+
+static inline bool event_queue_full(struct ec_event_queue *q)
+{
+   /* head==tail when both full and empty, but head!=NULL when full */
+   return q->head == q->tail && q->entries[q->head];
+}
+
+static struct ec_event *event_queue_pop(struct ec_event_queue *q)
+{
+   struct ec_event *ev;
+
+   if (event_queue_empty(q))
+   return NULL;
+
+   ev = q->entries[q->tail];
+   q->entries[q->tail] = NULL;
+   q->tail = (q->tail + 1) % q->capacity;
+
+   return ev;
+}
+
+/*
+ * If full, overwrite the oldest event and return it so the caller
+ * can kfree it. If not full, return NULL.
+ */
+static struct ec_event *event_queue_push(struct ec_event_queue *q,
+struct ec_event *ev)
+{
+   struct ec_event *popped = NULL;
+
+   if (event_queue_full(q))
+   popped = event_queue_pop(q);
+   q->entries[q->head] = ev;
+   q->head = (q->head + 1) % q->capacity;
+
+   return popped;
+}
+
+static void event_queue_free(struct ec_event_queue *q)
+{
+   struct ec_event *event;
+
+   while ((event = event_queue_pop(q)) != NULL)
+   kfree(event);
+
+   kfree(q);
+}
+
 /**
  * struct event_device_data - Data for a Wilco EC device tha

[PATCH v2 1/2] platform/chrome: wilco_ec: Fix unreleased lock in event_read()

2019-06-24 Thread Nick Crews
When copying an event to userspace failed, the event queue
lock was never released. This fixes that.

Reported-by: Dan Carpenter 
Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/wilco_ec/event.c 
b/drivers/platform/chrome/wilco_ec/event.c
index 4d2776f77dbd..1eed55681598 100644
--- a/drivers/platform/chrome/wilco_ec/event.c
+++ b/drivers/platform/chrome/wilco_ec/event.c
@@ -342,7 +342,7 @@ static ssize_t event_read(struct file *filp, char __user 
*buf, size_t count,
 struct ec_event_entry, list);
n_bytes_written = entry->size;
if (copy_to_user(buf, >event, n_bytes_written))
-   return -EFAULT;
+   n_bytes_written = -EFAULT;
list_del(>list);
kfree(entry);
dev_data->num_events--;
-- 
2.20.1



Re: [PATCH] platform/chrome: cros_ec_lpc: fix stream_open.cocci warnings

2019-06-24 Thread Nick Crews
I applied this in the new version as well.

On Fri, Jun 21, 2019 at 6:55 PM kbuild test robot  wrote:
>
> From: kbuild test robot 
>
> drivers/platform/chrome/wilco_ec/event.c:270:1-17: WARNING: event_fops: 
> .read() has stream semantic; safe to change nonseekable_open -> stream_open.
>
> Generated by: scripts/coccinelle/api/stream_open.cocci
>
> Fixes: 22c040fa21b6 ("platform/chrome: cros_ec_lpc: Choose Microchip EC at 
> runtime")
> Signed-off-by: kbuild test robot 
> ---
>
> tree:   
> https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git 
> for-next
> head:   9eecd07b34507de9d6a9c264d13d30e1ee5fabe8
> commit: 22c040fa21b604b9b3d88645e108fb2f0a74474b [21/22] platform/chrome: 
> cros_ec_lpc: Choose Microchip EC at runtime
>
> Please take the patch only if it's a positive warning. Thanks!
>
>  event.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> --- a/drivers/platform/chrome/wilco_ec/event.c
> +++ b/drivers/platform/chrome/wilco_ec/event.c
> @@ -267,7 +267,7 @@ static int event_open(struct inode *inod
>
> /* Increase refcount on device so dev_data is not freed */
> get_device(_data->dev);
> -   nonseekable_open(inode, filp);
> +   stream_open(inode, filp);
> filp->private_data = dev_data;
>
> return 0;


Re: [PATCH] platform/chrome: cros_ec_lpc: fix semicolon.cocci warnings

2019-06-24 Thread Nick Crews
I fixed this in the new version.

On Fri, Jun 21, 2019 at 6:55 PM kbuild test robot  wrote:
>
> From: kbuild test robot 
>
> drivers/platform/chrome/wilco_ec/event.c:161:3-4: Unneeded semicolon
>
>
>  Remove unneeded semicolon.
>
> Generated by: scripts/coccinelle/misc/semicolon.cocci
>
> Fixes: 22c040fa21b6 ("platform/chrome: cros_ec_lpc: Choose Microchip EC at 
> runtime")
> Signed-off-by: kbuild test robot 
> ---
>
> tree:   
> https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git 
> for-next
> head:   9eecd07b34507de9d6a9c264d13d30e1ee5fabe8
> commit: 22c040fa21b604b9b3d88645e108fb2f0a74474b [21/22] platform/chrome: 
> cros_ec_lpc: Choose Microchip EC at runtime
>
>  event.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> --- a/drivers/platform/chrome/wilco_ec/event.c
> +++ b/drivers/platform/chrome/wilco_ec/event.c
> @@ -158,7 +158,7 @@ static int enqueue_events(struct acpi_de
> dev_err(>dev, "Too many event words: %zu > 
> %d\n",
> num_words, EC_ACPI_MAX_EVENT_WORDS);
> return -EOVERFLOW;
> -   };
> +   }
>
> /* Ensure event does not overflow the available buffer */
> if ((offset + event_size) > length) {


Re: [PATCH -next] platform/chrome: wilco_ec: Use kmemdup in enqueue_events()

2019-06-21 Thread Nick Crews
Thanks Yue, looks good to me.

Nick

On Fri, Jun 21, 2019 at 7:59 AM YueHaibing  wrote:
>
> Use kmemdup rather than duplicating its implementation
>
> Signed-off-by: YueHaibing 
> ---
>  drivers/platform/chrome/wilco_ec/event.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/platform/chrome/wilco_ec/event.c 
> b/drivers/platform/chrome/wilco_ec/event.c
> index c975b76e6255..70156e75047e 100644
> --- a/drivers/platform/chrome/wilco_ec/event.c
> +++ b/drivers/platform/chrome/wilco_ec/event.c
> @@ -248,10 +248,9 @@ static int enqueue_events(struct acpi_device *adev, 
> const u8 *buf, u32 length)
> offset += event_size;
>
> /* Copy event into the queue */
> -   queue_event = kzalloc(event_size, GFP_KERNEL);
> +   queue_event = kmemdup(event, event_size, GFP_KERNEL);
> if (!queue_event)
> return -ENOMEM;
> -   memcpy(queue_event, event, event_size);
> event_queue_push(dev_data->events, queue_event);
> }
>
>
>


Re: [PATCH][next] platform/chrome: wilco_ec: fix null pointer dereference on failed kzalloc

2019-06-19 Thread Nick Crews
On Tue, Jun 18, 2019 at 11:30 PM Dan Carpenter  wrote:
>
> On Tue, Jun 18, 2019 at 04:39:24PM +0100, Colin King wrote:
> > diff --git a/drivers/platform/chrome/wilco_ec/event.c 
> > b/drivers/platform/chrome/wilco_ec/event.c
> > index c975b76e6255..e251a989b152 100644
> > --- a/drivers/platform/chrome/wilco_ec/event.c
> > +++ b/drivers/platform/chrome/wilco_ec/event.c
> > @@ -112,8 +112,11 @@ module_param(queue_size, int, 0644);
> >  static struct ec_event_queue *event_queue_new(int capacity)
> >  {
> >   size_t entries_size = sizeof(struct ec_event *) * capacity;
> > - struct ec_event_queue *q = kzalloc(sizeof(*q) + entries_size,
> > -GFP_KERNEL);
> > + struct ec_event_queue *q;
> > +
> > + q = kzalloc(sizeof(*q) + entries_size, GFP_KERNEL);
> > + if (!q)
> > + return NULL;
>
> We have a new struct_size() macro designed for these allocations.
>
> q = kzalloc(struct_size(q, entries, capacity), GFP_KERNEL);
>
> The advantage is that it checks for integer overflows.
>
> regards,
> dan carpenter
>

Thanks Dan, I like that.

Dmitry Torokhov also had some thoughts on this patch at
https://crrev.com/c/1661053, I'll send a patch that adds this and
fixes his concerns in a bit.

Cheers,
Nick


Re: [PATCH][next] platform/chrome: wilco_ec: fix null pointer dereference on failed kzalloc

2019-06-18 Thread Nick Crews
Thanks Colin, good catch.

Enric, could you squash this into the real commit?

On Tue, Jun 18, 2019 at 9:39 AM Colin King  wrote:
>
> From: Colin Ian King 
>
> If the kzalloc of the entries queue q fails a null pointer dereference
> occurs when accessing q->capacity and q->lock.  Add a kzalloc failure
> check and handle the null return case in the calling function
> event_device_add.
>
> Addresses-Coverity: ("Dereference null return")
> Fixes: 75589e37d1dc ("platform/chrome: wilco_ec: Add circular buffer as event 
> queue")
> Signed-off-by: Colin Ian King 
> ---
>  drivers/platform/chrome/wilco_ec/event.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/platform/chrome/wilco_ec/event.c 
> b/drivers/platform/chrome/wilco_ec/event.c
> index c975b76e6255..e251a989b152 100644
> --- a/drivers/platform/chrome/wilco_ec/event.c
> +++ b/drivers/platform/chrome/wilco_ec/event.c
> @@ -112,8 +112,11 @@ module_param(queue_size, int, 0644);
>  static struct ec_event_queue *event_queue_new(int capacity)
>  {
> size_t entries_size = sizeof(struct ec_event *) * capacity;
> -   struct ec_event_queue *q = kzalloc(sizeof(*q) + entries_size,
> -  GFP_KERNEL);
> +   struct ec_event_queue *q;
> +
> +   q = kzalloc(sizeof(*q) + entries_size, GFP_KERNEL);
> +   if (!q)
> +   return NULL;
>
> q->capacity = capacity;
> spin_lock_init(>lock);
> @@ -474,6 +477,11 @@ static int event_device_add(struct acpi_device *adev)
> /* Initialize the device data. */
> adev->driver_data = dev_data;
> dev_data->events = event_queue_new(queue_size);
> +   if (!dev_data->events) {
> +   kfree(dev_data);
> +   error = -ENOMEM;
> +   goto free_minor;
> +   }
> init_waitqueue_head(_data->wq);
> dev_data->exist = true;
> atomic_set(_data->available, 1);

Signed-off-by: Nick Crews 

> --
> 2.20.1
>


Re: [PATCH v5 3/3] platform/chrome: cros_ec_lpc_mec: Fix kernel-doc comment first line

2019-06-18 Thread Nick Crews
Thanks Enric, looks great.

On Fri, Jun 14, 2019 at 3:43 PM Enric Balletbo i Serra
 wrote:
>
> kernel-doc comments have a prescribed format. To be _particularly_ correct
> we should also capitalise the brief description and terminate it with a
> period.
>
> Signed-off-by: Enric Balletbo i Serra 
> ---
>
> Changes in v5:
> - Introduced this patch just to do some kernel-doc clean up.
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/platform/chrome/cros_ec_lpc_mec.c | 14 ++
>  1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.c 
> b/drivers/platform/chrome/cros_ec_lpc_mec.c
> index d8890bafb55d..9035b17e8c86 100644
> --- a/drivers/platform/chrome/cros_ec_lpc_mec.c
> +++ b/drivers/platform/chrome/cros_ec_lpc_mec.c
> @@ -17,12 +17,10 @@
>  static struct mutex io_mutex;
>  static u16 mec_emi_base, mec_emi_end;
>
> -/*
> - * cros_ec_lpc_mec_emi_write_address
> - *
> - * Initialize EMI read / write at a given address.
> +/**
> + * cros_ec_lpc_mec_emi_write_address() - Initialize EMI at a given address.
>   *
> - * @addr:Starting read / write address
> + * @addr: Starting read / write address
>   * @access_type: Type of access, typically 32-bit auto-increment
>   */
>  static void cros_ec_lpc_mec_emi_write_address(u16 addr,
> @@ -61,15 +59,15 @@ int cros_ec_lpc_mec_in_range(unsigned int offset, 
> unsigned int length)
> return 0;
>  }
>
> -/*
> - * cros_ec_lpc_io_bytes_mec - Read / write bytes to MEC EMI port
> +/**
> + * cros_ec_lpc_io_bytes_mec() - Read / write bytes to MEC EMI port.
>   *
>   * @io_type: MEC_IO_READ or MEC_IO_WRITE, depending on request
>   * @offset:  Base read / write address
>   * @length:  Number of bytes to read / write
>   * @buf: Destination / source buffer
>   *
> - * @return 8-bit checksum of all bytes read / written
> + * Return: 8-bit checksum of all bytes read / written
>   */
>  u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type,
> unsigned int offset, unsigned int length,

Reviewed-by: Nick Crews 

> --
> 2.20.1
>


Re: [PATCH v5 2/3] platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime

2019-06-18 Thread Nick Crews
Thanks for the patch Enric!

Just one nit.

On Fri, Jun 14, 2019 at 3:43 PM Enric Balletbo i Serra
 wrote:
>
> On many boards, communication between the kernel and the Embedded
> Controller happens over an LPC bus. In these cases, the kernel config
> CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
> Microchip Embedded Controller (MEC) that is different from the regular
> EC. On these devices, the same LPC bus is used, but the protocol is
> a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
> config is enabled. Currently, the kernel decides at compile-time whether
> or not to use the MEC variant, and, when that kernel option is selected
> it breaks the other boards. We would like a kind of runtime detection to
> avoid this.
>
> This patch adds that detection mechanism by probing the protocol at
> runtime, first we assume that a MEC variant is connected, and if the
> protocol fails it fallbacks to the regular EC. This adds a bit of
> overload because we try to read twice on those LPC boards that doesn't
> contain a MEC variant, but is a better solution than having to select the
> EC variant at compile-time.
>
> While here also fix the alignment in Kconfig file for this config option
> replacing the spaces by tabs.
>
> Signed-off-by: Enric Balletbo i Serra 
> Reviewed-by: Ezequiel Garcia 
> Tested-by: Nick Crews 
> ---
> Hi,
>
> This is another attempt to solve the issue to be able to select at
> runtime the CrOS MEC variant. My first thought was check for a device
> ID, the MEC1322 has a register that contains the device ID, however I
> am not sure if we can read that register from the host without
> modifying the firmware. Also, I am not sure if the MEC1322 is the only
> device used that supports that LPC protocol variant, so I ended with a
> more easy solution, check if the protocol fails or not. Some background
> on this issue can be found [1] and [2]
>
> The patch has been tested on:
> - Acer Chromebook R11 (Cyan - MEC variant)
> - Pixel Chromebook 2015 (Samus - non-MEC variant)
> - Dell Chromebook 11 (Wolf - non-MEC variant)
> - Toshiba Chromebook (Leon - non-MEC variant)
>
> Best regards,
> Enric
>
> [1] https://bugs.chromium.org/p/chromium/issues/detail?id=932626
> [2] 
> https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1474254
>
> Changes in v5:
> - Assign the methods in cros_ec_lpc_probe(), so down there
>   you can see explicitly what the defaults are
>
> Changes in v4:
> - Change the logic to test the protocols as suggested by Nick Crews.
> - Add the proper cros_ec_lpc_mec.h include. (Nick Crews)
> - Fix some const and missing casts. (Nick Crews)
> - Clean up related doc-strings. (Nick Crews)
>
> Changes in v3:
> - Kconfig: Split across multiple lines to keep it under 80 characters.
> - Improve kernel-doc as suggested by Nick Crews.
> - Convert msg in write function to const.
> - Add rb and tb tags.
>
> Changes in v2:
> - Remove global bool to indicate the kind of variant as suggested by Ezequiel.
> - Create an internal operations struct to allow different variants.
>
>  drivers/platform/chrome/Kconfig  |  29 ++---
>  drivers/platform/chrome/Makefile |   2 +-
>  drivers/platform/chrome/cros_ec_lpc.c| 158 ---
>  drivers/platform/chrome/wilco_ec/Kconfig |   2 +-
>  4 files changed, 95 insertions(+), 96 deletions(-)
>
> diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
> index 2826f7136f65..453e69733842 100644
> --- a/drivers/platform/chrome/Kconfig
> +++ b/drivers/platform/chrome/Kconfig
> @@ -83,28 +83,17 @@ config CROS_EC_SPI
>   'pre-amble' bytes before the response actually starts.
>
>  config CROS_EC_LPC
> -tristate "ChromeOS Embedded Controller (LPC)"
> -depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> -help
> -  If you say Y here, you get support for talking to the ChromeOS EC
> -  over an LPC bus. This uses a simple byte-level protocol with a
> -  checksum. This is used for userspace access only. The kernel
> -  typically has its own communication methods.
> -
> -  To compile this driver as a module, choose M here: the
> -  module will be called cros_ec_lpc.
> -
> -config CROS_EC_LPC_MEC
> -   bool "ChromeOS Embedded Controller LPC Microchip EC (MEC) variant"
> -   depends on CROS_EC_LPC
> -   default n
> +   tristate "ChromeOS Embedded Controller (LPC)"
> +   depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> help
> - If you say Y here, a va

Re: [PATCH v5 1/3] platform/chrome: cros_ec_lpc: Merge cros_ec_lpc and cros_ec_lpc_reg

2019-06-18 Thread Nick Crews
nt length,
> +u8 *dest)
> +{
> +   return lpc_read_bytes(offset, length, dest);
> +}
> +
> +static u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length,
> + u8 *msg)
> +{
> +   return lpc_write_bytes(offset, length, msg);
> +}
> +
> +static void cros_ec_lpc_reg_init(void)
> +{
> +}
> +
> +static void cros_ec_lpc_reg_destroy(void)
> +{
> +}
> +
> +#endif /* CONFIG_CROS_EC_LPC_MEC */
> +
>  static int ec_response_timed_out(void)
>  {
> unsigned long one_second = jiffies + HZ;
> diff --git a/drivers/platform/chrome/cros_ec_lpc_reg.c 
> b/drivers/platform/chrome/cros_ec_lpc_reg.c
> deleted file mode 100644
> index 0f5cd0ac8b49..
> --- a/drivers/platform/chrome/cros_ec_lpc_reg.c
> +++ /dev/null
> @@ -1,101 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -// LPC interface for ChromeOS Embedded Controller
> -//
> -// Copyright (C) 2016 Google, Inc
> -
> -#include 
> -#include 
> -#include 
> -
> -#include "cros_ec_lpc_mec.h"
> -
> -static u8 lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest)
> -{
> -   int i;
> -   int sum = 0;
> -
> -   for (i = 0; i < length; ++i) {
> -   dest[i] = inb(offset + i);
> -   sum += dest[i];
> -   }
> -
> -   /* Return checksum of all bytes read */
> -   return sum;
> -}
> -
> -static u8 lpc_write_bytes(unsigned int offset, unsigned int length, u8 *msg)
> -{
> -   int i;
> -   int sum = 0;
> -
> -   for (i = 0; i < length; ++i) {
> -   outb(msg[i], offset + i);
> -   sum += msg[i];
> -   }
> -
> -   /* Return checksum of all bytes written */
> -   return sum;
> -}
> -
> -#ifdef CONFIG_CROS_EC_LPC_MEC
> -
> -u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest)
> -{
> -   int in_range = cros_ec_lpc_mec_in_range(offset, length);
> -
> -   if (in_range < 0)
> -   return 0;
> -
> -   return in_range ?
> -   cros_ec_lpc_io_bytes_mec(MEC_IO_READ,
> -offset - EC_HOST_CMD_REGION0,
> -length, dest) :
> -   lpc_read_bytes(offset, length, dest);
> -}
> -
> -u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, u8 *msg)
> -{
> -   int in_range = cros_ec_lpc_mec_in_range(offset, length);
> -
> -   if (in_range < 0)
> -   return 0;
> -
> -   return in_range ?
> -   cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE,
> -offset - EC_HOST_CMD_REGION0,
> -length, msg) :
> -   lpc_write_bytes(offset, length, msg);
> -}
> -
> -void cros_ec_lpc_reg_init(void)
> -{
> -   cros_ec_lpc_mec_init(EC_HOST_CMD_REGION0,
> -EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE);
> -}
> -
> -void cros_ec_lpc_reg_destroy(void)
> -{
> -   cros_ec_lpc_mec_destroy();
> -}
> -
> -#else /* CONFIG_CROS_EC_LPC_MEC */
> -
> -u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest)
> -{
> -   return lpc_read_bytes(offset, length, dest);
> -}
> -
> -u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, u8 *msg)
> -{
> -   return lpc_write_bytes(offset, length, msg);
> -}
> -
> -void cros_ec_lpc_reg_init(void)
> -{
> -}
> -
> -void cros_ec_lpc_reg_destroy(void)
> -{
> -}
> -
> -#endif /* CONFIG_CROS_EC_LPC_MEC */
> diff --git a/drivers/platform/chrome/cros_ec_lpc_reg.h 
> b/drivers/platform/chrome/cros_ec_lpc_reg.h
> deleted file mode 100644
> index 416fd2572182..
> --- a/drivers/platform/chrome/cros_ec_lpc_reg.h
> +++ /dev/null
> @@ -1,45 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * LPC interface for ChromeOS Embedded Controller
> - *
> - * Copyright (C) 2016 Google, Inc
> - */
> -
> -#ifndef __CROS_EC_LPC_REG_H
> -#define __CROS_EC_LPC_REG_H
> -
> -/**
> - * cros_ec_lpc_read_bytes - Read bytes from a given LPC-mapped address.
> - * Returns 8-bit checksum of all bytes read.
> - *
> - * @offset: Base read address
> - * @length: Number of bytes to read
> - * @dest: Destination buffer
> - */
> -u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, u8 
> *dest);
> -
> -/**
> - * cros_ec_lpc_write_bytes - Write bytes to a given LPC-mapped address.
> - * Returns 8-bit checksum of all bytes written.
> - *
> - * @offset: Base write address
> - * @length: Number of bytes to write
> - * @msg: Write data buffer
> - */
> -u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, u8 
> *msg);
> -
> -/**
> - * cros_ec_lpc_reg_init
> - *
> - * Initialize register I/O.
> - */
> -void cros_ec_lpc_reg_init(void);
> -
> -/**
> - * cros_ec_lpc_reg_destroy
> - *
> - * Cleanup reg I/O.
> - */
> -void cros_ec_lpc_reg_destroy(void);
> -
> -#endif /* __CROS_EC_LPC_REG_H */

Reviewed-by: Nick Crews 

> --
> 2.20.1
>


[PATCH 2/2] platform/chrome: wilco_ec: Add circular buffer as event queue

2019-06-14 Thread Nick Crews
The current implementation of the event queue both
wastes space using a doubly linked list and isn't super
obvious in how it behaves. This converts the queue to an
actual circular buffer. The size of the queue is a
tunable module parameter. This also moves the lock
inside the queue, so the users of the queue don't have
to deal with it. In addition, this fixes a memory leak
that occurred when the ACPI device was removed, but the
events were not freed from the queue.

It also fixes a bug in event_read() where the queue
readers would not wake when the ACPI device was removed.
This also fixes some logging, removes an unneeded lock()
from around a check for dev_data->exist in
hangup_device(), removes an unneeded null event pointer
check in enqueue_events(), adds some helper macros to
calculate the size of events, and corrects some
comments.

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/event.c | 246 +--
 1 file changed, 143 insertions(+), 103 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/event.c 
b/drivers/platform/chrome/wilco_ec/event.c
index 1eed55681598..c975b76e6255 100644
--- a/drivers/platform/chrome/wilco_ec/event.c
+++ b/drivers/platform/chrome/wilco_ec/event.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -69,12 +70,120 @@ static DEFINE_IDA(event_ida);
 /* Size of circular queue of events. */
 #define MAX_NUM_EVENTS 64
 
+/**
+ * struct ec_event - Extended event returned by the EC.
+ * @size: Number of 16bit words in structure after the size word.
+ * @type: Extended event type, meaningless for us.
+ * @event: Event data words.  Max count is %EC_ACPI_MAX_EVENT_WORDS.
+ */
+struct ec_event {
+   u16 size;
+   u16 type;
+   u16 event[0];
+} __packed;
+
+#define ec_event_num_words(ev) (ev->size - 1)
+#define ec_event_size(ev) (sizeof(*ev) + (ec_event_num_words(ev) * 
sizeof(u16)))
+
+/**
+ * struct ec_event_queue - Circular queue for events
+ * @capacity: Number of elements the queue cab hold.
+ * @head: Next index to write to.
+ * @tail: Next index to read from.
+ * @full: head==tail when both full and empty, so use this to differentiate.
+ * @lock: Protect the queue from simultaneous read/writes.
+ * @entries: Array of events.
+ *
+ * If an event is added when the queue is full, the oldest event is 
overwritten.
+ */
+struct ec_event_queue {
+   int capacity;
+   int head;
+   int tail;
+   bool full;
+   spinlock_t lock;
+   struct ec_event *entries[0];
+};
+
+/* Maximum number of events to store in ec_event_queue */
+static int queue_size = 64;
+module_param(queue_size, int, 0644);
+
+static struct ec_event_queue *event_queue_new(int capacity)
+{
+   size_t entries_size = sizeof(struct ec_event *) * capacity;
+   struct ec_event_queue *q = kzalloc(sizeof(*q) + entries_size,
+  GFP_KERNEL);
+
+   q->capacity = capacity;
+   spin_lock_init(>lock);
+
+   return q;
+}
+
+static bool event_queue_empty(struct ec_event_queue *q)
+{
+   bool empty;
+
+   if (q->full)
+   return false;
+
+   spin_lock(>lock);
+   empty = q->head == q->tail;
+   spin_unlock(>lock);
+
+   return empty;
+}
+
+/* If full, free and overwrite the oldest event */
+static void event_queue_push(struct ec_event_queue *q, struct ec_event *ev)
+{
+   spin_lock(>lock);
+   if (q->full) {
+   kfree(q->entries[q->head]);
+   q->entries[q->head] = ev;
+   q->head = (q->head + 1) % q->capacity;
+   } else {
+   q->entries[q->head] = ev;
+   q->head = (q->head + 1) % q->capacity;
+   q->full = q->head == q->tail;
+   }
+   if (q->full)
+   q->tail = q->head;
+   spin_unlock(>lock);
+
+}
+
+static struct ec_event *event_queue_pop(struct ec_event_queue *q)
+{
+   struct ec_event *ev;
+
+   if (event_queue_empty(q))
+   return NULL;
+
+   spin_lock(>lock);
+   ev = q->entries[q->tail];
+   q->tail = (q->tail + 1) % q->capacity;
+   q->full = false;
+   spin_unlock(>lock);
+
+   return ev;
+}
+
+static void event_queue_free(struct ec_event_queue *q)
+{
+   struct ec_event *event;
+
+   while ((event = event_queue_pop(q)) != NULL)
+   kfree(event);
+
+   kfree(q);
+}
+
 /**
  * struct event_device_data - Data for a Wilco EC device that responds to ACPI.
  * @events: Circular queue of EC events to be provided to userspace.
- * @num_events: Number of events in the queue.
- * @lock: Mutex to guard the queue.
- * @wq: Wait queue to notify processes when events or available or the
+ * @wq: Wait queue to notify processes when events are available or the
  * device has been removed.
  * @cdev: Char dev that userspace read

[PATCH 1/2] platform/chrome: wilco_ec: Fix unreleased lock in event_read()

2019-06-14 Thread Nick Crews
When copying an event to userspace failed, the event queue
lock was never released. This fixes that.

Reported-by: Dan Carpenter 
Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/wilco_ec/event.c 
b/drivers/platform/chrome/wilco_ec/event.c
index 4d2776f77dbd..1eed55681598 100644
--- a/drivers/platform/chrome/wilco_ec/event.c
+++ b/drivers/platform/chrome/wilco_ec/event.c
@@ -342,7 +342,7 @@ static ssize_t event_read(struct file *filp, char __user 
*buf, size_t count,
 struct ec_event_entry, list);
n_bytes_written = entry->size;
if (copy_to_user(buf, >event, n_bytes_written))
-   return -EFAULT;
+   n_bytes_written = -EFAULT;
list_del(>list);
kfree(entry);
dev_data->num_events--;
-- 
2.20.1



Re: [PATCH v4] platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime

2019-06-14 Thread Nick Crews
On Thu, Jun 13, 2019 at 10:34 PM Enric Balletbo i Serra
 wrote:
>
> On many boards, communication between the kernel and the Embedded
> Controller happens over an LPC bus. In these cases, the kernel config
> CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
> Microchip Embedded Controller (MEC) that is different from the regular
> EC. On these devices, the same LPC bus is used, but the protocol is
> a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
> config is enabled. Currently, the kernel decides at compile-time whether
> or not to use the MEC variant, and, when that kernel option is selected
> it breaks the other boards. We would like a kind of runtime detection to
> avoid this.
>
> This patch adds that detection mechanism by probing the protocol at
> runtime, first we assume that a MEC variant is connected, and if the
> protocol fails it fallbacks to the regular EC. This adds a bit of
> overload because we try to read twice on those LPC boards that doesn't
> contain a MEC variant, but is a better solution than having to select the
> EC variant at compile-time.
>
> While here also fix the alignment in Kconfig file for this config option
> replacing the spaces by tabs.
>
> Signed-off-by: Enric Balletbo i Serra 
> Reviewed-by: Ezequiel Garcia 
> Tested-by: Nick Crews 
> ---
> Hi,
>
> This is another attempt to solve the issue to be able to select at
> runtime the CrOS MEC variant. My first thought was check for a device
> ID, the MEC1322 has a register that contains the device ID, however I
> am not sure if we can read that register from the host without
> modifying the firmware. Also, I am not sure if the MEC1322 is the only
> device used that supports that LPC protocol variant, so I ended with a
> more easy solution, check if the protocol fails or not. Some background
> on this issue can be found [1] and [2]
>
> The patch has been tested on:
>  - Acer Chromebook R11 (Cyan - MEC variant)
>  - Pixel Chromebook 2015 (Samus - non-MEC variant)
>  - Dell Chromebook 11 (Wolf - non-MEC variant)
>  - Toshiba Chromebook (Leon - non-MEC variant)
>
> Best regards,
>  Enric
>
> [1] https://bugs.chromium.org/p/chromium/issues/detail?id=932626
> [2] 
> https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1474254
>
> Changes in v4:
> - Change the logic to test the protocols as suggested by Nick Crews.
> - Add the proper cros_ec_lpc_mec.h include. (Nick Crews)
> - Fix some const and missing casts. (Nick Crews)
> - Clean up related doc-strings. (Nick Crews)
>
> Changes in v3:
> - Kconfig: Split across multiple lines to keep it under 80 characters.
> - Improve kernel-doc as suggested by Nick Crews.
> - Convert msg in write function to const.
> - Add rb and tb tags.
>
> Changes in v2:
> - Remove global bool to indicate the kind of variant as suggested by Ezequiel.
> - Create an internal operations struct to allow different variants.
>
>  drivers/platform/chrome/Kconfig   | 29 +++--
>  drivers/platform/chrome/Makefile  |  2 +-
>  drivers/platform/chrome/cros_ec_lpc.c | 78 ---
>  drivers/platform/chrome/cros_ec_lpc_mec.h | 14 
>  drivers/platform/chrome/cros_ec_lpc_reg.c | 41 
>  drivers/platform/chrome/cros_ec_lpc_reg.h | 23 +++
>  drivers/platform/chrome/wilco_ec/Kconfig  |  2 +-
>  7 files changed, 98 insertions(+), 91 deletions(-)
>
> diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
> index 2826f7136f65..453e69733842 100644
> --- a/drivers/platform/chrome/Kconfig
> +++ b/drivers/platform/chrome/Kconfig
> @@ -83,28 +83,17 @@ config CROS_EC_SPI
>   'pre-amble' bytes before the response actually starts.
>
>  config CROS_EC_LPC
> -tristate "ChromeOS Embedded Controller (LPC)"
> -depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> -help
> -  If you say Y here, you get support for talking to the ChromeOS EC
> -  over an LPC bus. This uses a simple byte-level protocol with a
> -  checksum. This is used for userspace access only. The kernel
> -  typically has its own communication methods.
> -
> -  To compile this driver as a module, choose M here: the
> -  module will be called cros_ec_lpc.
> -
> -config CROS_EC_LPC_MEC
> -   bool "ChromeOS Embedded Controller LPC Microchip EC (MEC) variant"
> -   depends on CROS_EC_LPC
> -   default n
> +   tristate "ChromeOS Embedded Controller (LPC)"
> +   depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> help
> - If you say Y here, a varia

Re: [PATCH v3] platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime

2019-06-13 Thread Nick Crews
Hi!

Thanks for the changes Enric! I had just a few more nits.

On Wed, Jun 12, 2019 at 2:30 PM Enric Balletbo i Serra
 wrote:
>
> On many boards, communication between the kernel and the Embedded
> Controller happens over an LPC bus. In these cases, the kernel config
> CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
> Microchip Embedded Controller (MEC) that is different from the regular
> EC. On these devices, the same LPC bus is used, but the protocol is
> a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
> config is enabled. Currently, the kernel decides at compile-time whether
> or not to use the MEC variant, and, when that kernel option is selected
> it breaks the other boards. We would like a kind of runtime detection to
> avoid this.
>
> This patch adds that detection mechanism by probing the protocol at
> runtime, first we assume that a MEC variant is connected, and if the
> protocol fails it fallbacks to the regular EC. This adds a bit of
> overload because we try to read twice on those LPC boards that doesn't
> contain a MEC variant, but is a better solution than having to select the
> EC variant at compile-time.
>
> While here also fix the alignment in Kconfig file for this config option
> replacing the spaces by tabs.
>
> Signed-off-by: Enric Balletbo i Serra 
> Reviewed-by: Ezequiel Garcia 
> Tested-by: Nick Crews 
> ---
> Hi,
>
> This is another attempt to solve the issue to be able to select at
> runtime the CrOS MEC variant. My first thought was check for a device
> ID,
> the MEC1322 has a register that contains the device ID, however I am not
> sure if we can read that register from the host without modifying the
> firmware. Also, I am not sure if the MEC1322 is the only device used
> that supports that LPC protocol variant, so I ended with a more easy
> solution, check if the protocol fails or not. Some background on this
> issue can be found [1] and [2]
>
> The patch has been tested on:
>  - Acer Chromebook R11 (Cyan - MEC variant)
>  - Pixel Chromebook 2015 (Samus - non-MEC variant)
>  - Dell Chromebook 11 (Wolf - non-MEC variant)
>  - Toshiba Chromebook (Leon - non-MEC variant)
>
> Best regards,
>  Enric
>
> [1] https://bugs.chromium.org/p/chromium/issues/detail?id=932626
> [2] 
> https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1474254
>
> Changes in v3:
> - Kconfig: Split across multiple lines to keep it under 80 characters.
> - Improve kernel-doc as suggested by Nick Crews.
> - Convert msg in write function to const.
> - Add rb and tb tags.
>
> Changes in v2:
> - Remove global bool to indicate the kind of variant as suggested by Ezequiel.
> - Create an internal operations struct to allow different variants.
>
>  drivers/platform/chrome/Kconfig   | 29 +++--
>  drivers/platform/chrome/Makefile  |  2 +-
>  drivers/platform/chrome/cros_ec_lpc.c | 77 ---
>  drivers/platform/chrome/cros_ec_lpc_reg.c | 38 +++
>  drivers/platform/chrome/cros_ec_lpc_reg.h | 17 -
>  drivers/platform/chrome/wilco_ec/Kconfig  |  2 +-
>  6 files changed, 89 insertions(+), 76 deletions(-)
>
> diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
> index 2826f7136f65..453e69733842 100644
> --- a/drivers/platform/chrome/Kconfig
> +++ b/drivers/platform/chrome/Kconfig
> @@ -83,28 +83,17 @@ config CROS_EC_SPI
>   'pre-amble' bytes before the response actually starts.
>
>  config CROS_EC_LPC
> -tristate "ChromeOS Embedded Controller (LPC)"
> -depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> -help
> -  If you say Y here, you get support for talking to the ChromeOS EC
> -  over an LPC bus. This uses a simple byte-level protocol with a
> -  checksum. This is used for userspace access only. The kernel
> -  typically has its own communication methods.
> -
> -  To compile this driver as a module, choose M here: the
> -  module will be called cros_ec_lpc.
> -
> -config CROS_EC_LPC_MEC
> -   bool "ChromeOS Embedded Controller LPC Microchip EC (MEC) variant"
> -   depends on CROS_EC_LPC
> -   default n
> +   tristate "ChromeOS Embedded Controller (LPC)"
> +   depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> help
> - If you say Y here, a variant LPC protocol for the Microchip EC
> - will be used. Note that this variant is not backward compatible
> - with non-Microchip ECs.
> + If you say Y here, you get support for talking to the ChromeOS EC
> + 

Re: [PATCH v2] platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime

2019-06-10 Thread Nick Crews
A few nits below, and otherwise looks good to me!

On Fri, Jun 7, 2019 at 2:51 PM Enric Balletbo Serra  wrote:
>
> Hi,
>
> Missatge de Guenter Roeck  del dia dv., 7 de juny
> 2019 a les 22:11:
> >
> > On Fri, Jun 7, 2019 at 12:27 PM Nick Crews  wrote:
> > >
> > > Hi!
> > >
> > > On Fri, Jun 7, 2019 at 12:03 PM Ezequiel Garcia  
> > > wrote:
> > > >
> > > > On Fri, 2019-06-07 at 12:27 +0200, Enric Balletbo i Serra wrote:
> > > > > On many boards, communication between the kernel and the Embedded
> > > > > Controller happens over an LPC bus. In these cases, the kernel config
> > > > > CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
> > > > > Microchip Embedded Controller (MEC) that is different from the regular
> > > > > EC. On these devices, the same LPC bus is used, but the protocol is
> > > > > a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
> > > > > config is enabled. Currently, the kernel decides at compile-time 
> > > > > whether
> > > > > or not to use the MEC variant, and, when that kernel option is 
> > > > > selected
> > > > > it breaks the other boards. We would like a kind of runtime detection 
> > > > > to
> > > > > avoid this.
> > > > >
> > > > > This patch adds that detection mechanism by probing the protocol at
> > > > > runtime, first we assume that a MEC variant is connected, and if the
> > > > > protocol fails it fallbacks to the regular EC. This adds a bit of
> > > > > overload because we try to read twice on those LPC boards that doesn't
> > > > > contain a MEC variant, but is a better solution than having to select 
> > > > > the
> > > > > EC variant at compile-time.
> > > > >
> > > > > While here also fix the alignment in Kconfig file for this config 
> > > > > option
> > > > > replacing the spaces by tabs.
> > > > >
> > > > > Signed-off-by: Enric Balletbo i Serra 
> > > > > ---
> > > > > Hi,
> > > > >
> > > > > This is the second attempt to solve the issue to be able to select at
> > > > > runtime the CrOS MEC variant. My first thought was check for a device
> > > > > ID,
> > > > > the MEC1322 has a register that contains the device ID, however I am 
> > > > > not
> > > > > sure if we can read that register from the host without modifying the
> > > > > firmware. Also, I am not sure if the MEC1322 is the only device used
> > > > > that supports that LPC protocol variant, so I ended with a more easy
> > > > > solution, check if the protocol fails or not. Some background on this
> > > > > issue can be found [1] and [2]
> > > > >
> > > > > The patch has been tested on:
> > > > >  - Acer Chromebook R11 (Cyan - MEC variant)
> > > > >  - Pixel Chromebook 2015 (Samus - non-MEC variant)
> > > > >  - Dell Chromebook 11 (Wolf - non-MEC variant)
> > > > >  - Toshiba Chromebook (Leon - non-MEC variant)
> > > > >
> > > > > Nick, could you test the patch for Wilco?

It works, which makes sense, as Wilco hardcodes in using
the MEC variant.

Tested-by: Nick Crews 

> > > > >
> > > > > Best regards,
> > > > >  Enric
> > > > >
> > > > > [1] https://bugs.chromium.org/p/chromium/issues/detail?id=932626
> > > > > [2] 
> > > > > https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1474254
> > > > >
> > > > > Changes in v2:
> > > > > - Remove global bool to indicate the kind of variant as suggested by 
> > > > > Ezequiel.
> > > > > - Create an internal operations struct to allow different variants.
> > > > >
> > > > >  drivers/platform/chrome/Kconfig   | 29 +++--
> > > > >  drivers/platform/chrome/Makefile  |  3 +-
> > > > >  drivers/platform/chrome/cros_ec_lpc.c | 76 
> > > > > ---
> > > > >  drivers/platform/chrome/cros_ec_lpc_reg.c | 39 +++-
> > > > >  drivers/platform/chrome/cros_ec_lpc_reg.h | 26 
> > > > >  drivers/platform/chrome/wilco_ec/Kconfig  |  2 +-
> > 

Re: [PATCH v2] platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime

2019-06-07 Thread Nick Crews
Actually adding Stefan Reinauer this time...

On Fri, Jun 7, 2019 at 1:26 PM Nick Crews  wrote:
>
> Hi!
>
> On Fri, Jun 7, 2019 at 12:03 PM Ezequiel Garcia  
> wrote:
> >
> > On Fri, 2019-06-07 at 12:27 +0200, Enric Balletbo i Serra wrote:
> > > On many boards, communication between the kernel and the Embedded
> > > Controller happens over an LPC bus. In these cases, the kernel config
> > > CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
> > > Microchip Embedded Controller (MEC) that is different from the regular
> > > EC. On these devices, the same LPC bus is used, but the protocol is
> > > a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
> > > config is enabled. Currently, the kernel decides at compile-time whether
> > > or not to use the MEC variant, and, when that kernel option is selected
> > > it breaks the other boards. We would like a kind of runtime detection to
> > > avoid this.
> > >
> > > This patch adds that detection mechanism by probing the protocol at
> > > runtime, first we assume that a MEC variant is connected, and if the
> > > protocol fails it fallbacks to the regular EC. This adds a bit of
> > > overload because we try to read twice on those LPC boards that doesn't
> > > contain a MEC variant, but is a better solution than having to select the
> > > EC variant at compile-time.
> > >
> > > While here also fix the alignment in Kconfig file for this config option
> > > replacing the spaces by tabs.
> > >
> > > Signed-off-by: Enric Balletbo i Serra 
> > > ---
> > > Hi,
> > >
> > > This is the second attempt to solve the issue to be able to select at
> > > runtime the CrOS MEC variant. My first thought was check for a device
> > > ID,
> > > the MEC1322 has a register that contains the device ID, however I am not
> > > sure if we can read that register from the host without modifying the
> > > firmware. Also, I am not sure if the MEC1322 is the only device used
> > > that supports that LPC protocol variant, so I ended with a more easy
> > > solution, check if the protocol fails or not. Some background on this
> > > issue can be found [1] and [2]
> > >
> > > The patch has been tested on:
> > >  - Acer Chromebook R11 (Cyan - MEC variant)
> > >  - Pixel Chromebook 2015 (Samus - non-MEC variant)
> > >  - Dell Chromebook 11 (Wolf - non-MEC variant)
> > >  - Toshiba Chromebook (Leon - non-MEC variant)
> > >
> > > Nick, could you test the patch for Wilco?
> > >
> > > Best regards,
> > >  Enric
> > >
> > > [1] https://bugs.chromium.org/p/chromium/issues/detail?id=932626
> > > [2] 
> > > https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1474254
> > >
> > > Changes in v2:
> > > - Remove global bool to indicate the kind of variant as suggested by 
> > > Ezequiel.
> > > - Create an internal operations struct to allow different variants.
> > >
> > >  drivers/platform/chrome/Kconfig   | 29 +++--
> > >  drivers/platform/chrome/Makefile  |  3 +-
> > >  drivers/platform/chrome/cros_ec_lpc.c | 76 ---
> > >  drivers/platform/chrome/cros_ec_lpc_reg.c | 39 +++-
> > >  drivers/platform/chrome/cros_ec_lpc_reg.h | 26 
> > >  drivers/platform/chrome/wilco_ec/Kconfig  |  2 +-
> > >  6 files changed, 98 insertions(+), 77 deletions(-)
> > >
> > > diff --git a/drivers/platform/chrome/Kconfig 
> > > b/drivers/platform/chrome/Kconfig
> > > index 2826f7136f65..453e69733842 100644
> > > --- a/drivers/platform/chrome/Kconfig
> > > +++ b/drivers/platform/chrome/Kconfig
> > > @@ -83,28 +83,17 @@ config CROS_EC_SPI
> > > 'pre-amble' bytes before the response actually starts.
> > >
> > >  config CROS_EC_LPC
> > > -tristate "ChromeOS Embedded Controller (LPC)"
> > > -depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> > > -help
> > > -  If you say Y here, you get support for talking to the ChromeOS 
> > > EC
> > > -  over an LPC bus. This uses a simple byte-level protocol with a
> > > -  checksum. This is used for userspace access only. The kernel
> > > -  typically has its own communication methods.
> > > -
> > > -  To compile this driver as 

Re: [PATCH v2] platform/chrome: cros_ec_lpc: Choose Microchip EC at runtime

2019-06-07 Thread Nick Crews
Hi!

On Fri, Jun 7, 2019 at 12:03 PM Ezequiel Garcia  wrote:
>
> On Fri, 2019-06-07 at 12:27 +0200, Enric Balletbo i Serra wrote:
> > On many boards, communication between the kernel and the Embedded
> > Controller happens over an LPC bus. In these cases, the kernel config
> > CONFIG_CROS_EC_LPC is enabled. Some of these LPC boards contain a
> > Microchip Embedded Controller (MEC) that is different from the regular
> > EC. On these devices, the same LPC bus is used, but the protocol is
> > a little different. In these cases, the CONFIG_CROS_EC_LPC_MEC kernel
> > config is enabled. Currently, the kernel decides at compile-time whether
> > or not to use the MEC variant, and, when that kernel option is selected
> > it breaks the other boards. We would like a kind of runtime detection to
> > avoid this.
> >
> > This patch adds that detection mechanism by probing the protocol at
> > runtime, first we assume that a MEC variant is connected, and if the
> > protocol fails it fallbacks to the regular EC. This adds a bit of
> > overload because we try to read twice on those LPC boards that doesn't
> > contain a MEC variant, but is a better solution than having to select the
> > EC variant at compile-time.
> >
> > While here also fix the alignment in Kconfig file for this config option
> > replacing the spaces by tabs.
> >
> > Signed-off-by: Enric Balletbo i Serra 
> > ---
> > Hi,
> >
> > This is the second attempt to solve the issue to be able to select at
> > runtime the CrOS MEC variant. My first thought was check for a device
> > ID,
> > the MEC1322 has a register that contains the device ID, however I am not
> > sure if we can read that register from the host without modifying the
> > firmware. Also, I am not sure if the MEC1322 is the only device used
> > that supports that LPC protocol variant, so I ended with a more easy
> > solution, check if the protocol fails or not. Some background on this
> > issue can be found [1] and [2]
> >
> > The patch has been tested on:
> >  - Acer Chromebook R11 (Cyan - MEC variant)
> >  - Pixel Chromebook 2015 (Samus - non-MEC variant)
> >  - Dell Chromebook 11 (Wolf - non-MEC variant)
> >  - Toshiba Chromebook (Leon - non-MEC variant)
> >
> > Nick, could you test the patch for Wilco?
> >
> > Best regards,
> >  Enric
> >
> > [1] https://bugs.chromium.org/p/chromium/issues/detail?id=932626
> > [2] 
> > https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1474254
> >
> > Changes in v2:
> > - Remove global bool to indicate the kind of variant as suggested by 
> > Ezequiel.
> > - Create an internal operations struct to allow different variants.
> >
> >  drivers/platform/chrome/Kconfig   | 29 +++--
> >  drivers/platform/chrome/Makefile  |  3 +-
> >  drivers/platform/chrome/cros_ec_lpc.c | 76 ---
> >  drivers/platform/chrome/cros_ec_lpc_reg.c | 39 +++-
> >  drivers/platform/chrome/cros_ec_lpc_reg.h | 26 
> >  drivers/platform/chrome/wilco_ec/Kconfig  |  2 +-
> >  6 files changed, 98 insertions(+), 77 deletions(-)
> >
> > diff --git a/drivers/platform/chrome/Kconfig 
> > b/drivers/platform/chrome/Kconfig
> > index 2826f7136f65..453e69733842 100644
> > --- a/drivers/platform/chrome/Kconfig
> > +++ b/drivers/platform/chrome/Kconfig
> > @@ -83,28 +83,17 @@ config CROS_EC_SPI
> > 'pre-amble' bytes before the response actually starts.
> >
> >  config CROS_EC_LPC
> > -tristate "ChromeOS Embedded Controller (LPC)"
> > -depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> > -help
> > -  If you say Y here, you get support for talking to the ChromeOS EC
> > -  over an LPC bus. This uses a simple byte-level protocol with a
> > -  checksum. This is used for userspace access only. The kernel
> > -  typically has its own communication methods.
> > -
> > -  To compile this driver as a module, choose M here: the
> > -  module will be called cros_ec_lpc.
> > -
> > -config CROS_EC_LPC_MEC
> > - bool "ChromeOS Embedded Controller LPC Microchip EC (MEC) variant"
> > - depends on CROS_EC_LPC
> > - default n
> > + tristate "ChromeOS Embedded Controller (LPC)"
> > + depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST)
> >   help
> > -   If you say Y here, a variant LPC protocol for the Microchip EC
> > -   will be used. Note that this variant is not backward compatible
> > -   with non-Microchip ECs.
> > +   If you say Y here, you get support for talking to the ChromeOS EC
> > +   over an LPC bus, including the LPC Microchip EC (MEC) variant.
> > +   This uses a simple byte-level protocol with a checksum. This is
> > +   used for userspace access only. The kernel typically has its own
> > +   communication methods.
> >
> > -   If you have a ChromeOS Embedded Controller Microchip EC variant
> > -   choose Y here.
> > +   To compile this driver as a module, choose M 

Re: [PATCH v2] platform/chrome: wilco_ec: Add version sysfs entries

2019-06-05 Thread Nick Crews
Thanks Raul and Enric, this looks good to me.

On Mon, Jun 3, 2019 at 2:40 PM Enric Balletbo i Serra
 wrote:
>
> Nick,
>
> On 3/6/19 20:16, Raul E Rangel wrote:
> > Add the ability to extract version information from the EC.
> >
> > Example Output:
> > $ cd /sys/bus/platform/devices/GOOG000C:00
> > $ tail build_date build_revision version model_number
> > ==> build_date <==
> > 04/25/19
> >
> > ==> build_revision <==
> > d2592cae0
> >
> > ==> version <==
> > 00.00.14
> >
> > ==> model_number <==
> > 08B6
> >
> > Signed-off-by: Raul E Rangel 

Reviewed-by: Nick Crews 

>
> Can I get your rb here?
>
> Thanks,
>  Enric
>
> > ---
> > This patch is rebased on chromeos-platform/for-next. It was originally
> > developed on the chromiumos 4.19 kernel which has the following patch
> > applied: https://lore.kernel.org/patchwork/patch/1062995/. That patch is
> > not currently upstream.
> >
> > Changes in v2:
> > - Removed version directory
> > - Renamed label to version
> > - Sorted documentation
> >
> >  .../ABI/testing/sysfs-platform-wilco-ec   | 31 
> >  drivers/platform/chrome/wilco_ec/sysfs.c  | 79 +++
> >  2 files changed, 110 insertions(+)
> >
> > diff --git a/Documentation/ABI/testing/sysfs-platform-wilco-ec 
> > b/Documentation/ABI/testing/sysfs-platform-wilco-ec
> > index 8e5d6eee44db2..8827a734f9331 100644
> > --- a/Documentation/ABI/testing/sysfs-platform-wilco-ec
> > +++ b/Documentation/ABI/testing/sysfs-platform-wilco-ec
> > @@ -7,3 +7,34 @@ Description:
> >   want to run their device headless or with a dock.
> >
> >   Input should be parseable by kstrtou8() to 0 or 1.
> > +
> > +What:  /sys/bus/platform/devices/GOOG000C\:00/build_date
> > +Date:  May 2019
> > +KernelVersion: 5.3
> > +Description:
> > +   Display Wilco Embedded Controller firmware build date.
> > +   Output will a MM/DD/YY string.
> > +
> > +What:  /sys/bus/platform/devices/GOOG000C\:00/build_revision
> > +Date:  May 2019
> > +KernelVersion: 5.3
> > +Description:
> > +   Display Wilco Embedded Controller build revision.
> > +   Output will a version string be similar to the example 
> > below:
> > +   d2592cae0
> > +
> > +What:  /sys/bus/platform/devices/GOOG000C\:00/model_number
> > +Date:  May 2019
> > +KernelVersion: 5.3
> > +Description:
> > +   Display Wilco Embedded Controller model number.
> > +   Output will a version string be similar to the example 
> > below:
> > +   08B6
> > +
> > +What:  /sys/bus/platform/devices/GOOG000C\:00/version
> > +Date:  May 2019
> > +KernelVersion: 5.3
> > +Description:
> > +   Display Wilco Embedded Controller firmware version.
> > +   The format of the string is x.y.z. Where x is major, y is 
> > minor
> > +   and z is the build number. For example: 95.00.06
> > diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
> > b/drivers/platform/chrome/wilco_ec/sysfs.c
> > index f84f0480460ae..3b86a21005d3e 100644
> > --- a/drivers/platform/chrome/wilco_ec/sysfs.c
> > +++ b/drivers/platform/chrome/wilco_ec/sysfs.c
> > @@ -23,6 +23,25 @@ struct boot_on_ac_request {
> >   u8 reserved7;
> >  } __packed;
> >
> > +#define CMD_EC_INFO  0x38
> > +enum get_ec_info_op {
> > + CMD_GET_EC_LABEL= 0,
> > + CMD_GET_EC_REV  = 1,
> > + CMD_GET_EC_MODEL= 2,
> > + CMD_GET_EC_BUILD_DATE   = 3,
> > +};
> > +
> > +struct get_ec_info_req {
> > + u8 cmd; /* Always CMD_EC_INFO */
> > + u8 reserved;
> > + u8 op;  /* One of enum get_ec_info_op */
> > +} __packed;
> > +
> > +struct get_ec_info_resp {
> > + u8 reserved[2];
> > + char value[9]; /* __nonstring: might not be null terminated */
> > +} __packed;
> > +
> >  static ssize_t boot_on_ac_store(struct device *dev,
> >   struct device_attribute *attr,
> >   const char *buf, size_t count)
> > @@ -57,8 +76,68 @@ static ssize_t boot_on_ac_store(struct device *dev,
> >
> >  static DEVICE_ATTR_WO(boot_on_ac);
> >
> > +static ssize_t 

Re: [PATCH v5] platform/chrome: wilco_ec: Add telemetry char device interface

2019-05-24 Thread Nick Crews
Hey Enric, thanks for the review!

On Fri, May 24, 2019 at 3:51 AM Enric Balletbo i Serra
 wrote:
>
> Hi Nick,
>
> I'm mostly fine with it but ...
>
> On 21/5/19 21:20, Nick Crews wrote:
> > The Wilco Embedded Controller is able to send telemetry data
> > which is useful for enterprise applications. A daemon running on
> > the OS sends a command to the EC via a write() to a char device,
> > and can read the response with a read(). The write() request is
> > verified by the driver to ensure that it is performing only one
> > of the whitelisted commands, and that no extraneous data is
> > being transmitted to the EC. The response is passed directly
> > back to the reader with no modification.
> >
> > The character device will appear as /dev/wilco_telemN, where N
> > is some small non-negative integer, starting with 0. Only one
>
> Still remains my question in the previous version.
>
> We will really have more than one /dev/wilco_telemN devices handled by this
> driver? Why not use a Miscellaneous Character Device Driver that will simplify
> the code?

We probably will not have more than one device handled by the driver,
but I did this
at the request of Dmitry. He wanted to just do it right the first time so no one
would have to fix it if in the future a second device was needed. FYI,
I did the same
thing for the events driver at https://lore.kernel.org/patchwork/patch/1078461/.

I just tried to find the email thread and/or the review on the
Chromium Gerrit that
documents this, but I couldn't find it. It must have been a private
message, so sorry I
can't link you to it.

Dmitry, am I interpreting your reasoning correctly?

Thanks,
Nick


Re: [PATCH] platform/chrome: wilco_ec: Add version sysfs entries

2019-05-23 Thread Nick Crews
On Tue, May 21, 2019 at 9:15 AM Raul E Rangel  wrote:
>
> Add the ability to extract version information from the EC.
>
> Signed-off-by: Raul E Rangel 

Looks good to me, thanks Raul!
I applied to the chromium branch, and it works.

Reviewed-by: Nick Crews 
Tested-by: Nick Crews 

> ---
>
> This patch is rebased on platform/chrome: wilco_ec: Add Boot on AC support.
> https://lkml.org/lkml/2019/4/16/1374
>
> That patch wasn't in the for-next branch, so I'm not 100% sure if it
> applies cleanly to for-next.

It doesn't apply cleanly :(
You can add 
https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git
as the platform/chrome remote to ensure that it will apply cleanly.
It would probably be good for you to re-send this after rebasing it on for-next.


[PATCH v4] platform/chrome: wilco_ec: Add event handling

2019-05-23 Thread Nick Crews
The Wilco Embedded Controller can create custom events that
are not handled as standard ACPI objects. These events can
contain information about changes in EC controlled features,
such as errors and events in the dock or display. For example,
an event is triggered if the dock is plugged into a display
incorrectly. These events are needed for telemetry and
diagnostics reasons, and for possibly alerting the user.

These events are triggered by the EC with an ACPI Notify(0x90),
and then the BIOS reads the event buffer from EC RAM via an
ACPI method. When the OS receives these events via ACPI,
it passes them along to this driver. The events are put into
a queue which can be read by a userspace daemon via a char device
that implements read() and poll(). The event queue acts as a
circular buffer of size 64, so if there are no userspace consumers
the kernel will not run out of memory. The char device will appear at
/dev/wilco_event{n}, where n is some small non-negative integer,
starting from 0. Standard ACPI events such as the battery getting
plugged/unplugged can also come through this path, but they are
dealt with via other paths, and are ignored here.

To test, you can tail the binary data with
$ cat /dev/wilco_event0 | hexdump -ve '1/1 "%x\n"'
and then create an event by plugging/unplugging the battery.

Signed-off-by: Nick Crews 
---
v4 changes:
- Added size limit to queue to kernel would not run out of
  memory if there were no userspace consumers
- Change pr_warn() to pr_err() in module_init()
- Fix two print format specifiers
- A couple renaming tweaks
- Removed "v2" from MODULE_LICENSE
v3 changes:
- Made commit description more accurate and useful.
- Added an exclusive lock for opening the char device,
  so only one userspace process can read events at a time.

 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +
 drivers/platform/chrome/wilco_ec/event.c  | 541 ++
 3 files changed, 552 insertions(+)
 create mode 100644 drivers/platform/chrome/wilco_ec/event.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..2c8f6f15f28f 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_EVENTS
+   tristate "Enable event forwarding from EC to userspace"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support for the EC to send events
+ (such as power state changes) to userspace. The EC sends the events
+ over ACPI, and a driver queues up the events to be read by a
+ userspace daemon from /dev/wilco_event using read() and poll().
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 72df9b5e1983..4d8a5f068f8b 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o 
properties.o sysfs.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_events-objs   := event.o
+obj-$(CONFIG_WILCO_EC_EVENTS)  += wilco_ec_events.o
diff --git a/drivers/platform/chrome/wilco_ec/event.c 
b/drivers/platform/chrome/wilco_ec/event.c
new file mode 100644
index ..4d2776f77dbd
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/event.c
@@ -0,0 +1,541 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACPI event handling for Wilco Embedded Controller
+ *
+ * Copyright 2019 Google LLC
+ *
+ * The Wilco Embedded Controller can create custom events that
+ * are not handled as standard ACPI objects. These events can
+ * contain information about changes in EC controlled features,
+ * such as errors and events in the dock or display. For example,
+ * an event is triggered if the dock is plugged into a display
+ * incorrectly. These events are needed for telemetry and
+ * diagnostics reasons, and for possibly alerting the user.
+
+ * These events are triggered by the EC with an ACPI Notify(0x90),
+ * and then the BIOS reads the event buffer from EC RAM via an
+ * ACPI method. When the OS receives these events via ACPI,
+ * it passes them along to this driver. The events are put into
+ * a queue which can be read by a userspace daemon via a char device
+ * that implements read() and poll(). The event queue acts as a
+ * circular buffer of size 64, so if there are no userspace consumers
+ * the kernel will not run out of memory. The char device will appear at
+ * /dev/wilco_event{n}, where n is some small non-negativ

[PATCH v5] platform/chrome: wilco_ec: Add telemetry char device interface

2019-05-21 Thread Nick Crews
The Wilco Embedded Controller is able to send telemetry data
which is useful for enterprise applications. A daemon running on
the OS sends a command to the EC via a write() to a char device,
and can read the response with a read(). The write() request is
verified by the driver to ensure that it is performing only one
of the whitelisted commands, and that no extraneous data is
being transmitted to the EC. The response is passed directly
back to the reader with no modification.

The character device will appear as /dev/wilco_telemN, where N
is some small non-negative integer, starting with 0. Only one
process may have the file descriptor open at a time. The calling
userspace program needs to keep the device file descriptor open
between the calls to write() and read() in order to preserve the
response. Up to 32 bytes will be available for reading.

For testing purposes, try requesting the EC's firmware build
date, by sending the WILCO_EC_TELEM_GET_VERSION command with
argument index=3. i.e. write [0x38, 0x00, 0x03]
to the device node. An ASCII string of the build date is
returned.

Signed-off-by: Nick Crews 
---
v5 changes:
- Free device data in callback so that it isn't freed while
  the character device is open.
- Remove under-used dev_num variable in probe()
- Change pr_warn to pr_err in module_init()
- Allow for telemetry requests smaller than 32 bytes,
  and improve the validation on the requests.
- Return -EMSGSIZE instead of -EINVAL in for too-long requests.
- Zero out response buffer before making a request, so the
  response is more clearly padded.
v3 changes:
- Change WILCO_EC_CMD_* commands to WILCO_EC_TELEM_* in
  order to differentiate from the 0xF0 commannds.
- Use kernel-doc style for wilco_ec_telem_request.
- Change "GPL v2" to "GPL" in MODULE_LICENSE.
- Fix formatting in check_args_length().
v2 changes:
- Add verification of userspace requests, so that only
  whitelisted commands and args can get sent to the EC
- Use EC firmware build date request as example/test
- Pass the wilco_ec_device to the child driver better,
  instead of the child driver needing to access the parent
  devices' data.

 drivers/platform/chrome/wilco_ec/Kconfig |   7 +
 drivers/platform/chrome/wilco_ec/Makefile|   2 +
 drivers/platform/chrome/wilco_ec/core.c  |  13 +
 drivers/platform/chrome/wilco_ec/debugfs.c   |   2 +-
 drivers/platform/chrome/wilco_ec/telemetry.c | 450 +++
 include/linux/platform_data/wilco-ec.h   |   2 +
 6 files changed, 475 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/telemetry.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..2fc03aa624cf 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,10 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_TELEMETRY
+   tristate "Enable querying telemetry data from EC"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to query EC telemetry data from
+ /dev/wilco_telem0 using write() and then read().
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 72df9b5e1983..72a99f854241 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o 
properties.o sysfs.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_telem-objs:= telemetry.o
+obj-$(CONFIG_WILCO_EC_TELEMETRY)   += wilco_ec_telem.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 45cf3a5ed062..3724bf4b77c6 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -93,8 +93,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_rtc;
}
 
+   /* Register child device that will be found by the telemetry driver. */
+   ec->telem_pdev = platform_device_register_data(dev, "wilco_telem",
+  PLATFORM_DEVID_AUTO,
+  ec, sizeof(*ec));
+   if (IS_ERR(ec->telem_pdev)) {
+   dev_err(dev, "Failed to create telemetry platform device\n");
+   ret = PTR_ERR(ec->telem_pdev);
+   goto remove_sysfs;
+   }
+
return 0;
 
+remove_sysfs:
+   wilco_ec_remove_sysfs(ec);
 unregister_rtc:
platform_device_unregister(ec->

Re: [PATCH v3 1/2] platform/chrome: wilco_ec: Add Boot on AC support

2019-05-10 Thread Nick Crews
Thanks for the review Enric!

I can resend the patch with the fixes, or if you think the fixes are
simple enough, you could tweak them as you apply them. Let
me know if you want me to resend a clean version.

> > +
> > +static DEVICE_ATTR_WO(boot_on_ac);
>
> Is not possible to read the flag? From the API description seems that it is.

It is not possible to read the flag. The API description is wrong,
I'll fix remove
the line about reading from the documentation.

> > +void wilco_ec_remove_sysfs(struct wilco_ec_device *ec)
> > +{
> > +   sysfs_create_group(>dev->kobj, _dev_attr_group);
>
> As Guenter pointed:  sysfs_remove_group()

Yes, exactly.


[PATCH v4 1/2] platform/chrome: wilco_ec: Remove 256 byte transfers

2019-05-08 Thread Nick Crews
The 0xF6 command, intended to send and receive 256 byte payloads to
and from the EC, is not needed. The 0xF5 command for 32 byte
payloads is sufficient. This patch removes support for the 0xF6
command and 256 byte payloads.

Signed-off-by: Nick Crews 
---
v4 changes:
- Fix debug format string to use %u instead of %zu
  since type of EC_MAILBOX_DATA_SIZE has changed.

 Documentation/ABI/testing/debugfs-wilco-ec | 16 +++-
 drivers/platform/chrome/wilco_ec/core.c|  4 +---
 drivers/platform/chrome/wilco_ec/debugfs.c | 10 ++
 drivers/platform/chrome/wilco_ec/mailbox.c | 21 +
 include/linux/platform_data/wilco-ec.h |  9 ++---
 5 files changed, 17 insertions(+), 43 deletions(-)

diff --git a/Documentation/ABI/testing/debugfs-wilco-ec 
b/Documentation/ABI/testing/debugfs-wilco-ec
index 73a5a66ddca6..9d8d9d2def5b 100644
--- a/Documentation/ABI/testing/debugfs-wilco-ec
+++ b/Documentation/ABI/testing/debugfs-wilco-ec
@@ -23,11 +23,9 @@ Description:
 
For writing, bytes 0-1 indicate the message type, one of enum
wilco_ec_msg_type. Byte 2+ consist of the data passed in the
-   request, starting at MBOX[0]
-
-   At least three bytes are required for writing, two for the type
-   and at least a single byte of data. Only the first
-   EC_MAILBOX_DATA_SIZE bytes of MBOX will be used.
+   request, starting at MBOX[0]. At least three bytes are required
+   for writing, two for the type and at least a single byte of
+   data.
 
Example:
// Request EC info type 3 (EC firmware build date)
@@ -40,7 +38,7 @@ Description:
$ cat /sys/kernel/debug/wilco_ec/raw
00 00 31 32 2f 32 31 2f 31 38 00 38 00 01 00 2f 00  
..12/21/18.8...
 
-   Note that the first 32 bytes of the received MBOX[] will be
-   printed, even if some of the data is junk. It is up to you to
-   know how many of the first bytes of data are the actual
-   response.
+   Note that the first 16 bytes of the received MBOX[] will be
+   printed, even if some of the data is junk, and skipping bytes
+   17 to 32. It is up to you to know how many of the first bytes of
+   data are the actual response.
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..d060d3aa5bae 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -52,9 +52,7 @@ static int wilco_ec_probe(struct platform_device *pdev)
ec->dev = dev;
mutex_init(>mailbox_lock);
 
-   /* Largest data buffer size requirement is extended data response */
-   ec->data_size = sizeof(struct wilco_ec_response) +
-   EC_MAILBOX_DATA_SIZE_EXTENDED;
+   ec->data_size = sizeof(struct wilco_ec_response) + EC_MAILBOX_DATA_SIZE;
ec->data_buffer = devm_kzalloc(dev, ec->data_size, GFP_KERNEL);
if (!ec->data_buffer)
return -ENOMEM;
diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index f163476d080d..281ec595e8e0 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -17,13 +17,13 @@
 #define DRV_NAME "wilco-ec-debugfs"
 
 /* The 256 raw bytes will take up more space when represented as a hex string 
*/
-#define FORMATTED_BUFFER_SIZE (EC_MAILBOX_DATA_SIZE_EXTENDED * 4)
+#define FORMATTED_BUFFER_SIZE (EC_MAILBOX_DATA_SIZE * 4)
 
 struct wilco_ec_debugfs {
struct wilco_ec_device *ec;
struct dentry *dir;
size_t response_size;
-   u8 raw_data[EC_MAILBOX_DATA_SIZE_EXTENDED];
+   u8 raw_data[EC_MAILBOX_DATA_SIZE];
u8 formatted_data[FORMATTED_BUFFER_SIZE];
 };
 static struct wilco_ec_debugfs *debug_info;
@@ -124,12 +124,6 @@ static ssize_t raw_write(struct file *file, const char 
__user *user_buf,
msg.response_data = debug_info->raw_data;
msg.response_size = EC_MAILBOX_DATA_SIZE;
 
-   /* Telemetry commands use extended response data */
-   if (msg.type == WILCO_EC_MSG_TELEMETRY_LONG) {
-   msg.flags |= WILCO_EC_FLAG_EXTENDED_DATA;
-   msg.response_size = EC_MAILBOX_DATA_SIZE_EXTENDED;
-   }
-
ret = wilco_ec_mailbox(debug_info->ec, );
if (ret < 0)
return ret;
diff --git a/drivers/platform/chrome/wilco_ec/mailbox.c 
b/drivers/platform/chrome/wilco_ec/mailbox.c
index 7fb58b487963..ced1f9f3dcee 100644
--- a/drivers/platform/chrome/wilco_ec/mailbox.c
+++ b/drivers/platform/chrome/wilco_ec/mailbox.c
@@ -119,7 +119,6 @@ static int wilco_ec_transfer(struct wilco_ec_device *ec,
struct wilco_ec_response *rs;
u8 checksum;
u8 flag;
-   size_t size;
 
  

[PATCH v4 2/2] platform/chrome: wilco_ec: Add telemetry char device interface

2019-05-08 Thread Nick Crews
The Wilco Embedded Controller is able to send telemetry data
which is useful for enterprise applications. A daemon running on
the OS sends a command to the EC via a write() to a char device,
and can read the response with a read(). The write() request is
verified by the driver to ensure that it is performing only one
of the whitelisted commands, and that no extraneous data is
being transmitted to the EC. The response is passed directly
back to the reader with no modification.

The character device will appear as /dev/wilco_telemN, where N
is some small non-negative integer, starting with 0. Only one
process may have the file descriptor open at a time. The calling
userspace program needs to keep the device file descriptor open
between the calls to write() and read() in order to preserve the
response. 32 bytes of data are expected for arguments, and 32
bytes will be available for reading.

For testing purposes, try requesting the EC's firmware build
date, by sending the WILCO_EC_TELEM_GET_VERSION command with
argument index=3. i.e. write [0x38, 0x00, 0x03, ...(29 more 0s)]
to the device node. An ASCII string of the build date is
returned.

Signed-off-by: Nick Crews 
---
v3 changes:
- Change WILCO_EC_CMD_* commands to WILCO_EC_TELEM_* in
  order to differentiate from the 0xF0 commannds.
- Use kernel-doc style for wilco_ec_telem_request.
- Change "GPL v2" to "GPL" in MODULE_LICENSE.
- Fix formatting in check_args_length().
v2 changes:
- Add verification of userspace requests, so that only
  whitelisted commands and args can get sent to the EC
- Use EC firmware build date request as example/test
- Pass the wilco_ec_device to the child driver better,
  instead of the child driver needing to access the parent
  devices' data.

 drivers/platform/chrome/wilco_ec/Kconfig |   7 +
 drivers/platform/chrome/wilco_ec/Makefile|   2 +
 drivers/platform/chrome/wilco_ec/core.c  |  13 +
 drivers/platform/chrome/wilco_ec/debugfs.c   |   2 +-
 drivers/platform/chrome/wilco_ec/telemetry.c | 439 +++
 include/linux/platform_data/wilco-ec.h   |   2 +
 6 files changed, 464 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/telemetry.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..2fc03aa624cf 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,10 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_TELEMETRY
+   tristate "Enable querying telemetry data from EC"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to query EC telemetry data from
+ /dev/wilco_telem0 using write() and then read().
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 29b734137786..5a244da3b6c3 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o 
properties.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_telem-objs:= telemetry.o
+obj-$(CONFIG_WILCO_EC_TELEMETRY)   += wilco_ec_telem.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index d060d3aa5bae..4cb05d80e5af 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -87,8 +87,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device that will be found by the telemetry driver. */
+   ec->telem_pdev = platform_device_register_data(dev, "wilco_telem",
+  PLATFORM_DEVID_AUTO,
+  ec, sizeof(*ec));
+   if (IS_ERR(ec->telem_pdev)) {
+   dev_err(dev, "Failed to create telemetry platform device\n");
+   ret = PTR_ERR(ec->telem_pdev);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -100,6 +112,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   platform_device_unregister(ec->telem_pdev);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_devic

[PATCH v9 1/2] power_supply: wilco_ec: Add charging config driver

2019-05-08 Thread Nick Crews
Add a driver to control the charging algorithm used on Wilco
devices. See Documentation/ABI/testing/sysfs-class-power-wilco
for the userspace interface and other info.

Signed-off-by: Nick Crews 
Reviewed-by: Enric Balletbo i Serra 
---
v9 changes:
-Split up adding the driver and adding the device.
v8 changes:
-Several documentation and comment fixups.
v6 changes:
-Remove CHARGE_MODE_ILLEGAL from enum charge_mode. It's not a
 public type, and error checking could be performed in other ways.
-Split up the commit so properties are added in a first commit
-Move CONFIG_CHARGER_WILCO to the power/supply Kconfig
-Use PTR_ERR_OR_ZERO() macro in probe()
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/power/supply/Kconfig  |   9 +
 drivers/power/supply/Makefile |   1 +
 drivers/power/supply/wilco-charger.c  | 187 ++
 4 files changed, 227 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/power/supply/wilco-charger.c

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..da1d6ffe5e3c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco-charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco-charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco-charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index e901b9879e7e..0c67eff871c8 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -660,4 +660,13 @@ config FUEL_GAUGE_SC27XX
 Say Y here to enable support for fuel gauge with SC27XX
 PMIC chips.
 
+config CHARGER_WILCO
+   tristate "Wilco EC based charger for ChromeOS"
+   depends on WILCO_EC
+   help
+ Say Y here to enable control of the charging routines performed
+ by the Embedded Controller on the Chromebook named Wilco. Further
+ information can be found 

[PATCH v9 2/2] platform/chrome: wilco_ec: Add charging config device

2019-05-08 Thread Nick Crews
Add a device to control the charging algorithm used on Wilco devices,
which will be picked up by the drivers/power/supply/wilco-charger.c
driver. See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

Signed-off-by: Nick Crews 
Reviewed-by: Enric Balletbo i Serra 
---
v9 changes:
-Split up adding the driver and adding the device.
v8 changes:
-Several documentation and comment fixups.
v6 changes:
-Remove CHARGE_MODE_ILLEGAL from enum charge_mode. It's not a
 public type, and error checking could be performed in other ways.
-Split up the commit so properties are added in a first commit
-Move CONFIG_CHARGER_WILCO to the power/supply Kconfig
-Use PTR_ERR_OR_ZERO() macro in probe()
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 drivers/platform/chrome/wilco_ec/core.c | 13 +
 include/linux/platform_data/wilco-ec.h  |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..a8e3ef59f4ea 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device to be found by charger config driver. */
+   ec->charger_pdev = platform_device_register_data(dev, "wilco-charger",
+PLATFORM_DEVID_AUTO,
+NULL, 0);
+   if (IS_ERR(ec->charger_pdev)) {
+   dev_err(dev, "Failed to create charger platform device\n");
+   ret = PTR_ERR(ec->charger_pdev);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -102,6 +114,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   platform_device_unregister(ec->charger_pdev);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
diff --git a/include/linux/platform_data/wilco-ec.h 
b/include/linux/platform_data/wilco-ec.h
index 50a21bd5fd44..66d9f177bec2 100644
--- a/include/linux/platform_data/wilco-ec.h
+++ b/include/linux/platform_data/wilco-ec.h
@@ -32,6 +32,7 @@
  * @data_size: Size of the data buffer used for EC communication.
  * @debugfs_pdev: The child platform_device used by the debugfs sub-driver.
  * @rtc_pdev: The child platform_device used by the RTC sub-driver.
+ * @charger_pdev: Child platform_device used by the charger config sub-driver.
  */
 struct wilco_ec_device {
struct device *dev;
@@ -43,6 +44,7 @@ struct wilco_ec_device {
size_t data_size;
struct platform_device *debugfs_pdev;
struct platform_device *rtc_pdev;
+   struct platform_device *charger_pdev;
 };
 
 /**
-- 
2.20.1



[PATCH v3 2/2] platform/chrome: wilco_ec: Add telemetry char device interface

2019-05-06 Thread Nick Crews
The Wilco Embedded Controller is able to send telemetry data
which is useful for enterprise applications. A daemon running on
the OS sends a command to the EC via a write() to a char device,
and can read the response with a read(). The write() request is
verified by the driver to ensure that it is performing only one
of the whitelisted commands, and that no extraneous data is
being transmitted to the EC. The response is passed directly
back to the reader with no modification.

The character device will appear as /dev/wilco_telemN, where N
is some small non-negative integer, starting with 0. Only one
process may have the file descriptor open at a time. The calling
userspace program needs to keep the device file descriptor open
between the calls to write() and read() in order to preserve the
response. 32 bytes of data are expected for arguments, and 32
bytes will be available for reading.

For testing purposes, try requesting the EC's firmware build
date, by sending the WILCO_EC_TELEM_GET_VERSION command with
argument index=3. i.e. write [0x38, 0x00, 0x03, ...(29 more 0s)]
to the device node. An ASCII string of the build date is
returned.

Signed-off-by: Nick Crews 
---
v3 changes:
- Change WILCO_EC_CMD_* commands to WILCO_EC_TELEM_* in
  order to differentiate from the 0xF0 commannds.
- Use kernel-doc style for wilco_ec_telem_request.
- Change "GPL v2" to "GPL" in MODULE_LICENSE.
- Fix formatting in check_args_length().
v2 changes:
- Add verification of userspace requests, so that only
  whitelisted commands and args can get sent to the EC
- Use EC firmware build date request as example/test
- Pass the wilco_ec_device to the child driver better,
  instead of the child driver needing to access the parent
  devices' data.

 drivers/platform/chrome/wilco_ec/Kconfig |   7 +
 drivers/platform/chrome/wilco_ec/Makefile|   2 +
 drivers/platform/chrome/wilco_ec/core.c  |  13 +
 drivers/platform/chrome/wilco_ec/debugfs.c   |   2 +-
 drivers/platform/chrome/wilco_ec/telemetry.c | 439 +++
 include/linux/platform_data/wilco-ec.h   |   2 +
 6 files changed, 464 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/telemetry.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..2fc03aa624cf 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,10 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_TELEMETRY
+   tristate "Enable querying telemetry data from EC"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to query EC telemetry data from
+ /dev/wilco_telem0 using write() and then read().
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..b4aa6d26a3df 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_telem-objs:= telemetry.o
+obj-$(CONFIG_WILCO_EC_TELEMETRY)   += wilco_ec_telem.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index d060d3aa5bae..4cb05d80e5af 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -87,8 +87,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device that will be found by the telemetry driver. */
+   ec->telem_pdev = platform_device_register_data(dev, "wilco_telem",
+  PLATFORM_DEVID_AUTO,
+  ec, sizeof(*ec));
+   if (IS_ERR(ec->telem_pdev)) {
+   dev_err(dev, "Failed to create telemetry platform device\n");
+   ret = PTR_ERR(ec->telem_pdev);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -100,6 +112,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   platform_device_unregister(ec->telem_pdev);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_device_unregister(

[PATCH v3 1/2] platform/chrome: wilco_ec: Remove 256 byte transfers

2019-05-06 Thread Nick Crews
The 0xF6 command, intended to send and receive 256 byte payloads to
and from the EC, is not needed. The 0xF5 command for 32 byte
payloads is sufficient. This patch removes support for the 0xF6
command and 256 byte payloads.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/debugfs-wilco-ec | 16 +++-
 drivers/platform/chrome/wilco_ec/core.c|  4 +---
 drivers/platform/chrome/wilco_ec/debugfs.c | 10 ++
 drivers/platform/chrome/wilco_ec/mailbox.c | 19 ---
 include/linux/platform_data/wilco-ec.h |  9 ++---
 5 files changed, 16 insertions(+), 42 deletions(-)

diff --git a/Documentation/ABI/testing/debugfs-wilco-ec 
b/Documentation/ABI/testing/debugfs-wilco-ec
index 73a5a66ddca6..9d8d9d2def5b 100644
--- a/Documentation/ABI/testing/debugfs-wilco-ec
+++ b/Documentation/ABI/testing/debugfs-wilco-ec
@@ -23,11 +23,9 @@ Description:
 
For writing, bytes 0-1 indicate the message type, one of enum
wilco_ec_msg_type. Byte 2+ consist of the data passed in the
-   request, starting at MBOX[0]
-
-   At least three bytes are required for writing, two for the type
-   and at least a single byte of data. Only the first
-   EC_MAILBOX_DATA_SIZE bytes of MBOX will be used.
+   request, starting at MBOX[0]. At least three bytes are required
+   for writing, two for the type and at least a single byte of
+   data.
 
Example:
// Request EC info type 3 (EC firmware build date)
@@ -40,7 +38,7 @@ Description:
$ cat /sys/kernel/debug/wilco_ec/raw
00 00 31 32 2f 32 31 2f 31 38 00 38 00 01 00 2f 00  
..12/21/18.8...
 
-   Note that the first 32 bytes of the received MBOX[] will be
-   printed, even if some of the data is junk. It is up to you to
-   know how many of the first bytes of data are the actual
-   response.
+   Note that the first 16 bytes of the received MBOX[] will be
+   printed, even if some of the data is junk, and skipping bytes
+   17 to 32. It is up to you to know how many of the first bytes of
+   data are the actual response.
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..d060d3aa5bae 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -52,9 +52,7 @@ static int wilco_ec_probe(struct platform_device *pdev)
ec->dev = dev;
mutex_init(>mailbox_lock);
 
-   /* Largest data buffer size requirement is extended data response */
-   ec->data_size = sizeof(struct wilco_ec_response) +
-   EC_MAILBOX_DATA_SIZE_EXTENDED;
+   ec->data_size = sizeof(struct wilco_ec_response) + EC_MAILBOX_DATA_SIZE;
ec->data_buffer = devm_kzalloc(dev, ec->data_size, GFP_KERNEL);
if (!ec->data_buffer)
return -ENOMEM;
diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index f163476d080d..281ec595e8e0 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -17,13 +17,13 @@
 #define DRV_NAME "wilco-ec-debugfs"
 
 /* The 256 raw bytes will take up more space when represented as a hex string 
*/
-#define FORMATTED_BUFFER_SIZE (EC_MAILBOX_DATA_SIZE_EXTENDED * 4)
+#define FORMATTED_BUFFER_SIZE (EC_MAILBOX_DATA_SIZE * 4)
 
 struct wilco_ec_debugfs {
struct wilco_ec_device *ec;
struct dentry *dir;
size_t response_size;
-   u8 raw_data[EC_MAILBOX_DATA_SIZE_EXTENDED];
+   u8 raw_data[EC_MAILBOX_DATA_SIZE];
u8 formatted_data[FORMATTED_BUFFER_SIZE];
 };
 static struct wilco_ec_debugfs *debug_info;
@@ -124,12 +124,6 @@ static ssize_t raw_write(struct file *file, const char 
__user *user_buf,
msg.response_data = debug_info->raw_data;
msg.response_size = EC_MAILBOX_DATA_SIZE;
 
-   /* Telemetry commands use extended response data */
-   if (msg.type == WILCO_EC_MSG_TELEMETRY_LONG) {
-   msg.flags |= WILCO_EC_FLAG_EXTENDED_DATA;
-   msg.response_size = EC_MAILBOX_DATA_SIZE_EXTENDED;
-   }
-
ret = wilco_ec_mailbox(debug_info->ec, );
if (ret < 0)
return ret;
diff --git a/drivers/platform/chrome/wilco_ec/mailbox.c 
b/drivers/platform/chrome/wilco_ec/mailbox.c
index 7fb58b487963..c9c6c3194d12 100644
--- a/drivers/platform/chrome/wilco_ec/mailbox.c
+++ b/drivers/platform/chrome/wilco_ec/mailbox.c
@@ -119,7 +119,6 @@ static int wilco_ec_transfer(struct wilco_ec_device *ec,
struct wilco_ec_response *rs;
u8 checksum;
u8 flag;
-   size_t size;
 
/* Write request header, then data */
cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, 0, sizeof(*rq), (u8

[PATCH v2 1/2] platform/chrome: wilco_ec: Remove 256 byte transfers

2019-05-02 Thread Nick Crews
The 0xF6 command, intended to send and receive 256 byte payloads to
and from the EC, is not needed. The 0xF5 command for 32 byte
payloads is sufficient. This patch removes support for the 0xF6
command and 256 byte payloads.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/debugfs-wilco-ec | 16 +++-
 drivers/platform/chrome/wilco_ec/core.c|  4 +---
 drivers/platform/chrome/wilco_ec/debugfs.c | 10 ++
 drivers/platform/chrome/wilco_ec/mailbox.c | 19 ---
 include/linux/platform_data/wilco-ec.h |  9 ++---
 5 files changed, 16 insertions(+), 42 deletions(-)

diff --git a/Documentation/ABI/testing/debugfs-wilco-ec 
b/Documentation/ABI/testing/debugfs-wilco-ec
index 73a5a66ddca6..9d8d9d2def5b 100644
--- a/Documentation/ABI/testing/debugfs-wilco-ec
+++ b/Documentation/ABI/testing/debugfs-wilco-ec
@@ -23,11 +23,9 @@ Description:
 
For writing, bytes 0-1 indicate the message type, one of enum
wilco_ec_msg_type. Byte 2+ consist of the data passed in the
-   request, starting at MBOX[0]
-
-   At least three bytes are required for writing, two for the type
-   and at least a single byte of data. Only the first
-   EC_MAILBOX_DATA_SIZE bytes of MBOX will be used.
+   request, starting at MBOX[0]. At least three bytes are required
+   for writing, two for the type and at least a single byte of
+   data.
 
Example:
// Request EC info type 3 (EC firmware build date)
@@ -40,7 +38,7 @@ Description:
$ cat /sys/kernel/debug/wilco_ec/raw
00 00 31 32 2f 32 31 2f 31 38 00 38 00 01 00 2f 00  
..12/21/18.8...
 
-   Note that the first 32 bytes of the received MBOX[] will be
-   printed, even if some of the data is junk. It is up to you to
-   know how many of the first bytes of data are the actual
-   response.
+   Note that the first 16 bytes of the received MBOX[] will be
+   printed, even if some of the data is junk, and skipping bytes
+   17 to 32. It is up to you to know how many of the first bytes of
+   data are the actual response.
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..d060d3aa5bae 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -52,9 +52,7 @@ static int wilco_ec_probe(struct platform_device *pdev)
ec->dev = dev;
mutex_init(>mailbox_lock);
 
-   /* Largest data buffer size requirement is extended data response */
-   ec->data_size = sizeof(struct wilco_ec_response) +
-   EC_MAILBOX_DATA_SIZE_EXTENDED;
+   ec->data_size = sizeof(struct wilco_ec_response) + EC_MAILBOX_DATA_SIZE;
ec->data_buffer = devm_kzalloc(dev, ec->data_size, GFP_KERNEL);
if (!ec->data_buffer)
return -ENOMEM;
diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index f163476d080d..281ec595e8e0 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -17,13 +17,13 @@
 #define DRV_NAME "wilco-ec-debugfs"
 
 /* The 256 raw bytes will take up more space when represented as a hex string 
*/
-#define FORMATTED_BUFFER_SIZE (EC_MAILBOX_DATA_SIZE_EXTENDED * 4)
+#define FORMATTED_BUFFER_SIZE (EC_MAILBOX_DATA_SIZE * 4)
 
 struct wilco_ec_debugfs {
struct wilco_ec_device *ec;
struct dentry *dir;
size_t response_size;
-   u8 raw_data[EC_MAILBOX_DATA_SIZE_EXTENDED];
+   u8 raw_data[EC_MAILBOX_DATA_SIZE];
u8 formatted_data[FORMATTED_BUFFER_SIZE];
 };
 static struct wilco_ec_debugfs *debug_info;
@@ -124,12 +124,6 @@ static ssize_t raw_write(struct file *file, const char 
__user *user_buf,
msg.response_data = debug_info->raw_data;
msg.response_size = EC_MAILBOX_DATA_SIZE;
 
-   /* Telemetry commands use extended response data */
-   if (msg.type == WILCO_EC_MSG_TELEMETRY_LONG) {
-   msg.flags |= WILCO_EC_FLAG_EXTENDED_DATA;
-   msg.response_size = EC_MAILBOX_DATA_SIZE_EXTENDED;
-   }
-
ret = wilco_ec_mailbox(debug_info->ec, );
if (ret < 0)
return ret;
diff --git a/drivers/platform/chrome/wilco_ec/mailbox.c 
b/drivers/platform/chrome/wilco_ec/mailbox.c
index 7fb58b487963..c9c6c3194d12 100644
--- a/drivers/platform/chrome/wilco_ec/mailbox.c
+++ b/drivers/platform/chrome/wilco_ec/mailbox.c
@@ -119,7 +119,6 @@ static int wilco_ec_transfer(struct wilco_ec_device *ec,
struct wilco_ec_response *rs;
u8 checksum;
u8 flag;
-   size_t size;
 
/* Write request header, then data */
cros_ec_lpc_io_bytes_mec(MEC_IO_WRITE, 0, sizeof(*rq), (u8

[PATCH v2 2/2] platform/chrome: wilco_ec: Add telemetry char device interface

2019-05-02 Thread Nick Crews
The Wilco Embedded Controller is able to send telemetry data
which is useful for enterprise applications. A daemon running on
the OS sends a command to the EC via a write() to a char device,
and can read the response with a read(). The write() request is
verified by the driver to ensure that it is performing only one
of the whitelisted commands, and that no extraneous data is
being transmitted to the EC. The response is passed directly
back to the reader with no modification.

The character device will appear as /dev/wilco_telemN, where N
is some small non-negative integer, starting with 0. Only one
process may have the file descriptor open at a time. The calling
userspace program needs to keep the device file descriptor open
between the calls to write() and read() in order to preserve the
response. 32 bytes of data are expected for arguments, and 32
bytes will be available for reading.

For testing purposes, try requesting the EC's firmware build
date, by sending the WILCO_EC_CMD_GET_VERSION command with
argument index=3. i.e. write [0x38, 0x00, 0x03, ...(29 more 0s)]
to the device node. An ASCII string of the build date is
returned.

Signed-off-by: Nick Crews 
---
v2 changes:
- Add verification of userspace requests, so that only
  whitelisted commands and args can get sent to the EC
- Use EC firmware build date request as example/test
- Pass the wilco_ec_device to the child driver better,
  instead of the child driver needing to access the parent
  devices' data.

 drivers/platform/chrome/wilco_ec/Kconfig |   7 +
 drivers/platform/chrome/wilco_ec/Makefile|   2 +
 drivers/platform/chrome/wilco_ec/core.c  |  13 +
 drivers/platform/chrome/wilco_ec/debugfs.c   |   2 +-
 drivers/platform/chrome/wilco_ec/telemetry.c | 433 +++
 include/linux/platform_data/wilco-ec.h   |   2 +
 6 files changed, 458 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/telemetry.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..2fc03aa624cf 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,10 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_TELEMETRY
+   tristate "Enable querying telemetry data from EC"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to query EC telemetry data from
+ /dev/wilco_telem0 using write() and then read().
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..b4aa6d26a3df 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_telem-objs:= telemetry.o
+obj-$(CONFIG_WILCO_EC_TELEMETRY)   += wilco_ec_telem.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index d060d3aa5bae..4cb05d80e5af 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -87,8 +87,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device that will be found by the telemetry driver. */
+   ec->telem_pdev = platform_device_register_data(dev, "wilco_telem",
+  PLATFORM_DEVID_AUTO,
+  ec, sizeof(*ec));
+   if (IS_ERR(ec->telem_pdev)) {
+   dev_err(dev, "Failed to create telemetry platform device\n");
+   ret = PTR_ERR(ec->telem_pdev);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -100,6 +112,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   platform_device_unregister(ec->telem_pdev);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index 281ec595e8e0..8d65a1e2f1a3 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -16,7 +16,7 @@
 

Re: [PATCH v3 1/2] platform/chrome: wilco_ec: Add Boot on AC support

2019-05-01 Thread Nick Crews
Hi Enric,

Are these two patches an acceptable use of sysfs? There were concerns
earlier about abusing sysfs, but I think that these two uses follow
other sysfs use-cases well.

Thanks,
Nick


Re: [PATCH v7 2/2] power_supply: platform/chrome: wilco_ec: Add charging config driver

2019-05-01 Thread Nick Crews
Hi Enric and Sebastian,

I sent out a v8 to address Enric's nits:
https://lore.kernel.org/patchwork/patch/1065815/

Thanks,
Nick


[PATCH v8 1/2] platform/chrome: wilco_ec: Add property helper library

2019-04-24 Thread Nick Crews
A Property is typically a data item that is stored to NVRAM
by the EC. Each of these data items has an index associated
with it, known as the Property ID (PID). Properties may have
variable lengths, up to a max of WILCO_EC_PROPERTY_MAX_SIZE
bytes. Properties can be simple integers, or they may be more
complex binary data.

This patch adds support for getting and setting properties.
This will be useful for setting the charge algorithm and charge
schedules, which all use properties.

Signed-off-by: Nick Crews 
Acked-for-chrome-by: Enric Balletbo i Serra 
---
v7 changes:
-Remove bogus gerrit FROMLIST tag in commit title
v6 changes:
-Add EC_* prefix to enum property_ops so they are more unique.
-Split up the commit so properties are added in a first commit
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 drivers/platform/chrome/wilco_ec/Makefile |   2 +-
 drivers/platform/chrome/wilco_ec/properties.c | 132 ++
 include/linux/platform_data/wilco-ec.h|  71 ++
 3 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c

diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..29b734137786 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-wilco_ec-objs  := core.o mailbox.o
+wilco_ec-objs  := core.o mailbox.o properties.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
diff --git a/drivers/platform/chrome/wilco_ec/properties.c 
b/drivers/platform/chrome/wilco_ec/properties.c
new file mode 100644
index ..e69682c95ea2
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/properties.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include 
+#include 
+#include 
+
+/* Operation code; what the EC should do with the property */
+enum ec_property_op {
+   EC_OP_GET = 0,
+   EC_OP_SET = 1,
+};
+
+struct ec_property_request {
+   u8 op; /* One of enum ec_property_op */
+   u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
+   u8 length;
+   u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
+} __packed;
+
+struct ec_property_response {
+   u8 reserved[2];
+   u8 op; /* One of enum ec_property_op */
+   u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
+   u8 length;
+   u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
+} __packed;
+
+static int send_property_msg(struct wilco_ec_device *ec,
+struct ec_property_request *rq,
+struct ec_property_response *rs)
+{
+   struct wilco_ec_message ec_msg;
+   int ret;
+
+   memset(_msg, 0, sizeof(ec_msg));
+   ec_msg.type = WILCO_EC_MSG_PROPERTY;
+   ec_msg.request_data = rq;
+   ec_msg.request_size = sizeof(*rq);
+   ec_msg.response_data = rs;
+   ec_msg.response_size = sizeof(*rs);
+
+   ret = wilco_ec_mailbox(ec, _msg);
+   if (ret < 0)
+   return ret;
+   if (rs->op != rq->op)
+   return -EBADMSG;
+   if (memcmp(rq->property_id, rs->property_id, sizeof(rs->property_id)))
+

[PATCH v8 2/2] power_supply: platform/chrome: wilco_ec: Add charging config driver

2019-04-24 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

Signed-off-by: Nick Crews 
Reviewed-by: Enric Balletbo i Serra 
---
v8 changes:
-Several documentation and comment fixups.
v6 changes:
-Remove CHARGE_MODE_ILLEGAL from enum charge_mode. It's not a
 public type, and error checking could be performed in other ways.
-Split up the commit so properties are added in a first commit
-Move CONFIG_CHARGER_WILCO to the power/supply Kconfig
-Use PTR_ERR_OR_ZERO() macro in probe()
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/core.c   |  13 ++
 drivers/power/supply/Kconfig  |   9 +
 drivers/power/supply/Makefile |   1 +
 drivers/power/supply/wilco-charger.c  | 187 ++
 include/linux/platform_data/wilco-ec.h|   2 +
 6 files changed, 242 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/power/supply/wilco-charger.c

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..da1d6ffe5e3c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco-charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco-charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco-charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..a8e3ef59f4ea 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device to be found by charger config driver. */
+   ec->charger_pdev = platform_device_register_data(dev, "wilco-charger",
+  

[PATCH v7 2/2] power_supply: platform/chrome: wilco_ec: Add charging config driver

2019-04-22 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

Signed-off-by: Nick Crews 
---
v6 changes:
-Remove CHARGE_MODE_ILLEGAL from enum charge_mode. It's not a
 public type, and error checking could be performed in other ways.
-Split up the commit so properties are added in a first commit
-Move CONFIG_CHARGER_WILCO to the power/supply Kconfig
-Use PTR_ERR_OR_ZERO() macro in probe()
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/core.c   |  13 ++
 drivers/power/supply/Kconfig  |   9 +
 drivers/power/supply/Makefile |   1 +
 drivers/power/supply/wilco-charger.c  | 187 ++
 include/linux/platform_data/wilco-ec.h|   2 +
 6 files changed, 242 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/power/supply/wilco-charger.c

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..7f3b01310476
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco_charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..a8e3ef59f4ea 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device to be found by charger config driver. */
+   ec->charger_pdev = platform_device_register_data(dev, "wilco-charger",
+PLATFORM_DEVID_AUTO,
+NULL, 0);
+ 

[PATCH v7 1/2] platform/chrome: wilco_ec: Add property helper library

2019-04-22 Thread Nick Crews
A Property is typically a data item that is stored to NVRAM
by the EC. Each of these data items has an index associated
with it, known as the Property ID (PID). Properties may have
variable lengths, up to a max of WILCO_EC_PROPERTY_MAX_SIZE
bytes. Properties can be simple integers, or they may be more
complex binary data.

This patch adds support for getting and setting properties.
This will be useful for setting the charge algorithm and charge
schedules, which all use properties.

Signed-off-by: Nick Crews 
---
v7 changes:
-Remove bogus gerrit FROMLIST tag in commit title
v6 changes:
-Add EC_* prefix to enum property_ops so they are more unique.
-Split up the commit so properties are added in a first commit
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 drivers/platform/chrome/wilco_ec/Makefile |   2 +-
 drivers/platform/chrome/wilco_ec/properties.c | 132 ++
 include/linux/platform_data/wilco-ec.h|  71 ++
 3 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c

diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..29b734137786 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-wilco_ec-objs  := core.o mailbox.o
+wilco_ec-objs  := core.o mailbox.o properties.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
diff --git a/drivers/platform/chrome/wilco_ec/properties.c 
b/drivers/platform/chrome/wilco_ec/properties.c
new file mode 100644
index ..e69682c95ea2
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/properties.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include 
+#include 
+#include 
+
+/* Operation code; what the EC should do with the property */
+enum ec_property_op {
+   EC_OP_GET = 0,
+   EC_OP_SET = 1,
+};
+
+struct ec_property_request {
+   u8 op; /* One of enum ec_property_op */
+   u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
+   u8 length;
+   u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
+} __packed;
+
+struct ec_property_response {
+   u8 reserved[2];
+   u8 op; /* One of enum ec_property_op */
+   u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
+   u8 length;
+   u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
+} __packed;
+
+static int send_property_msg(struct wilco_ec_device *ec,
+struct ec_property_request *rq,
+struct ec_property_response *rs)
+{
+   struct wilco_ec_message ec_msg;
+   int ret;
+
+   memset(_msg, 0, sizeof(ec_msg));
+   ec_msg.type = WILCO_EC_MSG_PROPERTY;
+   ec_msg.request_data = rq;
+   ec_msg.request_size = sizeof(*rq);
+   ec_msg.response_data = rs;
+   ec_msg.response_size = sizeof(*rs);
+
+   ret = wilco_ec_mailbox(ec, _msg);
+   if (ret < 0)
+   return ret;
+   if (rs->op != rq->op)
+   return -EBADMSG;
+   if (memcmp(rq->property_id, rs->property_id, sizeof(rs->property_id)))
+   return -EBADMSG;
+
+   return 0;
+}
+
+int wil

[PATCH v6 2/2] power_supply: platform/chrome: wilco_ec: Add charging config driver

2019-04-22 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

Signed-off-by: Nick Crews 
---
v6 changes:
-Remove CHARGE_MODE_ILLEGAL from enum charge_mode. It's not a
 public type, and error checking could be performed in other ways.
-Split up the commit so properties are added in a first commit
-Move CONFIG_CHARGER_WILCO to the power/supply Kconfig
-Use PTR_ERR_OR_ZERO() macro in probe()
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/core.c   |  13 ++
 drivers/power/supply/Kconfig  |   9 +
 drivers/power/supply/Makefile |   1 +
 drivers/power/supply/wilco-charger.c  | 187 ++
 include/linux/platform_data/wilco-ec.h|   2 +
 6 files changed, 242 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/power/supply/wilco-charger.c

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..7f3b01310476
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco_charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..a8e3ef59f4ea 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device to be found by charger config driver. */
+   ec->charger_pdev = platform_device_register_data(dev, "wilco-charger",
+PLATFORM_DEVID_AUTO,
+NULL, 0);
+ 

[PATCH v6 1/2] FROMLIST: platform/chrome: wilco_ec: Add property helper library

2019-04-22 Thread Nick Crews
A Property is typically a data item that is stored to NVRAM
by the EC. Each of these data items has an index associated
with it, known as the Property ID (PID). Properties may have
variable lengths, up to a max of WILCO_EC_PROPERTY_MAX_SIZE
bytes. Properties can be simple integers, or they may be more
complex binary data.

This patch adds support for getting and setting properties.
This will be useful for setting the charge algorithm and charge
schedules, which all use properties.

Signed-off-by: Nick Crews 
---
v6 changes:
-Add EC_* prefix to enum property_ops so they are more unique.
-Split up the commit so properties are added in a first commit
v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

 drivers/platform/chrome/wilco_ec/Makefile |   2 +-
 drivers/platform/chrome/wilco_ec/properties.c | 132 ++
 include/linux/platform_data/wilco-ec.h|  71 ++
 3 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c

diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..29b734137786 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-wilco_ec-objs  := core.o mailbox.o
+wilco_ec-objs  := core.o mailbox.o properties.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
diff --git a/drivers/platform/chrome/wilco_ec/properties.c 
b/drivers/platform/chrome/wilco_ec/properties.c
new file mode 100644
index ..e69682c95ea2
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/properties.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include 
+#include 
+#include 
+
+/* Operation code; what the EC should do with the property */
+enum ec_property_op {
+   EC_OP_GET = 0,
+   EC_OP_SET = 1,
+};
+
+struct ec_property_request {
+   u8 op; /* One of enum ec_property_op */
+   u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
+   u8 length;
+   u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
+} __packed;
+
+struct ec_property_response {
+   u8 reserved[2];
+   u8 op; /* One of enum ec_property_op */
+   u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
+   u8 length;
+   u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
+} __packed;
+
+static int send_property_msg(struct wilco_ec_device *ec,
+struct ec_property_request *rq,
+struct ec_property_response *rs)
+{
+   struct wilco_ec_message ec_msg;
+   int ret;
+
+   memset(_msg, 0, sizeof(ec_msg));
+   ec_msg.type = WILCO_EC_MSG_PROPERTY;
+   ec_msg.request_data = rq;
+   ec_msg.request_size = sizeof(*rq);
+   ec_msg.response_data = rs;
+   ec_msg.response_size = sizeof(*rs);
+
+   ret = wilco_ec_mailbox(ec, _msg);
+   if (ret < 0)
+   return ret;
+   if (rs->op != rq->op)
+   return -EBADMSG;
+   if (memcmp(rq->property_id, rs->property_id, sizeof(rs->property_id)))
+   return -EBADMSG;
+
+   return 0;
+}
+
+int wilco_ec_get_property(struct wilco_ec_device *ec,
+ 

[PATCH v5] power_supply: platform/chrome: wilco_ec: Add charging config driver

2019-04-18 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

v5 changes:
-Remove OP_SYNC, it has no immediate use case.
-Merge properties.h into wilco-ec.h
-Remove enum get_set_sync_op from the public interface,
 since without OP_SYNC they are irrelevant.
-Fix Kconfigs and Makefiles so they actually work
 with the v4 changes
-Tweak some formatting, spacing, and comments
-Fix validation of charge_type so illegal values
 can't be set. Before negative error codes were
 accidentally getting casted to positive numbers
-Remove more unneeded parentheses.
v4 changes:
-Use put_unaligned_le32() to store PID in request.
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +-
 drivers/platform/chrome/wilco_ec/core.c   |  13 ++
 drivers/platform/chrome/wilco_ec/properties.c | 134 
 drivers/power/supply/Makefile |   1 +
 drivers/power/supply/wilco-charger.c  | 190 ++
 include/linux/platform_data/wilco-ec.h|  73 +++
 8 files changed, 451 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c
 create mode 100644 drivers/power/supply/wilco-charger.c

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..7f3b01310476
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco_charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..ec0db8dd14c2 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config CHARGER_WILCO
+   tristate "Enable charger control"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to control the charging
+ routines performed by the Wilco Embedded Controller.
+ Further information can be found in
+ Documentation/ABI/t

Re: [PATCH v4 1/2] power_supply: Add more charge types and CHARGE_CONTROL_* properties

2019-04-18 Thread Nick Crews
On Wed, Apr 17, 2019 at 3:40 PM Sebastian Reichel  wrote:
>
> Hi,
>
> The changes itself look all good to me, but this does multiple
> things in a single patch, so please split it into multiple commits.

Thanks Sebastian!

I split this into 3 commits:
-add more charge_type's
-add more CHARGE_CONTROL_* properties
-Add missing documentation for other CHARGE_CONTROL_* properties

and just re-sent them.

>
> -- Sebastian
>


[PATCH v5 1/3] power_supply: Add Standard, Adaptive, and Custom charge types

2019-04-18 Thread Nick Crews
Add "Standard", "Adaptive", and "Custom" modes to the charge_type
property, to expand the existing "Trickle" and "Fast" modes.
I am adding them in order to support a new Chrome OS device,
but these properties should be general enough that they can be
used on other devices.

The meaning of "Standard" is obvious, but "Adaptive" and "Custom" are
more tricky: "Adaptive" means that the charge controller uses some
custom algorithm to change the charge type automatically, with no
configuration needed. "Custom" means that the charge controller uses the
POWER_SUPPLY_PROP_CHARGE_CONTROL_* properties as configuration for some
other algorithm.

v5 changes:
- Split up adding the charge types and adding the
  POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD and
  POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD properties into
  two different commits.
v4 changes:
- Add documentation for the new properties, and add documentation for
  the the previously missing charge_control_limit and
  charge_control_limit_max properties.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/sysfs-class-power | 12 +---
 drivers/power/supply/power_supply_sysfs.c   |  2 +-
 include/linux/power_supply.h|  8 ++--
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index 5e23e22dce1b..544c4e0ef8b6 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -119,10 +119,16 @@ Date: July 2009
 Contact:   linux...@vger.kernel.org
 Description:
Represents the type of charging currently being applied to the
-   battery.
+   battery. "Trickle", "Fast", and "Standard" all mean different
+   charging speeds. "Adaptive" means that the charger uses some
+   algorithm to adjust the charge rate dynamically, without
+   any user configuration required. "Custom" means that the charger
+   uses the charge_control_* properties as configuration for some
+   different algorithm.
 
-   Access: Read
-   Valid values: "Unknown", "N/A", "Trickle", "Fast"
+   Access: Read, Write
+   Valid values: "Unknown", "N/A", "Trickle", "Fast", "Standard",
+ "Adaptive", "Custom"
 
 What:  /sys/class/power_supply//charge_term_current
 Date:  July 2014
diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index dce24f596160..64dff5cfecc3 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -56,7 +56,7 @@ static const char * const power_supply_status_text[] = {
 };
 
 static const char * const power_supply_charge_type_text[] = {
-   "Unknown", "N/A", "Trickle", "Fast"
+   "Unknown", "N/A", "Trickle", "Fast", "Standard", "Adaptive", "Custom"
 };
 
 static const char * const power_supply_health_text[] = {
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 2f9c201a54d1..e86e05d8134d 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -40,11 +40,15 @@ enum {
POWER_SUPPLY_STATUS_FULL,
 };
 
+/* What algorithm is the charger using? */
 enum {
POWER_SUPPLY_CHARGE_TYPE_UNKNOWN = 0,
POWER_SUPPLY_CHARGE_TYPE_NONE,
-   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
-   POWER_SUPPLY_CHARGE_TYPE_FAST,
+   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,   /* slow speed */
+   POWER_SUPPLY_CHARGE_TYPE_FAST,  /* fast speed */
+   POWER_SUPPLY_CHARGE_TYPE_STANDARD,  /* normal speed */
+   POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE,  /* dynamically adjusted speed */
+   POWER_SUPPLY_CHARGE_TYPE_CUSTOM,/* use CHARGE_CONTROL_* props */
 };
 
 enum {
-- 
2.20.1



[PATCH v5 2/3] power_supply: Add CHARGE_CONTROL_{START_THRESHOLD,END_THRESHOLD} properties

2019-04-18 Thread Nick Crews
Add POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD
and POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD properties, to expand
the existing CHARGE_CONTROL_* properties. I am adding them in order
to support a new Chrome OS device, but these properties should be
general enough that they can be used on other devices.

When the charge_type is "Custom", the charge controller uses the
POWER_SUPPLY_PROP_CHARGE_CONTROL_* properties as configuration for some
other algorithm. For example, in the use case that I am supporting,
this means the battery begins charging when the percentage
level drops below POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD and
charging ceases when the percentage level goes above
POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD.

v5 changes:
- Add the other missing CHARGE_CONTROL_* properties documentation in
  a separate commit
- Split up adding the charge types and adding the
  POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD and
  POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD properties into
  two different commits.
v4 changes:
- Add documentation for the new properties, and add documentation for
  the the previously missing charge_control_limit and
  charge_control_limit_max properties.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/sysfs-class-power | 20 
 drivers/power/supply/power_supply_sysfs.c   |  2 ++
 include/linux/power_supply.h|  2 ++
 3 files changed, 24 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index 544c4e0ef8b6..a5b144f61de8 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -114,6 +114,26 @@ Description:
Access: Read
Valid values: Represented in microamps
 
+What:  
/sys/class/power_supply//charge_control_start_threshold
+Date:  April 2019
+Contact:   linux...@vger.kernel.org
+Description:
+   Represents a battery percentage level, below which charging will
+   begin.
+
+   Access: Read, Write
+   Valid values: 0 - 100 (percent)
+
+What:  
/sys/class/power_supply//charge_control_end_threshold
+Date:  April 2019
+Contact:   linux...@vger.kernel.org
+Description:
+   Represents a battery percentage level, above which charging will
+   stop.
+
+   Access: Read, Write
+   Valid values: 0 - 100 (percent)
+
 What:  /sys/class/power_supply//charge_type
 Date:  July 2009
 Contact:   linux...@vger.kernel.org
diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index 64dff5cfecc3..6104a3f03d46 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -274,6 +274,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(constant_charge_voltage_max),
POWER_SUPPLY_ATTR(charge_control_limit),
POWER_SUPPLY_ATTR(charge_control_limit_max),
+   POWER_SUPPLY_ATTR(charge_control_start_threshold),
+   POWER_SUPPLY_ATTR(charge_control_end_threshold),
POWER_SUPPLY_ATTR(input_current_limit),
POWER_SUPPLY_ATTR(energy_full_design),
POWER_SUPPLY_ATTR(energy_empty_design),
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index e86e05d8134d..d59205170232 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -125,6 +125,8 @@ enum power_supply_property {
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD, /* in percents! */
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD, /* in percents! */
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
-- 
2.20.1



[PATCH v5 3/3] power_supply: Add missing documentation for CHARGE_CONTROL_* properties

2019-04-18 Thread Nick Crews
The existing POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT and
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX properties
don't have documentation. I add that documentation here.

v5 changes:
- Split this commit out from the previous two commits.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/sysfs-class-power | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index a5b144f61de8..b77e30b9014e 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -114,6 +114,25 @@ Description:
Access: Read
Valid values: Represented in microamps
 
+What:  /sys/class/power_supply//charge_control_limit
+Date:  Oct 2012
+Contact:   linux...@vger.kernel.org
+Description:
+   Maximum allowable charging current. Used for charge rate
+   throttling for thermal cooling or improving battery health.
+
+   Access: Read, Write
+   Valid values: Represented in microamps
+
+What:  /sys/class/power_supply//charge_control_limit_max
+Date:  Oct 2012
+Contact:   linux...@vger.kernel.org
+Description:
+   Maximum legal value for the charge_control_limit property.
+
+   Access: Read
+   Valid values: Represented in microamps
+
 What:  
/sys/class/power_supply//charge_control_start_threshold
 Date:  April 2019
 Contact:   linux...@vger.kernel.org
-- 
2.20.1



Re: [PATCH v3 1/2] platform/chrome: wilco_ec: Add Boot on AC support

2019-04-18 Thread Nick Crews
There's one error that Guenter just found...

> +
> +int wilco_ec_add_sysfs(struct wilco_ec_device *ec)
> +{
> +   return sysfs_create_group(>dev->kobj, _dev_attr_group);
> +}
> +
> +void wilco_ec_remove_sysfs(struct wilco_ec_device *ec)
> +{
> +   sysfs_create_group(>dev->kobj, _dev_attr_group);

Should be sysfs_remove_group()


[PATCH v3 2/2] platform/chrome: wilco_ec: Add USB PowerShare Policy control

2019-04-16 Thread Nick Crews
USB PowerShare is a policy which affects charging via the special
USB PowerShare port (marked with a small lightning bolt or battery icon)
when in low power states:
- In S0, the port will always provide power.
- In S0ix, if power_share is enabled, then power will be supplied to
  the port when on AC or if battery is > 50%. Else no power is supplied.
- In S5, if power_share is enabled, then power will be supplied to
  the port when on AC. Else no power is supplied.

v3 changes:
- Drop a silly blank line
- Use val > 1 instead of val != 0 && val != 1
v2 changes:
- Move documentation to Documentation/ABI/testing/sysfs-platform-wilco-ec
- Zero out reserved bytes in requests.

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-platform-wilco-ec   | 16 
 drivers/platform/chrome/wilco_ec/sysfs.c  | 92 +++
 2 files changed, 108 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-platform-wilco-ec 
b/Documentation/ABI/testing/sysfs-platform-wilco-ec
index e074c203cd32..0c07d5e0b737 100644
--- a/Documentation/ABI/testing/sysfs-platform-wilco-ec
+++ b/Documentation/ABI/testing/sysfs-platform-wilco-ec
@@ -9,3 +9,19 @@ Description:
Input should be parseable by kstrtou8() to 0 or 1.
Output will be either "0\n" or "1\n".
 
+What:  /sys/bus/platform/devices/GOOG000C\:00/usb_power_share
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Control the USB PowerShare Policy. USB PowerShare is a policy
+   which affects charging via the special USB PowerShare port
+   (marked with a small lightning bolt or battery icon) when in
+   low power states:
+   - In S0, the port will always provide power.
+   - In S0ix, if power_share is enabled, then power will be
+ supplied to the port when on AC or if battery is > 50%.
+ Else no power is supplied.
+   - In S5, if power_share is enabled, then power will be supplied
+ to the port when on AC. Else no power is supplied.
+
+   Input should be either "0" or "1".
diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
b/drivers/platform/chrome/wilco_ec/sysfs.c
index 959b5da2eb16..14e1eee95d42 100644
--- a/drivers/platform/chrome/wilco_ec/sysfs.c
+++ b/drivers/platform/chrome/wilco_ec/sysfs.c
@@ -23,6 +23,26 @@ struct boot_on_ac_request {
u8 reserved7;
 } __packed;
 
+#define CMD_USB_POWER_SHARE 0x39
+
+enum usb_power_share_op {
+   POWER_SHARE_GET = 0,
+   POWER_SHARE_SET = 1,
+};
+
+struct usb_power_share_request {
+   u8 cmd; /* Always CMD_USB_POWER_SHARE */
+   u8 reserved;
+   u8 op;  /* One of enum usb_power_share_op */
+   u8 val; /* When setting, either 0 or 1 */
+} __packed;
+
+struct usb_power_share_response {
+   u8 reserved;
+   u8 status;  /* Set by EC to 0 on success, other value on failure */
+   u8 val; /* When getting, set by EC to either 0 or 1 */
+} __packed;
+
 static ssize_t boot_on_ac_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -57,8 +77,80 @@ static ssize_t boot_on_ac_store(struct device *dev,
 
 static DEVICE_ATTR_WO(boot_on_ac);
 
+static int send_usb_power_share(struct wilco_ec_device *ec,
+   struct usb_power_share_request *rq,
+   struct usb_power_share_response *rs)
+{
+   struct wilco_ec_message msg;
+   int ret;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = rq;
+   msg.request_size = sizeof(*rq);
+   msg.response_data = rs;
+   msg.response_size = sizeof(*rs);
+   ret = wilco_ec_mailbox(ec, );
+   if (ret < 0)
+   return ret;
+   if (rs->status)
+   return -EIO;
+
+   return 0;
+}
+
+static ssize_t usb_power_share_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct usb_power_share_request rq;
+   struct usb_power_share_response rs;
+   int ret;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_USB_POWER_SHARE;
+   rq.op = POWER_SHARE_GET;
+
+   ret = send_usb_power_share(ec, , );
+   if (ret < 0)
+   return ret;
+
+   return sprintf(buf, "%d\n", rs.val);
+}
+
+static ssize_t usb_power_share_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t count)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct usb_power_share_request rq;
+   struct usb_power_share_response rs;
+   int r

[PATCH v3 1/2] platform/chrome: wilco_ec: Add Boot on AC support

2019-04-16 Thread Nick Crews
Boot on AC is a policy which makes the device boot from S5 when AC
power is connected. This is useful for users who want to run their
device headless or with a dock.

v3 changes:
- Add docstring to wilco_ec_add_sysfs()
- Tweak a comment
- Use val > 1 instead of val != 0 && val != 1
v2 changes:
- Move documentation to Documentation/ABI/testing/sysfs-platform-wilco-ec

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-platform-wilco-ec   | 11 +++
 drivers/platform/chrome/wilco_ec/Makefile |  2 +-
 drivers/platform/chrome/wilco_ec/core.c   |  9 +++
 drivers/platform/chrome/wilco_ec/sysfs.c  | 77 +++
 include/linux/platform_data/wilco-ec.h| 12 +++
 5 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-platform-wilco-ec
 create mode 100644 drivers/platform/chrome/wilco_ec/sysfs.c

diff --git a/Documentation/ABI/testing/sysfs-platform-wilco-ec 
b/Documentation/ABI/testing/sysfs-platform-wilco-ec
new file mode 100644
index ..e074c203cd32
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-wilco-ec
@@ -0,0 +1,11 @@
+What:  /sys/bus/platform/devices/GOOG000C\:00/boot_on_ac
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Boot on AC is a policy which makes the device boot from S5
+   when AC power is connected. This is useful for users who
+   want to run their device headless or with a dock.
+
+   Input should be parseable by kstrtou8() to 0 or 1.
+   Output will be either "0\n" or "1\n".
+
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..1281dd7737c4 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-wilco_ec-objs  := core.o mailbox.o
+wilco_ec-objs  := core.o mailbox.o sysfs.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..abd15d04e57b 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,16 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   ret = wilco_ec_add_sysfs(ec);
+   if (ret < 0) {
+   dev_err(dev, "Failed to create sysfs entries: %d", ret);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -102,6 +110,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   wilco_ec_remove_sysfs(ec);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
b/drivers/platform/chrome/wilco_ec/sysfs.c
new file mode 100644
index ..959b5da2eb16
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/sysfs.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Sysfs properties to view and modify EC-controlled features on Wilco devices.
+ * The entries will appear under /sys/bus/platform/devices/GOOG000C:00/
+ *
+ * See Documentation/ABI/testing/sysfs-platform-wilco-ec for more information.
+ */
+
+#include 
+#include 
+
+#define CMD_KB_CMOS0x7C
+#define SUB_CMD_KB_CMOS_AUTO_ON0x03
+
+struct boot_on_ac_request {
+   u8 cmd; /* Always CMD_KB_CMOS */
+   u8 reserved1;
+   u8 sub_cmd; /* Always SUB_CMD_KB_CMOS_AUTO_ON */
+   u8 reserved3to5[3];
+   u8 val; /* Either 0 or 1 */
+   u8 reserved7;
+} __packed;
+
+static ssize_t boot_on_ac_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct boot_on_ac_request rq;
+   struct wilco_ec_message msg;
+   int ret;
+   u8 val;
+
+   ret = kstrtou8(buf, 10, );
+   if (ret < 0)
+   return ret;
+   if (val > 1)
+   return -EINVAL;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_KB_CMOS;
+   rq.sub_cmd = SUB_CMD_KB_CMOS_AUTO_ON;
+   rq.val = val;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   ms

[PATCH v4 2/2] power_supply: platform/chrome: wilco_ec: Add charging config driver

2019-04-16 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

v4 changes:
-Move implementation from
 drivers/platform/chrome/wilco_ec/charge_config.c to
 drivers/power/supply/wilco_charger.c
-Move drivers/platform/chrome/wilco_ec/properties.h to
 include/linux/platform_data/wilco-ec-properties.h
-Remove parentheses in switch statement in psp_val_to_charge_mode()
-Check for any negatvie return code from psp_val_to_charge_mode()
 instead of just -EINVAL so its less brittle
-Tweak comments in wilco-ec-properties.h
v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +
 drivers/platform/chrome/wilco_ec/core.c   |  16 ++
 drivers/platform/chrome/wilco_ec/properties.c | 125 
 drivers/power/supply/wilco_charger.c  | 190 ++
 .../linux/platform_data/wilco-ec-properties.h |  68 +++
 include/linux/platform_data/wilco-ec.h|   2 +
 8 files changed, 442 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c
 create mode 100644 drivers/power/supply/wilco_charger.c
 create mode 100644 include/linux/platform_data/wilco-ec-properties.h

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..7f3b01310476
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco_charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..1c427830bd57 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_CHARGE_CNTL
+   tristate "Enable charging control"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to control the charging
+ routines performed by the Wilco Embedded Controller.
+ Further information can be found in
+ Documentation/ABI/testing/sysfs-class-power-wilco)
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..7e980f56f793 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS)

[PATCH v4 1/2] power_supply: Add more charge types and CHARGE_CONTROL_* properties

2019-04-16 Thread Nick Crews
Add "Standard", "Adaptive", and "Custom" modes to the charge_type
property, to expand the existing "Trickle" and "Fast" modes.
In addition, add POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD
and POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD properties, to expand
the existing CHARGE_CONTROL_* properties. I am adding them in order
to support a new Chrome OS device, but these properties should be
general enough that they can be used on other devices.

The meaning of "Standard" is obvious, but "Adaptive" and "Custom" are
more tricky: "Adaptive" means that the charge controller uses some
custom algorithm to change the charge type automatically, with no
configuration needed. "Custom" means that the charge controller uses the
POWER_SUPPLY_PROP_CHARGE_CONTROL_* properties as configuration for some
other algorithm. For example, in the use case that I am supporting,
this means the battery begins charging when the percentage
level drops below POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD and
charging ceases when the percentage level goes above
POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD.

v4 changes:
- Add documentation for the new properties, and add documentation for
  the the previously missing charge_control_limit and
  charge_control_limit_max properties.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/sysfs-class-power | 51 +++--
 drivers/power/supply/power_supply_sysfs.c   |  4 +-
 include/linux/power_supply.h| 10 +++-
 3 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-power 
b/Documentation/ABI/testing/sysfs-class-power
index 5e23e22dce1b..b77e30b9014e 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -114,15 +114,60 @@ Description:
Access: Read
Valid values: Represented in microamps
 
+What:  /sys/class/power_supply//charge_control_limit
+Date:  Oct 2012
+Contact:   linux...@vger.kernel.org
+Description:
+   Maximum allowable charging current. Used for charge rate
+   throttling for thermal cooling or improving battery health.
+
+   Access: Read, Write
+   Valid values: Represented in microamps
+
+What:  /sys/class/power_supply//charge_control_limit_max
+Date:  Oct 2012
+Contact:   linux...@vger.kernel.org
+Description:
+   Maximum legal value for the charge_control_limit property.
+
+   Access: Read
+   Valid values: Represented in microamps
+
+What:  
/sys/class/power_supply//charge_control_start_threshold
+Date:  April 2019
+Contact:   linux...@vger.kernel.org
+Description:
+   Represents a battery percentage level, below which charging will
+   begin.
+
+   Access: Read, Write
+   Valid values: 0 - 100 (percent)
+
+What:  
/sys/class/power_supply//charge_control_end_threshold
+Date:  April 2019
+Contact:   linux...@vger.kernel.org
+Description:
+   Represents a battery percentage level, above which charging will
+   stop.
+
+   Access: Read, Write
+   Valid values: 0 - 100 (percent)
+
 What:  /sys/class/power_supply//charge_type
 Date:  July 2009
 Contact:   linux...@vger.kernel.org
 Description:
Represents the type of charging currently being applied to the
-   battery.
+   battery. "Trickle", "Fast", and "Standard" all mean different
+   charging speeds. "Adaptive" means that the charger uses some
+   algorithm to adjust the charge rate dynamically, without
+   any user configuration required. "Custom" means that the charger
+   uses the charge_control_* properties as configuration for some
+   different algorithm.
 
-   Access: Read
-   Valid values: "Unknown", "N/A", "Trickle", "Fast"
+   Access: Read, Write
+   Valid values: "Unknown", "N/A", "Trickle", "Fast", "Standard",
+ "Adaptive", "Custom"
 
 What:  /sys/class/power_supply//charge_term_current
 Date:  July 2014
diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index dce24f596160..6104a3f03d46 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -56,7 +56,7 @@ static const char * const power_supply_status_text[] = {
 };
 
 static const char * const power_supply_charge_type_text[] = {
-   "Unknown"

[PATCH] platform/chrome: wilco_ec: Add telemetry data char device interface

2019-04-12 Thread Nick Crews
The Wilco Embedded Controller is able to send telemetry data
which is useful for enterprise applications. A daemon running on
the OS sends a command to the EC via write() to char device,
and can read the response with a read() request.
Both the request and the response are in an opaque
binary format so that information which is proprietary to the
enterprise service provider is secure.

The character device will appear as /dev/wilco_telemN, where N is some
small non-negative integer, starting with 0. Only one process may have
the file descriptor open at a time. The calling userspace program needs
to keep the device file descriptor open between the calls to write() and
read() in order to preserve the response. Either 32 or 256 bytes of data
are expected for arguments, and the same number of bytes will be
returned.

For testing purposes, if the EC receives a byte sequence beginning with
0, it will return an inverted copy of the input sequence. For an
example, run the simple python script from
https://gist.github.com/52ab07c8519b56c0ec671d3338760516

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/Kconfig |   7 +
 drivers/platform/chrome/wilco_ec/Makefile|   2 +
 drivers/platform/chrome/wilco_ec/core.c  |  13 +
 drivers/platform/chrome/wilco_ec/telemetry.c | 312 +++
 include/linux/platform_data/wilco-ec.h   |   2 +
 5 files changed, 336 insertions(+)
 create mode 100644 drivers/platform/chrome/wilco_ec/telemetry.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..7846f6146b78 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,10 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_TELEMETRY
+   tristate "Enable querying telemetry data from EC"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to query opaque binary
+ telemetrydata from /dev/wilco_telem using write() and then read().
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..b4aa6d26a3df 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_telem-objs:= telemetry.o
+obj-$(CONFIG_WILCO_EC_TELEMETRY)   += wilco_ec_telem.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..517d9627fecc 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,20 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   /* Register child device that will be found by the telemetry driver. */
+   ec->telem_pdev = platform_device_register_data(dev, "wilco_telem",
+  PLATFORM_DEVID_AUTO,
+  NULL, 0);
+   if (IS_ERR(ec->telem_pdev)) {
+   dev_err(dev, "Failed to create telemetry platform device\n");
+   ret = PTR_ERR(ec->telem_pdev);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -102,6 +114,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   platform_device_unregister(ec->telem_pdev);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c 
b/drivers/platform/chrome/wilco_ec/telemetry.c
new file mode 100644
index ..6b3dc84bd0f2
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/telemetry.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Telemetry communication for Wilco EC
+ *
+ * Copyright 2019 Google LLC
+ *
+ * The Wilco Embedded Controller is able to send telemetry data
+ * which is useful for enterprise applications. A daemon running on
+ * the OS sends a command to the EC via a write() to a char device, and
+ * can read the response with a read() request. Both the request
+ * and the response are in an opaque binary format so that information
+ * which

[PATCH v4 1/2] platform/chrome: wilco_ec: Fix documentation for debugfs raw attribute

2019-04-12 Thread Nick Crews
In a previous refactor [repo chrome-platform, branch for-next,
commit 9cced499d6fdb60434ffa94f8f4b5087ad35802b
("platform/chrome: wilco_ec: Standardize mailbox interface")], the
documentation for the raw debugfs attribute became incorrect, but I
forgot to fix it. This patch fixes it, as well as de-duplicates
the documentation by removing it from the source file header comment.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/debugfs-wilco-ec | 32 ++
 drivers/platform/chrome/wilco_ec/debugfs.c | 27 +-
 2 files changed, 22 insertions(+), 37 deletions(-)

diff --git a/Documentation/ABI/testing/debugfs-wilco-ec 
b/Documentation/ABI/testing/debugfs-wilco-ec
index f814f112e213..7ff6b45be703 100644
--- a/Documentation/ABI/testing/debugfs-wilco-ec
+++ b/Documentation/ABI/testing/debugfs-wilco-ec
@@ -4,20 +4,30 @@ KernelVersion:5.1
 Description:
Write and read raw mailbox commands to the EC.
 
-   For writing:
-   Bytes 0-1 indicate the message type:
-   00 F0 = Execute Legacy Command
-   00 F2 = Read/Write NVRAM Property
-   Byte 2 provides the command code
-   Bytes 3+ consist of the data passed in the request
+   You can write a hexadecimal sentence to raw, and that series of
+   bytes will be sent to the EC. Then, you can read the bytes of
+   response by reading from raw.
 
-   At least three bytes are required, for the msg type and command,
-   with additional bytes optional for additional data.
+   For writing, bytes 0-1 indicate the message type, one of enum
+   wilco_ec_msg_type. Byte 2+ consist of the data passed in the
+   request, starting at MBOX[0]
+
+   At least three bytes are required for writing, two for the type
+   and at least a single byte of data. Only the first
+   EC_MAILBOX_DATA_SIZE bytes of MBOX will be used.
 
Example:
// Request EC info type 3 (EC firmware build date)
-   $ echo 00 f0 38 00 03 00 > raw
+   // Corresponds with sending type 0x00f0 with
+   // MBOX = [38, 00, 03, 00]
+   $ echo 00 f0 38 00 03 00 > /sys/kernel/debug/wilco_ec/raw
// View the result. The decoded ASCII result "12/21/18" is
// included after the raw hex.
-   $ cat raw
-   00 31 32 2f 32 31 2f 31 38 00 38 00 01 00 2f 00  .12/21/18.8...
+   // Corresponds with MBOX = [00, 00, 31, 32, 2f, 32, 31, 38, ...]
+   $ cat /sys/kernel/debug/wilco_ec/raw
+   00 00 31 32 2f 32 31 2f 31 38 00 38 00 01 00 2f 00  
..12/21/18.8...
+
+   Note that the first 32 bytes of the received MBOX[] will be
+   printed, even if some of the data is junk. It is up to you to
+   know how many of the first bytes of data are the actual
+   response.
diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index 17c4c9068aaf..8d307378c1cb 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -4,32 +4,7 @@
  *
  * Copyright 2019 Google LLC
  *
- * There is only one attribute used for debugging, called raw.
- * You can write a hexadecimal sentence to raw, and that series of bytes
- * will be sent to the EC. Then, you can read the bytes of response
- * by reading from raw.
- *
- * For writing:
- * Bytes 0-1 indicate the message type, one of enum wilco_ec_msg_type
- * Byte 2+ consist of the data passed in the request, starting at MBOX[0]
- *
- * At least three bytes are required for writing, two for the type and at
- * least a single byte of data. Only the first EC_MAILBOX_DATA_SIZE bytes
- * of MBOX will be used.
- *
- * Example:
- * // Request EC info type 3 (EC firmware build date)
- * // Corresponds with sending type 0x00f0 with MBOX = [38, 00, 03, 00]
- * $ echo 00 f0 38 00 03 00 > /sys/kernel/debug/wilco_ec/raw
- * // View the result. The decoded ASCII result "12/21/18" is
- * // included after the raw hex.
- * // Corresponds with MBOX = [00, 00, 31, 32, 2f, 32, 31, ...]
- * $ cat /sys/kernel/debug/wilco_ec/raw
- * 00 00 31 32 2f 32 31 2f 31 38 00 38 00 01 00 2f 00  ..12/21/18.8...
- *
- * Note that the first 32 bytes of the received MBOX[] will be printed,
- * even if some of the data is junk. It is up to you to know how many of
- * the first bytes of data are the actual response.
+ * See Documentation/ABI/testing/debugfs-wilco-ec for usage.
  */
 
 #include 
-- 
2.20.1



[PATCH v4 2/2] platform/chrome: wilco_ec: Add h1_gpio status to debugfs

2019-04-12 Thread Nick Crews
As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
tests, we need to ensure that the H1 chip is properly setting
some GPIO lines. The h1_gpio attribute exposes the state
of the lines:
- ENTRY_TO_FACT_MODE in BIT(0)
- SPI_CHROME_SEL in BIT(1)

There are two reasons that I am exposing this in debugfs,
and not as a GPIO:
1. This is only useful for testing, so end users shouldn't ever
care about this. In fact, if it passes the tests, then the value of
h1_gpio will always be 2, so it would be really uninteresting for users.
2. This GPIO is not connected to, controlled by, or really even related
to the AP. The GPIO runs between the EC and the H1 security chip.

Changes in v4:
- Use "0x02x\n" instead of "02x\n" for format string
- Use DEFINE_DEBUGFS_ATTRIBUTE()
- Add documentation
Changes in v3:
- Fix documentation to correspond with formatting change in v2.
Changes in v2:
- Zero out the unused fields in the request.
- Format result as "%02x\n" instead of as a decimal.

Signed-off-by: Nick Crews 
---
 Documentation/ABI/testing/debugfs-wilco-ec | 13 ++
 drivers/platform/chrome/wilco_ec/debugfs.c | 47 ++
 2 files changed, 60 insertions(+)

diff --git a/Documentation/ABI/testing/debugfs-wilco-ec 
b/Documentation/ABI/testing/debugfs-wilco-ec
index 7ff6b45be703..73a5a66ddca6 100644
--- a/Documentation/ABI/testing/debugfs-wilco-ec
+++ b/Documentation/ABI/testing/debugfs-wilco-ec
@@ -1,3 +1,16 @@
+What:  /sys/kernel/debug/wilco_ec/h1_gpio
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
+   tests, we need to ensure that the H1 chip is properly setting
+   some GPIO lines. The h1_gpio attribute exposes the state
+   of the lines:
+   - ENTRY_TO_FACT_MODE in BIT(0)
+   - SPI_CHROME_SEL in BIT(1)
+
+   Output will formatted with "0x%02x\n".
+
 What:  /sys/kernel/debug/wilco_ec/raw
 Date:  January 2019
 KernelVersion: 5.1
diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index 8d307378c1cb..20482e590587 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -164,6 +164,51 @@ static const struct file_operations fops_raw = {
.llseek = no_llseek,
 };
 
+#define CMD_KB_CHROME  0x88
+#define SUB_CMD_H1_GPIO0x0A
+
+struct h1_gpio_status_request {
+   u8 cmd; /* Always CMD_KB_CHROME */
+   u8 reserved;
+   u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */
+} __packed;
+
+struct hi_gpio_status_response {
+   u8 status;  /* 0 if allowed */
+   u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL */
+} __packed;
+
+static int h1_gpio_get(void *arg, u64 *val)
+{
+   struct wilco_ec_device *ec = arg;
+   struct h1_gpio_status_request rq;
+   struct hi_gpio_status_response rs;
+   struct wilco_ec_message msg;
+   int ret;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_KB_CHROME;
+   rq.sub_cmd = SUB_CMD_H1_GPIO;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = 
+   msg.request_size = sizeof(rq);
+   msg.response_data = 
+   msg.response_size = sizeof(rs);
+   ret = wilco_ec_mailbox(ec, );
+   if (ret < 0)
+   return ret;
+   if (rs.status)
+   return -EIO;
+
+   *val = rs.val;
+
+   return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_h1_gpio, h1_gpio_get, NULL, "0x%02x\n");
+
 /**
  * wilco_ec_debugfs_probe() - Create the debugfs node
  * @pdev: The platform device, probably created in core.c
@@ -185,6 +230,8 @@ static int wilco_ec_debugfs_probe(struct platform_device 
*pdev)
if (!debug_info->dir)
return 0;
debugfs_create_file("raw", 0644, debug_info->dir, NULL, _raw);
+   debugfs_create_file("h1_gpio", 0444, debug_info->dir, ec,
+   _h1_gpio);
 
return 0;
 }
-- 
2.20.1



[PATCH v3 2/2] power_supply: platform/chrome: wilco_ec: Add charging config driver

2019-04-11 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

v3 changes:
-Add this changelog
-Fix commit message tags
v2 changes:
-Update Documentation to say KernelVersion 5.2
-Update Documentation to explain Trickle mode better.
-rename things from using *PCC* to *CHARGE*
-Split up conversions between POWER_SUPPLY_PROP_CHARGE_TYPE values
and Wilco EC codes
-Use devm_ flavor of power_supply_register(), which simplifies things
-Add extra error checking on property messages received from the EC
-Fix bug in memcpy() calls in properties.c
-Refactor fill_property_id()
-Add valid input checks to charge_type
-Properly convert charge_type when get()ting

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +
 .../platform/chrome/wilco_ec/charge_config.c  | 190 ++
 drivers/platform/chrome/wilco_ec/core.c   |  14 ++
 drivers/platform/chrome/wilco_ec/properties.c | 134 
 drivers/platform/chrome/wilco_ec/properties.h |  68 +++
 include/linux/platform_data/wilco-ec.h|   2 +
 8 files changed, 449 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/platform/chrome/wilco_ec/charge_config.c
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.h

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..7f3b01310476
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco_charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..1c427830bd57 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_CHARGE_CNTL
+   tristate "Enable charging control"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to control the charging
+ routines performed by the Wilco Embedded Controller.
+ Further information can be found in
+ Documentation/ABI/testing/sysfs-class-power-wilco)
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..7e980f56f793 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_charging-objs := charge_config.o properties.o
+obj-$(CONFIG_WILCO_EC_CHARGE_CNTL) += wilco_ec_charging.o
diff --git a/drivers/platform/chrome/wilco_ec/charge_config.c 
b/drivers/platform/chrome/wilco_ec/charge_config.c
new file mode 100644
index ..7c41b847396d
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/charge_config.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identi

[PATCH v3 1/2] power_supply: Add more charge types and CHARGE_CONTROL_* properties

2019-04-11 Thread Nick Crews
Add "Standard", "Adaptive", and "Custom" modes to the charge_type
property, to expand the existing "Trickle" and "Fast" modes.
In addition, add POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD
and POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD properties, to expand
the existing CHARGE_CONTROL_* properties. I am adding them in order
to support a new Chrome OS device, but these properties should be
general enough that they can be used on other devices.

The meaning of "Standard" is obvious, but "Adaptive" and "Custom" are
more tricky: "Adaptive" means that the charge controller uses some
custom algorithm to change the charge type automatically, with no
configuration needed. "Custom" means that the charge controller uses the
POWER_SUPPLY_PROP_CHARGE_CONTROL_* properties as configuration for some
other algorithm. For example, in the use case that I am supporting,
this means the battery begins charging when the percentage
level drops below POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD and
charging ceases when the percentage level goes above
POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD.

Signed-off-by: Nick Crews 
---
 drivers/power/supply/power_supply_sysfs.c |  4 +++-
 include/linux/power_supply.h  | 10 --
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index dce24f596160..6104a3f03d46 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -56,7 +56,7 @@ static const char * const power_supply_status_text[] = {
 };
 
 static const char * const power_supply_charge_type_text[] = {
-   "Unknown", "N/A", "Trickle", "Fast"
+   "Unknown", "N/A", "Trickle", "Fast", "Standard", "Adaptive", "Custom"
 };
 
 static const char * const power_supply_health_text[] = {
@@ -274,6 +274,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(constant_charge_voltage_max),
POWER_SUPPLY_ATTR(charge_control_limit),
POWER_SUPPLY_ATTR(charge_control_limit_max),
+   POWER_SUPPLY_ATTR(charge_control_start_threshold),
+   POWER_SUPPLY_ATTR(charge_control_end_threshold),
POWER_SUPPLY_ATTR(input_current_limit),
POWER_SUPPLY_ATTR(energy_full_design),
POWER_SUPPLY_ATTR(energy_empty_design),
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 2f9c201a54d1..d59205170232 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -40,11 +40,15 @@ enum {
POWER_SUPPLY_STATUS_FULL,
 };
 
+/* What algorithm is the charger using? */
 enum {
POWER_SUPPLY_CHARGE_TYPE_UNKNOWN = 0,
POWER_SUPPLY_CHARGE_TYPE_NONE,
-   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
-   POWER_SUPPLY_CHARGE_TYPE_FAST,
+   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,   /* slow speed */
+   POWER_SUPPLY_CHARGE_TYPE_FAST,  /* fast speed */
+   POWER_SUPPLY_CHARGE_TYPE_STANDARD,  /* normal speed */
+   POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE,  /* dynamically adjusted speed */
+   POWER_SUPPLY_CHARGE_TYPE_CUSTOM,/* use CHARGE_CONTROL_* props */
 };
 
 enum {
@@ -121,6 +125,8 @@ enum power_supply_property {
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD, /* in percents! */
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD, /* in percents! */
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
-- 
2.20.1



[PATCH v2 1/2] power_supply: Add more charge types and CHARGE_CONTROL_* properties

2019-04-11 Thread Nick Crews
Add "Standard", "Adaptive", and "Custom" modes to the charge_type
property, to expand the existing "Trickle" and "Fast" modes.
In addition, add POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD
and POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD properties, to expand
the existing CHARGE_CONTROL_* properties. I am adding them in order
to support a new Chrome OS device, but these properties should be
general enough that they can be used on other devices.

The meaning of "Standard" is obvious, but "Adaptive" and "Custom" are
more tricky: "Adaptive" means that the charge controller uses some
custom algorithm to change the charge type automatically, with no
configuration needed. "Custom" means that the charge controller uses the
POWER_SUPPLY_PROP_CHARGE_CONTROL_* properties as configuration for some
other algorithm. For example, in the use case that I am supporting,
this means the battery begins charging when the percentage
level drops below POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD and
charging ceases when the percentage level goes above
POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD.

Signed-off-by: Nick Crews 
---
 drivers/power/supply/power_supply_sysfs.c |  4 +++-
 include/linux/power_supply.h  | 10 --
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index dce24f596160..6104a3f03d46 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -56,7 +56,7 @@ static const char * const power_supply_status_text[] = {
 };
 
 static const char * const power_supply_charge_type_text[] = {
-   "Unknown", "N/A", "Trickle", "Fast"
+   "Unknown", "N/A", "Trickle", "Fast", "Standard", "Adaptive", "Custom"
 };
 
 static const char * const power_supply_health_text[] = {
@@ -274,6 +274,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(constant_charge_voltage_max),
POWER_SUPPLY_ATTR(charge_control_limit),
POWER_SUPPLY_ATTR(charge_control_limit_max),
+   POWER_SUPPLY_ATTR(charge_control_start_threshold),
+   POWER_SUPPLY_ATTR(charge_control_end_threshold),
POWER_SUPPLY_ATTR(input_current_limit),
POWER_SUPPLY_ATTR(energy_full_design),
POWER_SUPPLY_ATTR(energy_empty_design),
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 2f9c201a54d1..d59205170232 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -40,11 +40,15 @@ enum {
POWER_SUPPLY_STATUS_FULL,
 };
 
+/* What algorithm is the charger using? */
 enum {
POWER_SUPPLY_CHARGE_TYPE_UNKNOWN = 0,
POWER_SUPPLY_CHARGE_TYPE_NONE,
-   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
-   POWER_SUPPLY_CHARGE_TYPE_FAST,
+   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,   /* slow speed */
+   POWER_SUPPLY_CHARGE_TYPE_FAST,  /* fast speed */
+   POWER_SUPPLY_CHARGE_TYPE_STANDARD,  /* normal speed */
+   POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE,  /* dynamically adjusted speed */
+   POWER_SUPPLY_CHARGE_TYPE_CUSTOM,/* use CHARGE_CONTROL_* props */
 };
 
 enum {
@@ -121,6 +125,8 @@ enum power_supply_property {
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD, /* in percents! */
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD, /* in percents! */
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
-- 
2.20.1



[PATCH v2 2/2] power_supply: wilco_ec: Add charging config driver for Wilco EC

2019-04-11 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +
 .../platform/chrome/wilco_ec/charge_config.c  | 190 ++
 drivers/platform/chrome/wilco_ec/core.c   |  14 ++
 drivers/platform/chrome/wilco_ec/properties.c | 134 
 drivers/platform/chrome/wilco_ec/properties.h |  68 +++
 include/linux/platform_data/wilco-ec.h|   2 +
 8 files changed, 449 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/platform/chrome/wilco_ec/charge_config.c
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.h

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..7f3b01310476
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco_charger/charge_type
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan, intended for users who
+   primarily use their Chromebook while connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..1c427830bd57 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_CHARGE_CNTL
+   tristate "Enable charging control"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to control the charging
+ routines performed by the Wilco Embedded Controller.
+ Further information can be found in
+ Documentation/ABI/testing/sysfs-class-power-wilco)
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..7e980f56f793 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_charging-objs := charge_config.o properties.o
+obj-$(CONFIG_WILCO_EC_CHARGE_CNTL) += wilco_ec_charging.o
diff --git a/drivers/platform/chrome/wilco_ec/charge_config.c 
b/drivers/platform/chrome/wilco_ec/charge_config.c
new file mode 100644
index ..7c41b847396d
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/charge_config.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Charging control driver for the Wilco EC
+ *
+ * Copyright 2019 Google LLC
+ *
+ * See Documentation/ABI/testing/sysfs-class-power-wilco for
+ * userspace interface and other info.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "properties.h"
+
+#define DRV_NAME "wilco-ec-charging"
+
+/* Property IDs and related EC constants */
+#define PID_CHARGE_MODE0x0710
+#define PID_CHARGE_LOWER_LIMIT 0x0711
+#define PID_CHARGE_UPPER_LIMIT 0x0712
+
+enum charge_mode {
+   CHARGE_MODE_STD = 1,/* Used for Standard */
+

Re: [PATCH v3] platform/chrome: wilco_ec: Add h1_gpio status to debugfs

2019-04-11 Thread Nick Crews
Thanks for the comments Enric! I'll resend in a day or two.

On Thu, Apr 11, 2019 at 3:43 PM Enric Balletbo Serra
 wrote:
>
> Hi Nick,
>
> Some comments below ...
>
> Missatge de Nick Crews  del dia dj., 11 d’abr.
> 2019 a les 0:09:
> >
> > As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
> > tests, we need to ensure that the H1 chip is properly setting
> > some GPIO lines. The h1_gpio attribute exposes the state
> > of the lines:
> > - ENTRY_TO_FACT_MODE in BIT(0)
> > - SPI_CHROME_SEL in BIT(1)
> >
> > There are two reasons that I am exposing this in debugfs,
> > and not as a GPIO:
> > 1. This is only useful for testing, so end users shouldn't ever
> > care about this. In fact, if it passes the tests, then the value of
> > h1_gpio will always be 2, so it would be really uninteresting for users.
> > 2. This GPIO is not connected to, controlled by, or really even related
> > to the AP. The GPIO runs between the EC and the H1 security chip.
> >
> > Changes in v3:
> > - Fix documentation to correspond with formatting change in v2.
> > Changes in v2:
> > - Zero out the unused fields in the request.
> > - Format result as "%02x\n" instead of as a decimal.
>
> I don't really mind, but wouldn't be more clear prefix with 0x (0x%02x)?

I figured this would be easier for a program to parse, but you're right it
would be more clear. I can change it.

>
> >
> > Signed-off-by: Nick Crews 
> > ---
> >  drivers/platform/chrome/wilco_ec/debugfs.c | 64 +-
>
> ABI documentation missing.

Whoops, will do. The Documentation is out of date with the raw
attribute as well,
so I'll fix that too.

>
> >  1 file changed, 63 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
> > b/drivers/platform/chrome/wilco_ec/debugfs.c
> > index 17c4c9068aaf..1b93243c8954 100644
> > --- a/drivers/platform/chrome/wilco_ec/debugfs.c
> > +++ b/drivers/platform/chrome/wilco_ec/debugfs.c
> > @@ -4,7 +4,7 @@
> >   *
> >   * Copyright 2019 Google LLC
> >   *
> > - * There is only one attribute used for debugging, called raw.
> > + * The raw attribute is very useful for EC debugging.
> >   * You can write a hexadecimal sentence to raw, and that series of bytes
> >   * will be sent to the EC. Then, you can read the bytes of response
> >   * by reading from raw.
> > @@ -30,6 +30,16 @@
> >   * Note that the first 32 bytes of the received MBOX[] will be printed,
> >   * even if some of the data is junk. It is up to you to know how many of
> >   * the first bytes of data are the actual response.
> > + *
> > + * There is also another debugfs attribute, called h1_gpio.
> > + * As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
> > + * tests, we need to ensure that the H1 chip is properly setting
> > + * some GPIO lines. The h1_gpio attribute exposes the state
> > + * of the lines:
> > + * - ENTRY_TO_FACT_MODE in BIT(0)
> > + * - SPI_CHROME_SEL in BIT(1)
> > +
> > + * Output will formatted with "%02x\n".
> >   */
> >
> >  #include 
> > @@ -189,6 +199,56 @@ static const struct file_operations fops_raw = {
> > .llseek = no_llseek,
> >  };
> >
> > +#define CMD_KB_CHROME  0x88
> > +#define SUB_CMD_H1_GPIO0x0A
> > +
> > +struct h1_gpio_status_request {
> > +   u8 cmd; /* Always CMD_KB_CHROME */
> > +   u8 reserved;
> > +   u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */
> > +} __packed;
> > +
> > +struct hi_gpio_status_response {
> > +   u8 status;  /* 0 if allowed */
> > +   u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL 
> > */
> > +} __packed;
> > +
> > +static ssize_t h1_gpio_read(struct file *file, char __user *user_buf,
> > +   size_t count, loff_t *ppos)
> > +{
> > +   struct h1_gpio_status_request rq;
> > +   struct hi_gpio_status_response rs;
> > +   struct wilco_ec_message msg;
> > +   char buf[4];
> > +   int ret;
> > +
> > +   memset(, 0, sizeof(rq));
> > +   rq.cmd = CMD_KB_CHROME;
> > +   rq.sub_cmd = SUB_CMD_H1_GPIO;
> > +
> > +   memset(, 0, sizeof(msg));
> > +   msg.type = WILCO_EC_MSG_LEGACY;
> > +   msg.request_data = 
> > +   msg.request_size = sizeof(rq);
> > +   msg.response_data = 
> > +   msg.response_size = sizeof(rs);
> > +   ret = wilco_ec_mailbox(debug_info-&

[PATCH v2 2/2] platform/chrome: wilco_ec: Add USB PowerShare Policy control

2019-04-10 Thread Nick Crews
USB PowerShare is a policy which affects charging via the special
USB PowerShare port (marked with a small lightning bolt or battery icon)
when in low power states:
- In S0, the port will always provide power.
- In S0ix, if power_share is enabled, then power will be supplied to
  the port when on AC or if battery is > 50%. Else no power is supplied.
- In S5, if power_share is enabled, then power will be supplied to
  the port when on AC. Else no power is supplied.

v2 changes:
- Move documentation to Documentation/ABI/testing/sysfs-platform-wilco-ec
- Zero out reserved bytes in requests.

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-platform-wilco-ec   | 16 
 drivers/platform/chrome/wilco_ec/sysfs.c  | 93 +++
 2 files changed, 109 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-platform-wilco-ec 
b/Documentation/ABI/testing/sysfs-platform-wilco-ec
index e074c203cd32..0c07d5e0b737 100644
--- a/Documentation/ABI/testing/sysfs-platform-wilco-ec
+++ b/Documentation/ABI/testing/sysfs-platform-wilco-ec
@@ -9,3 +9,19 @@ Description:
Input should be parseable by kstrtou8() to 0 or 1.
Output will be either "0\n" or "1\n".
 
+What:  /sys/bus/platform/devices/GOOG000C\:00/usb_power_share
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Control the USB PowerShare Policy. USB PowerShare is a policy
+   which affects charging via the special USB PowerShare port
+   (marked with a small lightning bolt or battery icon) when in
+   low power states:
+   - In S0, the port will always provide power.
+   - In S0ix, if power_share is enabled, then power will be
+ supplied to the port when on AC or if battery is > 50%.
+ Else no power is supplied.
+   - In S5, if power_share is enabled, then power will be supplied
+ to the port when on AC. Else no power is supplied.
+
+   Input should be either "0" or "1".
diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
b/drivers/platform/chrome/wilco_ec/sysfs.c
index d1dbd4d2e6db..03dedf87ea1b 100644
--- a/drivers/platform/chrome/wilco_ec/sysfs.c
+++ b/drivers/platform/chrome/wilco_ec/sysfs.c
@@ -23,6 +23,26 @@ struct boot_on_ac_request {
u8 reserved7;
 } __packed;
 
+#define CMD_USB_POWER_SHARE 0x39
+
+enum usb_power_share_op {
+   POWER_SHARE_GET = 0,
+   POWER_SHARE_SET = 1,
+};
+
+struct usb_power_share_request {
+   u8 cmd; /* Always CMD_USB_POWER_SHARE */
+   u8 reserved;
+   u8 op;  /* One of enum usb_power_share_op */
+   u8 val; /* When setting, either 0 or 1 */
+} __packed;
+
+struct usb_power_share_response {
+   u8 reserved;
+   u8 status;  /* Set by EC to 0 on success, other value on failure */
+   u8 val; /* When getting, set by EC to either 0 or 1 */
+} __packed;
+
 static ssize_t boot_on_ac_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -57,8 +77,81 @@ static ssize_t boot_on_ac_store(struct device *dev,
 
 static DEVICE_ATTR_WO(boot_on_ac);
 
+static int send_usb_power_share(struct wilco_ec_device *ec,
+   struct usb_power_share_request *rq,
+   struct usb_power_share_response *rs)
+{
+   struct wilco_ec_message msg;
+   int ret;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = rq;
+   msg.request_size = sizeof(*rq);
+   msg.response_data = rs;
+   msg.response_size = sizeof(*rs);
+   ret = wilco_ec_mailbox(ec, );
+   if (ret < 0)
+   return ret;
+
+   if (rs->status)
+   return -EIO;
+
+   return 0;
+}
+
+static ssize_t usb_power_share_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct usb_power_share_request rq;
+   struct usb_power_share_response rs;
+   int ret;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_USB_POWER_SHARE;
+   rq.op = POWER_SHARE_GET;
+
+   ret = send_usb_power_share(ec, , );
+   if (ret < 0)
+   return ret;
+
+   return sprintf(buf, "%d\n", rs.val);
+}
+
+static ssize_t usb_power_share_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t count)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct usb_power_share_request rq;
+   struct usb_power_share_response rs;
+   int ret;
+   u8 val;
+
+   ret = kstrtou8(buf, 10, );
+   if (ret < 0)
+   return r

[PATCH v2 1/2] platform/chrome: wilco_ec: Add Boot on AC support

2019-04-10 Thread Nick Crews
Boot on AC is a policy which makes the device boot from S5 when AC
power is connected. This is useful for users who want to run their
device headless or with a dock.

v2 changes:
- Move documentation to Documentation/ABI/testing/sysfs-platform-wilco-ec

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-platform-wilco-ec   | 11 +++
 drivers/platform/chrome/wilco_ec/Makefile |  2 +-
 drivers/platform/chrome/wilco_ec/core.c   |  9 +++
 drivers/platform/chrome/wilco_ec/sysfs.c  | 77 +++
 include/linux/platform_data/wilco-ec.h|  3 +
 5 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-platform-wilco-ec
 create mode 100644 drivers/platform/chrome/wilco_ec/sysfs.c

diff --git a/Documentation/ABI/testing/sysfs-platform-wilco-ec 
b/Documentation/ABI/testing/sysfs-platform-wilco-ec
new file mode 100644
index ..e074c203cd32
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-wilco-ec
@@ -0,0 +1,11 @@
+What:  /sys/bus/platform/devices/GOOG000C\:00/boot_on_ac
+Date:  April 2019
+KernelVersion: 5.2
+Description:
+   Boot on AC is a policy which makes the device boot from S5
+   when AC power is connected. This is useful for users who
+   want to run their device headless or with a dock.
+
+   Input should be parseable by kstrtou8() to 0 or 1.
+   Output will be either "0\n" or "1\n".
+
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..1281dd7737c4 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-wilco_ec-objs  := core.o mailbox.o
+wilco_ec-objs  := core.o mailbox.o sysfs.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..abd15d04e57b 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,16 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   ret = wilco_ec_add_sysfs(ec);
+   if (ret < 0) {
+   dev_err(dev, "Failed to create sysfs entries: %d", ret);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -102,6 +110,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   wilco_ec_remove_sysfs(ec);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
b/drivers/platform/chrome/wilco_ec/sysfs.c
new file mode 100644
index ..d1dbd4d2e6db
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/sysfs.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Sysfs properties to view and modify EC-controlled features on Wilco devices.
+ * The entries will appear under /sys/bus/platform/devices/GOOG000C:00/
+ *
+ * See Documentation/ABI/testing/sysfs-platform-wilco-ec for more information.
+ */
+
+#include 
+#include 
+
+#define CMD_KB_CMOS0x7C
+#define SUB_CMD_KB_CMOS_AUTO_ON0x03
+
+struct boot_on_ac_request {
+   u8 cmd; /* Always CMD_KB_CMOS */
+   u8 reserved1;
+   u8 sub_cmd; /* Always SUB_CMD_KB_CMOS_AUTO_ON */
+   u8 reserved3to5[3];
+   u8 val; /* Either 0 or 1*/
+   u8 reserved7;
+} __packed;
+
+static ssize_t boot_on_ac_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct boot_on_ac_request rq;
+   struct wilco_ec_message msg;
+   int ret;
+   u8 val;
+
+   ret = kstrtou8(buf, 10, );
+   if (ret < 0)
+   return ret;
+   if (val != 0 && val != 1)
+   return -EINVAL;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_KB_CMOS;
+   rq.sub_cmd = SUB_CMD_KB_CMOS_AUTO_ON;
+   rq.val = val;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = 
+   msg.request_size = sizeof(rq);
+   ret = wilco_ec_mailbox(ec, );
+   i

[PATCH v3] platform/chrome: wilco_ec: Add h1_gpio status to debugfs

2019-04-10 Thread Nick Crews
As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
tests, we need to ensure that the H1 chip is properly setting
some GPIO lines. The h1_gpio attribute exposes the state
of the lines:
- ENTRY_TO_FACT_MODE in BIT(0)
- SPI_CHROME_SEL in BIT(1)

There are two reasons that I am exposing this in debugfs,
and not as a GPIO:
1. This is only useful for testing, so end users shouldn't ever
care about this. In fact, if it passes the tests, then the value of
h1_gpio will always be 2, so it would be really uninteresting for users.
2. This GPIO is not connected to, controlled by, or really even related
to the AP. The GPIO runs between the EC and the H1 security chip.

Changes in v3:
- Fix documentation to correspond with formatting change in v2.
Changes in v2:
- Zero out the unused fields in the request.
- Format result as "%02x\n" instead of as a decimal.

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/debugfs.c | 64 +-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index 17c4c9068aaf..1b93243c8954 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -4,7 +4,7 @@
  *
  * Copyright 2019 Google LLC
  *
- * There is only one attribute used for debugging, called raw.
+ * The raw attribute is very useful for EC debugging.
  * You can write a hexadecimal sentence to raw, and that series of bytes
  * will be sent to the EC. Then, you can read the bytes of response
  * by reading from raw.
@@ -30,6 +30,16 @@
  * Note that the first 32 bytes of the received MBOX[] will be printed,
  * even if some of the data is junk. It is up to you to know how many of
  * the first bytes of data are the actual response.
+ *
+ * There is also another debugfs attribute, called h1_gpio.
+ * As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
+ * tests, we need to ensure that the H1 chip is properly setting
+ * some GPIO lines. The h1_gpio attribute exposes the state
+ * of the lines:
+ * - ENTRY_TO_FACT_MODE in BIT(0)
+ * - SPI_CHROME_SEL in BIT(1)
+
+ * Output will formatted with "%02x\n".
  */
 
 #include 
@@ -189,6 +199,56 @@ static const struct file_operations fops_raw = {
.llseek = no_llseek,
 };
 
+#define CMD_KB_CHROME  0x88
+#define SUB_CMD_H1_GPIO0x0A
+
+struct h1_gpio_status_request {
+   u8 cmd; /* Always CMD_KB_CHROME */
+   u8 reserved;
+   u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */
+} __packed;
+
+struct hi_gpio_status_response {
+   u8 status;  /* 0 if allowed */
+   u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL */
+} __packed;
+
+static ssize_t h1_gpio_read(struct file *file, char __user *user_buf,
+   size_t count, loff_t *ppos)
+{
+   struct h1_gpio_status_request rq;
+   struct hi_gpio_status_response rs;
+   struct wilco_ec_message msg;
+   char buf[4];
+   int ret;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_KB_CHROME;
+   rq.sub_cmd = SUB_CMD_H1_GPIO;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = 
+   msg.request_size = sizeof(rq);
+   msg.response_data = 
+   msg.response_size = sizeof(rs);
+   ret = wilco_ec_mailbox(debug_info->ec, );
+   if (ret < 0)
+   return ret;
+   if (rs.status)
+   return -EIO;
+
+   sprintf(buf, "%02x\n", rs.val);
+
+   return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
+}
+
+static const struct file_operations fops_h1_gpio = {
+   .owner = THIS_MODULE,
+   .read = h1_gpio_read,
+   .llseek = no_llseek,
+};
+
 /**
  * wilco_ec_debugfs_probe() - Create the debugfs node
  * @pdev: The platform device, probably created in core.c
@@ -210,6 +270,8 @@ static int wilco_ec_debugfs_probe(struct platform_device 
*pdev)
if (!debug_info->dir)
return 0;
debugfs_create_file("raw", 0644, debug_info->dir, NULL, _raw);
+   debugfs_create_file("h1_gpio", 0444, debug_info->dir, NULL,
+   _h1_gpio);
 
return 0;
 }
-- 
2.20.1



[PATCH v2] platform/chrome: wilco_ec: Add h1_gpio status to debugfs

2019-04-10 Thread Nick Crews
As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
tests, we need to ensure that the H1 chip is properly setting
some GPIO lines. The h1_gpio attribute exposes the state
of the lines:
- ENTRY_TO_FACT_MODE in BIT(0)
- SPI_CHROME_SEL in BIT(1)

There are two reasons that I am exposing this in debugfs,
and not as a GPIO:
1. This is only useful for testing, so end users shouldn't ever
care about this. In fact, if it passes the tests, then the value of
h1_gpio will always be 2, so it would be really uninteresting for users.
2. This GPIO is not connected to, controlled by, or really even related
to the AP. The GPIO runs between the EC and the H1 security chip.

Changes in v2:
- Zero out the unused fields in the request.
- Format result as "%02x\n" instead of as a decimal.

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/debugfs.c | 64 +-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index 17c4c9068aaf..e1d9a6b73be9 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -4,7 +4,7 @@
  *
  * Copyright 2019 Google LLC
  *
- * There is only one attribute used for debugging, called raw.
+ * The raw attribute is very useful for EC debugging.
  * You can write a hexadecimal sentence to raw, and that series of bytes
  * will be sent to the EC. Then, you can read the bytes of response
  * by reading from raw.
@@ -30,6 +30,16 @@
  * Note that the first 32 bytes of the received MBOX[] will be printed,
  * even if some of the data is junk. It is up to you to know how many of
  * the first bytes of data are the actual response.
+ *
+ * There is also another debugfs attribute, called h1_gpio.
+ * As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
+ * tests, we need to ensure that the H1 chip is properly setting
+ * some GPIO lines. The h1_gpio attribute exposes the state
+ * of the lines:
+ * - ENTRY_TO_FACT_MODE in BIT(0)
+ * - SPI_CHROME_SEL in BIT(1)
+
+ * Output will be "0\n", "1\n", "2\n", or "3\n".
  */
 
 #include 
@@ -189,6 +199,56 @@ static const struct file_operations fops_raw = {
.llseek = no_llseek,
 };
 
+#define CMD_KB_CHROME  0x88
+#define SUB_CMD_H1_GPIO0x0A
+
+struct h1_gpio_status_request {
+   u8 cmd; /* Always CMD_KB_CHROME */
+   u8 reserved;
+   u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */
+} __packed;
+
+struct hi_gpio_status_response {
+   u8 status;  /* 0 if allowed */
+   u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL */
+} __packed;
+
+static ssize_t h1_gpio_read(struct file *file, char __user *user_buf,
+   size_t count, loff_t *ppos)
+{
+   struct h1_gpio_status_request rq;
+   struct hi_gpio_status_response rs;
+   struct wilco_ec_message msg;
+   char buf[4];
+   int ret;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_KB_CHROME;
+   rq.sub_cmd = SUB_CMD_H1_GPIO;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = 
+   msg.request_size = sizeof(rq);
+   msg.response_data = 
+   msg.response_size = sizeof(rs);
+   ret = wilco_ec_mailbox(debug_info->ec, );
+   if (ret < 0)
+   return ret;
+   if (rs.status)
+   return -EIO;
+
+   sprintf(buf, "%02x\n", rs.val);
+
+   return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
+}
+
+static const struct file_operations fops_h1_gpio = {
+   .owner = THIS_MODULE,
+   .read = h1_gpio_read,
+   .llseek = no_llseek,
+};
+
 /**
  * wilco_ec_debugfs_probe() - Create the debugfs node
  * @pdev: The platform device, probably created in core.c
@@ -210,6 +270,8 @@ static int wilco_ec_debugfs_probe(struct platform_device 
*pdev)
if (!debug_info->dir)
return 0;
debugfs_create_file("raw", 0644, debug_info->dir, NULL, _raw);
+   debugfs_create_file("h1_gpio", 0444, debug_info->dir, NULL,
+   _h1_gpio);
 
return 0;
 }
-- 
2.20.1



[PATCH] platform/chrome: wilco_ec: Add h1_gpio status to debugfs

2019-04-10 Thread Nick Crews
As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
tests, we need to ensure that the H1 chip is properly setting
some GPIO lines. The h1_gpio attribute exposes the state
of the lines:
- ENTRY_TO_FACT_MODE in BIT(0)
- SPI_CHROME_SEL in BIT(1)

There are two reasons that I am exposing this in debugfs,
and not as a GPIO:
1. This is only useful for testing, so end users shouldn't ever
care about this. In fact, if it passes the tests, then the value of
h1_gpio will always be 2, so it would be really uninteresting for users.
2. This GPIO is not connected to, controlled by, or really even related
to the AP. The GPIO runs between the EC and the H1 security chip.

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/debugfs.c | 66 +-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index 17c4c9068aaf..198c16476efc 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -4,7 +4,7 @@
  *
  * Copyright 2019 Google LLC
  *
- * There is only one attribute used for debugging, called raw.
+ * The raw attribute is very useful for EC debugging.
  * You can write a hexadecimal sentence to raw, and that series of bytes
  * will be sent to the EC. Then, you can read the bytes of response
  * by reading from raw.
@@ -30,6 +30,16 @@
  * Note that the first 32 bytes of the received MBOX[] will be printed,
  * even if some of the data is junk. It is up to you to know how many of
  * the first bytes of data are the actual response.
+ *
+ * There is also another debugfs attribute, called h1_gpio.
+ * As part of Chrome OS's FAFT (Fully Automated Firmware Testing)
+ * tests, we need to ensure that the H1 chip is properly setting
+ * some GPIO lines. The h1_gpio attribute exposes the state
+ * of the lines:
+ * - ENTRY_TO_FACT_MODE in BIT(0)
+ * - SPI_CHROME_SEL in BIT(1)
+
+ * Output will be "0\n", "1\n", "2\n", or "3\n".
  */
 
 #include 
@@ -189,6 +199,58 @@ static const struct file_operations fops_raw = {
.llseek = no_llseek,
 };
 
+#define CMD_KB_CHROME  0x88
+#define SUB_CMD_H1_GPIO0x0A
+
+struct h1_gpio_status_request {
+   u8 cmd; /* Always CMD_KB_CHROME */
+   u8 reserved;
+   u8 sub_cmd; /* Always SUB_CMD_H1_GPIO */
+} __packed;
+
+struct hi_gpio_status_response {
+   u8 status;  /* 0 if allowed */
+   u8 val; /* BIT(0)=ENTRY_TO_FACT_MODE, BIT(1)=SPI_CHROME_SEL */
+} __packed;
+
+static ssize_t h1_gpio_read(struct file *file, char __user *user_buf,
+   size_t count, loff_t *ppos)
+{
+   struct h1_gpio_status_request rq;
+   struct hi_gpio_status_response rs;
+   struct wilco_ec_message msg;
+   char buf[3];
+   int ret;
+
+   rq.cmd = CMD_KB_CHROME;
+   rq.sub_cmd = SUB_CMD_H1_GPIO;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = 
+   msg.request_size = sizeof(rq);
+   msg.response_data = 
+   msg.response_size = sizeof(rs);
+   ret = wilco_ec_mailbox(debug_info->ec, );
+   if (ret < 0)
+   return ret;
+   if (rs.status)
+   return -EIO;
+   if (rs.val > 3)
+   return -EBADMSG;
+
+   /* When rs.val <= 3, it's guaranteed to fit in buf after formatting */
+   sprintf(buf, "%d\n", rs.val);
+
+   return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
+}
+
+static const struct file_operations fops_h1_gpio = {
+   .owner = THIS_MODULE,
+   .read = h1_gpio_read,
+   .llseek = no_llseek,
+};
+
 /**
  * wilco_ec_debugfs_probe() - Create the debugfs node
  * @pdev: The platform device, probably created in core.c
@@ -210,6 +272,8 @@ static int wilco_ec_debugfs_probe(struct platform_device 
*pdev)
if (!debug_info->dir)
return 0;
debugfs_create_file("raw", 0644, debug_info->dir, NULL, _raw);
+   debugfs_create_file("h1_gpio", 0444, debug_info->dir, NULL,
+   _h1_gpio);
 
return 0;
 }
-- 
2.20.1



Re: [PATCH v3] platform/chrome: Add Wilco EC Event Handling

2019-04-09 Thread Nick Crews
Hi!

I know people had questions with the structure/uses of the events in the
previous versions of this patch. Does this clear things up?

Thanks, Nick

On Wed, Apr 3, 2019 at 6:31 PM Nick Crews  wrote:
>
> The Wilco Embedded Controller can create custom events that
> are not handled as standard ACPI objects. These events can
> contain information about changes in EC controlled features,
> such as errors and events in the dock or display. For example,
> an event is triggered if the dock is plugged into a display
> incorrectly. These events are needed for telemetry and
> diagnostics reasons, and for possibly alerting the user.
>
> These events are triggered by the EC with an ACPI Notify(0x90),
> and then the BIOS reads the event buffer from EC RAM via an
> ACPI method. When the OS receives these events via ACPI,
> it passes them along to this driver. The events are put into
> a queue which can be read by a userspace daemon via a char device
> that implements read() and poll(). The char device will appear at
> /dev/wilco_event{n}, where n is some small non-negative integer,
> starting from 0. Standard ACPI events such as the battery getting
> plugged/unplugged can also come through this path, but they are
> dealt with via other paths, and are ignored here.
>
> To test, you can tail the binary data with
> $ cat /dev/wilco_event0 | hexdump -ve '1/1 "%x\n"'
> and then create an event by pressing fn+Esc.
>
> v3 changes:
> - Made commit description more accurate and useful.
> - Added an exclusive lock for opening the char device,
>   so only one userspace process can read events at a time.
>
> Signed-off-by: Nick Crews 


[PATCH v6] platform/chrome: Add Wilco EC keyboard backlight LEDs support

2019-04-08 Thread Nick Crews
The EC is in charge of controlling the keyboard backlight on
the Wilco platform. We expose a standard LED class device at
/sys/class/leds/chromeos::kbd_backlight. This driver is modeled
after the standard Chrome OS keyboard backlight driver at
drivers/platform/chrome/cros_kbd_led_backlight.c

Some Wilco devices do not support a keyboard backlight. This
is checked via wilco_ec_keyboard_leds_exist() in the core driver,
and a platform_device will only be registered by the core if
a backlight is supported.

After an EC reset the backlight could be in a non-PWM mode.
Earlier in the boot sequence the BIOS should send a command to
the EC to set the brightness, so things **should** be set up,
but we double check in probe() as we query the initial brightness.
If not set up, then set the brightness to 0.

Since the EC will never change the backlight level of its own accord,
we don't need to implement a brightness_get() method.

v6 changes:
-Remove bogus extra de-referencing in send_kbbl_msg()
-Actually return error if mailbox() fails in send_kbbl_msg()
-Use SET_STATE, not GET_STATE sub-command in set_brightness()

v4 changes:
-Call keyboard_led_set_brightness() directly within
 initialize_brightness(), instead of calling the library function.

v3 changes:
-Since this behaves the same as the standard Chrome OS keyboard
 backlight, rename the led device to "chromeos::kbd_backlight"
-Move wilco_ec_keyboard_backlight_exists() into core module, so
 that the core does not depend upon the keyboard backlight driver.
-This required moving some code into wilco-ec.h
-Refactor out some common code in set_brightness() and
 initialize_brightness()

v2 changes:
-Remove and fix uses of led vs LED in kconfig
-Assume BIOS initializes brightness, but double check in probe()
-Remove get_brightness() callback, as EC never changes brightness
 by itself.
-Use a __packed struct as message instead of opaque array
-Add exported wilco_ec_keyboard_leds_exist() so the core driver
 now only creates a platform _device if relevant
-Fix use of keyboard_led_set_brightness() since it can sleep

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +
 drivers/platform/chrome/wilco_ec/core.c   |  58 ++
 .../chrome/wilco_ec/kbd_led_backlight.c   | 166 ++
 include/linux/platform_data/wilco-ec.h|  38 
 5 files changed, 273 insertions(+)
 create mode 100644 drivers/platform/chrome/wilco_ec/kbd_led_backlight.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..d8cf4a60d1b5 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_KBD_BACKLIGHT
+   tristate "Enable keyboard backlight control"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to set the keyboard backlight
+ brightness. This happens via a standard LED driver that uses the
+ Wilco EC mailbox interface. A standard LED class device will
+ appear under /sys/class/leds/chromeos::kbd_backlight
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..8436539813cd 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_kbd_backlight-objs   := kbd_led_backlight.o
+obj-$(CONFIG_WILCO_EC_KBD_BACKLIGHT)   += wilco_kbd_backlight.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..3c45c157b7da 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -38,11 +38,47 @@ static struct resource *wilco_get_resource(struct 
platform_device *pdev,
   dev_name(dev));
 }
 
+/**
+ * wilco_ec_keyboard_backlight_exists() - Is the keyboad backlight supported?
+ * @ec: EC device to query.
+ * @exists: Return value to fill in.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int wilco_ec_keyboard_backlight_exists(struct wilco_ec_device *ec,
+ bool *exists)
+{
+   struct wilco_ec_kbbl_msg request;
+   struct wilco_ec_kbbl_msg response;
+   struct wilco_ec_message msg;
+   int ret;
+
+   memset(, 0, sizeof(request));
+   request.command = WILCO_EC_COMMAND_KBBL;
+ 

Re: [PATCH v5 3/3] platform/chrome: Standardize Chrome OS keyboard backlight name

2019-04-08 Thread Nick Crews
I've just found a few [embarrassing :)] bugs in this version,
so after we figure out the naming, please wait for me to send
out another patch that fixes these.

Thanks, Nick

On Thu, Apr 4, 2019 at 11:10 AM Nick Crews  wrote:
>
> We want all backlights for the system keyboard to
> use a common name, so the name "platform::kbd_backlight"
> would be better than the current "chromeos::kbd_backlight"
> name. Normally this wouldn't be worth changing, but the new
> Wilco keyboard backlight driver uses the "platform" name.
> We want to make it so all Chrome OS devices are consistent,
> so we'll change the name here too.
>
> The Power Manager daemon only looks for LEDs that match the
> pattern "*:kbd_backlight", so this change won't affect that.
>
> Signed-off-by: Nick Crews 
> ---
>  drivers/platform/chrome/cros_kbd_led_backlight.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/platform/chrome/cros_kbd_led_backlight.c 
> b/drivers/platform/chrome/cros_kbd_led_backlight.c
> index aa409f0201fb..c56c8405f39c 100644
> --- a/drivers/platform/chrome/cros_kbd_led_backlight.c
> +++ b/drivers/platform/chrome/cros_kbd_led_backlight.c
> @@ -77,7 +77,7 @@ static int keyboard_led_probe(struct platform_device *pdev)
> if (!cdev)
> return -ENOMEM;
>
> -   cdev->name = "chromeos::kbd_backlight";
> +   cdev->name = "platform::kbd_backlight";
> cdev->max_brightness = ACPI_KEYBOARD_BACKLIGHT_MAX;
> cdev->flags |= LED_CORE_SUSPENDRESUME;
> cdev->brightness_set = keyboard_led_set_brightness;
> --
> 2.20.1
>


[PATCH 2/2] power_supply: wilco_ec: Add charging config driver for Wilco EC

2019-04-05 Thread Nick Crews
Add control of the charging algorithm used on Wilco devices.
See Documentation/ABI/testing/sysfs-class-power-wilco for the
userspace interface and other info.

Signed-off-by: Nick Crews 
---
 .../ABI/testing/sysfs-class-power-wilco   |  30 +++
 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +
 .../platform/chrome/wilco_ec/charge_config.c  | 182 ++
 drivers/platform/chrome/wilco_ec/core.c   |  14 ++
 drivers/platform/chrome/wilco_ec/properties.c | 129 +
 drivers/platform/chrome/wilco_ec/properties.h |  68 +++
 include/linux/platform_data/wilco-ec.h|   2 +
 8 files changed, 436 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-wilco
 create mode 100644 drivers/platform/chrome/wilco_ec/charge_config.c
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.c
 create mode 100644 drivers/platform/chrome/wilco_ec/properties.h

diff --git a/Documentation/ABI/testing/sysfs-class-power-wilco 
b/Documentation/ABI/testing/sysfs-class-power-wilco
new file mode 100644
index ..ef78e3d4a4bd
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-wilco
@@ -0,0 +1,30 @@
+What:  /sys/class/power_supply/wilco_charger/charge_type
+Date:  April 2019
+KernelVersion: 5.1
+Description:
+   What charging algorithm to use:
+
+   Standard: Fully charges battery at a standard rate.
+   Adaptive: Battery settings adaptively optimized based on
+   typical battery usage pattern.
+   Fast: Battery charges over a shorter period.
+   Trickle: Extends battery lifespan for users who use
+   their Chromebooks connected to AC.
+   Custom: A low and high threshold percentage is specified.
+   Charging begins when level drops below
+   charge_control_start_threshold, and ceases when
+   level is above charge_control_end_threshold.
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_start_threshold
+Date:  April 2019
+KernelVersion: 5.1
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [50, 95].
+
+What:  
/sys/class/power_supply/wilco_charger/charge_control_end_threshold
+Date:  April 2019
+KernelVersion: 5.1
+Description:
+   Used when charge_type="Custom", as described above. Measured in
+   percentages. The valid range is [55, 100].
diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..1c427830bd57 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_CHARGE_CNTL
+   tristate "Enable charging control"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to control the charging
+ routines performed by the Wilco Embedded Controller.
+ Further information can be found in
+ Documentation/ABI/testing/sysfs-class-power-wilco)
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..7e980f56f793 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_ec_charging-objs := charge_config.o properties.o
+obj-$(CONFIG_WILCO_EC_CHARGE_CNTL) += wilco_ec_charging.o
diff --git a/drivers/platform/chrome/wilco_ec/charge_config.c 
b/drivers/platform/chrome/wilco_ec/charge_config.c
new file mode 100644
index ..907526829444
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/charge_config.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Charging control driver for the Wilco EC
+ *
+ * Copyright 2019 Google LLC
+ *
+ * See Documentation/ABI/testing/sysfs-class-power-wilco for
+ * userspace interface and other info.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "properties.h"
+
+#define DRV_NAME "wilco-ec-charging"
+
+/* Property IDs and related EC constants */
+#define PID_PCC_MODE   0x0710
+#define PID_PCC_LOWER_LIMIT0x0711
+#define PID_PCC_UPPER_LIMIT0x0712
+
+enum charge_mode {
+   CHARGE_MODE_STD = 1,/* Used for Standard */
+   CHARGE_MODE_EXP = 2,/* Expre

[PATCH 1/2] power_supply: Add more charge types and CHARGE_CONTROL_* properties

2019-04-05 Thread Nick Crews
Add "Standard", "Adaptive", and "Custom" modes to the charge_type
property, to expand the existing "Trickle" and "Fast" modes.
In addition, add POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD
and POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD properties, to expand
the existing CHARGE_CONTROL_* properties. I am adding them in order
to support a new Chrome OS device, but these properties should be
general enough that they can be used on other devices.

The meaning of "Standard" is obvious, but "Adaptive" and "Custom" are
more tricky: "Adaptive" means that the charge controller uses some
custom algorithm to change the charge type automatically, with no
configuration needed. "Custom" means that the charge controller uses the
POWER_SUPPLY_PROP_CHARGE_CONTROL_* properties as configuration for some
other algorithm. For example, in the use case that I am supporting,
this means the battery begins charging when the percentage
level drops below POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD and
charging ceases when the percentage level goes above
POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD.

Signed-off-by: Nick Crews 
---
 drivers/power/supply/power_supply_sysfs.c |  4 +++-
 include/linux/power_supply.h  | 10 --
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/power/supply/power_supply_sysfs.c 
b/drivers/power/supply/power_supply_sysfs.c
index dce24f596160..6104a3f03d46 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -56,7 +56,7 @@ static const char * const power_supply_status_text[] = {
 };
 
 static const char * const power_supply_charge_type_text[] = {
-   "Unknown", "N/A", "Trickle", "Fast"
+   "Unknown", "N/A", "Trickle", "Fast", "Standard", "Adaptive", "Custom"
 };
 
 static const char * const power_supply_health_text[] = {
@@ -274,6 +274,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(constant_charge_voltage_max),
POWER_SUPPLY_ATTR(charge_control_limit),
POWER_SUPPLY_ATTR(charge_control_limit_max),
+   POWER_SUPPLY_ATTR(charge_control_start_threshold),
+   POWER_SUPPLY_ATTR(charge_control_end_threshold),
POWER_SUPPLY_ATTR(input_current_limit),
POWER_SUPPLY_ATTR(energy_full_design),
POWER_SUPPLY_ATTR(energy_empty_design),
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 2f9c201a54d1..d59205170232 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -40,11 +40,15 @@ enum {
POWER_SUPPLY_STATUS_FULL,
 };
 
+/* What algorithm is the charger using? */
 enum {
POWER_SUPPLY_CHARGE_TYPE_UNKNOWN = 0,
POWER_SUPPLY_CHARGE_TYPE_NONE,
-   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
-   POWER_SUPPLY_CHARGE_TYPE_FAST,
+   POWER_SUPPLY_CHARGE_TYPE_TRICKLE,   /* slow speed */
+   POWER_SUPPLY_CHARGE_TYPE_FAST,  /* fast speed */
+   POWER_SUPPLY_CHARGE_TYPE_STANDARD,  /* normal speed */
+   POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE,  /* dynamically adjusted speed */
+   POWER_SUPPLY_CHARGE_TYPE_CUSTOM,/* use CHARGE_CONTROL_* props */
 };
 
 enum {
@@ -121,6 +125,8 @@ enum power_supply_property {
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD, /* in percents! */
+   POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD, /* in percents! */
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
-- 
2.20.1



Re: [PATCH 1/3] platform/chrome: wilco_ec: Standardize mailbox interface

2019-04-05 Thread Nick Crews
>
> Now I'm confused, isn't this the same patch I picked this morning from
> you and is already applied in chrome-platform for-next?
>

Sorry, I didn't see that it was already applied in for-next. Just ignore
this patch and assume that the next two in this series are based
off the current state of for-next.


[PATCH 2/3] platform/chrome: wilco_ec: Add USB PowerShare Policy control

2019-04-05 Thread Nick Crews
USB PowerShare is a policy which affects charging via the special
USB PowerShare port (marked with a small lightning bolt or battery icon)
when in low power states:
- In S0, the port will always provide power.
- In S0ix, if power_share is enabled, then power will be supplied to
  the port when on AC or if battery is > 50%. Else no power is supplied.
- In S5, if power_share is enabled, then power will be supplied to
  the port when on AC. Else no power is supplied.

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/Makefile |   2 +-
 drivers/platform/chrome/wilco_ec/core.c   |   9 ++
 drivers/platform/chrome/wilco_ec/sysfs.c  | 129 ++
 include/linux/platform_data/wilco-ec.h|   3 +
 4 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/chrome/wilco_ec/sysfs.c

diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..1281dd7737c4 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-wilco_ec-objs  := core.o mailbox.o
+wilco_ec-objs  := core.o mailbox.o sysfs.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..abd15d04e57b 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -89,8 +89,16 @@ static int wilco_ec_probe(struct platform_device *pdev)
goto unregister_debugfs;
}
 
+   ret = wilco_ec_add_sysfs(ec);
+   if (ret < 0) {
+   dev_err(dev, "Failed to create sysfs entries: %d", ret);
+   goto unregister_rtc;
+   }
+
return 0;
 
+unregister_rtc:
+   platform_device_unregister(ec->rtc_pdev);
 unregister_debugfs:
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
@@ -102,6 +110,7 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+   wilco_ec_remove_sysfs(ec);
platform_device_unregister(ec->rtc_pdev);
if (ec->debugfs_pdev)
platform_device_unregister(ec->debugfs_pdev);
diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
b/drivers/platform/chrome/wilco_ec/sysfs.c
new file mode 100644
index ..ec5211257a58
--- /dev/null
+++ b/drivers/platform/chrome/wilco_ec/sysfs.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Sysfs properties used to modify EC-controlled features on Wilco devices.
+ * The entries will appear under /sys/bus/platform/devices/GOOG000C:00/
+ *
+ * USB PowerShare is a policy which affects charging via the special
+ * USB PowerShare port (marked with a small lightning bolt or battery icon)
+ * when in low power states:
+ * - In S0, the port will always provide power.
+ * - In S0ix, if power_share is enabled, then power will be supplied to
+ *   the port when on AC or if battery is > 50%. Else no power is supplied.
+ * - In S5, if power_share is enabled, then power will be supplied to
+ *   the port when on AC. Else no power is supplied.
+ */
+
+#include 
+#include 
+
+#define CMD_USB_POWER_SHARE 0x39
+
+enum usb_power_share_op {
+   POWER_SHARE_GET = 0,
+   POWER_SHARE_SET = 1,
+};
+
+struct usb_power_share_request {
+   u8 cmd; /* Always CMD_USB_POWER_SHARE */
+   u8 reserved;
+   u8 op;  /* One of enum usb_power_share_op */
+   u8 val; /* When setting, either 0 or 1 */
+} __packed;
+
+struct usb_power_share_response {
+   u8 reserved;
+   u8 status;  /* Set by EC to 0 on success, other value on failure */
+   u8 val; /* When getting, set by EC to either 0 or 1 */
+} __packed;
+
+static int send_usb_power_share(struct wilco_ec_device *ec,
+   struct usb_power_share_request *rq,
+   struct usb_power_share_response *rs)
+{
+   struct wilco_ec_message msg;
+   int ret;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = rq;
+   msg.request_size = sizeof(*rq);
+   msg.response_data = rs;
+   msg.response_size = sizeof(*rs);
+   ret = wilco_ec_mailbox(ec, );
+   if (ret < 0)
+   return ret;
+
+   if (rs->status)
+   return -EIO;
+
+   return 0;
+}
+
+static ssize_t usb_power_share_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct

[PATCH 1/3] platform/chrome: wilco_ec: Standardize mailbox interface

2019-04-05 Thread Nick Crews
The current API for the wilco EC mailbox interface is bad.

It assumes that most messages sent to the EC follow a similar structure,
with a command byte in MBOX[0], followed by a junk byte, followed by
actual data. This doesn't happen in several cases, such as setting the
RTC time, using the raw debugfs interface, and reading or writing
properties such as the Peak Shift policy (this last to be submitted soon).

Similarly for the response message from the EC, the current interface
assumes that the first byte of data is always 0, and the second byte
is unused. However, in both setting and getting the RTC time, in the
debugfs interface, and for reading and writing properties, this isn't
true.

The current way to resolve this is to use WILCO_EC_FLAG_RAW* flags to
specify when and when not to skip these initial bytes in the sent and
received message. They are confusing and used so much that they are
normal, and not exceptions. In addition, the first byte of
response in the debugfs interface is still always skipped, which is
weird, since this raw interface should be giving the entire result.

Additionally, sent messages assume the first byte is a command, and so
struct wilco_ec_message contains the "command" field. In setting or
getting properties however, the first byte is not a command, and so this
field has to be filled with a byte that isn't actually a command. This
is again inconsistent.

wilco_ec_message contains a result field as well, copied from
wilco_ec_response->result. The message result field should be removed:
if the message fails, the cause is already logged, and the callers are
alerted. They will never care about the actual state of the result flag.

These flags and different cases make the wilco_ec_transfer() function,
used in wilco_ec_mailbox(), really gross, dealing with a bunch of
different cases. It's difficult to figure out what it is doing.

Finally, making these assumptions about the structure of a message make
it so that the messages do not correspond well with the specification
for the EC's mailbox interface. For instance, this interface
specification may say that MBOX[9] in the received message contains
some information, but the calling code needs to remember that the first
byte of response is always skipped, and because it didn't set the
RESPONSE_RAW flag, the next byte is also skipped, so this information
is actually contained within wilco_ec_message->response_data[7]. This
makes it difficult to maintain this code in the future.

To fix these problems this patch standardizes the mailbox interface by:
- Removing the WILCO_EC_FLAG_RAW* flags
- Removing the command and reserved_raw bytes from wilco_ec_request
- Removing the mbox0 byte from wilco_ec_response
- Simplifying wilco_ec_transfer() because of these changes
- Gives the callers of wilco_ec_mailbox() the responsibility of exactly
  and consistently defining the structure of the mailbox request and
  response
- Removing command and result from wilco_ec_message.

This results in the reduction of total code, and makes it much more
maintainable and understandable.

Signed-off-by: Nick Crews 
Acked-by: Alexandre Belloni 
---
 drivers/platform/chrome/wilco_ec/debugfs.c | 43 ---
 drivers/platform/chrome/wilco_ec/mailbox.c | 53 --
 drivers/rtc/rtc-wilco-ec.c | 63 +-
 include/linux/platform_data/wilco-ec.h | 22 +---
 4 files changed, 83 insertions(+), 98 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index c090db2cd5be..17c4c9068aaf 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -10,25 +10,26 @@
  * by reading from raw.
  *
  * For writing:
- * Bytes 0-1 indicate the message type:
- * 00 F0 = Execute Legacy Command
- * 00 F2 = Read/Write NVRAM Property
- * Byte 2 provides the command code
- * Bytes 3+ consist of the data passed in the request
+ * Bytes 0-1 indicate the message type, one of enum wilco_ec_msg_type
+ * Byte 2+ consist of the data passed in the request, starting at MBOX[0]
  *
- * When referencing the EC interface spec, byte 2 corresponds to MBOX[0],
- * byte 3 corresponds to MBOX[1], etc.
- *
- * At least three bytes are required, for the msg type and command,
- * with additional bytes optional for additional data.
+ * At least three bytes are required for writing, two for the type and at
+ * least a single byte of data. Only the first EC_MAILBOX_DATA_SIZE bytes
+ * of MBOX will be used.
  *
  * Example:
  * // Request EC info type 3 (EC firmware build date)
- * $ echo 00 f0 38 00 03 00 > raw
+ * // Corresponds with sending type 0x00f0 with MBOX = [38, 00, 03, 00]
+ * $ echo 00 f0 38 00 03 00 > /sys/kernel/debug/wilco_ec/raw
  * // View the result. The decoded ASCII result "12/21/18" is
  * // included after the raw hex.
- * $ cat raw
- * 00 31 32 2f 32 31 2f 31 38 0

[PATCH 3/3] platform/chrome: wilco_ec: Add Boot on AC support

2019-04-05 Thread Nick Crews
Boot on AC is a policy which makes the device boot from S5 when AC
power is connected. This is useful for users who want to run their
device headless or with a dock.

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/wilco_ec/sysfs.c | 52 
 1 file changed, 52 insertions(+)

diff --git a/drivers/platform/chrome/wilco_ec/sysfs.c 
b/drivers/platform/chrome/wilco_ec/sysfs.c
index ec5211257a58..52cbdb1f30b6 100644
--- a/drivers/platform/chrome/wilco_ec/sysfs.c
+++ b/drivers/platform/chrome/wilco_ec/sysfs.c
@@ -5,6 +5,10 @@
  * Sysfs properties used to modify EC-controlled features on Wilco devices.
  * The entries will appear under /sys/bus/platform/devices/GOOG000C:00/
  *
+ * Boot on AC is a policy which makes the device boot from S5 when AC
+ * power is connected. This is useful for users who want to run their
+ * device headless or with a dock.
+ *
  * USB PowerShare is a policy which affects charging via the special
  * USB PowerShare port (marked with a small lightning bolt or battery icon)
  * when in low power states:
@@ -18,6 +22,18 @@
 #include 
 #include 
 
+#define CMD_KB_CMOS0x7C
+#define SUB_CMD_KB_CMOS_AUTO_ON0x03
+
+struct boot_on_ac_request {
+   u8 cmd; /* Always CMD_KB_CMOS */
+   u8 reserved1;
+   u8 sub_cmd; /* Always SUB_CMD_KB_CMOS_AUTO_ON */
+   u8 reserved3to5[3];
+   u8 val; /* Either 0 or 1*/
+   u8 reserved7;
+} __packed;
+
 #define CMD_USB_POWER_SHARE 0x39
 
 enum usb_power_share_op {
@@ -38,6 +54,41 @@ struct usb_power_share_response {
u8 val; /* When getting, set by EC to either 0 or 1 */
 } __packed;
 
+static ssize_t boot_on_ac_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   struct wilco_ec_device *ec = dev_get_drvdata(dev);
+   struct boot_on_ac_request rq;
+   struct wilco_ec_message msg;
+   int ret;
+   u8 val;
+
+   ret = kstrtou8(buf, 10, );
+   if (ret < 0)
+   return ret;
+
+   if (val != 0 && val != 1)
+   return -EINVAL;
+
+   memset(, 0, sizeof(rq));
+   rq.cmd = CMD_KB_CMOS;
+   rq.sub_cmd = SUB_CMD_KB_CMOS_AUTO_ON;
+   rq.val = val;
+
+   memset(, 0, sizeof(msg));
+   msg.type = WILCO_EC_MSG_LEGACY;
+   msg.request_data = 
+   msg.request_size = sizeof(rq);
+   ret = wilco_ec_mailbox(ec, );
+   if (ret < 0)
+   return ret;
+
+   return count;
+}
+
+static DEVICE_ATTR_WO(boot_on_ac);
+
 static int send_usb_power_share(struct wilco_ec_device *ec,
struct usb_power_share_request *rq,
struct usb_power_share_response *rs)
@@ -110,6 +161,7 @@ static ssize_t usb_power_share_store(struct device *dev,
 static DEVICE_ATTR_RW(usb_power_share);
 
 static struct attribute *wilco_dev_attrs[] = {
+   _attr_boot_on_ac.attr,
_attr_usb_power_share.attr,
NULL,
 };
-- 
2.20.1



[PATCH] platform/chrome: wilco_ec: Standardize mailbox interface

2019-04-04 Thread Nick Crews
I sent this out previously in a series with a keyboard backlight driver
(https://lkml.org/lkml/2019/4/4/1370), but the backlight driver is
still in flux, and I wanted to get this committed ASAP. Thus I'm
sending this as a separate series, in hopes that this can be
expedited.

The current API for the wilco EC mailbox interface is bad.

It assumes that most messages sent to the EC follow a similar structure,
with a command byte in MBOX[0], followed by a junk byte, followed by
actual data. This doesn't happen in several cases, such as setting the
RTC time, using the raw debugfs interface, and reading or writing
properties such as the Peak Shift policy (this last to be submitted soon).

Similarly for the response message from the EC, the current interface
assumes that the first byte of data is always 0, and the second byte
is unused. However, in both setting and getting the RTC time, in the
debugfs interface, and for reading and writing properties, this isn't
true.

The current way to resolve this is to use WILCO_EC_FLAG_RAW* flags to
specify when and when not to skip these initial bytes in the sent and
received message. They are confusing and used so much that they are
normal, and not exceptions. In addition, the first byte of
response in the debugfs interface is still always skipped, which is
weird, since this raw interface should be giving the entire result.

Additionally, sent messages assume the first byte is a command, and so
struct wilco_ec_message contains the "command" field. In setting or
getting properties however, the first byte is not a command, and so this
field has to be filled with a byte that isn't actually a command. This
is again inconsistent.

wilco_ec_message contains a result field as well, copied from
wilco_ec_response->result. The message result field should be removed:
if the message fails, the cause is already logged, and the callers are
alerted. They will never care about the actual state of the result flag.

These flags and different cases make the wilco_ec_transfer() function,
used in wilco_ec_mailbox(), really gross, dealing with a bunch of
different cases. It's difficult to figure out what it is doing.

Finally, making these assumptions about the structure of a message make
it so that the messages do not correspond well with the specification
for the EC's mailbox interface. For instance, this interface
specification may say that MBOX[9] in the received message contains
some information, but the calling code needs to remember that the first
byte of response is always skipped, and because it didn't set the
RESPONSE_RAW flag, the next byte is also skipped, so this information
is actually contained within wilco_ec_message->response_data[7]. This
makes it difficult to maintain this code in the future.

To fix these problems this patch standardizes the mailbox interface by:
- Removing the WILCO_EC_FLAG_RAW* flags
- Removing the command and reserved_raw bytes from wilco_ec_request
- Removing the mbox0 byte from wilco_ec_response
- Simplifying wilco_ec_transfer() because of these changes
- Gives the callers of wilco_ec_mailbox() the responsibility of exactly
  and consistently defining the structure of the mailbox request and
  response
- Removing command and result from wilco_ec_message.

This results in the reduction of total code, and makes it much more
maintainable and understandable.

Signed-off-by: Nick Crews 
Acked-by: Alexandre Belloni 
---
 drivers/platform/chrome/wilco_ec/debugfs.c | 43 ---
 drivers/platform/chrome/wilco_ec/mailbox.c | 53 --
 drivers/rtc/rtc-wilco-ec.c | 63 +-
 include/linux/platform_data/wilco-ec.h | 22 +---
 4 files changed, 83 insertions(+), 98 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index c090db2cd5be..17c4c9068aaf 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -10,25 +10,26 @@
  * by reading from raw.
  *
  * For writing:
- * Bytes 0-1 indicate the message type:
- * 00 F0 = Execute Legacy Command
- * 00 F2 = Read/Write NVRAM Property
- * Byte 2 provides the command code
- * Bytes 3+ consist of the data passed in the request
+ * Bytes 0-1 indicate the message type, one of enum wilco_ec_msg_type
+ * Byte 2+ consist of the data passed in the request, starting at MBOX[0]
  *
- * When referencing the EC interface spec, byte 2 corresponds to MBOX[0],
- * byte 3 corresponds to MBOX[1], etc.
- *
- * At least three bytes are required, for the msg type and command,
- * with additional bytes optional for additional data.
+ * At least three bytes are required for writing, two for the type and at
+ * least a single byte of data. Only the first EC_MAILBOX_DATA_SIZE bytes
+ * of MBOX will be used.
  *
  * Example:
  * // Request EC info type 3 (EC firmware build date)
- * $ echo 00 f0 38 00 03 00 > raw
+ * // Corresponds with 

Re: [PATCH v5 3/3] platform/chrome: Standardize Chrome OS keyboard backlight name

2019-04-04 Thread Nick Crews
On Thu, Apr 4, 2019 at 11:43 AM Dmitry Torokhov  wrote:
>
> On Thu, Apr 4, 2019 at 10:36 AM Guenter Roeck  wrote:
> >
> > On Thu, Apr 4, 2019 at 10:11 AM Nick Crews  wrote:
> > >
> > > We want all backlights for the system keyboard to
> > > use a common name, so the name "platform::kbd_backlight"
> > > would be better than the current "chromeos::kbd_backlight"
> > > name. Normally this wouldn't be worth changing, but the new
> > > Wilco keyboard backlight driver uses the "platform" name.
> > > We want to make it so all Chrome OS devices are consistent,
> > > so we'll change the name here too.
> > >
> >
> > Wondering - who is the "we" you are talking about ?

You're right, I should have been more precise.
I was referring to Pavel, Enric, and myself. Pavel had this opinion here:
https://lkml.org/lkml/2019/4/4/1040. I don't know what Pavel meant by "we"
in that comment, but I would guess that could mean the other LED maintainers
as well? I talked with Enric 1:1 and he didn't see the problem with changing it,
though perhaps he was only considering our use of the LED via powerd,
and not users in general. I'm guessing Pavel's and Enric's meanings though,
excuse me if I am misinterpreting.

>
> This also has a potential of breaking existing setups if somebody did
> happen to match on entire name instead of suffix. Such changes have to
> be considered very carefully; at this point I am against of doing
> this.

Would it make sense to keep the old name as is, and only make the new
Wilco name begin with "platform:"? What would you think is best?

>
> Thanks.
>
> --
> Dmitry


[PATCH v5 3/3] platform/chrome: Standardize Chrome OS keyboard backlight name

2019-04-04 Thread Nick Crews
We want all backlights for the system keyboard to
use a common name, so the name "platform::kbd_backlight"
would be better than the current "chromeos::kbd_backlight"
name. Normally this wouldn't be worth changing, but the new
Wilco keyboard backlight driver uses the "platform" name.
We want to make it so all Chrome OS devices are consistent,
so we'll change the name here too.

The Power Manager daemon only looks for LEDs that match the
pattern "*:kbd_backlight", so this change won't affect that.

Signed-off-by: Nick Crews 
---
 drivers/platform/chrome/cros_kbd_led_backlight.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/cros_kbd_led_backlight.c 
b/drivers/platform/chrome/cros_kbd_led_backlight.c
index aa409f0201fb..c56c8405f39c 100644
--- a/drivers/platform/chrome/cros_kbd_led_backlight.c
+++ b/drivers/platform/chrome/cros_kbd_led_backlight.c
@@ -77,7 +77,7 @@ static int keyboard_led_probe(struct platform_device *pdev)
if (!cdev)
return -ENOMEM;
 
-   cdev->name = "chromeos::kbd_backlight";
+   cdev->name = "platform::kbd_backlight";
cdev->max_brightness = ACPI_KEYBOARD_BACKLIGHT_MAX;
cdev->flags |= LED_CORE_SUSPENDRESUME;
cdev->brightness_set = keyboard_led_set_brightness;
-- 
2.20.1



[PATCH v5 2/3] platform/chrome: Add Wilco EC keyboard backlight LEDs support

2019-04-04 Thread Nick Crews
The EC is in charge of controlling the keyboard backlight on
the Wilco platform. We expose a standard LED class device at
/sys/class/leds/platform::kbd_backlight. This driver is modeled
after the standard Chrome OS keyboard backlight driver at
drivers/platform/chrome/cros_kbd_led_backlight.c

Some Wilco devices do not support a keyboard backlight. This
is checked via wilco_ec_keyboard_leds_exist() in the core driver,
and a platform_device will only be registered by the core if
a backlight is supported.

After an EC reset the backlight could be in a non-PWM mode.
Earlier in the boot sequence the BIOS should send a command to
the EC to set the brightness, so things **should** be set up,
but we double check in probe() as we query the initial brightness.
If not set up, then set the brightness to 0.

Since the EC will never change the backlight level of its own accord,
we don't need to implement a brightness_get() method.

v5 changes:
-Rename the LED device to "platform::kbd_backlight", to
denote that this is the built-in system keyboard.

v4 changes:
-Call keyboard_led_set_brightness() directly within
 initialize_brightness(), instead of calling the library function.

v3 changes:
-Since this behaves the same as the standard Chrome OS keyboard
 backlight, rename the led device to "chromeos::kbd_backlight"
-Move wilco_ec_keyboard_backlight_exists() into core module, so
 that the core does not depend upon the keyboard backlight driver.
-This required moving some code into wilco-ec.h
-Refactor out some common code in set_brightness() and
 initialize_brightness()

v2 changes:
-Remove and fix uses of led vs LED in kconfig
-Assume BIOS initializes brightness, but double check in probe()
-Remove get_brightness() callback, as EC never changes brightness
 by itself.
-Use a __packed struct as message instead of opaque array
-Add exported wilco_ec_keyboard_leds_exist() so the core driver
 now only creates a platform _device if relevant
-Fix use of keyboard_led_set_brightness() since it can sleep

Signed-off-by: Nick Crews 
Acked-by: Jacek Anaszewski 
---
 drivers/platform/chrome/wilco_ec/Kconfig  |   9 +
 drivers/platform/chrome/wilco_ec/Makefile |   2 +
 drivers/platform/chrome/wilco_ec/core.c   |  58 ++
 .../chrome/wilco_ec/kbd_led_backlight.c   | 168 ++
 include/linux/platform_data/wilco-ec.h|  38 
 5 files changed, 275 insertions(+)
 create mode 100644 drivers/platform/chrome/wilco_ec/kbd_led_backlight.c

diff --git a/drivers/platform/chrome/wilco_ec/Kconfig 
b/drivers/platform/chrome/wilco_ec/Kconfig
index e09e4cebe9b4..d8cf4a60d1b5 100644
--- a/drivers/platform/chrome/wilco_ec/Kconfig
+++ b/drivers/platform/chrome/wilco_ec/Kconfig
@@ -18,3 +18,12 @@ config WILCO_EC_DEBUGFS
  manipulation and allow for testing arbitrary commands.  This
  interface is intended for debug only and will not be present
  on production devices.
+
+config WILCO_EC_KBD_BACKLIGHT
+   tristate "Enable keyboard backlight control"
+   depends on WILCO_EC
+   help
+ If you say Y here, you get support to set the keyboard backlight
+ brightness. This happens via a standard LED driver that uses the
+ Wilco EC mailbox interface. A standard LED class device will
+ appear under /sys/class/leds/chromeos::kbd_backlight
diff --git a/drivers/platform/chrome/wilco_ec/Makefile 
b/drivers/platform/chrome/wilco_ec/Makefile
index 063e7fb4ea17..8436539813cd 100644
--- a/drivers/platform/chrome/wilco_ec/Makefile
+++ b/drivers/platform/chrome/wilco_ec/Makefile
@@ -4,3 +4,5 @@ wilco_ec-objs   := core.o mailbox.o
 obj-$(CONFIG_WILCO_EC) += wilco_ec.o
 wilco_ec_debugfs-objs  := debugfs.o
 obj-$(CONFIG_WILCO_EC_DEBUGFS) += wilco_ec_debugfs.o
+wilco_kbd_backlight-objs   := kbd_led_backlight.o
+obj-$(CONFIG_WILCO_EC_KBD_BACKLIGHT)   += wilco_kbd_backlight.o
diff --git a/drivers/platform/chrome/wilco_ec/core.c 
b/drivers/platform/chrome/wilco_ec/core.c
index 05e1e2be1c91..3c45c157b7da 100644
--- a/drivers/platform/chrome/wilco_ec/core.c
+++ b/drivers/platform/chrome/wilco_ec/core.c
@@ -38,11 +38,47 @@ static struct resource *wilco_get_resource(struct 
platform_device *pdev,
   dev_name(dev));
 }
 
+/**
+ * wilco_ec_keyboard_backlight_exists() - Is the keyboad backlight supported?
+ * @ec: EC device to query.
+ * @exists: Return value to fill in.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int wilco_ec_keyboard_backlight_exists(struct wilco_ec_device *ec,
+ bool *exists)
+{
+   struct wilco_ec_kbbl_msg request;
+   struct wilco_ec_kbbl_msg response;
+   struct wilco_ec_message msg;
+   int ret;
+
+   memset(, 0, sizeof(request));
+   request.command = WILCO_EC_COMMAND_KBBL;
+   request.subcmd = WILCO_KBBL_SUBCMD_GET_

[PATCH v5 1/3] platform/chrome: wilco_ec: Standardize mailbox interface

2019-04-04 Thread Nick Crews
The current API for the wilco EC mailbox interface is bad.

It assumes that most messages sent to the EC follow a similar structure,
with a command byte in MBOX[0], followed by a junk byte, followed by
actual data. This doesn't happen in several cases, such as setting the
RTC time, using the raw debugfs interface, and reading or writing
properties such as the Peak Shift policy (this last to be submitted soon).

Similarly for the response message from the EC, the current interface
assumes that the first byte of data is always 0, and the second byte
is unused. However, in both setting and getting the RTC time, in the
debugfs interface, and for reading and writing properties, this isn't
true.

The current way to resolve this is to use WILCO_EC_FLAG_RAW* flags to
specify when and when not to skip these initial bytes in the sent and
received message. They are confusing and used so much that they are
normal, and not exceptions. In addition, the first byte of
response in the debugfs interface is still always skipped, which is
weird, since this raw interface should be giving the entire result.

Additionally, sent messages assume the first byte is a command, and so
struct wilco_ec_message contains the "command" field. In setting or
getting properties however, the first byte is not a command, and so this
field has to be filled with a byte that isn't actually a command. This
is again inconsistent.

wilco_ec_message contains a result field as well, copied from
wilco_ec_response->result. The message result field should be removed:
if the message fails, the cause is already logged, and the callers are
alerted. They will never care about the actual state of the result flag.

These flags and different cases make the wilco_ec_transfer() function,
used in wilco_ec_mailbox(), really gross, dealing with a bunch of
different cases. It's difficult to figure out what it is doing.

Finally, making these assumptions about the structure of a message make
it so that the messages do not correspond well with the specification
for the EC's mailbox interface. For instance, this interface
specification may say that MBOX[9] in the received message contains
some information, but the calling code needs to remember that the first
byte of response is always skipped, and because it didn't set the
RESPONSE_RAW flag, the next byte is also skipped, so this information
is actually contained within wilco_ec_message->response_data[7]. This
makes it difficult to maintain this code in the future.

To fix these problems this patch standardizes the mailbox interface by:
- Removing the WILCO_EC_FLAG_RAW* flags
- Removing the command and reserved_raw bytes from wilco_ec_request
- Removing the mbox0 byte from wilco_ec_response
- Simplifying wilco_ec_transfer() because of these changes
- Gives the callers of wilco_ec_mailbox() the responsibility of exactly
  and consistently defining the structure of the mailbox request and
  response
- Removing command and result from wilco_ec_message.

This results in the reduction of total code, and makes it much more
maintainable and understandable.

Signed-off-by: Nick Crews 
Acked-by: Alexandre Belloni 
---
 drivers/platform/chrome/wilco_ec/debugfs.c | 43 ---
 drivers/platform/chrome/wilco_ec/mailbox.c | 53 --
 drivers/rtc/rtc-wilco-ec.c | 63 +-
 include/linux/platform_data/wilco-ec.h | 22 +---
 4 files changed, 83 insertions(+), 98 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c 
b/drivers/platform/chrome/wilco_ec/debugfs.c
index c090db2cd5be..17c4c9068aaf 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -10,25 +10,26 @@
  * by reading from raw.
  *
  * For writing:
- * Bytes 0-1 indicate the message type:
- * 00 F0 = Execute Legacy Command
- * 00 F2 = Read/Write NVRAM Property
- * Byte 2 provides the command code
- * Bytes 3+ consist of the data passed in the request
+ * Bytes 0-1 indicate the message type, one of enum wilco_ec_msg_type
+ * Byte 2+ consist of the data passed in the request, starting at MBOX[0]
  *
- * When referencing the EC interface spec, byte 2 corresponds to MBOX[0],
- * byte 3 corresponds to MBOX[1], etc.
- *
- * At least three bytes are required, for the msg type and command,
- * with additional bytes optional for additional data.
+ * At least three bytes are required for writing, two for the type and at
+ * least a single byte of data. Only the first EC_MAILBOX_DATA_SIZE bytes
+ * of MBOX will be used.
  *
  * Example:
  * // Request EC info type 3 (EC firmware build date)
- * $ echo 00 f0 38 00 03 00 > raw
+ * // Corresponds with sending type 0x00f0 with MBOX = [38, 00, 03, 00]
+ * $ echo 00 f0 38 00 03 00 > /sys/kernel/debug/wilco_ec/raw
  * // View the result. The decoded ASCII result "12/21/18" is
  * // included after the raw hex.
- * $ cat raw
- * 00 31 32 2f 32 31 2f 31 38 0

  1   2   3   >