Message ID | 20230130-topic-sm8450-upstream-pmic-glink-v3-4-4c860d265d28@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | soc: qcom: add UCSI function to PMIC GLINK | expand |
On 09/03/2023 15:27, 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@linaro.org> > --- > drivers/soc/qcom/pmic_glink.c | 63 ++++++++++++++++++++++++++++++++++++------- > 1 file changed, 53 insertions(+), 10 deletions(-) > > diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c > index bb3fb57abcc6..48e015fee8e9 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 long client_mask; > + > struct auxiliary_device altmode_aux; > struct auxiliary_device ps_aux; > struct auxiliary_device ucsi_aux; > @@ -233,6 +245,7 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = { > > 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 +262,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_device_get_match_data(&pdev->dev); This is incorrect. of_device_get_match_data() already returns match->data, rather than a matching of_device_id(). > + if (match) > + pg->client_mask = (unsigned long)match->data; > + else > + pg->client_mask = PMIC_GLINK_CLIENT_DEFAULT; > + > + 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 +306,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 +324,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; > @@ -301,7 +338,13 @@ static int pmic_glink_remove(struct platform_device *pdev) > return 0; > } > > +/* Do not handle altmode for now on those platforms */ > +static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | > + BIT(PMIC_GLINK_CLIENT_UCSI); > + > static const struct of_device_id pmic_glink_of_match[] = { > + { .compatible = "qcom,sm8450-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, > + { .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, > { .compatible = "qcom,pmic-glink", }, > {} > }; >
diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index bb3fb57abcc6..48e015fee8e9 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 long client_mask; + struct auxiliary_device altmode_aux; struct auxiliary_device ps_aux; struct auxiliary_device ucsi_aux; @@ -233,6 +245,7 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = { 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 +262,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_device_get_match_data(&pdev->dev); + if (match) + pg->client_mask = (unsigned long)match->data; + else + pg->client_mask = PMIC_GLINK_CLIENT_DEFAULT; + + 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 +306,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 +324,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; @@ -301,7 +338,13 @@ static int pmic_glink_remove(struct platform_device *pdev) return 0; } +/* Do not handle altmode for now on those platforms */ +static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | + BIT(PMIC_GLINK_CLIENT_UCSI); + static const struct of_device_id pmic_glink_of_match[] = { + { .compatible = "qcom,sm8450-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, + { .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, { .compatible = "qcom,pmic-glink", }, {} };
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@linaro.org> --- drivers/soc/qcom/pmic_glink.c | 63 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 10 deletions(-)