All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pengyu Luo <mitltlatltl@gmail.com>
To: bryan.odonoghue@linaro.org
Cc: andersson@kernel.org, conor+dt@kernel.org,
	devicetree@vger.kernel.org, dmitry.baryshkov@linaro.org,
	gregkh@linuxfoundation.org, hdegoede@redhat.com,
	heikki.krogerus@linux.intel.com, ilpo.jarvinen@linux.intel.com,
	konradybcio@kernel.org, krzk+dt@kernel.org,
	linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pm@vger.kernel.org, linux-usb@vger.kernel.org,
	mitltlatltl@gmail.com, nikita@trvn.ru,
	platform-driver-x86@vger.kernel.org, robh@kernel.org,
	sre@kernel.org
Subject: Re: [PATCH 3/5] usb: typec: ucsi: add Huawei Matebook E Go (sc8280xp) ucsi driver
Date: Sat, 28 Dec 2024 22:38:29 +0800	[thread overview]
Message-ID: <20241228143830.613658-1-mitltlatltl@gmail.com> (raw)
In-Reply-To: <c17372ed-baf0-40a7-b267-25f1ff849cf7@linaro.org>

On Sat, Dec 28, 2024 at 9:06 PM Bryan O'Donoghue <bryan.odonoghue@linaro.org> wrote:
> On 27/12/2024 17:13, Pengyu Luo wrote:
> > The Huawei Matebook E Go (sc8280xp) tablet provides implements UCSI
> > interface in the onboard EC. Add the glue driver to interface the
> > platform's UCSI implementation.
> >
> > Signed-off-by: Pengyu Luo <mitltlatltl@gmail.com>
> > ---
> >   drivers/usb/typec/ucsi/Kconfig              |   9 +
> >   drivers/usb/typec/ucsi/Makefile             |   1 +
> >   drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c | 481 ++++++++++++++++++++
> >   3 files changed, 491 insertions(+)
> >   create mode 100644 drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
> >
> > diff --git a/drivers/usb/typec/ucsi/Kconfig b/drivers/usb/typec/ucsi/Kconfig
> > index 680e1b87b..0d0f07488 100644
> > --- a/drivers/usb/typec/ucsi/Kconfig
> > +++ b/drivers/usb/typec/ucsi/Kconfig
> > @@ -78,4 +78,13 @@ config UCSI_LENOVO_YOGA_C630
> >         To compile the driver as a module, choose M here: the module will be
> >         called ucsi_yoga_c630.
> >
> > +config UCSI_HUAWEI_GAOKUN
> > +     tristate "UCSI Interface Driver for Huawei Matebook E Go (sc8280xp)"
> > +     depends on EC_HUAWEI_GAOKUN
> > +     help
> > +       This driver enables UCSI support on the Huawei Matebook E Go tablet.
> > +
> > +       To compile the driver as a module, choose M here: the module will be
> > +       called ucsi_huawei_gaokun.
> > +
> >   endif
> > diff --git a/drivers/usb/typec/ucsi/Makefile b/drivers/usb/typec/ucsi/Makefile
> > index aed41d238..0b400122b 100644
> > --- a/drivers/usb/typec/ucsi/Makefile
> > +++ b/drivers/usb/typec/ucsi/Makefile
> > @@ -22,3 +22,4 @@ obj-$(CONFIG_UCSI_CCG)                      += ucsi_ccg.o
> >   obj-$(CONFIG_UCSI_STM32G0)          += ucsi_stm32g0.o
> >   obj-$(CONFIG_UCSI_PMIC_GLINK)               += ucsi_glink.o
> >   obj-$(CONFIG_UCSI_LENOVO_YOGA_C630) += ucsi_yoga_c630.o
> > +obj-$(CONFIG_UCSI_HUAWEI_GAOKUN)     += ucsi_huawei_gaokun.o
> > diff --git a/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
> > new file mode 100644
> > index 000000000..84ed0407d
> > --- /dev/null
> > +++ b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
> > @@ -0,0 +1,481 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * ucsi-huawei-gaokun - A UCSI driver for HUAWEI Matebook E Go (sc8280xp)
> > + *
> > + * reference: drivers/usb/typec/ucsi/ucsi_yoga_c630.c
> > + *            drivers/usb/typec/ucsi/ucsi_glink.c
> > + *            drivers/soc/qcom/pmic_glink_altmode.c
> > + *
> > + * Copyright (C) 2024 Pengyu Luo <mitltlatltl@gmail.com>
> > + */
> > +
> > +#include <linux/auxiliary_bus.h>
> > +#include <linux/bitops.h>
> > +#include <linux/completion.h>
> > +#include <linux/container_of.h>
> > +#include <linux/delay.h>
> > +#include <linux/module.h>
> > +#include <linux/notifier.h>
> > +#include <linux/of.h>
> > +#include <linux/string.h>
> > +#include <linux/workqueue_types.h>
> > +
> > +#include <linux/usb/pd_vdo.h>
> > +#include <drm/bridge/aux-bridge.h
>
> Is there a reason you don't have strict include alphanumeric ordering here ?
>

These two is dp/alt mode related, so listing them out. Above of them are
general things.

> >
> > +
> > +#include "ucsi.h"
> > +#include <linux/platform_data/huawei-gaokun-ec.h>
> > +
> > +
> > +#define EC_EVENT_UCSI        0x21
> > +#define EC_EVENT_USB 0x22
> > +
> > +#define GAOKUN_CCX_MASK              GENMASK(1, 0)
> > +#define GAOKUN_MUX_MASK              GENMASK(3, 2)
> > +
> > +#define GAOKUN_DPAM_MASK     GENMASK(3, 0)
> > +#define GAOKUN_HPD_STATE_MASK        BIT(4)
> > +#define GAOKUN_HPD_IRQ_MASK  BIT(5)
> > +
> > +#define CCX_TO_ORI(ccx) (++ccx % 3)
>
> Why do you increment the value of the enum ?
> Seems strange.
>

EC's logic, it is just a trick. Qualcomm maps
0 1 2 to normal, reverse, none(no device insert)
typec lib maps 1 2 0 to that.

> > +
> > +#define GET_IDX(updt) (ffs(updt) - 1)
> > +
> > +/* Configuration Channel Extension */
> > +enum gaokun_ucsi_ccx {
> > +     USBC_CCX_NORMAL,
> > +     USBC_CCX_REVERSE,
> > +     USBC_CCX_NONE,
> > +};
> > +
> > +enum gaokun_ucsi_mux {
> > +     USBC_MUX_NONE,
> > +     USBC_MUX_USB_2L,
> > +     USBC_MUX_DP_4L,
> > +     USBC_MUX_USB_DP,
> > +};
> > +
> > +struct gaokun_ucsi_reg {
> > +     u8 port_num;
> > +     u8 port_updt;
> > +     u8 port_data[4];
> > +     u8 checksum;
> > +     u8 reserved;
> > +} __packed;
> > +
> > +struct gaokun_ucsi_port {
> > +     struct completion usb_ack;
> > +     spinlock_t lock;
> > +
> > +     struct gaokun_ucsi *ucsi;
> > +     struct auxiliary_device *bridge;
> > +
> > +     int idx;
> > +     enum gaokun_ucsi_ccx ccx;
> > +     enum gaokun_ucsi_mux mux;
> > +     u8 mode;
> > +     u16 svid;
> > +     u8 hpd_state;
> > +     u8 hpd_irq;
> > +};
> > +
> > +struct gaokun_ucsi {
> > +     struct gaokun_ec *ec;
> > +     struct ucsi *ucsi;
> > +     struct gaokun_ucsi_port *ports;
> > +     struct device *dev;
> > +     struct work_struct work;
> > +     struct notifier_block nb;
> > +     u16 version;
> > +     u8 port_num;
> > +};
> > +
> > +/* -------------------------------------------------------------------------- */
> > +/* For UCSI */
> > +
> > +static int gaokun_ucsi_read_version(struct ucsi *ucsi, u16 *version)
> > +{
> > +     struct gaokun_ucsi *uec = ucsi_get_drvdata(ucsi);
> > +
> > +     *version = uec->version;
> > +
> > +     return 0;
> > +}
> > +
> > +static int gaokun_ucsi_read_cci(struct ucsi *ucsi, u32 *cci)
> > +{
> > +     struct gaokun_ucsi *uec = ucsi_get_drvdata(ucsi);
> > +     u8 buf[GAOKUN_UCSI_READ_SIZE];
> > +     int ret;
> > +
> > +     ret = gaokun_ec_ucsi_read(uec->ec, buf);
> > +     if (ret)
> > +             return ret;
> > +
> > +     memcpy(cci, buf, sizeof(*cci));
> > +
> > +     return 0;
> > +}
> > +
> > +static int gaokun_ucsi_read_message_in(struct ucsi *ucsi,
> > +                                    void *val, size_t val_len)
> > +{
> > +     struct gaokun_ucsi *uec = ucsi_get_drvdata(ucsi);
> > +     u8 buf[GAOKUN_UCSI_READ_SIZE];
> > +     int ret;
> > +
> > +     ret = gaokun_ec_ucsi_read(uec->ec, buf);
> > +     if (ret)
> > +             return ret;
> > +
> > +     memcpy(val, buf + GAOKUN_UCSI_CCI_SIZE,
> > +            min(val_len, GAOKUN_UCSI_DATA_SIZE));
> > +
> > +     return 0;
> > +}
> > +
> > +static int gaokun_ucsi_async_control(struct ucsi *ucsi, u64 command)
> > +{
> > +     struct gaokun_ucsi *uec = ucsi_get_drvdata(ucsi);
> > +     u8 buf[GAOKUN_UCSI_WRITE_SIZE] = {};
> > +
> > +     memcpy(buf, &command, sizeof(command));
> > +
> > +     return gaokun_ec_ucsi_write(uec->ec, buf);
> > +}
> > +
> > +static void gaokun_ucsi_update_connector(struct ucsi_connector *con)
> > +{
> > +     struct gaokun_ucsi *uec = ucsi_get_drvdata(con->ucsi);
> > +
> > +     if (con->num > uec->port_num)
> > +             return;
> > +
> > +     con->typec_cap.orientation_aware = true;
> > +}
> > +
> > +static void gaokun_set_orientation(struct ucsi_connector *con,
> > +                                struct gaokun_ucsi_port *port)
> > +{
> > +     enum gaokun_ucsi_ccx ccx;
> > +     unsigned long flags;
> > +
> > +     spin_lock_irqsave(&port->lock, flags);
> > +     ccx = port->ccx;
> > +     spin_unlock_irqrestore(&port->lock, flags);
> > +
> > +     typec_set_orientation(con->port, CCX_TO_ORI(ccx));
> > +}
> > +
> > +static void gaokun_ucsi_connector_status(struct ucsi_connector *con)
> > +{
> > +     struct gaokun_ucsi *uec = ucsi_get_drvdata(con->ucsi);
> > +     int idx;
> > +
> > +     idx = con->num - 1;
> > +     if (con->num > uec->port_num) {
> > +             dev_warn(uec->ucsi->dev, "set orientation out of range: con%d\n", idx);
> > +             return;
> > +     }
> > +
> > +     gaokun_set_orientation(con, &uec->ports[idx]);
> > +}
> > +
> > +const struct ucsi_operations gaokun_ucsi_ops = {
> > +     .read_version = gaokun_ucsi_read_version,
> > +     .read_cci = gaokun_ucsi_read_cci,
> > +     .read_message_in = gaokun_ucsi_read_message_in,
> > +     .sync_control = ucsi_sync_control_common,
> > +     .async_control = gaokun_ucsi_async_control,
> > +     .update_connector = gaokun_ucsi_update_connector,
> > +     .connector_status = gaokun_ucsi_connector_status,
> > +};
> > +
> > +/* -------------------------------------------------------------------------- */
> > +/* For Altmode */
> > +
> > +static void gaokun_ucsi_port_update(struct gaokun_ucsi_port *port,
> > +                                 const u8 *port_data)
> > +{
> > +     unsigned long flags;
> > +     u8 dcc, ddi;
> > +     int offset = port->idx * 2; /* every port has 2 Bytes data */
> > +
> > +     dcc = port_data[offset];
> > +     ddi = port_data[offset + 1];
> > +
> > +     spin_lock_irqsave(&port->lock, flags);
> > +
> > +     port->ccx = FIELD_GET(GAOKUN_CCX_MASK, dcc);
> > +     port->mux = FIELD_GET(GAOKUN_MUX_MASK, dcc);
> > +     port->mode = FIELD_GET(GAOKUN_DPAM_MASK, ddi);
> > +     port->hpd_state = FIELD_GET(GAOKUN_HPD_STATE_MASK, ddi);
> > +     port->hpd_irq = FIELD_GET(GAOKUN_HPD_IRQ_MASK, ddi);
> > +
> > +     switch (port->mux) {
> > +     case USBC_MUX_NONE:
> > +             port->svid = 0;
> > +             break;
> > +     case USBC_MUX_USB_2L:
> > +             port->svid = USB_SID_PD;
> > +             break;
> > +     case USBC_MUX_DP_4L:
> > +     case USBC_MUX_USB_DP:
> > +             port->svid = USB_SID_DISPLAYPORT;
> > +             if (port->ccx == USBC_CCX_REVERSE)
> > +                     port->mode -= 6;
>
> why minus six ?
> needs a comment.
>

EC's logic. I don't know why, it is a quirk from Qualcomm or Huawei.
I will mention this.

> > +             break;
> > +     default:
> > +             break;
> > +     }
> > +
> > +     spin_unlock_irqrestore(&port->lock, flags);
> > +}
> > +
> > +static int gaokun_ucsi_refresh(struct gaokun_ucsi *uec)
> > +{
> > +     struct gaokun_ucsi_reg ureg;
> > +     int ret, idx;
> > +
> > +     ret = gaokun_ec_ucsi_get_reg(uec->ec, (u8 *)&ureg);
> > +     if (ret)
> > +             return -EIO;
> > +
> > +     uec->port_num = ureg.port_num;
> > +     idx = GET_IDX(ureg.port_updt);
> > +
> > +     if (idx >= 0 && idx < ureg.port_num)
> > +             gaokun_ucsi_port_update(&uec->ports[idx], ureg.port_data);
>
> Since you are checking the validity of the index, you should -EINVAL if
> the index is out of range.
>

EC / pmic glink encode every port in a bit
0/1/2/4/... => ???/left/right/some port

I remap it to -1/0/1/2, to access specific port exceptions(-1) are not
harmful, later in gaokun_ucsi_altmode_notify_ind

	if (idx < 0)
		gaokun_ec_ucsi_pan_ack(uec->ec, idx);
	else
		gaokun_ucsi_handle_altmode(&uec->ports[idx]);

gaokun_ec_ucsi_pan_ack can handle exceptions.

> > +
> > +     return idx;
> > +}
> > +
> > +static void gaokun_ucsi_handle_altmode(struct gaokun_ucsi_port *port)
> > +{
> > +     struct gaokun_ucsi *uec = port->ucsi;
> > +     int idx = port->idx;
> > +
> > +     if (idx >= uec->ucsi->cap.num_connectors || !uec->ucsi->connector) {
> > +             dev_warn(uec->ucsi->dev, "altmode port out of range: %d\n", idx);
> > +             return;
> > +     }
> > +
> > +     /* UCSI callback .connector_status() have set orientation */
> > +     if (port->bridge)
> > +             drm_aux_hpd_bridge_notify(&port->bridge->dev,
> > +                                       port->hpd_state ?
> > +                                       connector_status_connected :
> > +                                       connector_status_disconnected);
> > +
> > +     gaokun_ec_ucsi_pan_ack(uec->ec, port->idx);
> > +}
> > +
> > +static void gaokun_ucsi_altmode_notify_ind(struct gaokun_ucsi *uec)
> > +{
> > +     int idx;
> > +
> > +     idx = gaokun_ucsi_refresh(uec);
> > +     if (idx < 0)
> > +             gaokun_ec_ucsi_pan_ack(uec->ec, idx);
> > +     else
> > +             gaokun_ucsi_handle_altmode(&uec->ports[idx]);
> > +}
> > +
> > +/*
> > + * USB event is necessary for enabling altmode, the event should follow
> > + * UCSI event, if not after timeout(this notify may be disabled somehow),
> > + * then force to enable altmode.
> > + */
> > +static void gaokun_ucsi_handle_no_usb_event(struct gaokun_ucsi *uec, int idx)
> > +{
> > +     struct gaokun_ucsi_port *port;
> > +
> > +     port = &uec->ports[idx];
> > +     if (!wait_for_completion_timeout(&port->usb_ack, 2 * HZ)) {
> > +             dev_warn(uec->dev, "No USB EVENT, triggered by UCSI EVENT");
> > +             gaokun_ucsi_altmode_notify_ind(uec);
> > +     }
> > +}
> > +
> > +static int gaokun_ucsi_notify(struct notifier_block *nb,
> > +                           unsigned long action, void *data)
> > +{
> > +     u32 cci;
> > +     struct gaokun_ucsi *uec = container_of(nb, struct gaokun_ucsi, nb);
> > +
> > +     switch (action) {
> > +     case EC_EVENT_USB:
> > +             gaokun_ucsi_altmode_notify_ind(uec);
> > +             return NOTIFY_OK;
> > +
> > +     case EC_EVENT_UCSI:
> > +             uec->ucsi->ops->read_cci(uec->ucsi, &cci);
> > +             ucsi_notify_common(uec->ucsi, cci);
> > +             if (UCSI_CCI_CONNECTOR(cci))
> > +                     gaokun_ucsi_handle_no_usb_event(uec, UCSI_CCI_CONNECTOR(cci) - 1);
> > +
> > +             return NOTIFY_OK;
> > +
> > +     default:
> > +             return NOTIFY_DONE;
> > +     }
> > +}
> > +
> > +static int gaokun_ucsi_get_port_num(struct gaokun_ucsi *uec)
> > +{
> > +     struct gaokun_ucsi_reg ureg;
> > +     int ret;
> > +
> > +     ret = gaokun_ec_ucsi_get_reg(uec->ec, (u8 *)&ureg);
> > +
> > +     return ret ? 0 : ureg.port_num;
> > +}
> > +
> > +static int gaokun_ucsi_ports_init(struct gaokun_ucsi *uec)
> > +{
> > +     u32 port;
> > +     int i, ret, port_num;
> > +     struct device *dev = uec->dev;
> > +     struct gaokun_ucsi_port *ucsi_port;
> > +     struct fwnode_handle *fwnode;
> > +
> > +     port_num = gaokun_ucsi_get_port_num(uec);
> > +     uec->port_num = port_num;
> > +
> > +     uec->ports = devm_kzalloc(dev, port_num * sizeof(*(uec->ports)),
> > +                               GFP_KERNEL);
> > +     if (!uec->ports)
> > +             return -ENOMEM;
> > +
> > +     for (i = 0; i < port_num; ++i) {
> > +             ucsi_port = &uec->ports[i];
> > +             ucsi_port->ccx = USBC_CCX_NONE;
> > +             ucsi_port->idx = i;
> > +             ucsi_port->ucsi = uec;
> > +             init_completion(&ucsi_port->usb_ack);
> > +             spin_lock_init(&ucsi_port->lock);
> > +     }
> > +
> > +     device_for_each_child_node(dev, fwnode) {
> > +             ret = fwnode_property_read_u32(fwnode, "reg", &port);
> > +             if (ret < 0) {
> > +                     dev_err(dev, "missing reg property of %pOFn\n", fwnode);
> > +                     fwnode_handle_put(fwnode);
> > +                     return ret;
> > +             }
> > +
> > +             if (port >= port_num) {
> > +                     dev_warn(dev, "invalid connector number %d, ignoring\n", port);
> > +                     continue;
> > +             }
> > +
> > +             ucsi_port = &uec->ports[port];
> > +             ucsi_port->bridge = devm_drm_dp_hpd_bridge_alloc(dev, to_of_node(fwnode));
> > +             if (IS_ERR(ucsi_port->bridge)) {
> > +                     fwnode_handle_put(fwnode);
> > +                     return PTR_ERR(ucsi_port->bridge);
> > +             }
> > +     }
> > +
> > +     for (i = 0; i < port_num; i++) {
> > +             if (!uec->ports[i].bridge)
> > +                     continue;
> > +
> > +             ret = devm_drm_dp_hpd_bridge_add(dev, uec->ports[i].bridge);
> > +             if (ret)
> > +                     return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void gaokun_ucsi_register_worker(struct work_struct *work)
> > +{
> > +     struct gaokun_ucsi *uec;
> > +     struct ucsi *ucsi;
> > +     int ret;
> > +
> > +     uec = container_of(work, struct gaokun_ucsi, work);
> > +     ucsi = uec->ucsi;
> > +
> > +     ucsi->quirks = UCSI_NO_PARTNER_PDOS | UCSI_DELAY_DEVICE_PDOS;
> > +
> > +     ssleep(3); /* EC can't handle UCSI properly in the early stage */
>
> Could you not schedule work for + 3 seconds instead of sleeping here -
> representing the required stall time in some sort of state machine ?
>

I see, I will check work schedule interface.

> 3 seconds is an incredibly long time for a computer to sleep.
>

This module will be loaded at about 5th second after power up, if not
sleep, we will receive something disharmonious, sleeping for 3 seconds is
a hack.

> > +
> > +     ret = gaokun_ec_register_notify(uec->ec, &uec->nb);
> > +     if (ret) {
> > +             dev_err_probe(ucsi->dev, ret, "notifier register failed\n");
> > +             return;
> > +     }
> > +
> > +     ret = ucsi_register(ucsi);
> > +     if (ret)
> > +             dev_err_probe(ucsi->dev, ret, "ucsi register failed\n");
> > +}
> > +
> > +static int gaokun_ucsi_register(struct gaokun_ucsi *uec)
> > +{
> > +     schedule_work(&uec->work);
> > +
> > +     return 0;
> > +}
> > +
> > +static int gaokun_ucsi_probe(struct auxiliary_device *adev,
> > +                          const struct auxiliary_device_id *id)
> > +{
> > +     struct gaokun_ec *ec = adev->dev.platform_data;
> > +     struct device *dev = &adev->dev;
> > +     struct gaokun_ucsi *uec;
> > +     int ret;
> > +
> > +     uec = devm_kzalloc(dev, sizeof(*uec), GFP_KERNEL);
> > +     if (!uec)
> > +             return -ENOMEM;
> > +
> > +     uec->ec = ec;
> > +     uec->dev = dev;
> > +     uec->version = 0x0100;
> > +     uec->nb.notifier_call = gaokun_ucsi_notify;
> > +
> > +     INIT_WORK(&uec->work, gaokun_ucsi_register_worker);
> > +
> > +     ret = gaokun_ucsi_ports_init(uec);
> > +     if (ret)
> > +             return ret;
> > +
> > +     uec->ucsi = ucsi_create(dev, &gaokun_ucsi_ops);
> > +     if (IS_ERR(uec->ucsi))
> > +             return PTR_ERR(uec->ucsi);
> > +
> > +     ucsi_set_drvdata(uec->ucsi, uec);
> > +     auxiliary_set_drvdata(adev, uec);
> > +
> > +     return gaokun_ucsi_register(uec);
> > +}
> > +
> > +static void gaokun_ucsi_remove(struct auxiliary_device *adev)
> > +{
> > +     struct gaokun_ucsi *uec = auxiliary_get_drvdata(adev);
> > +
> > +     gaokun_ec_unregister_notify(uec->ec, &uec->nb);
> > +     ucsi_unregister(uec->ucsi);
> > +     ucsi_destroy(uec->ucsi);
> > +}
> > +
> > +static const struct auxiliary_device_id gaokun_ucsi_id_table[] = {
> > +     { .name = GAOKUN_MOD_NAME "." GAOKUN_DEV_UCSI, },
> > +     {}
> > +};
> > +MODULE_DEVICE_TABLE(auxiliary, gaokun_ucsi_id_table);
> > +
> > +static struct auxiliary_driver gaokun_ucsi_driver = {
> > +     .name = GAOKUN_DEV_UCSI,
> > +     .id_table = gaokun_ucsi_id_table,
> > +     .probe = gaokun_ucsi_probe,
> > +     .remove = gaokun_ucsi_remove,
> > +};
> > +
> > +module_auxiliary_driver(gaokun_ucsi_driver);
> > +
> > +MODULE_DESCRIPTION("HUAWEI Matebook E Go UCSI driver");
> > +MODULE_LICENSE("GPL");
>


Best Wishes,
Pengyu

  reply	other threads:[~2024-12-28 14:39 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-27 17:13 [PATCH 0/5] platform: arm64: Huawei Matebook E Go embedded controller Pengyu Luo
2024-12-27 17:13 ` [PATCH 1/5] dt-bindings: platform: Add Huawei Matebook E Go EC Pengyu Luo
2024-12-27 18:18   ` Rob Herring (Arm)
2024-12-28  9:54   ` Krzysztof Kozlowski
2024-12-28 10:50     ` Pengyu Luo
2024-12-29  9:50       ` Krzysztof Kozlowski
2024-12-29 10:12         ` Pengyu Luo
2024-12-30  7:28           ` Aiqun(Maria) Yu
2024-12-30  7:35             ` Krzysztof Kozlowski
2024-12-30  9:10               ` Aiqun(Maria) Yu
2024-12-30  8:00             ` Pengyu Luo
2025-01-01  5:57             ` Pengyu Luo
2024-12-27 17:13 ` [PATCH 2/5] platform: arm64: add Huawei Matebook E Go (sc8280xp) EC driver Pengyu Luo
2024-12-27 18:21   ` Maya Matuszczyk
2024-12-28  5:42     ` Pengyu Luo
2024-12-28  9:58   ` Krzysztof Kozlowski
2024-12-28 11:34     ` [PATCH 1/5] dt-bindings: platform: Add Huawei Matebook E Go EC Pengyu Luo
2024-12-29  4:08       ` Dmitry Baryshkov
2024-12-29  9:04         ` [PATCH 2/5] platform: arm64: add Huawei Matebook E Go (sc8280xp) EC driver Pengyu Luo
2024-12-29  9:44           ` Krzysztof Kozlowski
2024-12-29  9:43       ` [PATCH 1/5] dt-bindings: platform: Add Huawei Matebook E Go EC Krzysztof Kozlowski
2024-12-29 10:28         ` Pengyu Luo
2024-12-29 21:45           ` Krzysztof Kozlowski
2024-12-28 12:33   ` [PATCH 2/5] platform: arm64: add Huawei Matebook E Go (sc8280xp) EC driver Bryan O'Donoghue
2024-12-28 13:51     ` Pengyu Luo
2024-12-29 15:32       ` Ilpo Järvinen
2024-12-29 15:55         ` Pengyu Luo
2024-12-29 14:49   ` Markus Elfring
2024-12-30  9:04   ` Aiqun(Maria) Yu
2024-12-30 10:44     ` Pengyu Luo
2024-12-31  5:00       ` Aiqun(Maria) Yu
2024-12-31  7:44         ` Pengyu Luo
2024-12-31 11:09           ` Bryan O'Donoghue
2025-01-03  5:38           ` Dmitry Baryshkov
2025-01-03  7:19             ` Pengyu Luo
2025-01-01 11:27         ` Pengyu Luo
2024-12-27 17:13 ` [PATCH 3/5] usb: typec: ucsi: add Huawei Matebook E Go (sc8280xp) ucsi driver Pengyu Luo
2024-12-28 13:06   ` Bryan O'Donoghue
2024-12-28 14:38     ` Pengyu Luo [this message]
2024-12-29 14:51       ` Bryan O'Donoghue
2024-12-29 16:25         ` Pengyu Luo
2024-12-29  4:40   ` Dmitry Baryshkov
2024-12-29  9:05     ` Pengyu Luo
2025-01-06  3:33       ` Dmitry Baryshkov
2025-01-06  9:20         ` [PATCH 1/5] dt-bindings: platform: Add Huawei Matebook E Go EC Pengyu Luo
2025-01-06  9:22         ` [PATCH 3/5] usb: typec: ucsi: add Huawei Matebook E Go (sc8280xp) ucsi driver Pengyu Luo
2024-12-29 16:15   ` Markus Elfring
2024-12-27 17:13 ` [PATCH 4/5] power: supply: add Huawei Matebook E Go (sc8280xp) psy driver Pengyu Luo
2024-12-27 17:13 ` [PATCH 5/5] arm64: dts: qcom: gaokun3: Add Embedded Controller node Pengyu Luo
2024-12-30 14:53   ` Konrad Dybcio
2024-12-30 16:22     ` Pengyu Luo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241228143830.613658-1-mitltlatltl@gmail.com \
    --to=mitltlatltl@gmail.com \
    --cc=andersson@kernel.org \
    --cc=bryan.odonoghue@linaro.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hdegoede@redhat.com \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=konradybcio@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=nikita@trvn.ru \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sre@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.