Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Documentation/devicetree/bindings/regulator/qcom,wcn3990-pmu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ properties:
maxItems: 1
description: GPIO line indicating the state of the clock supply to the BT module

interrupts:
maxItems: 1
description: SW_CTRL wake interrupt, asserted when the WCN chip is active

interrupt-names:
const: wakeup

wakeup-source:
type: boolean
description:
Mark the PMU as a wakeup source. Requires the "wakeup" interrupt to be
present. When set, the SW_CTRL IRQ is used to wake the application
processor from system suspend.

clocks:
maxItems: 1
description: Reference clock handle
Expand All @@ -67,6 +81,14 @@ required:
- vddrf-supply
- vddch0-supply

dependencies:
wakeup-source:
required:
- interrupt-names
anyOf:
- required: [interrupts]
- required: [interrupts-extended]

additionalProperties: false

examples:
Expand Down
4 changes: 4 additions & 0 deletions arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "shikra-cqm-som.dtsi"
#include "shikra-evk.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/net/ti-dp83867.h>

/ {
Expand Down Expand Up @@ -140,6 +141,9 @@
vddch0-supply = <&pm4125_l22>;

swctrl-gpios = <&tlmm 88 GPIO_ACTIVE_HIGH>;
interrupts-extended = <&tlmm 88 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "wakeup";
wakeup-source;

regulators {
vreg_pmu_io: ldo0 {
Expand Down
4 changes: 4 additions & 0 deletions arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "shikra-cqm-som.dtsi"
#include "shikra-evk.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/net/ti-dp83867.h>

/ {
Expand Down Expand Up @@ -122,6 +123,9 @@
vddch0-supply = <&pm4125_l22>;

swctrl-gpios = <&tlmm 88 GPIO_ACTIVE_HIGH>;
interrupts-extended = <&tlmm 88 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "wakeup";
wakeup-source;

regulators {
vreg_pmu_io: ldo0 {
Expand Down
3 changes: 3 additions & 0 deletions arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@
vddch0-supply = <&vreg_wcn_3p3>;

swctrl-gpios = <&tlmm 88 GPIO_ACTIVE_HIGH>;
interrupts-extended = <&tlmm 88 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "wakeup";
wakeup-source;

regulators {
vreg_pmu_io: ldo0 {
Expand Down
30 changes: 30 additions & 0 deletions drivers/power/sequencing/pwrseq-qcom-wcn.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/pm_wakeup.h>
#include <linux/regulator/consumer.h>
#include <linux/pwrseq/provider.h>
#include <linux/string.h>
Expand Down Expand Up @@ -454,11 +456,17 @@ static int pwrseq_qcom_wcn3990_match(struct pwrseq_device *pwrseq,
return pwrseq_qcom_wcn_match_regulator(pwrseq, dev, "vdd-1.8-xo-supply");
}

static void pwrseq_qcom_wcn_clear_wake_irq(void *data)
{
dev_pm_clear_wake_irq(data);
}

static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pwrseq_qcom_wcn_ctx *ctx;
struct pwrseq_config config;
int wake_irq;
int i, ret;

ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
Expand Down Expand Up @@ -496,6 +504,28 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(ctx->bt_gpio),
"Failed to get the Bluetooth enable GPIO\n");

if (of_property_read_bool(dev->of_node, "wakeup-source")) {
wake_irq = platform_get_irq_byname(pdev, "wakeup");
if (wake_irq < 0)
return dev_err_probe(dev, wake_irq,
"Failed to get the SW_CTRL wake IRQ\n");

ret = devm_device_init_wakeup(dev);
if (ret)
return dev_err_probe(dev, ret,
"Failed to enable wakeup\n");

ret = dev_pm_set_dedicated_wake_irq(dev, wake_irq);
if (ret)
return dev_err_probe(dev, ret,
"Failed to set the SW_CTRL wake IRQ\n");

ret = devm_add_action_or_reset(dev,
pwrseq_qcom_wcn_clear_wake_irq, dev);
if (ret)
return ret;
}

/*
* FIXME: This should actually be GPIOD_OUT_LOW, but doing so would
* cause the WLAN power to be toggled, resulting in PCIe link down.
Expand Down