aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/firmware/qcom,scm.txt2
-rw-r--r--drivers/firmware/qcom_scm.c49
2 files changed, 39 insertions, 12 deletions
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
index 3b4436e56865..20f26fbce875 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
@@ -10,8 +10,10 @@ Required properties:
10 * "qcom,scm-apq8064" for APQ8064 platforms 10 * "qcom,scm-apq8064" for APQ8064 platforms
11 * "qcom,scm-msm8660" for MSM8660 platforms 11 * "qcom,scm-msm8660" for MSM8660 platforms
12 * "qcom,scm-msm8690" for MSM8690 platforms 12 * "qcom,scm-msm8690" for MSM8690 platforms
13 * "qcom,scm-msm8996" for MSM8996 platforms
13 * "qcom,scm" for later processors (MSM8916, APQ8084, MSM8974, etc) 14 * "qcom,scm" for later processors (MSM8916, APQ8084, MSM8974, etc)
14- clocks: One to three clocks may be required based on compatible. 15- clocks: One to three clocks may be required based on compatible.
16 * No clock required for "qcom,scm-msm8996"
15 * Only core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660", and "qcom,scm-msm8960" 17 * Only core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660", and "qcom,scm-msm8960"
16 * Core, iface, and bus clocks required for "qcom,scm" 18 * Core, iface, and bus clocks required for "qcom,scm"
17- clock-names: Must contain "core" for the core clock, "iface" for the interface 19- clock-names: Must contain "core" for the core clock, "iface" for the interface
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 9bf66aefdbd0..893f953eaccf 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -28,6 +28,10 @@
28 28
29#include "qcom_scm.h" 29#include "qcom_scm.h"
30 30
31#define SCM_HAS_CORE_CLK BIT(0)
32#define SCM_HAS_IFACE_CLK BIT(1)
33#define SCM_HAS_BUS_CLK BIT(2)
34
31struct qcom_scm { 35struct qcom_scm {
32 struct device *dev; 36 struct device *dev;
33 struct clk *core_clk; 37 struct clk *core_clk;
@@ -323,32 +327,40 @@ EXPORT_SYMBOL(qcom_scm_is_available);
323static int qcom_scm_probe(struct platform_device *pdev) 327static int qcom_scm_probe(struct platform_device *pdev)
324{ 328{
325 struct qcom_scm *scm; 329 struct qcom_scm *scm;
330 unsigned long clks;
326 int ret; 331 int ret;
327 332
328 scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL); 333 scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL);
329 if (!scm) 334 if (!scm)
330 return -ENOMEM; 335 return -ENOMEM;
331 336
332 scm->core_clk = devm_clk_get(&pdev->dev, "core"); 337 clks = (unsigned long)of_device_get_match_data(&pdev->dev);
333 if (IS_ERR(scm->core_clk)) { 338 if (clks & SCM_HAS_CORE_CLK) {
334 if (PTR_ERR(scm->core_clk) == -EPROBE_DEFER) 339 scm->core_clk = devm_clk_get(&pdev->dev, "core");
340 if (IS_ERR(scm->core_clk)) {
341 if (PTR_ERR(scm->core_clk) != -EPROBE_DEFER)
342 dev_err(&pdev->dev,
343 "failed to acquire core clk\n");
335 return PTR_ERR(scm->core_clk); 344 return PTR_ERR(scm->core_clk);
336 345 }
337 scm->core_clk = NULL;
338 } 346 }
339 347
340 if (of_device_is_compatible(pdev->dev.of_node, "qcom,scm")) { 348 if (clks & SCM_HAS_IFACE_CLK) {
341 scm->iface_clk = devm_clk_get(&pdev->dev, "iface"); 349 scm->iface_clk = devm_clk_get(&pdev->dev, "iface");
342 if (IS_ERR(scm->iface_clk)) { 350 if (IS_ERR(scm->iface_clk)) {
343 if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER) 351 if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER)
344 dev_err(&pdev->dev, "failed to acquire iface clk\n"); 352 dev_err(&pdev->dev,
353 "failed to acquire iface clk\n");
345 return PTR_ERR(scm->iface_clk); 354 return PTR_ERR(scm->iface_clk);
346 } 355 }
356 }
347 357
358 if (clks & SCM_HAS_BUS_CLK) {
348 scm->bus_clk = devm_clk_get(&pdev->dev, "bus"); 359 scm->bus_clk = devm_clk_get(&pdev->dev, "bus");
349 if (IS_ERR(scm->bus_clk)) { 360 if (IS_ERR(scm->bus_clk)) {
350 if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER) 361 if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER)
351 dev_err(&pdev->dev, "failed to acquire bus clk\n"); 362 dev_err(&pdev->dev,
363 "failed to acquire bus clk\n");
352 return PTR_ERR(scm->bus_clk); 364 return PTR_ERR(scm->bus_clk);
353 } 365 }
354 } 366 }
@@ -374,10 +386,23 @@ static int qcom_scm_probe(struct platform_device *pdev)
374} 386}
375 387
376static const struct of_device_id qcom_scm_dt_match[] = { 388static const struct of_device_id qcom_scm_dt_match[] = {
377 { .compatible = "qcom,scm-apq8064",}, 389 { .compatible = "qcom,scm-apq8064",
378 { .compatible = "qcom,scm-msm8660",}, 390 .data = (void *) SCM_HAS_CORE_CLK,
379 { .compatible = "qcom,scm-msm8960",}, 391 },
380 { .compatible = "qcom,scm",}, 392 { .compatible = "qcom,scm-msm8660",
393 .data = (void *) SCM_HAS_CORE_CLK,
394 },
395 { .compatible = "qcom,scm-msm8960",
396 .data = (void *) SCM_HAS_CORE_CLK,
397 },
398 { .compatible = "qcom,scm-msm8996",
399 .data = NULL, /* no clocks */
400 },
401 { .compatible = "qcom,scm",
402 .data = (void *)(SCM_HAS_CORE_CLK
403 | SCM_HAS_IFACE_CLK
404 | SCM_HAS_BUS_CLK),
405 },
381 {} 406 {}
382}; 407};
383 408