Loading Documentation/devicetree/bindings/coresight/coresight.txt +11 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,8 @@ Optional properties: registers to be saved and restored - qcom,cti-ack-atomic : boolean, indicating cti interrupt acknowledgement needs to be done in atomic context - qcom,cti-gpio-trigin : cti trigger input driven by gpio - qcom,cti-gpio-trigout : cti trigger output sent to gpio - qcom,pc-save : program counter save implemented - qcom,blk-size : block size for tmc-etr to usb transfers - qcom,memory-size : size of coherent memory to be allocated for tmc-etr buffer Loading Loading @@ -170,6 +172,11 @@ Optional properties: for tpiu component - nidnt-gpio : specifies gpio for NIDnT hardware detection - nidnt-gpio-polarity : specifies gpio polarity for NIDnT hardware detection - pinctrl-names : names corresponding to the numbered pinctrl. The allowed names are subset of the following: cti-trigin-pctrl, cti-trigout-pctrl. Used for cti component - pinctrl-<n>: list of pinctrl phandles for the different pinctrl states. Refer to "Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt". Examples: Loading Loading @@ -278,6 +285,10 @@ Examples: coresight-id = <15>; coresight-name = "coresight-cti0"; coresight-nr-inports = <0>; qcom,cti-gpio-trigout = <1>; pinctrl-names = "cti-trigout-pctrl"; pinctrl-0 = <&trigout_a>; }; cti1: cti@fc309000 { Loading drivers/coresight/coresight-cti.c +220 −10 Original line number Diff line number Diff line Loading @@ -77,12 +77,18 @@ struct cti_state { unsigned int ctiouten[CTI_MAX_TRIGGERS]; }; struct cti_pctrl { struct pinctrl *pctrl; int trig; }; struct cti_drvdata { void __iomem *base; struct device *dev; struct coresight_device *csdev; struct clk *clk; spinlock_t spinlock; struct mutex mutex; struct coresight_cti cti; int refcnt; int cpu; Loading @@ -91,6 +97,8 @@ struct cti_drvdata { bool cti_ack_atomic; bool l2_off; struct cti_state *state; struct cti_pctrl *gpio_trigin; struct cti_pctrl *gpio_trigout; }; static LIST_HEAD(cti_list); Loading Loading @@ -129,6 +137,98 @@ static void cti_enable(struct cti_drvdata *drvdata) CTI_LOCK(drvdata); } int cti_trigin_gpio_enable(struct cti_drvdata *drvdata) { int ret; struct pinctrl *pctrl; struct pinctrl_state *pctrl_state; if (drvdata->gpio_trigin->pctrl) return 0; pctrl = devm_pinctrl_get(drvdata->dev); if (IS_ERR(pctrl)) { dev_err(drvdata->dev, "pinctrl get failed\n"); return PTR_ERR(pctrl); } pctrl_state = pinctrl_lookup_state(pctrl, "cti-trigin-pctrl"); if (IS_ERR(pctrl_state)) { dev_err(drvdata->dev, "pinctrl get state failed\n"); ret = PTR_ERR(pctrl_state); goto err; } ret = pinctrl_select_state(pctrl, pctrl_state); if (ret) { dev_err(drvdata->dev, "pinctrl enable state failed\n"); goto err; } drvdata->gpio_trigin->pctrl = pctrl; return 0; err: devm_pinctrl_put(pctrl); return ret; } int cti_trigout_gpio_enable(struct cti_drvdata *drvdata) { int ret; struct pinctrl *pctrl; struct pinctrl_state *pctrl_state; if (drvdata->gpio_trigout->pctrl) return 0; pctrl = devm_pinctrl_get(drvdata->dev); if (IS_ERR(pctrl)) { dev_err(drvdata->dev, "pinctrl get failed\n"); return PTR_ERR(pctrl); } pctrl_state = pinctrl_lookup_state(pctrl, "cti-trigout-pctrl"); if (IS_ERR(pctrl_state)) { dev_err(drvdata->dev, "pinctrl get state failed\n"); ret = PTR_ERR(pctrl_state); goto err; } ret = pinctrl_select_state(pctrl, pctrl_state); if (ret) { dev_err(drvdata->dev, "pinctrl enable state failed\n"); goto err; } drvdata->gpio_trigout->pctrl = pctrl; return 0; err: devm_pinctrl_put(pctrl); return ret; } void cti_trigin_gpio_disable(struct cti_drvdata *drvdata) { if (!drvdata->gpio_trigin->pctrl) return; devm_pinctrl_put(drvdata->gpio_trigin->pctrl); drvdata->gpio_trigin->pctrl = NULL; } void cti_trigout_gpio_disable(struct cti_drvdata *drvdata) { if (!drvdata->gpio_trigout->pctrl) return; devm_pinctrl_put(drvdata->gpio_trigout->pctrl); drvdata->gpio_trigout->pctrl = NULL; } static void __cti_map_trigin(struct cti_drvdata *drvdata, int trig, int ch) { uint32_t ctien; Loading Loading @@ -167,21 +267,39 @@ int coresight_cti_map_trigin(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (drvdata->gpio_trigin->trig == trig) { ret = cti_trigin_gpio_enable(drvdata); if (ret) goto err0; } ret = clk_prepare_enable(drvdata->clk); if (ret) return ret; goto err1; spin_lock_irqsave(&drvdata->spinlock, flag); ret = cti_cpu_verify_access(drvdata); if (ret) goto err; goto err2; __cti_map_trigin(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); return 0; err2: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); err1: cti_trigin_gpio_disable(drvdata); err0: mutex_unlock(&drvdata->mutex); return ret; } EXPORT_SYMBOL(coresight_cti_map_trigin); Loading Loading @@ -224,21 +342,39 @@ int coresight_cti_map_trigout(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (drvdata->gpio_trigout->trig == trig) { ret = cti_trigout_gpio_enable(drvdata); if (ret) goto err0; } ret = clk_prepare_enable(drvdata->clk); if (ret) return ret; goto err1; spin_lock_irqsave(&drvdata->spinlock, flag); ret = cti_cpu_verify_access(drvdata); if (ret) goto err; goto err2; __cti_map_trigout(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); return 0; err2: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); err1: cti_trigout_gpio_disable(drvdata); err0: mutex_unlock(&drvdata->mutex); return ret; } EXPORT_SYMBOL(coresight_cti_map_trigout); Loading Loading @@ -292,6 +428,8 @@ void coresight_cti_unmap_trigin(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (clk_prepare_enable(drvdata->clk)) return; Loading @@ -301,10 +439,20 @@ void coresight_cti_unmap_trigin(struct coresight_cti *cti, int trig, int ch) goto err; __cti_unmap_trigin(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); if (drvdata->gpio_trigin->trig == trig) cti_trigin_gpio_disable(drvdata); mutex_unlock(&drvdata->mutex); return; err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); } EXPORT_SYMBOL(coresight_cti_unmap_trigin); Loading Loading @@ -344,6 +492,8 @@ void coresight_cti_unmap_trigout(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (clk_prepare_enable(drvdata->clk)) return; Loading @@ -353,10 +503,20 @@ void coresight_cti_unmap_trigout(struct coresight_cti *cti, int trig, int ch) goto err; __cti_unmap_trigout(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); if (drvdata->gpio_trigout->trig == trig) cti_trigout_gpio_disable(drvdata); mutex_unlock(&drvdata->mutex); return; err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); } EXPORT_SYMBOL(coresight_cti_unmap_trigout); Loading Loading @@ -384,12 +544,15 @@ void coresight_cti_reset(struct coresight_cti *cti) { struct cti_drvdata *drvdata; unsigned long flag; int trig; if (IS_ERR_OR_NULL(cti)) return; drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (clk_prepare_enable(drvdata->clk)) return; Loading @@ -399,10 +562,24 @@ void coresight_cti_reset(struct coresight_cti *cti) goto err; __cti_reset(drvdata); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); for (trig = 0; trig < CTI_MAX_TRIGGERS; trig++) { if (drvdata->gpio_trigin->trig == trig) cti_trigin_gpio_disable(drvdata); if (drvdata->gpio_trigout->trig == trig) cti_trigout_gpio_disable(drvdata); } mutex_unlock(&drvdata->mutex); return; err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); } EXPORT_SYMBOL(coresight_cti_reset); Loading Loading @@ -1116,6 +1293,7 @@ static const struct attribute_group *cti_attr_grps[] = { static int cti_probe(struct platform_device *pdev) { int ret, cpu; int trig; struct device *dev = &pdev->dev; struct coresight_platform_data *pdata; struct cti_drvdata *drvdata; Loading Loading @@ -1150,6 +1328,8 @@ static int cti_probe(struct platform_device *pdev) spin_lock_init(&drvdata->spinlock); mutex_init(&drvdata->mutex); drvdata->clk = devm_clk_get(dev, "core_clk"); if (IS_ERR(drvdata->clk)) return PTR_ERR(drvdata->clk); Loading @@ -1158,6 +1338,36 @@ static int cti_probe(struct platform_device *pdev) if (ret) return ret; drvdata->gpio_trigin = devm_kzalloc(dev, sizeof(struct cti_pctrl), GFP_KERNEL); if (!drvdata->gpio_trigin) return -ENOMEM; drvdata->gpio_trigin->trig = -1; if (pdev->dev.of_node) { ret = of_property_read_u32(pdev->dev.of_node, "qcom,cti-gpio-trigin", &trig); if (!ret) drvdata->gpio_trigin->trig = trig; else if (ret != -EINVAL) return ret; } drvdata->gpio_trigout = devm_kzalloc(dev, sizeof(struct cti_pctrl), GFP_KERNEL); if (!drvdata->gpio_trigout) return -ENOMEM; drvdata->gpio_trigout->trig = -1; if (pdev->dev.of_node) { ret = of_property_read_u32(pdev->dev.of_node, "qcom,cti-gpio-trigout", &trig); if (!ret) drvdata->gpio_trigout->trig = trig; else if (ret != -EINVAL) return ret; } if (pdev->dev.of_node) { drvdata->cti_ack_atomic = of_property_read_bool(pdev->dev.of_node, Loading Loading
Documentation/devicetree/bindings/coresight/coresight.txt +11 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,8 @@ Optional properties: registers to be saved and restored - qcom,cti-ack-atomic : boolean, indicating cti interrupt acknowledgement needs to be done in atomic context - qcom,cti-gpio-trigin : cti trigger input driven by gpio - qcom,cti-gpio-trigout : cti trigger output sent to gpio - qcom,pc-save : program counter save implemented - qcom,blk-size : block size for tmc-etr to usb transfers - qcom,memory-size : size of coherent memory to be allocated for tmc-etr buffer Loading Loading @@ -170,6 +172,11 @@ Optional properties: for tpiu component - nidnt-gpio : specifies gpio for NIDnT hardware detection - nidnt-gpio-polarity : specifies gpio polarity for NIDnT hardware detection - pinctrl-names : names corresponding to the numbered pinctrl. The allowed names are subset of the following: cti-trigin-pctrl, cti-trigout-pctrl. Used for cti component - pinctrl-<n>: list of pinctrl phandles for the different pinctrl states. Refer to "Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt". Examples: Loading Loading @@ -278,6 +285,10 @@ Examples: coresight-id = <15>; coresight-name = "coresight-cti0"; coresight-nr-inports = <0>; qcom,cti-gpio-trigout = <1>; pinctrl-names = "cti-trigout-pctrl"; pinctrl-0 = <&trigout_a>; }; cti1: cti@fc309000 { Loading
drivers/coresight/coresight-cti.c +220 −10 Original line number Diff line number Diff line Loading @@ -77,12 +77,18 @@ struct cti_state { unsigned int ctiouten[CTI_MAX_TRIGGERS]; }; struct cti_pctrl { struct pinctrl *pctrl; int trig; }; struct cti_drvdata { void __iomem *base; struct device *dev; struct coresight_device *csdev; struct clk *clk; spinlock_t spinlock; struct mutex mutex; struct coresight_cti cti; int refcnt; int cpu; Loading @@ -91,6 +97,8 @@ struct cti_drvdata { bool cti_ack_atomic; bool l2_off; struct cti_state *state; struct cti_pctrl *gpio_trigin; struct cti_pctrl *gpio_trigout; }; static LIST_HEAD(cti_list); Loading Loading @@ -129,6 +137,98 @@ static void cti_enable(struct cti_drvdata *drvdata) CTI_LOCK(drvdata); } int cti_trigin_gpio_enable(struct cti_drvdata *drvdata) { int ret; struct pinctrl *pctrl; struct pinctrl_state *pctrl_state; if (drvdata->gpio_trigin->pctrl) return 0; pctrl = devm_pinctrl_get(drvdata->dev); if (IS_ERR(pctrl)) { dev_err(drvdata->dev, "pinctrl get failed\n"); return PTR_ERR(pctrl); } pctrl_state = pinctrl_lookup_state(pctrl, "cti-trigin-pctrl"); if (IS_ERR(pctrl_state)) { dev_err(drvdata->dev, "pinctrl get state failed\n"); ret = PTR_ERR(pctrl_state); goto err; } ret = pinctrl_select_state(pctrl, pctrl_state); if (ret) { dev_err(drvdata->dev, "pinctrl enable state failed\n"); goto err; } drvdata->gpio_trigin->pctrl = pctrl; return 0; err: devm_pinctrl_put(pctrl); return ret; } int cti_trigout_gpio_enable(struct cti_drvdata *drvdata) { int ret; struct pinctrl *pctrl; struct pinctrl_state *pctrl_state; if (drvdata->gpio_trigout->pctrl) return 0; pctrl = devm_pinctrl_get(drvdata->dev); if (IS_ERR(pctrl)) { dev_err(drvdata->dev, "pinctrl get failed\n"); return PTR_ERR(pctrl); } pctrl_state = pinctrl_lookup_state(pctrl, "cti-trigout-pctrl"); if (IS_ERR(pctrl_state)) { dev_err(drvdata->dev, "pinctrl get state failed\n"); ret = PTR_ERR(pctrl_state); goto err; } ret = pinctrl_select_state(pctrl, pctrl_state); if (ret) { dev_err(drvdata->dev, "pinctrl enable state failed\n"); goto err; } drvdata->gpio_trigout->pctrl = pctrl; return 0; err: devm_pinctrl_put(pctrl); return ret; } void cti_trigin_gpio_disable(struct cti_drvdata *drvdata) { if (!drvdata->gpio_trigin->pctrl) return; devm_pinctrl_put(drvdata->gpio_trigin->pctrl); drvdata->gpio_trigin->pctrl = NULL; } void cti_trigout_gpio_disable(struct cti_drvdata *drvdata) { if (!drvdata->gpio_trigout->pctrl) return; devm_pinctrl_put(drvdata->gpio_trigout->pctrl); drvdata->gpio_trigout->pctrl = NULL; } static void __cti_map_trigin(struct cti_drvdata *drvdata, int trig, int ch) { uint32_t ctien; Loading Loading @@ -167,21 +267,39 @@ int coresight_cti_map_trigin(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (drvdata->gpio_trigin->trig == trig) { ret = cti_trigin_gpio_enable(drvdata); if (ret) goto err0; } ret = clk_prepare_enable(drvdata->clk); if (ret) return ret; goto err1; spin_lock_irqsave(&drvdata->spinlock, flag); ret = cti_cpu_verify_access(drvdata); if (ret) goto err; goto err2; __cti_map_trigin(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); return 0; err2: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); err1: cti_trigin_gpio_disable(drvdata); err0: mutex_unlock(&drvdata->mutex); return ret; } EXPORT_SYMBOL(coresight_cti_map_trigin); Loading Loading @@ -224,21 +342,39 @@ int coresight_cti_map_trigout(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (drvdata->gpio_trigout->trig == trig) { ret = cti_trigout_gpio_enable(drvdata); if (ret) goto err0; } ret = clk_prepare_enable(drvdata->clk); if (ret) return ret; goto err1; spin_lock_irqsave(&drvdata->spinlock, flag); ret = cti_cpu_verify_access(drvdata); if (ret) goto err; goto err2; __cti_map_trigout(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); return 0; err2: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); err1: cti_trigout_gpio_disable(drvdata); err0: mutex_unlock(&drvdata->mutex); return ret; } EXPORT_SYMBOL(coresight_cti_map_trigout); Loading Loading @@ -292,6 +428,8 @@ void coresight_cti_unmap_trigin(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (clk_prepare_enable(drvdata->clk)) return; Loading @@ -301,10 +439,20 @@ void coresight_cti_unmap_trigin(struct coresight_cti *cti, int trig, int ch) goto err; __cti_unmap_trigin(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); if (drvdata->gpio_trigin->trig == trig) cti_trigin_gpio_disable(drvdata); mutex_unlock(&drvdata->mutex); return; err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); } EXPORT_SYMBOL(coresight_cti_unmap_trigin); Loading Loading @@ -344,6 +492,8 @@ void coresight_cti_unmap_trigout(struct coresight_cti *cti, int trig, int ch) drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (clk_prepare_enable(drvdata->clk)) return; Loading @@ -353,10 +503,20 @@ void coresight_cti_unmap_trigout(struct coresight_cti *cti, int trig, int ch) goto err; __cti_unmap_trigout(drvdata, trig, ch); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); if (drvdata->gpio_trigout->trig == trig) cti_trigout_gpio_disable(drvdata); mutex_unlock(&drvdata->mutex); return; err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); } EXPORT_SYMBOL(coresight_cti_unmap_trigout); Loading Loading @@ -384,12 +544,15 @@ void coresight_cti_reset(struct coresight_cti *cti) { struct cti_drvdata *drvdata; unsigned long flag; int trig; if (IS_ERR_OR_NULL(cti)) return; drvdata = to_cti_drvdata(cti); mutex_lock(&drvdata->mutex); if (clk_prepare_enable(drvdata->clk)) return; Loading @@ -399,10 +562,24 @@ void coresight_cti_reset(struct coresight_cti *cti) goto err; __cti_reset(drvdata); err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); for (trig = 0; trig < CTI_MAX_TRIGGERS; trig++) { if (drvdata->gpio_trigin->trig == trig) cti_trigin_gpio_disable(drvdata); if (drvdata->gpio_trigout->trig == trig) cti_trigout_gpio_disable(drvdata); } mutex_unlock(&drvdata->mutex); return; err: spin_unlock_irqrestore(&drvdata->spinlock, flag); clk_disable_unprepare(drvdata->clk); mutex_unlock(&drvdata->mutex); } EXPORT_SYMBOL(coresight_cti_reset); Loading Loading @@ -1116,6 +1293,7 @@ static const struct attribute_group *cti_attr_grps[] = { static int cti_probe(struct platform_device *pdev) { int ret, cpu; int trig; struct device *dev = &pdev->dev; struct coresight_platform_data *pdata; struct cti_drvdata *drvdata; Loading Loading @@ -1150,6 +1328,8 @@ static int cti_probe(struct platform_device *pdev) spin_lock_init(&drvdata->spinlock); mutex_init(&drvdata->mutex); drvdata->clk = devm_clk_get(dev, "core_clk"); if (IS_ERR(drvdata->clk)) return PTR_ERR(drvdata->clk); Loading @@ -1158,6 +1338,36 @@ static int cti_probe(struct platform_device *pdev) if (ret) return ret; drvdata->gpio_trigin = devm_kzalloc(dev, sizeof(struct cti_pctrl), GFP_KERNEL); if (!drvdata->gpio_trigin) return -ENOMEM; drvdata->gpio_trigin->trig = -1; if (pdev->dev.of_node) { ret = of_property_read_u32(pdev->dev.of_node, "qcom,cti-gpio-trigin", &trig); if (!ret) drvdata->gpio_trigin->trig = trig; else if (ret != -EINVAL) return ret; } drvdata->gpio_trigout = devm_kzalloc(dev, sizeof(struct cti_pctrl), GFP_KERNEL); if (!drvdata->gpio_trigout) return -ENOMEM; drvdata->gpio_trigout->trig = -1; if (pdev->dev.of_node) { ret = of_property_read_u32(pdev->dev.of_node, "qcom,cti-gpio-trigout", &trig); if (!ret) drvdata->gpio_trigout->trig = trig; else if (ret != -EINVAL) return ret; } if (pdev->dev.of_node) { drvdata->cti_ack_atomic = of_property_read_bool(pdev->dev.of_node, Loading