From ae42ddae882a385c95b9ed890907089c748c1863 Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Fri, 1 Jul 2016 12:53:14 -0700 Subject: [PATCH] mfd: qcom-i2c-pmic: add option to skip irq control Some MFD PMIC configurations do not support interrupts. Make the interrupt controller optional to support these PMIC configrations. Without an interrupt controller this driver simply passes a regmap to its children. CRs-Fixed: 1037797 Change-Id: I52b909dd226494987c79ed106ffdf9892d966ef1 Signed-off-by: Nicholas Troast --- .../devicetree/bindings/mfd/qcom-i2c-pmic.txt | 10 +++++----- drivers/mfd/qcom-i2c-pmic.c | 23 +++++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/qcom-i2c-pmic.txt b/Documentation/devicetree/bindings/mfd/qcom-i2c-pmic.txt index 9c7c856ea42b..7e9aee1a96b3 100644 --- a/Documentation/devicetree/bindings/mfd/qcom-i2c-pmic.txt +++ b/Documentation/devicetree/bindings/mfd/qcom-i2c-pmic.txt @@ -32,29 +32,29 @@ Platform independent properties: Definition: 7-bit I2C address of the device. - interrupt-parent - Usage: required + Usage: optional Value type: Definition: phandle of the interrupt controller which services the summary interrupt. - interrupts - Usage: required + Usage: optional Value type: Definition: Summary interrupt specifier. - interrupt-controller - Usage: required + Usage: optional Value type: Definition: Boolean flag which indicates this device node is an interrupt controller. - #interrupt-cells - Usage: required + Usage: optional Value type: Definition: Number of cells to encode an interrupt source. - qcom,periph-map - Usage: required + Usage: optional Value type: Definition: A list of u32 arrays. This provides a mapping between the summary status register bits and peripheral addresses. diff --git a/drivers/mfd/qcom-i2c-pmic.c b/drivers/mfd/qcom-i2c-pmic.c index 4d0bdce755a6..9eb75d876577 100644 --- a/drivers/mfd/qcom-i2c-pmic.c +++ b/drivers/mfd/qcom-i2c-pmic.c @@ -58,7 +58,6 @@ struct i2c_pmic_periph { struct i2c_pmic { struct device *dev; - struct i2c_client *client; struct regmap *regmap; struct irq_domain *domain; struct i2c_pmic_periph *periph; @@ -497,25 +496,28 @@ static struct regmap_config i2c_pmic_regmap_config = { static int i2c_pmic_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int rc; struct i2c_pmic *chip; + int rc = 0; chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; + chip->dev = &client->dev; chip->regmap = devm_regmap_init_i2c(client, &i2c_pmic_regmap_config); if (!chip->regmap) return -ENODEV; + i2c_set_clientdata(client, chip); + if (!of_property_read_bool(chip->dev->of_node, "interrupt-controller")) + goto probe_children; + chip->domain = irq_domain_add_tree(client->dev.of_node, &i2c_pmic_domain_ops, chip); - if (!chip->domain) - return -ENOMEM; - - chip->client = client; - chip->dev = &client->dev; - i2c_set_clientdata(client, chip); + if (!chip->domain) { + rc = -ENOMEM; + goto cleanup; + } rc = i2c_pmic_parse_dt(chip); if (rc < 0) { @@ -549,6 +551,8 @@ static int i2c_pmic_probe(struct i2c_client *client, } enable_irq_wake(client->irq); + +probe_children: of_platform_populate(chip->dev->of_node, NULL, NULL, chip->dev); pr_info("I2C PMIC probe successful\n"); return rc; @@ -565,7 +569,8 @@ static int i2c_pmic_remove(struct i2c_client *client) struct i2c_pmic *chip = i2c_get_clientdata(client); of_platform_depopulate(chip->dev); - irq_domain_remove(chip->domain); + if (chip->domain) + irq_domain_remove(chip->domain); i2c_set_clientdata(client, NULL); return 0; } -- 2.11.0