of: of_spmi: Add support for spmi-dev-container binding

The spmi-dev-container binding is intended for SPMI
configurations that have multiple device nodes associated with
only one spmi_device. By default, if this flag is not specified,
each device node will create a new spmi_device.

Sometimes having multiple spmi_devices for SPMI device nodes is
superfluous. One example of this is gpios. In some architectures,
a single gpio is treated as a unique device. But from a gpio_chip
perspective, the chip is comprised of many gpios. Beyond wasting
memory allocating a unique spmi_device per gpio, the implication
of not coalescing spmi_devices is that the clients probe() routine
would be called N number of times. But this sort of behavior makes
it difficult to realize when a gpio_chip starts and stops. If we
assume that one gpio_chip represents one call to probe(), then
this problem is solved, since all gpios in that chip will be
passed as resources.

In order to support multiple device nodes per spmi_device, we
also need to extend the data structures for spmi_resources.

This change also makes an effort to cleanup some of the error
handling for illegal combinations of device bindings, as well as
adding some additional documentation.

Change-Id: If3ce2aaaa07bdf79e0d9fdedf16419e74a00fbec
Signed-off-by: Michael Bohan <mbohan@codeaurora.org>
diff --git a/include/linux/of_spmi.h b/include/linux/of_spmi.h
index d07ce63..fe09dec 100644
--- a/include/linux/of_spmi.h
+++ b/include/linux/of_spmi.h
@@ -14,6 +14,17 @@
 #include <linux/of_irq.h>
 
 #ifdef CONFIG_OF_SPMI
+/**
+ * of_spmi_register_devices() - Register devices in the SPMI Device Tree
+ * @ctrl: spmi_controller which devices should be registered to.
+ *
+ * This routine scans the SPMI Device Tree, allocating resources and
+ * creating spmi_devices according to the SPMI bus Device Tree
+ * hierarchy. Details of this hierarchy can be found in
+ * Documentation/devicetree/bindings/spmi. This routine is normally
+ * called from the probe routine of the driver registering as a
+ * spmi_controller.
+ */
 int of_spmi_register_devices(struct spmi_controller *ctrl);
 #else
 static int of_spmi_register_devices(struct spmi_controller *ctrl)
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index ffcb24e..927978a 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -88,24 +88,36 @@
 #define to_spmi_driver(d) container_of(d, struct spmi_driver, driver)
 
 /**
+ * struct spmi_resource: spmi_resource for one device_node
+ * @num_resources: number of resources for this device node
+ * @resources: array of resources for this device_node
+ * @of_node: device_node of the resource in question
+ */
+struct spmi_resource {
+	struct resource		*resource;
+	u32			num_resources;
+	struct device_node	*of_node;
+};
+
+/**
  * Client/device handle (struct spmi_device):
  * ------------------------------------------
- * This is the client/device handle returned when a SPMI device
- * is registered with a controller.
- * Pointer to this structure is used by client-driver as a handle.
- * @dev: driver model representation of the device.
- * @name: name of driver to use with this device.
- * @ctrl: SPMI controller managing the bus hosting this device.
- * @resource: array of resources for this device_node
- * @num_resources: number of resources for this device node
- * @sid: slave identifier.
+ *  This is the client/device handle returned when a SPMI device
+ *  is registered with a controller.
+ *  Pointer to this structure is used by client-driver as a handle.
+ *  @dev: Driver model representation of the device.
+ *  @name: Name of driver to use with this device.
+ *  @ctrl: SPMI controller managing the bus hosting this device.
+ *  @dev_node: array of SPMI resources - one entry per device_node.
+ *  @num_dev_node: number of device_node structures.
+ *  @sid: Slave Identifier.
  */
 struct spmi_device {
 	struct device		dev;
 	const char		*name;
 	struct spmi_controller	*ctrl;
-	struct resource		*resource;
-	u32			num_resources;
+	struct spmi_resource	*dev_node;
+	u32			num_dev_node;
 	u8			sid;
 };
 #define to_spmi_device(d) container_of(d, struct spmi_device, dev)
@@ -115,16 +127,16 @@
  * @slave_id: slave identifier.
  * @spmi_device: device to be registered with the SPMI framework.
  * @of_node: pointer to the OpenFirmware device node.
- * @num_resources: number of resources for this device node
- * @resource: array of resources for this device_node
+ * @dev_node: one spmi_resource for each device_node.
+ * @num_dev_node: number of device_node structures.
  * @platform_data: goes to spmi_device.dev.platform_data
  */
 struct spmi_boardinfo {
 	char			name[SPMI_NAME_SIZE];
 	uint8_t			slave_id;
 	struct device_node	*of_node;
-	u32			num_resources;
-	struct resource		*resource;
+	struct spmi_resource	*dev_node;
+	u32			num_dev_node;
 	const void		*platform_data;
 };