aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2014-06-10 15:02:39 +0100
committerAndrey Konovalov <andrey.konovalov@linaro.org>2014-07-25 20:54:47 +0400
commit4e8b6bbe71f7721dc87dfb471525d066d49271b8 (patch)
treeadbc7d15445270a62720b977a97485d4d5583655
parent3850b119ebed7188d4b7b51355378fd2de0f7909 (diff)
soc: qcom: do not disable the iface clock in probe
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>
-rw-r--r--drivers/soc/qcom/qcom_gsbi.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c
index 447458e696a9..7e1f120f2b32 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);