Message ID | 1402410717-12977-1-git-send-email-srinivas.kandagatla@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Jun 10, 2014, at 9:31 AM, Srinivas Kandagatla <srinivas.kandagatla@linaro.org> wrote: > The use case here is when we have a bootconsole which is printing the > characters on serial console and gsbi driver comes up after some time. > As gsbi driver disables the clock in probe the bootconsole locks up. > > This patch fixes the problem by disabling the clock in platform remove > rather than in probe. > > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > --- > drivers/soc/qcom/qcom_gsbi.c | 46 +++++++++++++++++++++++++++++++------------- > 1 file changed, 33 insertions(+), 13 deletions(-) It seems like we shouldn’t need this change. Adding Stephen to see if there is a reason we don’t have the clk’s enable_count adjusted for how the bootloader setup clks. - k > > diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c > index ab7b441..64fb298 100644 > --- a/drivers/soc/qcom/qcom_gsbi.c > +++ b/drivers/soc/qcom/qcom_gsbi.c > @@ -22,44 +22,63 @@ > #define GSBI_CTRL_REG 0x0000 > #define GSBI_PROTOCOL_SHIFT 4 > > +struct gsbi_info { > + struct clk *hclk; > + u32 mode; > + u32 crci; > +}; > + > static int gsbi_probe(struct platform_device *pdev) > { > struct device_node *node = pdev->dev.of_node; > struct resource *res; > void __iomem *base; > - struct clk *hclk; > - u32 mode, crci = 0; > + struct gsbi_info *gsbi; > + > + gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL); > + > + if (!gsbi) > + return -ENOMEM; > > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > base = devm_ioremap_resource(&pdev->dev, res); > if (IS_ERR(base)) > return PTR_ERR(base); > > - if (of_property_read_u32(node, "qcom,mode", &mode)) { > + if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) { > dev_err(&pdev->dev, "missing mode configuration\n"); > return -EINVAL; > } > > /* not required, so default to 0 if not present */ > - of_property_read_u32(node, "qcom,crci", &crci); > + of_property_read_u32(node, "qcom,crci", &gsbi->crci); > > - dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", mode, crci); > + dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", > + gsbi->mode, gsbi->crci); > + gsbi->hclk = devm_clk_get(&pdev->dev, "iface"); > + if (IS_ERR(gsbi->hclk)) > + return PTR_ERR(gsbi->hclk); > > - hclk = devm_clk_get(&pdev->dev, "iface"); > - if (IS_ERR(hclk)) > - return PTR_ERR(hclk); > + clk_prepare_enable(gsbi->hclk); > > - clk_prepare_enable(hclk); > - > - writel_relaxed((mode << GSBI_PROTOCOL_SHIFT) | crci, > + writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci, > base + GSBI_CTRL_REG); > > /* make sure the gsbi control write is not reordered */ > wmb(); > > - clk_disable_unprepare(hclk); > + platform_set_drvdata(pdev, gsbi); > + > + return of_platform_populate(node, NULL, NULL, &pdev->dev); > +} > + > +static int gsbi_remove(struct platform_device *pdev) > +{ > + struct gsbi_info *gsbi = platform_get_drvdata(pdev); > + > + clk_disable_unprepare(gsbi->hclk); > > - return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); > + return 0; > } > > static const struct of_device_id gsbi_dt_match[] = { > @@ -76,6 +95,7 @@ static struct platform_driver gsbi_driver = { > .of_match_table = gsbi_dt_match, > }, > .probe = gsbi_probe, > + .remove = gsbi_remove, > }; > > module_platform_driver(gsbi_driver); > -- > 1.9.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
On 06/10/14 08:20, Kumar Gala wrote: > On Jun 10, 2014, at 9:31 AM, Srinivas Kandagatla <srinivas.kandagatla@linaro.org> wrote: > >> The use case here is when we have a bootconsole which is printing the >> characters on serial console and gsbi driver comes up after some time. >> As gsbi driver disables the clock in probe the bootconsole locks up. >> >> This patch fixes the problem by disabling the clock in platform remove >> rather than in probe. >> >> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> >> --- >> drivers/soc/qcom/qcom_gsbi.c | 46 +++++++++++++++++++++++++++++++------------- >> 1 file changed, 33 insertions(+), 13 deletions(-) > It seems like we shouldn’t need this change. Adding Stephen to see if there is a reason we don’t have the clk’s enable_count adjusted for how the bootloader setup clks. This is a long standing problem with the clock framework. In our vendor tree we've added something called "handoff" which basically detects the state of all clocks upon registration and keeps clocks enabled until late_init() if the clocks were enabled at the time of registration. For this case though "handoff" doesn't seem necessary. It's easier to just disable the clock when the driver is removed. With finer grained power management this driver can participate in runtime_pm and disable the ahb clock when the device is runtime suspended; which would only happen when the child devices (uart/spi/i2c) are also runtime suspended. > - k > >> diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c >> index ab7b441..64fb298 100644 >> --- a/drivers/soc/qcom/qcom_gsbi.c >> +++ b/drivers/soc/qcom/qcom_gsbi.c >> @@ -22,44 +22,63 @@ >> #define GSBI_CTRL_REG 0x0000 >> #define GSBI_PROTOCOL_SHIFT 4 >> >> +struct gsbi_info { >> + struct clk *hclk; >> + u32 mode; >> + u32 crci; >> +}; What does mode and crci have to do with this patch? Can't we just put the clock into the platform data?
On Tue, Jun 10, 2014 at 10:39:02AM -0700, Stephen Boyd wrote: <snip> > >> diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c > >> index ab7b441..64fb298 100644 > >> --- a/drivers/soc/qcom/qcom_gsbi.c > >> +++ b/drivers/soc/qcom/qcom_gsbi.c > >> @@ -22,44 +22,63 @@ > >> #define GSBI_CTRL_REG 0x0000 > >> #define GSBI_PROTOCOL_SHIFT 4 > >> > >> +struct gsbi_info { > >> + struct clk *hclk; > >> + u32 mode; > >> + u32 crci; > >> +}; > > What does mode and crci have to do with this patch? Can't we just put > the clock into the platform data? I second this notion.
On 10/06/14 18:39, Stephen Boyd wrote: > On 06/10/14 08:20, Kumar Gala wrote: >> On Jun 10, 2014, at 9:31 AM, Srinivas Kandagatla <srinivas.kandagatla@linaro.org> wrote: >> >>> The use case here is when we have a bootconsole which is printing the >>> characters on serial console and gsbi driver comes up after some time. >>> As gsbi driver disables the clock in probe the bootconsole locks up. >>> >>> This patch fixes the problem by disabling the clock in platform remove >>> rather than in probe. >>> >>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> >>> --- >>> drivers/soc/qcom/qcom_gsbi.c | 46 +++++++++++++++++++++++++++++++------------- >>> 1 file changed, 33 insertions(+), 13 deletions(-) >> It seems like we shouldn’t need this change. Adding Stephen to see if there is a reason we don’t have the clk’s enable_count adjusted for how the bootloader setup clks. > > This is a long standing problem with the clock framework. In our vendor > tree we've added something called "handoff" which basically detects the > state of all clocks upon registration and keeps clocks enabled until > late_init() if the clocks were enabled at the time of registration. > > For this case though "handoff" doesn't seem necessary. It's easier to > just disable the clock when the driver is removed. With finer grained > power management this driver can participate in runtime_pm and disable > the ahb clock when the device is runtime suspended; which would only > happen when the child devices (uart/spi/i2c) are also runtime suspended. I had same thought about gsbi participating in PM. > >> - k >> >>> diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c >>> index ab7b441..64fb298 100644 >>> --- a/drivers/soc/qcom/qcom_gsbi.c >>> +++ b/drivers/soc/qcom/qcom_gsbi.c >>> @@ -22,44 +22,63 @@ >>> #define GSBI_CTRL_REG 0x0000 >>> #define GSBI_PROTOCOL_SHIFT 4 >>> >>> +struct gsbi_info { >>> + struct clk *hclk; >>> + u32 mode; >>> + u32 crci; >>> +}; > > What does mode and crci have to do with this patch? Can't we just put > the clock into the platform data? It has nothing to do with this but, for completeness and we might need this if we are doing PM in future. for example pm resume might want to reconfigure the gsbi. Am Ok with either approaches. --srini > -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Jun 10, 2014 at 06:47:29PM +0100, Srinivas Kandagatla wrote: <snip> > >What does mode and crci have to do with this patch? Can't we just put > >the clock into the platform data? > It has nothing to do with this but, for completeness and we might > need this if we are doing PM in future. for example pm resume might > want to reconfigure the gsbi. Yes, setting idle mode would save some power.
Hi Andy, Do you know who is going to queue this patch for 3.17? thanks, srini On 10/06/14 15:31, Srinivas Kandagatla wrote: > The use case here is when we have a bootconsole which is printing the > characters on serial console and gsbi driver comes up after some time. > As gsbi driver disables the clock in probe the bootconsole locks up. > > This patch fixes the problem by disabling the clock in platform remove > rather than in probe. > > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > --- > drivers/soc/qcom/qcom_gsbi.c | 46 +++++++++++++++++++++++++++++++------------- > 1 file changed, 33 insertions(+), 13 deletions(-) > > diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c > index ab7b441..64fb298 100644 > --- a/drivers/soc/qcom/qcom_gsbi.c > +++ b/drivers/soc/qcom/qcom_gsbi.c > @@ -22,44 +22,63 @@ > #define GSBI_CTRL_REG 0x0000 > #define GSBI_PROTOCOL_SHIFT 4 > > +struct gsbi_info { > + struct clk *hclk; > + u32 mode; > + u32 crci; > +}; > + > static int gsbi_probe(struct platform_device *pdev) > { > struct device_node *node = pdev->dev.of_node; > struct resource *res; > void __iomem *base; > - struct clk *hclk; > - u32 mode, crci = 0; > + struct gsbi_info *gsbi; > + > + gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL); > + > + if (!gsbi) > + return -ENOMEM; > > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > base = devm_ioremap_resource(&pdev->dev, res); > if (IS_ERR(base)) > return PTR_ERR(base); > > - if (of_property_read_u32(node, "qcom,mode", &mode)) { > + if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) { > dev_err(&pdev->dev, "missing mode configuration\n"); > return -EINVAL; > } > > /* not required, so default to 0 if not present */ > - of_property_read_u32(node, "qcom,crci", &crci); > + of_property_read_u32(node, "qcom,crci", &gsbi->crci); > > - dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", mode, crci); > + dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", > + gsbi->mode, gsbi->crci); > + gsbi->hclk = devm_clk_get(&pdev->dev, "iface"); > + if (IS_ERR(gsbi->hclk)) > + return PTR_ERR(gsbi->hclk); > > - hclk = devm_clk_get(&pdev->dev, "iface"); > - if (IS_ERR(hclk)) > - return PTR_ERR(hclk); > + clk_prepare_enable(gsbi->hclk); > > - clk_prepare_enable(hclk); > - > - writel_relaxed((mode << GSBI_PROTOCOL_SHIFT) | crci, > + writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci, > base + GSBI_CTRL_REG); > > /* make sure the gsbi control write is not reordered */ > wmb(); > > - clk_disable_unprepare(hclk); > + platform_set_drvdata(pdev, gsbi); > + > + return of_platform_populate(node, NULL, NULL, &pdev->dev); > +} > + > +static int gsbi_remove(struct platform_device *pdev) > +{ > + struct gsbi_info *gsbi = platform_get_drvdata(pdev); > + > + clk_disable_unprepare(gsbi->hclk); > > - return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); > + return 0; > } > > static const struct of_device_id gsbi_dt_match[] = { > @@ -76,6 +95,7 @@ static struct platform_driver gsbi_driver = { > .of_match_table = gsbi_dt_match, > }, > .probe = gsbi_probe, > + .remove = gsbi_remove, > }; > > module_platform_driver(gsbi_driver); > -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Andy/Kumar, If its not too late, Can we queue this fix for 3.17-rc1 or rc2? thanks, srini On 10/06/14 15:31, Srinivas Kandagatla wrote: > The use case here is when we have a bootconsole which is printing the > characters on serial console and gsbi driver comes up after some time. > As gsbi driver disables the clock in probe the bootconsole locks up. > > This patch fixes the problem by disabling the clock in platform remove > rather than in probe. > > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > --- > drivers/soc/qcom/qcom_gsbi.c | 46 +++++++++++++++++++++++++++++++------------- > 1 file changed, 33 insertions(+), 13 deletions(-) > > diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c > index ab7b441..64fb298 100644 > --- a/drivers/soc/qcom/qcom_gsbi.c > +++ b/drivers/soc/qcom/qcom_gsbi.c > @@ -22,44 +22,63 @@ > #define GSBI_CTRL_REG 0x0000 > #define GSBI_PROTOCOL_SHIFT 4 > > +struct gsbi_info { > + struct clk *hclk; > + u32 mode; > + u32 crci; > +}; > + > static int gsbi_probe(struct platform_device *pdev) > { > struct device_node *node = pdev->dev.of_node; > struct resource *res; > void __iomem *base; > - struct clk *hclk; > - u32 mode, crci = 0; > + struct gsbi_info *gsbi; > + > + gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL); > + > + if (!gsbi) > + return -ENOMEM; > > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > base = devm_ioremap_resource(&pdev->dev, res); > if (IS_ERR(base)) > return PTR_ERR(base); > > - if (of_property_read_u32(node, "qcom,mode", &mode)) { > + if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) { > dev_err(&pdev->dev, "missing mode configuration\n"); > return -EINVAL; > } > > /* not required, so default to 0 if not present */ > - of_property_read_u32(node, "qcom,crci", &crci); > + of_property_read_u32(node, "qcom,crci", &gsbi->crci); > > - dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", mode, crci); > + dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", > + gsbi->mode, gsbi->crci); > + gsbi->hclk = devm_clk_get(&pdev->dev, "iface"); > + if (IS_ERR(gsbi->hclk)) > + return PTR_ERR(gsbi->hclk); > > - hclk = devm_clk_get(&pdev->dev, "iface"); > - if (IS_ERR(hclk)) > - return PTR_ERR(hclk); > + clk_prepare_enable(gsbi->hclk); > > - clk_prepare_enable(hclk); > - > - writel_relaxed((mode << GSBI_PROTOCOL_SHIFT) | crci, > + writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci, > base + GSBI_CTRL_REG); > > /* make sure the gsbi control write is not reordered */ > wmb(); > > - clk_disable_unprepare(hclk); > + platform_set_drvdata(pdev, gsbi); > + > + return of_platform_populate(node, NULL, NULL, &pdev->dev); > +} > + > +static int gsbi_remove(struct platform_device *pdev) > +{ > + struct gsbi_info *gsbi = platform_get_drvdata(pdev); > + > + clk_disable_unprepare(gsbi->hclk); > > - return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); > + return 0; > } > > static const struct of_device_id gsbi_dt_match[] = { > @@ -76,6 +95,7 @@ static struct platform_driver gsbi_driver = { > .of_match_table = gsbi_dt_match, > }, > .probe = gsbi_probe, > + .remove = gsbi_remove, > }; > > module_platform_driver(gsbi_driver); > -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c index ab7b441..64fb298 100644 --- a/drivers/soc/qcom/qcom_gsbi.c +++ b/drivers/soc/qcom/qcom_gsbi.c @@ -22,44 +22,63 @@ #define GSBI_CTRL_REG 0x0000 #define GSBI_PROTOCOL_SHIFT 4 +struct gsbi_info { + struct clk *hclk; + u32 mode; + u32 crci; +}; + static int gsbi_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct resource *res; void __iomem *base; - struct clk *hclk; - u32 mode, crci = 0; + struct gsbi_info *gsbi; + + gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL); + + if (!gsbi) + return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); - if (of_property_read_u32(node, "qcom,mode", &mode)) { + if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) { dev_err(&pdev->dev, "missing mode configuration\n"); return -EINVAL; } /* not required, so default to 0 if not present */ - of_property_read_u32(node, "qcom,crci", &crci); + of_property_read_u32(node, "qcom,crci", &gsbi->crci); - dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", mode, crci); + dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", + gsbi->mode, gsbi->crci); + gsbi->hclk = devm_clk_get(&pdev->dev, "iface"); + if (IS_ERR(gsbi->hclk)) + return PTR_ERR(gsbi->hclk); - hclk = devm_clk_get(&pdev->dev, "iface"); - if (IS_ERR(hclk)) - return PTR_ERR(hclk); + clk_prepare_enable(gsbi->hclk); - clk_prepare_enable(hclk); - - writel_relaxed((mode << GSBI_PROTOCOL_SHIFT) | crci, + writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci, base + GSBI_CTRL_REG); /* make sure the gsbi control write is not reordered */ wmb(); - clk_disable_unprepare(hclk); + platform_set_drvdata(pdev, gsbi); + + return of_platform_populate(node, NULL, NULL, &pdev->dev); +} + +static int gsbi_remove(struct platform_device *pdev) +{ + struct gsbi_info *gsbi = platform_get_drvdata(pdev); + + clk_disable_unprepare(gsbi->hclk); - return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + return 0; } static const struct of_device_id gsbi_dt_match[] = { @@ -76,6 +95,7 @@ static struct platform_driver gsbi_driver = { .of_match_table = gsbi_dt_match, }, .probe = gsbi_probe, + .remove = gsbi_remove, }; module_platform_driver(gsbi_driver);
The use case here is when we have a bootconsole which is printing the characters on serial console and gsbi driver comes up after some time. As gsbi driver disables the clock in probe the bootconsole locks up. This patch fixes the problem by disabling the clock in platform remove rather than in probe. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> --- drivers/soc/qcom/qcom_gsbi.c | 46 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-)