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);