On Fri, Feb 10, 2023 at 04:02:07PM +0100, Neil Armstrong wrote: > Only register UCSI on know working devices, like on the SM8450 > or Sm8550 which requires UCSI to get USB mode switch events. > > Signed-off-by: Neil Armstrong <neil.armstrong@xxxxxxxxxx> > --- > drivers/soc/qcom/pmic_glink.c | 67 ++++++++++++++++++++++++++++++++++++------- > 1 file changed, 57 insertions(+), 10 deletions(-) > > diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c > index bb3fb57abcc6..c7f091f4a8c1 100644 > --- a/drivers/soc/qcom/pmic_glink.c > +++ b/drivers/soc/qcom/pmic_glink.c > @@ -4,6 +4,7 @@ > * Copyright (c) 2022, Linaro Ltd > */ > #include <linux/auxiliary_bus.h> > +#include <linux/of_device.h> > #include <linux/module.h> > #include <linux/platform_device.h> > #include <linux/rpmsg.h> > @@ -11,12 +12,23 @@ > #include <linux/soc/qcom/pdr.h> > #include <linux/soc/qcom/pmic_glink.h> > > +enum { > + PMIC_GLINK_CLIENT_BATT = 0, > + PMIC_GLINK_CLIENT_ALTMODE, > + PMIC_GLINK_CLIENT_UCSI, > +}; > + > +#define PMIC_GLINK_CLIENT_DEFAULT (BIT(PMIC_GLINK_CLIENT_BATT) | \ > + BIT(PMIC_GLINK_CLIENT_ALTMODE)) > + > struct pmic_glink { > struct device *dev; > struct pdr_handle *pdr; > > struct rpmsg_endpoint *ept; > > + unsigned int client_mask; > + > struct auxiliary_device altmode_aux; > struct auxiliary_device ps_aux; > struct auxiliary_device ucsi_aux; > @@ -231,8 +243,19 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = { > }, > }; > > +/* Do not handle altmode for now on those platforms */ > +static const unsigned int pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | > + BIT(PMIC_GLINK_CLIENT_UCSI); > + > +static const struct of_device_id pmic_glink_of_client_mask[] = { > + { .compatible = "qcom,sm8450-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, > + { .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, > + {} > +}; > + > static int pmic_glink_probe(struct platform_device *pdev) > { > + const struct of_device_id *match; > struct pdr_service *service; > struct pmic_glink *pg; > int ret; > @@ -249,12 +272,27 @@ static int pmic_glink_probe(struct platform_device *pdev) > mutex_init(&pg->client_lock); > mutex_init(&pg->state_lock); > > - ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode"); > - if (ret) > - return ret; > - ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply"); > - if (ret) > - goto out_release_altmode_aux; > + match = of_match_device(pmic_glink_of_client_mask, &pdev->dev); > + if (match) > + pg->client_mask = *(const unsigned int *)match->data; Make pmic_glink_sm8450_client_mask unsigned long instead, then it will have the same size as void * and you don't need to dereference it here... > + else > + pg->client_mask = PMIC_GLINK_CLIENT_DEFAULT; Let's move these bits to pmic_glink_of_match[] to avoid having two different of_device_id to keep in sync. And hopefully we could have "qcom,pmic_glink" represent the case of having all 3 bits set soon, and special case what you have as "default" here... Regards, Bjorn > + > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) { > + ret = pmic_glink_add_aux_device(pg, &pg->ucsi_aux, "ucsi"); > + if (ret) > + return ret; > + } > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) { > + ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode"); > + if (ret) > + goto out_release_ucsi_aux; > + } > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) { > + ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply"); > + if (ret) > + goto out_release_altmode_aux; > + } > > pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg); > if (IS_ERR(pg->pdr)) { > @@ -278,9 +316,14 @@ static int pmic_glink_probe(struct platform_device *pdev) > out_release_pdr_handle: > pdr_handle_release(pg->pdr); > out_release_aux_devices: > - pmic_glink_del_aux_device(pg, &pg->ps_aux); > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) > + pmic_glink_del_aux_device(pg, &pg->ps_aux); > out_release_altmode_aux: > - pmic_glink_del_aux_device(pg, &pg->altmode_aux); > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) > + pmic_glink_del_aux_device(pg, &pg->altmode_aux); > +out_release_ucsi_aux: > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) > + pmic_glink_del_aux_device(pg, &pg->ucsi_aux); > > return ret; > } > @@ -291,8 +334,12 @@ static int pmic_glink_remove(struct platform_device *pdev) > > pdr_handle_release(pg->pdr); > > - pmic_glink_del_aux_device(pg, &pg->ps_aux); > - pmic_glink_del_aux_device(pg, &pg->altmode_aux); > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) > + pmic_glink_del_aux_device(pg, &pg->ps_aux); > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) > + pmic_glink_del_aux_device(pg, &pg->altmode_aux); > + if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) > + pmic_glink_del_aux_device(pg, &pg->ucsi_aux); > > mutex_lock(&__pmic_glink_lock); > __pmic_glink = NULL; > > -- > 2.34.1 >