diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2019-03-18 13:31:24 -0400 |
---|---|---|
committer | Florian Fainelli <f.fainelli@gmail.com> | 2019-03-18 13:31:24 -0400 |
commit | 4823a031f096d6d5fd16fccd8a3dd51b05a6becf (patch) | |
tree | 6cd1ecc3300a60c03e971065bcbbf77164b514a9 | |
parent | 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b (diff) | |
parent | 7a9b6be9fe58194d9a349159176e8cc0d8f10ef8 (diff) |
Merge tag 'tags/bcm2835-drivers-next-2019-03-12' into soc/fixes
This pull request brings in a build fix for arm64 with bcm2835
enabled, and fixes the driver in the presence of -EPROBE_DEFER.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-rw-r--r-- | arch/arm64/Kconfig.platforms | 1 | ||||
-rw-r--r-- | drivers/soc/bcm/bcm2835-power.c | 49 |
2 files changed, 43 insertions, 7 deletions
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 70498a033cf5..b5ca9c50876d 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms | |||
@@ -27,6 +27,7 @@ config ARCH_BCM2835 | |||
27 | bool "Broadcom BCM2835 family" | 27 | bool "Broadcom BCM2835 family" |
28 | select TIMER_OF | 28 | select TIMER_OF |
29 | select GPIOLIB | 29 | select GPIOLIB |
30 | select MFD_CORE | ||
30 | select PINCTRL | 31 | select PINCTRL |
31 | select PINCTRL_BCM2835 | 32 | select PINCTRL_BCM2835 |
32 | select ARM_AMBA | 33 | select ARM_AMBA |
diff --git a/drivers/soc/bcm/bcm2835-power.c b/drivers/soc/bcm/bcm2835-power.c index 9351349cf0a9..1e0041ec8132 100644 --- a/drivers/soc/bcm/bcm2835-power.c +++ b/drivers/soc/bcm/bcm2835-power.c | |||
@@ -150,7 +150,12 @@ struct bcm2835_power { | |||
150 | 150 | ||
151 | static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg) | 151 | static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg) |
152 | { | 152 | { |
153 | u64 start = ktime_get_ns(); | 153 | u64 start; |
154 | |||
155 | if (!reg) | ||
156 | return 0; | ||
157 | |||
158 | start = ktime_get_ns(); | ||
154 | 159 | ||
155 | /* Enable the module's async AXI bridges. */ | 160 | /* Enable the module's async AXI bridges. */ |
156 | ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP); | 161 | ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP); |
@@ -165,7 +170,12 @@ static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg) | |||
165 | 170 | ||
166 | static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg) | 171 | static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg) |
167 | { | 172 | { |
168 | u64 start = ktime_get_ns(); | 173 | u64 start; |
174 | |||
175 | if (!reg) | ||
176 | return 0; | ||
177 | |||
178 | start = ktime_get_ns(); | ||
169 | 179 | ||
170 | /* Enable the module's async AXI bridges. */ | 180 | /* Enable the module's async AXI bridges. */ |
171 | ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP); | 181 | ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP); |
@@ -475,7 +485,7 @@ static int bcm2835_power_pd_power_off(struct generic_pm_domain *domain) | |||
475 | } | 485 | } |
476 | } | 486 | } |
477 | 487 | ||
478 | static void | 488 | static int |
479 | bcm2835_init_power_domain(struct bcm2835_power *power, | 489 | bcm2835_init_power_domain(struct bcm2835_power *power, |
480 | int pd_xlate_index, const char *name) | 490 | int pd_xlate_index, const char *name) |
481 | { | 491 | { |
@@ -483,6 +493,17 @@ bcm2835_init_power_domain(struct bcm2835_power *power, | |||
483 | struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index]; | 493 | struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index]; |
484 | 494 | ||
485 | dom->clk = devm_clk_get(dev->parent, name); | 495 | dom->clk = devm_clk_get(dev->parent, name); |
496 | if (IS_ERR(dom->clk)) { | ||
497 | int ret = PTR_ERR(dom->clk); | ||
498 | |||
499 | if (ret == -EPROBE_DEFER) | ||
500 | return ret; | ||
501 | |||
502 | /* Some domains don't have a clk, so make sure that we | ||
503 | * don't deref an error pointer later. | ||
504 | */ | ||
505 | dom->clk = NULL; | ||
506 | } | ||
486 | 507 | ||
487 | dom->base.name = name; | 508 | dom->base.name = name; |
488 | dom->base.power_on = bcm2835_power_pd_power_on; | 509 | dom->base.power_on = bcm2835_power_pd_power_on; |
@@ -495,6 +516,8 @@ bcm2835_init_power_domain(struct bcm2835_power *power, | |||
495 | pm_genpd_init(&dom->base, NULL, true); | 516 | pm_genpd_init(&dom->base, NULL, true); |
496 | 517 | ||
497 | power->pd_xlate.domains[pd_xlate_index] = &dom->base; | 518 | power->pd_xlate.domains[pd_xlate_index] = &dom->base; |
519 | |||
520 | return 0; | ||
498 | } | 521 | } |
499 | 522 | ||
500 | /** bcm2835_reset_reset - Resets a block that has a reset line in the | 523 | /** bcm2835_reset_reset - Resets a block that has a reset line in the |
@@ -592,7 +615,7 @@ static int bcm2835_power_probe(struct platform_device *pdev) | |||
592 | { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM0 }, | 615 | { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM0 }, |
593 | { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM1 }, | 616 | { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM1 }, |
594 | }; | 617 | }; |
595 | int ret, i; | 618 | int ret = 0, i; |
596 | u32 id; | 619 | u32 id; |
597 | 620 | ||
598 | power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); | 621 | power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); |
@@ -619,8 +642,11 @@ static int bcm2835_power_probe(struct platform_device *pdev) | |||
619 | 642 | ||
620 | power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names); | 643 | power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names); |
621 | 644 | ||
622 | for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) | 645 | for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) { |
623 | bcm2835_init_power_domain(power, i, power_domain_names[i]); | 646 | ret = bcm2835_init_power_domain(power, i, power_domain_names[i]); |
647 | if (ret) | ||
648 | goto fail; | ||
649 | } | ||
624 | 650 | ||
625 | for (i = 0; i < ARRAY_SIZE(domain_deps); i++) { | 651 | for (i = 0; i < ARRAY_SIZE(domain_deps); i++) { |
626 | pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base, | 652 | pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base, |
@@ -634,12 +660,21 @@ static int bcm2835_power_probe(struct platform_device *pdev) | |||
634 | 660 | ||
635 | ret = devm_reset_controller_register(dev, &power->reset); | 661 | ret = devm_reset_controller_register(dev, &power->reset); |
636 | if (ret) | 662 | if (ret) |
637 | return ret; | 663 | goto fail; |
638 | 664 | ||
639 | of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate); | 665 | of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate); |
640 | 666 | ||
641 | dev_info(dev, "Broadcom BCM2835 power domains driver"); | 667 | dev_info(dev, "Broadcom BCM2835 power domains driver"); |
642 | return 0; | 668 | return 0; |
669 | |||
670 | fail: | ||
671 | for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) { | ||
672 | struct generic_pm_domain *dom = &power->domains[i].base; | ||
673 | |||
674 | if (dom->name) | ||
675 | pm_genpd_remove(dom); | ||
676 | } | ||
677 | return ret; | ||
643 | } | 678 | } |
644 | 679 | ||
645 | static int bcm2835_power_remove(struct platform_device *pdev) | 680 | static int bcm2835_power_remove(struct platform_device *pdev) |