gpio: qpnp-gpio: Issue lookups based on device name
qpnp-gpio manages gpio_chip queries based on the slave
ID. This has a limitation in that it restricts the number of
gpio_chips per slave ID to one. However, some PMICs have both MPP
and GPIO on the same slave, and thus the slave ID is not a
meaningful unit to search for.
Instead, make use of the 'label' binding to give the
primary dev-container node a name. This name will serve as the
gpio_chip label, which can be used in lookups.
Change-Id: Ic20caeb4622d73449a983992275446c733ddd89a
Signed-off-by: Michael Bohan <mbohan@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/gpio/qpnp-pin.txt b/Documentation/devicetree/bindings/gpio/qpnp-pin.txt
index 548a5b1..caed9ae 100644
--- a/Documentation/devicetree/bindings/gpio/qpnp-pin.txt
+++ b/Documentation/devicetree/bindings/gpio/qpnp-pin.txt
@@ -19,6 +19,8 @@
- #address-cells: Specify one address field. This must be set to '1'.
- #size-cells: Specify one size-cell. This must be set to '1'.
- compatible = "qcom,qpnp-pin" : Specify driver matching for this driver.
+ - label: String giving the name for the gpio_chip device. This name
+ should be unique on the system and portray the specifics of the device.
-Child Nodes-
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 5573413..8841667 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -30,6 +30,7 @@
#gpio-cells = <2>;
#address-cells = <1>;
#size-cells = <1>;
+ label = "pm8941-gpio";
gpio@c000 {
reg = <0xc000 0x100>;
diff --git a/drivers/gpio/qpnp-pin.c b/drivers/gpio/qpnp-pin.c
index d5a1792..cc72363 100644
--- a/drivers/gpio/qpnp-pin.c
+++ b/drivers/gpio/qpnp-pin.c
@@ -285,8 +285,8 @@
Q_REG_ADDR(q_spec, Q_REG_MODE_CTL),
&q_spec->regs[Q_REG_I_MODE_CTL], Q_NUM_CTL_REGS);
if (rc) {
- dev_err(&q_chip->spmi->dev, "%s: unable to write master"
- " enable\n", __func__);
+ dev_err(&q_chip->spmi->dev, "%s: unable to write master enable\n",
+ __func__);
goto gpio_cfg;
}
@@ -331,14 +331,16 @@
}
EXPORT_SYMBOL(qpnp_pin_config);
-int qpnp_pin_map(uint16_t slave_id, uint32_t pmic_pin)
+#define Q_MAX_CHIP_NAME 128
+int qpnp_pin_map(const char *name, uint32_t pmic_pin)
{
struct qpnp_pin_chip *q_chip;
struct qpnp_pin_spec *q_spec = NULL;
mutex_lock(&qpnp_pin_chips_lock);
list_for_each_entry(q_chip, &qpnp_pin_chips, chip_list) {
- if (q_chip->spmi->sid != slave_id)
+ if (strncmp(q_chip->gpio_chip.label, name,
+ Q_MAX_CHIP_NAME) != 0)
continue;
if (q_chip->pmic_pin_lowest <= pmic_pin &&
q_chip->pmic_pin_highest >= pmic_pin) {
@@ -794,7 +796,7 @@
BUG_ON(Q_NUM_PARAMS != ARRAY_SIZE(dfs_args));
- q_chip->dfs_dir = debugfs_create_dir(dev->of_node->name,
+ q_chip->dfs_dir = debugfs_create_dir(q_chip->gpio_chip.label,
driver_dfs_dir);
if (q_chip->dfs_dir == NULL) {
dev_err(dev, "%s: cannot register chip debugfs directory %s\n",
@@ -828,9 +830,8 @@
}
return 0;
dfs_err:
- dev_err(dev, "%s: cannot register debugfs for pmic gpio %u on"
- " chip %s\n", __func__,
- q_spec->pmic_pin, dev->of_node->name);
+ dev_err(dev, "%s: cannot register debugfs for pmic gpio %u on chip %s\n",
+ __func__, q_spec->pmic_pin, dev->of_node->name);
debugfs_remove_recursive(q_chip->dfs_dir);
return -ENFILE;
}
@@ -851,6 +852,14 @@
int lowest_gpio = UINT_MAX, highest_gpio = 0;
u32 intspec[3], gpio;
char buf[2];
+ const char *dev_name;
+
+ dev_name = spmi_get_primary_dev_name(spmi);
+ if (!dev_name) {
+ dev_err(&spmi->dev, "%s: label binding undefined for node %s\n",
+ __func__, spmi->dev.of_node->full_name);
+ return -EINVAL;
+ }
q_chip = kzalloc(sizeof(*q_chip), GFP_KERNEL);
if (!q_chip) {
@@ -882,8 +891,8 @@
}
if (highest_gpio < lowest_gpio) {
- dev_err(&spmi->dev, "%s: no device nodes specified in"
- " topology\n", __func__);
+ dev_err(&spmi->dev, "%s: no device nodes specified in topology\n",
+ __func__);
rc = -EINVAL;
goto err_probe;
} else if (lowest_gpio == 0) {
@@ -923,8 +932,7 @@
d_node = &spmi->dev_node[i];
res = spmi_get_resource(spmi, d_node, IORESOURCE_MEM, 0);
if (!res) {
- dev_err(&spmi->dev, "%s: node %s is missing has no"
- " base address definition\n",
+ dev_err(&spmi->dev, "%s: node %s is missing has no base address definition\n",
__func__, d_node->of_node->full_name);
}
@@ -939,9 +947,8 @@
q_spec = kzalloc(sizeof(struct qpnp_pin_spec),
GFP_KERNEL);
if (!q_spec) {
- dev_err(&spmi->dev, "%s: unable to allocate"
- " memory\n",
- __func__);
+ dev_err(&spmi->dev, "%s: unable to allocate memory\n",
+ __func__);
rc = -ENOMEM;
goto err_probe;
}
@@ -970,8 +977,8 @@
q_spec->irq = irq_create_of_mapping(q_chip->int_ctrl,
intspec, 3);
if (!q_spec->irq) {
- dev_err(&spmi->dev, "%s: invalid irq for gpio"
- " %u\n", __func__, gpio);
+ dev_err(&spmi->dev, "%s: invalid irq for gpio %u\n",
+ __func__, gpio);
rc = -EINVAL;
goto err_probe;
}
@@ -982,7 +989,7 @@
q_chip->gpio_chip.base = -1;
q_chip->gpio_chip.ngpio = spmi->num_dev_node;
- q_chip->gpio_chip.label = "qpnp-pin";
+ q_chip->gpio_chip.label = dev_name;
q_chip->gpio_chip.direction_input = qpnp_pin_direction_input;
q_chip->gpio_chip.direction_output = qpnp_pin_direction_output;
q_chip->gpio_chip.to_irq = qpnp_pin_to_irq;
diff --git a/include/linux/qpnp/pin.h b/include/linux/qpnp/pin.h
index aaa0ad8..16de80a 100644
--- a/include/linux/qpnp/pin.h
+++ b/include/linux/qpnp/pin.h
@@ -106,11 +106,11 @@
/**
* qpnp_pin_map - Obtain Linux GPIO number from device spec
- * @slave_id: slave_id of the spmi_device for the gpio in question.
+ * @name: Name assigned by the 'label' binding for the primary node.
* @pmic_pin: PMIC pin number to lookup.
*
* This routine is used in legacy configurations that do not support
* Device Tree. If you are using Device Tree, you should not use this.
- * For such cases, use of_get_gpio() instead.
+ * For such cases, use of_get_gpio() or friends instead.
*/
-int qpnp_pin_map(uint16_t slave_id, uint32_t pmic_pin);
+int qpnp_pin_map(const char *name, uint32_t pmic_pin);