All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] mfd: tps65912: Driver rewrite with DT support
@ 2015-09-24 14:52 ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

In an effort to cleanup this driver and add Device Tree support
the driver has been rewritten based on new driver styles and
modern kernel driver helpers. This has nearly halved the lines
of code while keeping all previous functionality.

Platform file based initialization has been dropped as there is
no examples of this use in the kernel.

v1 can be found here: [1] v2: [2]

Changes from v2:
 - Split the series further into subsystems

Changes from v1:
 - Split the rewrite into delete/create patches
 - several small fixes as discussed in v1 thread

[1] http://www.spinics.net/lists/devicetree/msg93863.html
[2] http://www.spinics.net/lists/devicetree/msg95003.html

Andrew F. Davis (5):
  Documentation: tps65912: Add DT bindings for the TPS65912 PMIC
  mfd: tps65912: Remove old driver in preparation for new driver
  mfd: tps65912: Add driver for the TPS65912 PMIC
  regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  gpio: tps65912: Add GPIO driver for the TPS65912 PMIC

 .../devicetree/bindings/gpio/gpio-tps65912.txt     |  16 +
 Documentation/devicetree/bindings/mfd/tps65912.txt |  42 ++
 .../bindings/regulator/tps65912-regulator.txt      |  32 +
 drivers/gpio/Kconfig                               |   2 +-
 drivers/gpio/gpio-tps65912.c                       | 291 ++++----
 drivers/mfd/Kconfig                                |  20 +-
 drivers/mfd/Makefile                               |   3 +-
 drivers/mfd/tps65912-core.c                        | 289 +++-----
 drivers/mfd/tps65912-i2c.c                         | 225 +++---
 drivers/mfd/tps65912-irq.c                         | 217 ------
 drivers/mfd/tps65912-spi.c                         | 226 +++---
 drivers/regulator/Kconfig                          |   2 +-
 drivers/regulator/tps65912-regulator.c             | 781 +++++++--------------
 include/linux/mfd/tps65912.h                       | 255 ++++---
 14 files changed, 925 insertions(+), 1476 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/tps65912-regulator.txt
 rewrite drivers/gpio/gpio-tps65912.c (68%)
 rewrite drivers/mfd/tps65912-core.c (96%)
 rewrite drivers/mfd/tps65912-i2c.c (93%)
 delete mode 100644 drivers/mfd/tps65912-irq.c
 rewrite drivers/mfd/tps65912-spi.c (92%)
 rewrite drivers/regulator/tps65912-regulator.c (94%)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH v3 0/5] mfd: tps65912: Driver rewrite with DT support
@ 2015-09-24 14:52 ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

In an effort to cleanup this driver and add Device Tree support
the driver has been rewritten based on new driver styles and
modern kernel driver helpers. This has nearly halved the lines
of code while keeping all previous functionality.

Platform file based initialization has been dropped as there is
no examples of this use in the kernel.

v1 can be found here: [1] v2: [2]

Changes from v2:
 - Split the series further into subsystems

Changes from v1:
 - Split the rewrite into delete/create patches
 - several small fixes as discussed in v1 thread

[1] http://www.spinics.net/lists/devicetree/msg93863.html
[2] http://www.spinics.net/lists/devicetree/msg95003.html

Andrew F. Davis (5):
  Documentation: tps65912: Add DT bindings for the TPS65912 PMIC
  mfd: tps65912: Remove old driver in preparation for new driver
  mfd: tps65912: Add driver for the TPS65912 PMIC
  regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  gpio: tps65912: Add GPIO driver for the TPS65912 PMIC

 .../devicetree/bindings/gpio/gpio-tps65912.txt     |  16 +
 Documentation/devicetree/bindings/mfd/tps65912.txt |  42 ++
 .../bindings/regulator/tps65912-regulator.txt      |  32 +
 drivers/gpio/Kconfig                               |   2 +-
 drivers/gpio/gpio-tps65912.c                       | 291 ++++----
 drivers/mfd/Kconfig                                |  20 +-
 drivers/mfd/Makefile                               |   3 +-
 drivers/mfd/tps65912-core.c                        | 289 +++-----
 drivers/mfd/tps65912-i2c.c                         | 225 +++---
 drivers/mfd/tps65912-irq.c                         | 217 ------
 drivers/mfd/tps65912-spi.c                         | 226 +++---
 drivers/regulator/Kconfig                          |   2 +-
 drivers/regulator/tps65912-regulator.c             | 781 +++++++--------------
 include/linux/mfd/tps65912.h                       | 255 ++++---
 14 files changed, 925 insertions(+), 1476 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/tps65912-regulator.txt
 rewrite drivers/gpio/gpio-tps65912.c (68%)
 rewrite drivers/mfd/tps65912-core.c (96%)
 rewrite drivers/mfd/tps65912-i2c.c (93%)
 delete mode 100644 drivers/mfd/tps65912-irq.c
 rewrite drivers/mfd/tps65912-spi.c (92%)
 rewrite drivers/regulator/tps65912-regulator.c (94%)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH v3 1/5] Documentation: tps65912: Add DT bindings for the TPS65912 PMIC
  2015-09-24 14:52 ` Andrew F. Davis
@ 2015-09-24 14:52   ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

The TPS65912 PMIC contains several regulators and a GPIO controller.
Add bindings for the TPS65912 PMIC.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 .../devicetree/bindings/gpio/gpio-tps65912.txt     | 16 +++++++++
 Documentation/devicetree/bindings/mfd/tps65912.txt | 42 ++++++++++++++++++++++
 .../bindings/regulator/tps65912-regulator.txt      | 32 +++++++++++++++++
 3 files changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/tps65912-regulator.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-tps65912.txt b/Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
new file mode 100644
index 0000000..0c5c05c4
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
@@ -0,0 +1,16 @@
+* TPS65912 GPIO Controller bindings
+
+Required properties:
+ - compatible : Should be "ti,tps65912-gpio".
+ - gpio-controller : Marks the device node as a GPIO Controller.
+ - #gpio-cells : Should be two.  The first cell is the pin number and
+     the second cell is used to specify flags.
+     See include/dt-bindings/gpio/gpio.h for possible values.
+
+Example:
+
+	gpio4: tps65912_gpio {
+		compatible = "ti,tps65912-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
diff --git a/Documentation/devicetree/bindings/mfd/tps65912.txt b/Documentation/devicetree/bindings/mfd/tps65912.txt
new file mode 100644
index 0000000..a2c94b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/tps65912.txt
@@ -0,0 +1,42 @@
+* TPS65912 Power Management Integrated Circuit bindings
+
+Required properties:
+ - compatible : Should be "ti,tps65912".
+ - reg : Slave address or chip select number (I2C / SPI).
+ - interrupt-parent : The parent interrupt controller.
+ - interrupts : The interrupt line the device is connected to.
+ - interrupt-controller : Marks the device node as an interrupt controller.
+ - #interrupt-cells: The number of cells to describe an IRQ, this should be 2.
+     The first cell is the IRQ number.
+     The second cell is the flags, encoded as the trigger masks from
+     ../interrupt-controller/interrupts.txt
+
+Additional nodes defined in:
+ - Regulators: ../regulator/tps65912-regulator.txt
+ - GPIO: ../gpio/gpio-tps65912.txt.
+
+Example:
+
+	pmic: tps65912@2d {
+		compatible = "ti,tps65912";
+		reg = <0x2d>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		dcdc1: regulator-dcdc1 {
+			compatible = "ti,tps65912-dcdc1";
+			regulator-name = "vdd_core";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <1144000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		gpio4: tps65912_gpio {
+			compatible = "ti,tps65912-gpio";
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/regulator/tps65912-regulator.txt b/Documentation/devicetree/bindings/regulator/tps65912-regulator.txt
new file mode 100644
index 0000000..e8c21f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/tps65912-regulator.txt
@@ -0,0 +1,32 @@
+* TPS65912 regulator bindings
+
+Required properties:
+ - compatible: Should be:
+   - "ti,tps65912-dcdc1" for DCDC1
+   - "ti,tps65912-dcdc2" for DCDC2
+   - "ti,tps65912-dcdc3" for DCDC3
+   - "ti,tps65912-dcdc4" for DCDC4
+   - "ti,tps65912-ldo1" for LDO1
+   - "ti,tps65912-ldo2" for LDO2
+   - "ti,tps65912-ldo3" for LDO3
+   - "ti,tps65912-ldo4" for LDO4
+   - "ti,tps65912-ldo5" for LDO5
+   - "ti,tps65912-ldo6" for LDO6
+   - "ti,tps65912-ldo7" for LDO7
+   - "ti,tps65912-ldo8" for LDO8
+   - "ti,tps65912-ldo9" for LDO9
+   - "ti,tps65912-ldo10" for LDO10
+
+Optional properties:
+ - Any optional property defined in ../regulator/regulator.txt
+
+Example:
+
+	xyz: regulator@0 {
+		compatible = "ti,tps65912-dcdc1";
+		regulator-name = "vdd_core";
+		regulator-min-microvolt = <912000>;
+		regulator-max-microvolt = <1144000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 1/5] Documentation: tps65912: Add DT bindings for the TPS65912 PMIC
@ 2015-09-24 14:52   ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

The TPS65912 PMIC contains several regulators and a GPIO controller.
Add bindings for the TPS65912 PMIC.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 .../devicetree/bindings/gpio/gpio-tps65912.txt     | 16 +++++++++
 Documentation/devicetree/bindings/mfd/tps65912.txt | 42 ++++++++++++++++++++++
 .../bindings/regulator/tps65912-regulator.txt      | 32 +++++++++++++++++
 3 files changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/tps65912.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/tps65912-regulator.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-tps65912.txt b/Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
new file mode 100644
index 0000000..0c5c05c4
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-tps65912.txt
@@ -0,0 +1,16 @@
+* TPS65912 GPIO Controller bindings
+
+Required properties:
+ - compatible : Should be "ti,tps65912-gpio".
+ - gpio-controller : Marks the device node as a GPIO Controller.
+ - #gpio-cells : Should be two.  The first cell is the pin number and
+     the second cell is used to specify flags.
+     See include/dt-bindings/gpio/gpio.h for possible values.
+
+Example:
+
+	gpio4: tps65912_gpio {
+		compatible = "ti,tps65912-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
diff --git a/Documentation/devicetree/bindings/mfd/tps65912.txt b/Documentation/devicetree/bindings/mfd/tps65912.txt
new file mode 100644
index 0000000..a2c94b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/tps65912.txt
@@ -0,0 +1,42 @@
+* TPS65912 Power Management Integrated Circuit bindings
+
+Required properties:
+ - compatible : Should be "ti,tps65912".
+ - reg : Slave address or chip select number (I2C / SPI).
+ - interrupt-parent : The parent interrupt controller.
+ - interrupts : The interrupt line the device is connected to.
+ - interrupt-controller : Marks the device node as an interrupt controller.
+ - #interrupt-cells: The number of cells to describe an IRQ, this should be 2.
+     The first cell is the IRQ number.
+     The second cell is the flags, encoded as the trigger masks from
+     ../interrupt-controller/interrupts.txt
+
+Additional nodes defined in:
+ - Regulators: ../regulator/tps65912-regulator.txt
+ - GPIO: ../gpio/gpio-tps65912.txt.
+
+Example:
+
+	pmic: tps65912@2d {
+		compatible = "ti,tps65912";
+		reg = <0x2d>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		dcdc1: regulator-dcdc1 {
+			compatible = "ti,tps65912-dcdc1";
+			regulator-name = "vdd_core";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <1144000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		gpio4: tps65912_gpio {
+			compatible = "ti,tps65912-gpio";
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/regulator/tps65912-regulator.txt b/Documentation/devicetree/bindings/regulator/tps65912-regulator.txt
new file mode 100644
index 0000000..e8c21f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/tps65912-regulator.txt
@@ -0,0 +1,32 @@
+* TPS65912 regulator bindings
+
+Required properties:
+ - compatible: Should be:
+   - "ti,tps65912-dcdc1" for DCDC1
+   - "ti,tps65912-dcdc2" for DCDC2
+   - "ti,tps65912-dcdc3" for DCDC3
+   - "ti,tps65912-dcdc4" for DCDC4
+   - "ti,tps65912-ldo1" for LDO1
+   - "ti,tps65912-ldo2" for LDO2
+   - "ti,tps65912-ldo3" for LDO3
+   - "ti,tps65912-ldo4" for LDO4
+   - "ti,tps65912-ldo5" for LDO5
+   - "ti,tps65912-ldo6" for LDO6
+   - "ti,tps65912-ldo7" for LDO7
+   - "ti,tps65912-ldo8" for LDO8
+   - "ti,tps65912-ldo9" for LDO9
+   - "ti,tps65912-ldo10" for LDO10
+
+Optional properties:
+ - Any optional property defined in ../regulator/regulator.txt
+
+Example:
+
+	xyz: regulator@0 {
+		compatible = "ti,tps65912-dcdc1";
+		regulator-name = "vdd_core";
+		regulator-min-microvolt = <912000>;
+		regulator-max-microvolt = <1144000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 2/5] mfd: tps65912: Remove old driver in preparation for new driver
  2015-09-24 14:52 ` Andrew F. Davis
@ 2015-09-24 14:52   ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

The old tps65912 driver is being replaced, delete old driver.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/gpio/Kconfig                   |   6 -
 drivers/gpio/Makefile                  |   1 -
 drivers/gpio/gpio-tps65912.c           | 153 ----------
 drivers/mfd/Kconfig                    |  26 --
 drivers/mfd/Makefile                   |   4 -
 drivers/mfd/tps65912-core.c            | 175 -----------
 drivers/mfd/tps65912-i2c.c             | 139 ---------
 drivers/mfd/tps65912-irq.c             | 217 -------------
 drivers/mfd/tps65912-spi.c             | 141 ---------
 drivers/regulator/Kconfig              |   6 -
 drivers/regulator/Makefile             |   1 -
 drivers/regulator/tps65912-regulator.c | 541 ---------------------------------
 include/linux/mfd/tps65912.h           | 328 --------------------
 13 files changed, 1738 deletions(-)
 delete mode 100644 drivers/gpio/gpio-tps65912.c
 delete mode 100644 drivers/mfd/tps65912-core.c
 delete mode 100644 drivers/mfd/tps65912-i2c.c
 delete mode 100644 drivers/mfd/tps65912-irq.c
 delete mode 100644 drivers/mfd/tps65912-spi.c
 delete mode 100644 drivers/regulator/tps65912-regulator.c
 delete mode 100644 include/linux/mfd/tps65912.h

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b4fc9e4..fb28483 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -838,12 +838,6 @@ config GPIO_TPS65910
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
 
-config GPIO_TPS65912
-	tristate "TI TPS65912 GPIO"
-	depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI)
-	help
-	  This driver supports TPS65912 gpio chip
-
 config GPIO_TWL4030
 	tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
 	depends on TWL4030_CORE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f79a7c4..605bf89 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -96,7 +96,6 @@ obj-$(CONFIG_GPIO_TIMBERDALE)	+= gpio-timberdale.o
 obj-$(CONFIG_GPIO_PALMAS)	+= gpio-palmas.o
 obj-$(CONFIG_GPIO_TPS6586X)	+= gpio-tps6586x.o
 obj-$(CONFIG_GPIO_TPS65910)	+= gpio-tps65910.o
-obj-$(CONFIG_GPIO_TPS65912)	+= gpio-tps65912.o
 obj-$(CONFIG_GPIO_TS5500)	+= gpio-ts5500.o
 obj-$(CONFIG_GPIO_TWL4030)	+= gpio-twl4030.o
 obj-$(CONFIG_GPIO_TWL6040)	+= gpio-twl6040.o
diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
deleted file mode 100644
index 9cdbc0c..0000000
--- a/drivers/gpio/gpio-tps65912.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- * This driver is based on wm8350 implementation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/mfd/core.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/mfd/tps65912.h>
-
-struct tps65912_gpio_data {
-	struct tps65912 *tps65912;
-	struct gpio_chip gpio_chip;
-};
-
-#define to_tgd(gc) container_of(gc, struct tps65912_gpio_data, gpio_chip)
-
-static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-	int val;
-
-	val = tps65912_reg_read(tps65912, TPS65912_GPIO1 + offset);
-
-	if (val & GPIO_STS_MASK)
-		return 1;
-
-	return 0;
-}
-
-static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
-			      int value)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-
-	if (value)
-		tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset,
-							GPIO_SET_MASK);
-	else
-		tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset,
-								GPIO_SET_MASK);
-}
-
-static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
-				int value)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-
-	/* Set the initial value */
-	tps65912_gpio_set(gc, offset, value);
-
-	return tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset,
-								GPIO_CFG_MASK);
-}
-
-static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-
-	return tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset,
-								GPIO_CFG_MASK);
-}
-
-static struct gpio_chip template_chip = {
-	.label			= "tps65912",
-	.owner			= THIS_MODULE,
-	.direction_input	= tps65912_gpio_input,
-	.direction_output	= tps65912_gpio_output,
-	.get			= tps65912_gpio_get,
-	.set			= tps65912_gpio_set,
-	.can_sleep		= true,
-	.ngpio			= 5,
-	.base			= -1,
-};
-
-static int tps65912_gpio_probe(struct platform_device *pdev)
-{
-	struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
-	struct tps65912_board *pdata = dev_get_platdata(tps65912->dev);
-	struct tps65912_gpio_data *tps65912_gpio;
-	int ret;
-
-	tps65912_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65912_gpio),
-				     GFP_KERNEL);
-	if (tps65912_gpio == NULL)
-		return -ENOMEM;
-
-	tps65912_gpio->tps65912 = tps65912;
-	tps65912_gpio->gpio_chip = template_chip;
-	tps65912_gpio->gpio_chip.dev = &pdev->dev;
-	if (pdata && pdata->gpio_base)
-		tps65912_gpio->gpio_chip.base = pdata->gpio_base;
-
-	ret = gpiochip_add(&tps65912_gpio->gpio_chip);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret);
-		return ret;
-	}
-
-	platform_set_drvdata(pdev, tps65912_gpio);
-
-	return ret;
-}
-
-static int tps65912_gpio_remove(struct platform_device *pdev)
-{
-	struct tps65912_gpio_data  *tps65912_gpio = platform_get_drvdata(pdev);
-
-	gpiochip_remove(&tps65912_gpio->gpio_chip);
-	return 0;
-}
-
-static struct platform_driver tps65912_gpio_driver = {
-	.driver = {
-		.name = "tps65912-gpio",
-	},
-	.probe = tps65912_gpio_probe,
-	.remove = tps65912_gpio_remove,
-};
-
-static int __init tps65912_gpio_init(void)
-{
-	return platform_driver_register(&tps65912_gpio_driver);
-}
-subsys_initcall(tps65912_gpio_init);
-
-static void __exit tps65912_gpio_exit(void)
-{
-	platform_driver_unregister(&tps65912_gpio_driver);
-}
-module_exit(tps65912_gpio_exit);
-
-MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("GPIO interface for TPS65912 PMICs");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tps65912-gpio");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 99d6367..9a8df8e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1167,32 +1167,6 @@ config MFD_TPS65910
 	  if you say yes here you get support for the TPS65910 series of
 	  Power Management chips.
 
-config MFD_TPS65912
-	bool "TI TPS65912 Power Management chip"
-	depends on GPIOLIB
-	select MFD_CORE
-	help
-	  If you say yes here you get support for the TPS65912 series of
-	  PM chips.
-
-config MFD_TPS65912_I2C
-	bool "TI TPS65912 Power Management chip with I2C"
-	select MFD_CORE
-	select MFD_TPS65912
-	depends on I2C=y && GPIOLIB
-	help
-	  If you say yes here you get support for the TPS65912 series of
-	  PM chips with I2C interface.
-
-config MFD_TPS65912_SPI
-	bool "TI TPS65912 Power Management chip with SPI"
-	select MFD_CORE
-	select MFD_TPS65912
-	depends on SPI_MASTER && GPIOLIB
-	help
-	  If you say yes here you get support for the TPS65912 series of
-	  PM chips with SPI interface.
-
 config MFD_TPS80031
 	bool "TI TPS80031/TPS80032 Power Management chips"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a59e3fc..004aa76 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -69,10 +69,6 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
-tps65912-objs                   := tps65912-core.o tps65912-irq.o
-obj-$(CONFIG_MFD_TPS65912)	+= tps65912.o
-obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
-obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
 obj-$(CONFIG_MFD_TPS80031)	+= tps80031.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
deleted file mode 100644
index 1f82d60..0000000
--- a/drivers/mfd/tps65912-core.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * tps65912-core.c  --  TI TPS65912x
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This driver is based on wm8350 implementation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/tps65912.h>
-
-static const struct mfd_cell tps65912s[] = {
-	{
-		.name = "tps65912-pmic",
-	},
-};
-
-int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask)
-{
-	u8 data;
-	int err;
-
-	mutex_lock(&tps65912->io_mutex);
-
-	err = tps65912->read(tps65912, reg, 1, &data);
-	if (err) {
-		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
-		goto out;
-	}
-
-	data |= mask;
-	err = tps65912->write(tps65912, reg, 1, &data);
-	if (err)
-		dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);
-
-out:
-	mutex_unlock(&tps65912->io_mutex);
-	return err;
-}
-EXPORT_SYMBOL_GPL(tps65912_set_bits);
-
-int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask)
-{
-	u8 data;
-	int err;
-
-	mutex_lock(&tps65912->io_mutex);
-	err = tps65912->read(tps65912, reg, 1, &data);
-	if (err) {
-		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
-		goto out;
-	}
-
-	data &= ~mask;
-	err = tps65912->write(tps65912, reg, 1, &data);
-	if (err)
-		dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);
-
-out:
-	mutex_unlock(&tps65912->io_mutex);
-	return err;
-}
-EXPORT_SYMBOL_GPL(tps65912_clear_bits);
-
-static inline int tps65912_read(struct tps65912 *tps65912, u8 reg)
-{
-	u8 val;
-	int err;
-
-	err = tps65912->read(tps65912, reg, 1, &val);
-	if (err < 0)
-		return err;
-
-	return val;
-}
-
-static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val)
-{
-	return tps65912->write(tps65912, reg, 1, &val);
-}
-
-int tps65912_reg_read(struct tps65912 *tps65912, u8 reg)
-{
-	int data;
-
-	mutex_lock(&tps65912->io_mutex);
-
-	data = tps65912_read(tps65912, reg);
-	if (data < 0)
-		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
-
-	mutex_unlock(&tps65912->io_mutex);
-	return data;
-}
-EXPORT_SYMBOL_GPL(tps65912_reg_read);
-
-int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val)
-{
-	int err;
-
-	mutex_lock(&tps65912->io_mutex);
-
-	err = tps65912_write(tps65912, reg, val);
-	if (err < 0)
-		dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg);
-
-	mutex_unlock(&tps65912->io_mutex);
-	return err;
-}
-EXPORT_SYMBOL_GPL(tps65912_reg_write);
-
-int tps65912_device_init(struct tps65912 *tps65912)
-{
-	struct tps65912_board *pmic_plat_data = dev_get_platdata(tps65912->dev);
-	struct tps65912_platform_data *init_data;
-	int ret, dcdc_avs, value;
-
-	init_data = kzalloc(sizeof(struct tps65912_platform_data), GFP_KERNEL);
-	if (init_data == NULL)
-		return -ENOMEM;
-
-	mutex_init(&tps65912->io_mutex);
-	dev_set_drvdata(tps65912->dev, tps65912);
-
-	dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 |
-			pmic_plat_data->is_dcdc2_avs  << 1 |
-				pmic_plat_data->is_dcdc3_avs << 2 |
-					pmic_plat_data->is_dcdc4_avs << 3);
-	if (dcdc_avs) {
-		tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value);
-		dcdc_avs |= value;
-		tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs);
-	}
-
-	ret = mfd_add_devices(tps65912->dev, -1,
-			      tps65912s, ARRAY_SIZE(tps65912s),
-			      NULL, 0, NULL);
-	if (ret < 0)
-		goto err;
-
-	init_data->irq = pmic_plat_data->irq;
-	init_data->irq_base = pmic_plat_data->irq_base;
-	ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
-	if (ret < 0)
-		goto err;
-
-	kfree(init_data);
-	return ret;
-
-err:
-	kfree(init_data);
-	mfd_remove_devices(tps65912->dev);
-	return ret;
-}
-
-void tps65912_device_exit(struct tps65912 *tps65912)
-{
-	mfd_remove_devices(tps65912->dev);
-	tps65912_irq_exit(tps65912);
-}
-
-MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("TPS65912x chip family multi-function driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c
deleted file mode 100644
index 7e55640..0000000
--- a/drivers/mfd/tps65912-i2c.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * tps65912-i2c.c  --  I2C access for TI TPS65912x PMIC
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This driver is based on wm8350 implementation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/tps65912.h>
-
-static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg,
-				  int bytes, void *dest)
-{
-	struct i2c_client *i2c = tps65912->control_data;
-	struct i2c_msg xfer[2];
-	int ret;
-
-	/* Write register */
-	xfer[0].addr = i2c->addr;
-	xfer[0].flags = 0;
-	xfer[0].len = 1;
-	xfer[0].buf = &reg;
-
-	/* Read data */
-	xfer[1].addr = i2c->addr;
-	xfer[1].flags = I2C_M_RD;
-	xfer[1].len = bytes;
-	xfer[1].buf = dest;
-
-	ret = i2c_transfer(i2c->adapter, xfer, 2);
-	if (ret == 2)
-		ret = 0;
-	else if (ret >= 0)
-		ret = -EIO;
-	return ret;
-}
-
-static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg,
-				   int bytes, void *src)
-{
-	struct i2c_client *i2c = tps65912->control_data;
-	/* we add 1 byte for device register */
-	u8 msg[TPS6591X_MAX_REGISTER + 1];
-	int ret;
-
-	if (bytes > TPS6591X_MAX_REGISTER)
-		return -EINVAL;
-
-	msg[0] = reg;
-	memcpy(&msg[1], src, bytes);
-
-	ret = i2c_master_send(i2c, msg, bytes + 1);
-	if (ret < 0)
-		return ret;
-	if (ret != bytes + 1)
-		return -EIO;
-
-	return 0;
-}
-
-static int tps65912_i2c_probe(struct i2c_client *i2c,
-			    const struct i2c_device_id *id)
-{
-	struct tps65912 *tps65912;
-
-	tps65912 = devm_kzalloc(&i2c->dev,
-				sizeof(struct tps65912), GFP_KERNEL);
-	if (tps65912 == NULL)
-		return -ENOMEM;
-
-	i2c_set_clientdata(i2c, tps65912);
-	tps65912->dev = &i2c->dev;
-	tps65912->control_data = i2c;
-	tps65912->read = tps65912_i2c_read;
-	tps65912->write = tps65912_i2c_write;
-
-	return tps65912_device_init(tps65912);
-}
-
-static int tps65912_i2c_remove(struct i2c_client *i2c)
-{
-	struct tps65912 *tps65912 = i2c_get_clientdata(i2c);
-
-	tps65912_device_exit(tps65912);
-
-	return 0;
-}
-
-static const struct i2c_device_id tps65912_i2c_id[] = {
-	{"tps65912", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id);
-
-static struct i2c_driver tps65912_i2c_driver = {
-	.driver = {
-		   .name = "tps65912",
-	},
-	.probe = tps65912_i2c_probe,
-	.remove = tps65912_i2c_remove,
-	.id_table = tps65912_i2c_id,
-};
-
-static int __init tps65912_i2c_init(void)
-{
-	int ret;
-
-	ret = i2c_add_driver(&tps65912_i2c_driver);
-	if (ret != 0)
-		pr_err("Failed to register TPS65912 I2C driver: %d\n", ret);
-
-	return ret;
-}
-/* init early so consumer devices can complete system boot */
-subsys_initcall(tps65912_i2c_init);
-
-static void __exit tps65912_i2c_exit(void)
-{
-	i2c_del_driver(&tps65912_i2c_driver);
-}
-module_exit(tps65912_i2c_exit);
-
-MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("TPS6591x chip family multi-function driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps65912-irq.c b/drivers/mfd/tps65912-irq.c
deleted file mode 100644
index db2c29c..0000000
--- a/drivers/mfd/tps65912-irq.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * tps65912-irq.c  --  TI TPS6591x
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- * This driver is based on wm8350 implementation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/mfd/tps65912.h>
-
-static inline int irq_to_tps65912_irq(struct tps65912 *tps65912,
-							int irq)
-{
-	return irq - tps65912->irq_base;
-}
-
-/*
- * This is a threaded IRQ handler so can access I2C/SPI.  Since the
- * IRQ handler explicitly clears the IRQ it handles the IRQ line
- * will be reasserted and the physical IRQ will be handled again if
- * another interrupt is asserted while we run - in the normal course
- * of events this is a rare occurrence so we save I2C/SPI reads. We're
- * also assuming that it's rare to get lots of interrupts firing
- * simultaneously so try to minimise I/O.
- */
-static irqreturn_t tps65912_irq(int irq, void *irq_data)
-{
-	struct tps65912 *tps65912 = irq_data;
-	u32 irq_sts;
-	u32 irq_mask;
-	u8 reg;
-	int i;
-
-
-	tps65912->read(tps65912, TPS65912_INT_STS, 1, &reg);
-	irq_sts = reg;
-	tps65912->read(tps65912, TPS65912_INT_STS2, 1, &reg);
-	irq_sts |= reg << 8;
-	tps65912->read(tps65912, TPS65912_INT_STS3, 1, &reg);
-	irq_sts |= reg << 16;
-	tps65912->read(tps65912, TPS65912_INT_STS4, 1, &reg);
-	irq_sts |= reg << 24;
-
-	tps65912->read(tps65912, TPS65912_INT_MSK, 1, &reg);
-	irq_mask = reg;
-	tps65912->read(tps65912, TPS65912_INT_MSK2, 1, &reg);
-	irq_mask |= reg << 8;
-	tps65912->read(tps65912, TPS65912_INT_MSK3, 1, &reg);
-	irq_mask |= reg << 16;
-	tps65912->read(tps65912, TPS65912_INT_MSK4, 1, &reg);
-	irq_mask |= reg << 24;
-
-	irq_sts &= ~irq_mask;
-	if (!irq_sts)
-		return IRQ_NONE;
-
-	for (i = 0; i < tps65912->irq_num; i++) {
-		if (!(irq_sts & (1 << i)))
-			continue;
-
-		handle_nested_irq(tps65912->irq_base + i);
-	}
-
-	/* Write the STS register back to clear IRQs we handled */
-	reg = irq_sts & 0xFF;
-	irq_sts >>= 8;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS, 1, &reg);
-	reg = irq_sts & 0xFF;
-	irq_sts >>= 8;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS2, 1, &reg);
-	reg = irq_sts & 0xFF;
-	irq_sts >>= 8;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS3, 1, &reg);
-	reg = irq_sts & 0xFF;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS4, 1, &reg);
-
-	return IRQ_HANDLED;
-}
-
-static void tps65912_irq_lock(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-
-	mutex_lock(&tps65912->irq_lock);
-}
-
-static void tps65912_irq_sync_unlock(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-	u32 reg_mask;
-	u8 reg;
-
-	tps65912->read(tps65912, TPS65912_INT_MSK, 1, &reg);
-	reg_mask = reg;
-	tps65912->read(tps65912, TPS65912_INT_MSK2, 1, &reg);
-	reg_mask |= reg << 8;
-	tps65912->read(tps65912, TPS65912_INT_MSK3, 1, &reg);
-	reg_mask |= reg << 16;
-	tps65912->read(tps65912, TPS65912_INT_MSK4, 1, &reg);
-	reg_mask |= reg << 24;
-
-	if (tps65912->irq_mask != reg_mask) {
-		reg = tps65912->irq_mask & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK, 1, &reg);
-		reg = tps65912->irq_mask >> 8 & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK2, 1, &reg);
-		reg = tps65912->irq_mask >> 16 & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK3, 1, &reg);
-		reg = tps65912->irq_mask >> 24 & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK4, 1, &reg);
-	}
-
-	mutex_unlock(&tps65912->irq_lock);
-}
-
-static void tps65912_irq_enable(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-
-	tps65912->irq_mask &= ~(1 << irq_to_tps65912_irq(tps65912, data->irq));
-}
-
-static void tps65912_irq_disable(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-
-	tps65912->irq_mask |= (1 << irq_to_tps65912_irq(tps65912, data->irq));
-}
-
-static struct irq_chip tps65912_irq_chip = {
-	.name = "tps65912",
-	.irq_bus_lock = tps65912_irq_lock,
-	.irq_bus_sync_unlock = tps65912_irq_sync_unlock,
-	.irq_disable = tps65912_irq_disable,
-	.irq_enable = tps65912_irq_enable,
-};
-
-int tps65912_irq_init(struct tps65912 *tps65912, int irq,
-			    struct tps65912_platform_data *pdata)
-{
-	int ret, cur_irq;
-	int flags = IRQF_ONESHOT;
-	u8 reg;
-
-	if (!irq) {
-		dev_warn(tps65912->dev, "No interrupt support, no core IRQ\n");
-		return 0;
-	}
-
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(tps65912->dev, "No interrupt support, no IRQ base\n");
-		return 0;
-	}
-
-	/* Clear unattended interrupts */
-	tps65912->read(tps65912, TPS65912_INT_STS, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS, 1, &reg);
-	tps65912->read(tps65912, TPS65912_INT_STS2, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS2, 1, &reg);
-	tps65912->read(tps65912, TPS65912_INT_STS3, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS3, 1, &reg);
-	tps65912->read(tps65912, TPS65912_INT_STS4, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS4, 1, &reg);
-
-	/* Mask top level interrupts */
-	tps65912->irq_mask = 0xFFFFFFFF;
-
-	mutex_init(&tps65912->irq_lock);
-	tps65912->chip_irq = irq;
-	tps65912->irq_base = pdata->irq_base;
-
-	tps65912->irq_num = TPS65912_NUM_IRQ;
-
-	/* Register with genirq */
-	for (cur_irq = tps65912->irq_base;
-	     cur_irq < tps65912->irq_num + tps65912->irq_base;
-	     cur_irq++) {
-		irq_set_chip_data(cur_irq, tps65912);
-		irq_set_chip_and_handler(cur_irq, &tps65912_irq_chip,
-					 handle_edge_irq);
-		irq_set_nested_thread(cur_irq, 1);
-		irq_clear_status_flags(cur_irq, IRQ_NOREQUEST | IRQ_NOPROBE);
-	}
-
-	ret = request_threaded_irq(irq, NULL, tps65912_irq, flags,
-				   "tps65912", tps65912);
-
-	irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
-	if (ret != 0)
-		dev_err(tps65912->dev, "Failed to request IRQ: %d\n", ret);
-
-	return ret;
-}
-
-int tps65912_irq_exit(struct tps65912 *tps65912)
-{
-	free_irq(tps65912->chip_irq, tps65912);
-	return 0;
-}
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
deleted file mode 100644
index de60ad9..0000000
--- a/drivers/mfd/tps65912-spi.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * tps65912-spi.c  --  SPI access for TI TPS65912x PMIC
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This driver is based on wm8350 implementation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/tps65912.h>
-
-static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr,
-							int bytes, void *src)
-{
-	struct spi_device *spi = tps65912->control_data;
-	u8 *data = (u8 *) src;
-	int ret;
-	/* bit 23 is the read/write bit */
-	unsigned long spi_data = 1 << 23 | addr << 15 | *data;
-	struct spi_transfer xfer;
-	struct spi_message msg;
-	u32 tx_buf;
-
-	tx_buf = spi_data;
-
-	xfer.tx_buf	= &tx_buf;
-	xfer.rx_buf	= NULL;
-	xfer.len	= sizeof(unsigned long);
-	xfer.bits_per_word = 24;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	ret = spi_sync(spi, &msg);
-	return ret;
-}
-
-static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr,
-							int bytes, void *dest)
-{
-	struct spi_device *spi = tps65912->control_data;
-	/* bit 23 is the read/write bit */
-	unsigned long spi_data = 0 << 23 | addr << 15;
-	struct spi_transfer xfer;
-	struct spi_message msg;
-	int ret;
-	u8 *data = (u8 *) dest;
-	u32 tx_buf, rx_buf;
-
-	tx_buf = spi_data;
-	rx_buf = 0;
-
-	xfer.tx_buf	= &tx_buf;
-	xfer.rx_buf	= &rx_buf;
-	xfer.len	= sizeof(unsigned long);
-	xfer.bits_per_word = 24;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	if (spi == NULL)
-		return 0;
-
-	ret = spi_sync(spi, &msg);
-	if (ret == 0)
-		*data = (u8) (rx_buf & 0xFF);
-	return ret;
-}
-
-static int tps65912_spi_probe(struct spi_device *spi)
-{
-	struct tps65912 *tps65912;
-
-	tps65912 = devm_kzalloc(&spi->dev,
-				sizeof(struct tps65912), GFP_KERNEL);
-	if (tps65912 == NULL)
-		return -ENOMEM;
-
-	tps65912->dev = &spi->dev;
-	tps65912->control_data = spi;
-	tps65912->read = tps65912_spi_read;
-	tps65912->write = tps65912_spi_write;
-
-	spi_set_drvdata(spi, tps65912);
-
-	return tps65912_device_init(tps65912);
-}
-
-static int tps65912_spi_remove(struct spi_device *spi)
-{
-	struct tps65912 *tps65912 = spi_get_drvdata(spi);
-
-	tps65912_device_exit(tps65912);
-
-	return 0;
-}
-
-static struct spi_driver tps65912_spi_driver = {
-	.driver = {
-		.name = "tps65912",
-		.owner = THIS_MODULE,
-	},
-	.probe	= tps65912_spi_probe,
-	.remove = tps65912_spi_remove,
-};
-
-static int __init tps65912_spi_init(void)
-{
-	int ret;
-
-	ret = spi_register_driver(&tps65912_spi_driver);
-	if (ret != 0)
-		pr_err("Failed to register TPS65912 SPI driver: %d\n", ret);
-
-	return 0;
-}
-/* init early so consumer devices can complete system boot */
-subsys_initcall(tps65912_spi_init);
-
-static void __exit tps65912_spi_exit(void)
-{
-	spi_unregister_driver(&tps65912_spi_driver);
-}
-module_exit(tps65912_spi_exit);
-
-MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd");
-MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 64bccff..3cb2de9 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -727,12 +727,6 @@ config REGULATOR_TPS65910
 	help
 	  This driver supports TPS65910/TPS65911 voltage regulator chips.
 
-config REGULATOR_TPS65912
-	tristate "TI TPS65912 Power regulator"
-	depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI)
-	help
-	    This driver supports TPS65912 voltage regulator chip.
-
 config REGULATOR_TPS80031
 	tristate "TI TPS80031/TPS80032 power regualtor driver"
 	depends on MFD_TPS80031
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0f81749..222ff5f 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -91,7 +91,6 @@ obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
-obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
 obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
 obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
deleted file mode 100644
index 9503d54..0000000
--- a/drivers/regulator/tps65912-regulator.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * tps65912.c  --  TI tps65912
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- * This driver is based on wm8350 implementation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/mfd/tps65912.h>
-
-/* DCDC's */
-#define TPS65912_REG_DCDC1	0
-#define TPS65912_REG_DCDC2	1
-#define TPS65912_REG_DCDC3	2
-#define TPS65912_REG_DCDC4	3
-
-/* LDOs */
-#define TPS65912_REG_LDO1	4
-#define TPS65912_REG_LDO2	5
-#define TPS65912_REG_LDO3	6
-#define TPS65912_REG_LDO4	7
-#define TPS65912_REG_LDO5	8
-#define TPS65912_REG_LDO6	9
-#define TPS65912_REG_LDO7	10
-#define TPS65912_REG_LDO8	11
-#define TPS65912_REG_LDO9	12
-#define TPS65912_REG_LDO10	13
-
-/* Number of step-down converters available */
-#define TPS65912_NUM_DCDC	4
-
-/* Number of LDO voltage regulators  available */
-#define TPS65912_NUM_LDO	10
-
-/* Number of total regulators available */
-#define TPS65912_NUM_REGULATOR		(TPS65912_NUM_DCDC + TPS65912_NUM_LDO)
-
-#define TPS65912_REG_ENABLED	0x80
-#define OP_SELREG_MASK		0x40
-#define OP_SELREG_SHIFT		6
-
-struct tps_info {
-	const char *name;
-};
-
-static struct tps_info tps65912_regs[] = {
-	{
-		.name = "DCDC1",
-	},
-	{
-		.name = "DCDC2",
-	},
-	{
-		.name = "DCDC3",
-	},
-	{
-		.name = "DCDC4",
-	},
-	{
-		.name = "LDO1",
-	},
-	{
-		.name = "LDO2",
-	},
-	{
-		.name = "LDO3",
-	},
-	{
-		.name = "LDO4",
-	},
-	{
-		.name = "LDO5",
-	},
-	{
-		.name = "LDO6",
-	},
-	{
-		.name = "LDO7",
-	},
-	{
-		.name = "LDO8",
-	},
-	{
-		.name = "LDO9",
-	},
-	{
-		.name = "LDO10",
-	},
-};
-
-struct tps65912_reg {
-	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
-	struct tps65912 *mfd;
-	struct regulator_dev *rdev[TPS65912_NUM_REGULATOR];
-	struct tps_info *info[TPS65912_NUM_REGULATOR];
-	/* for read/write access */
-	struct mutex io_lock;
-	int mode;
-	int (*get_ctrl_reg)(int);
-	int dcdc_range[TPS65912_NUM_DCDC];
-	int pwm_mode_reg;
-	int eco_reg;
-};
-
-static const struct regulator_linear_range tps65912_ldo_ranges[] = {
-	REGULATOR_LINEAR_RANGE(800000, 0, 32, 25000),
-	REGULATOR_LINEAR_RANGE(1650000, 33, 60, 50000),
-	REGULATOR_LINEAR_RANGE(3100000, 61, 63, 100000),
-};
-
-static int tps65912_get_range(struct tps65912_reg *pmic, int id)
-{
-	struct tps65912 *mfd = pmic->mfd;
-	int range;
-
-	switch (id) {
-	case TPS65912_REG_DCDC1:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC1_LIMIT);
-		break;
-	case TPS65912_REG_DCDC2:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC2_LIMIT);
-		break;
-	case TPS65912_REG_DCDC3:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC3_LIMIT);
-		break;
-	case TPS65912_REG_DCDC4:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC4_LIMIT);
-		break;
-	default:
-		return 0;
-	}
-
-	if (range >= 0)
-		range = (range & DCDC_LIMIT_RANGE_MASK)
-			>> DCDC_LIMIT_RANGE_SHIFT;
-
-	pmic->dcdc_range[id] = range;
-	return range;
-}
-
-static unsigned long tps65912_vsel_to_uv_range0(u8 vsel)
-{
-	unsigned long uv;
-
-	uv = ((vsel * 12500) + 500000);
-	return uv;
-}
-
-static unsigned long tps65912_vsel_to_uv_range1(u8 vsel)
-{
-	unsigned long uv;
-
-	 uv = ((vsel * 12500) + 700000);
-	return uv;
-}
-
-static unsigned long tps65912_vsel_to_uv_range2(u8 vsel)
-{
-	unsigned long uv;
-
-	uv = ((vsel * 25000) + 500000);
-	return uv;
-}
-
-static unsigned long tps65912_vsel_to_uv_range3(u8 vsel)
-{
-	unsigned long uv;
-
-	if (vsel == 0x3f)
-		uv = 3800000;
-	else
-		uv = ((vsel * 50000) + 500000);
-
-	return uv;
-}
-
-static int tps65912_get_ctrl_register(int id)
-{
-	if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4)
-		return id * 3 + TPS65912_DCDC1_AVS;
-	else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10)
-		return id - TPS65912_REG_LDO5 + TPS65912_LDO5;
-	else
-		return -EINVAL;
-}
-
-static int tps65912_get_sel_register(struct tps65912_reg *pmic, int id)
-{
-	struct tps65912 *mfd = pmic->mfd;
-	int opvsel;
-	u8 reg = 0;
-
-	if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4) {
-		opvsel = tps65912_reg_read(mfd, id * 3 + TPS65912_DCDC1_OP);
-		if (opvsel & OP_SELREG_MASK)
-			reg = id * 3 + TPS65912_DCDC1_AVS;
-		else
-			reg = id * 3 + TPS65912_DCDC1_OP;
-	} else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10) {
-		reg = id - TPS65912_REG_LDO5 + TPS65912_LDO5;
-	} else {
-		return -EINVAL;
-	}
-
-	return reg;
-}
-
-static int tps65912_get_mode_regiters(struct tps65912_reg *pmic, int id)
-{
-	switch (id) {
-	case TPS65912_REG_DCDC1:
-		pmic->pwm_mode_reg = TPS65912_DCDC1_CTRL;
-		pmic->eco_reg = TPS65912_DCDC1_AVS;
-		break;
-	case TPS65912_REG_DCDC2:
-		pmic->pwm_mode_reg = TPS65912_DCDC2_CTRL;
-		pmic->eco_reg = TPS65912_DCDC2_AVS;
-		break;
-	case TPS65912_REG_DCDC3:
-		pmic->pwm_mode_reg = TPS65912_DCDC3_CTRL;
-		pmic->eco_reg = TPS65912_DCDC3_AVS;
-		break;
-	case TPS65912_REG_DCDC4:
-		pmic->pwm_mode_reg = TPS65912_DCDC4_CTRL;
-		pmic->eco_reg = TPS65912_DCDC4_AVS;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int tps65912_reg_is_enabled(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int reg, value, id = rdev_get_id(dev);
-
-	if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_LDO10)
-		return -EINVAL;
-
-	reg = pmic->get_ctrl_reg(id);
-	if (reg < 0)
-		return reg;
-
-	value = tps65912_reg_read(mfd, reg);
-	if (value < 0)
-		return value;
-
-	return value & TPS65912_REG_ENABLED;
-}
-
-static int tps65912_reg_enable(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev);
-	int reg;
-
-	if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_LDO10)
-		return -EINVAL;
-
-	reg = pmic->get_ctrl_reg(id);
-	if (reg < 0)
-		return reg;
-
-	return tps65912_set_bits(mfd, reg, TPS65912_REG_ENABLED);
-}
-
-static int tps65912_reg_disable(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev), reg;
-
-	reg = pmic->get_ctrl_reg(id);
-	if (reg < 0)
-		return reg;
-
-	return tps65912_clear_bits(mfd, reg, TPS65912_REG_ENABLED);
-}
-
-static int tps65912_set_mode(struct regulator_dev *dev, unsigned int mode)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int pwm_mode, eco, id = rdev_get_id(dev);
-
-	tps65912_get_mode_regiters(pmic, id);
-
-	pwm_mode = tps65912_reg_read(mfd, pmic->pwm_mode_reg);
-	eco = tps65912_reg_read(mfd, pmic->eco_reg);
-
-	pwm_mode &= DCDCCTRL_DCDC_MODE_MASK;
-	eco &= DCDC_AVS_ECO_MASK;
-
-	switch (mode) {
-	case REGULATOR_MODE_FAST:
-		/* Verify if mode alredy set */
-		if (pwm_mode && !eco)
-			break;
-		tps65912_set_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK);
-		tps65912_clear_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK);
-		break;
-	case REGULATOR_MODE_NORMAL:
-	case REGULATOR_MODE_IDLE:
-		if (!pwm_mode && !eco)
-			break;
-		tps65912_clear_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK);
-		tps65912_clear_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK);
-		break;
-	case REGULATOR_MODE_STANDBY:
-		if (!pwm_mode && eco)
-			break;
-		tps65912_clear_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK);
-		tps65912_set_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static unsigned int tps65912_get_mode(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int pwm_mode, eco, mode = 0, id = rdev_get_id(dev);
-
-	tps65912_get_mode_regiters(pmic, id);
-
-	pwm_mode = tps65912_reg_read(mfd, pmic->pwm_mode_reg);
-	eco = tps65912_reg_read(mfd, pmic->eco_reg);
-
-	pwm_mode &= DCDCCTRL_DCDC_MODE_MASK;
-	eco &= DCDC_AVS_ECO_MASK;
-
-	if (pwm_mode && !eco)
-		mode = REGULATOR_MODE_FAST;
-	else if (!pwm_mode && !eco)
-		mode = REGULATOR_MODE_NORMAL;
-	else if (!pwm_mode && eco)
-		mode = REGULATOR_MODE_STANDBY;
-
-	return mode;
-}
-
-static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	int range, voltage = 0, id = rdev_get_id(dev);
-
-	if (id > TPS65912_REG_DCDC4)
-		return -EINVAL;
-
-	range = pmic->dcdc_range[id];
-
-	switch (range) {
-	case 0:
-		/* 0.5 - 1.2875V in 12.5mV steps */
-		voltage = tps65912_vsel_to_uv_range0(selector);
-		break;
-	case 1:
-		/* 0.7 - 1.4875V in 12.5mV steps */
-		voltage = tps65912_vsel_to_uv_range1(selector);
-		break;
-	case 2:
-		/* 0.5 - 2.075V in 25mV steps */
-		voltage = tps65912_vsel_to_uv_range2(selector);
-		break;
-	case 3:
-		/* 0.5 - 3.8V in 50mV steps */
-		voltage = tps65912_vsel_to_uv_range3(selector);
-		break;
-	}
-	return voltage;
-}
-
-static int tps65912_get_voltage_sel(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev);
-	int reg, vsel;
-
-	reg = tps65912_get_sel_register(pmic, id);
-	if (reg < 0)
-		return reg;
-
-	vsel = tps65912_reg_read(mfd, reg);
-	vsel &= 0x3F;
-
-	return vsel;
-}
-
-static int tps65912_set_voltage_sel(struct regulator_dev *dev,
-					 unsigned selector)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev);
-	int value;
-	u8 reg;
-
-	reg = tps65912_get_sel_register(pmic, id);
-	value = tps65912_reg_read(mfd, reg);
-	value &= 0xC0;
-	return tps65912_reg_write(mfd, reg, selector | value);
-}
-
-/* Operations permitted on DCDCx */
-static struct regulator_ops tps65912_ops_dcdc = {
-	.is_enabled = tps65912_reg_is_enabled,
-	.enable = tps65912_reg_enable,
-	.disable = tps65912_reg_disable,
-	.set_mode = tps65912_set_mode,
-	.get_mode = tps65912_get_mode,
-	.get_voltage_sel = tps65912_get_voltage_sel,
-	.set_voltage_sel = tps65912_set_voltage_sel,
-	.list_voltage = tps65912_list_voltage,
-};
-
-/* Operations permitted on LDOx */
-static struct regulator_ops tps65912_ops_ldo = {
-	.is_enabled = tps65912_reg_is_enabled,
-	.enable = tps65912_reg_enable,
-	.disable = tps65912_reg_disable,
-	.get_voltage_sel = tps65912_get_voltage_sel,
-	.set_voltage_sel = tps65912_set_voltage_sel,
-	.list_voltage = regulator_list_voltage_linear_range,
-	.map_voltage = regulator_map_voltage_linear_range,
-};
-
-static int tps65912_probe(struct platform_device *pdev)
-{
-	struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
-	struct regulator_config config = { };
-	struct tps_info *info;
-	struct regulator_init_data *reg_data;
-	struct regulator_dev *rdev;
-	struct tps65912_reg *pmic;
-	struct tps65912_board *pmic_plat_data;
-	int i;
-
-	pmic_plat_data = dev_get_platdata(tps65912->dev);
-	if (!pmic_plat_data)
-		return -EINVAL;
-
-	reg_data = pmic_plat_data->tps65912_pmic_init_data;
-
-	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
-	if (!pmic)
-		return -ENOMEM;
-
-	mutex_init(&pmic->io_lock);
-	pmic->mfd = tps65912;
-	platform_set_drvdata(pdev, pmic);
-
-	pmic->get_ctrl_reg = &tps65912_get_ctrl_register;
-	info = tps65912_regs;
-
-	for (i = 0; i < TPS65912_NUM_REGULATOR; i++, info++, reg_data++) {
-		int range = 0;
-		/* Register the regulators */
-		pmic->info[i] = info;
-
-		pmic->desc[i].name = info->name;
-		pmic->desc[i].id = i;
-		pmic->desc[i].n_voltages = 64;
-		if (i > TPS65912_REG_DCDC4) {
-			pmic->desc[i].ops = &tps65912_ops_ldo;
-			pmic->desc[i].linear_ranges = tps65912_ldo_ranges;
-			pmic->desc[i].n_linear_ranges =
-					ARRAY_SIZE(tps65912_ldo_ranges);
-		} else {
-			pmic->desc[i].ops = &tps65912_ops_dcdc;
-		}
-		pmic->desc[i].type = REGULATOR_VOLTAGE;
-		pmic->desc[i].owner = THIS_MODULE;
-		range = tps65912_get_range(pmic, i);
-
-		config.dev = tps65912->dev;
-		config.init_data = reg_data;
-		config.driver_data = pmic;
-
-		rdev = devm_regulator_register(&pdev->dev, &pmic->desc[i],
-					       &config);
-		if (IS_ERR(rdev)) {
-			dev_err(tps65912->dev,
-				"failed to register %s regulator\n",
-				pdev->name);
-			return PTR_ERR(rdev);
-		}
-
-		/* Save regulator for cleanup */
-		pmic->rdev[i] = rdev;
-	}
-	return 0;
-}
-
-static struct platform_driver tps65912_driver = {
-	.driver = {
-		.name = "tps65912-pmic",
-	},
-	.probe = tps65912_probe,
-};
-
-static int __init tps65912_init(void)
-{
-	return platform_driver_register(&tps65912_driver);
-}
-subsys_initcall(tps65912_init);
-
-static void __exit tps65912_cleanup(void)
-{
-	platform_driver_unregister(&tps65912_driver);
-}
-module_exit(tps65912_cleanup);
-
-MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("TPS65912 voltage regulator driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tps65912-pmic");
diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h
deleted file mode 100644
index 6d30903..0000000
--- a/include/linux/mfd/tps65912.h
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * tps65912.h  --  TI TPS6591x
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- */
-
-#ifndef __LINUX_MFD_TPS65912_H
-#define __LINUX_MFD_TPS65912_H
-
-/* TPS regulator type list */
-#define REGULATOR_LDO		0
-#define REGULATOR_DCDC		1
-
-/*
- * List of registers for TPS65912
- */
-
-#define TPS65912_DCDC1_CTRL		0x00
-#define TPS65912_DCDC2_CTRL		0x01
-#define TPS65912_DCDC3_CTRL		0x02
-#define TPS65912_DCDC4_CTRL		0x03
-#define TPS65912_DCDC1_OP		0x04
-#define TPS65912_DCDC1_AVS		0x05
-#define TPS65912_DCDC1_LIMIT		0x06
-#define TPS65912_DCDC2_OP		0x07
-#define TPS65912_DCDC2_AVS		0x08
-#define TPS65912_DCDC2_LIMIT		0x09
-#define TPS65912_DCDC3_OP		0x0A
-#define TPS65912_DCDC3_AVS		0x0B
-#define TPS65912_DCDC3_LIMIT		0x0C
-#define TPS65912_DCDC4_OP		0x0D
-#define TPS65912_DCDC4_AVS		0x0E
-#define TPS65912_DCDC4_LIMIT		0x0F
-#define TPS65912_LDO1_OP		0x10
-#define TPS65912_LDO1_AVS		0x11
-#define TPS65912_LDO1_LIMIT		0x12
-#define TPS65912_LDO2_OP		0x13
-#define TPS65912_LDO2_AVS		0x14
-#define TPS65912_LDO2_LIMIT		0x15
-#define TPS65912_LDO3_OP		0x16
-#define TPS65912_LDO3_AVS		0x17
-#define TPS65912_LDO3_LIMIT		0x18
-#define TPS65912_LDO4_OP		0x19
-#define TPS65912_LDO4_AVS		0x1A
-#define TPS65912_LDO4_LIMIT		0x1B
-#define TPS65912_LDO5			0x1C
-#define TPS65912_LDO6			0x1D
-#define TPS65912_LDO7			0x1E
-#define TPS65912_LDO8			0x1F
-#define TPS65912_LDO9			0x20
-#define TPS65912_LDO10			0x21
-#define TPS65912_THRM			0x22
-#define TPS65912_CLK32OUT		0x23
-#define TPS65912_DEVCTRL		0x24
-#define TPS65912_DEVCTRL2		0x25
-#define TPS65912_I2C_SPI_CFG		0x26
-#define TPS65912_KEEP_ON		0x27
-#define TPS65912_KEEP_ON2		0x28
-#define TPS65912_SET_OFF1		0x29
-#define TPS65912_SET_OFF2		0x2A
-#define TPS65912_DEF_VOLT		0x2B
-#define TPS65912_DEF_VOLT_MAPPING	0x2C
-#define TPS65912_DISCHARGE		0x2D
-#define TPS65912_DISCHARGE2		0x2E
-#define TPS65912_EN1_SET1		0x2F
-#define TPS65912_EN1_SET2		0x30
-#define TPS65912_EN2_SET1		0x31
-#define TPS65912_EN2_SET2		0x32
-#define TPS65912_EN3_SET1		0x33
-#define TPS65912_EN3_SET2		0x34
-#define TPS65912_EN4_SET1		0x35
-#define TPS65912_EN4_SET2		0x36
-#define TPS65912_PGOOD			0x37
-#define TPS65912_PGOOD2			0x38
-#define TPS65912_INT_STS		0x39
-#define TPS65912_INT_MSK		0x3A
-#define TPS65912_INT_STS2		0x3B
-#define TPS65912_INT_MSK2		0x3C
-#define TPS65912_INT_STS3		0x3D
-#define TPS65912_INT_MSK3		0x3E
-#define TPS65912_INT_STS4		0x3F
-#define TPS65912_INT_MSK4		0x40
-#define TPS65912_GPIO1			0x41
-#define TPS65912_GPIO2			0x42
-#define TPS65912_GPIO3			0x43
-#define TPS65912_GPIO4			0x44
-#define TPS65912_GPIO5			0x45
-#define TPS65912_VMON			0x46
-#define TPS65912_LEDA_CTRL1		0x47
-#define TPS65912_LEDA_CTRL2		0x48
-#define TPS65912_LEDA_CTRL3		0x49
-#define TPS65912_LEDA_CTRL4		0x4A
-#define TPS65912_LEDA_CTRL5		0x4B
-#define TPS65912_LEDA_CTRL6		0x4C
-#define TPS65912_LEDA_CTRL7		0x4D
-#define TPS65912_LEDA_CTRL8		0x4E
-#define TPS65912_LEDB_CTRL1		0x4F
-#define TPS65912_LEDB_CTRL2		0x50
-#define TPS65912_LEDB_CTRL3		0x51
-#define TPS65912_LEDB_CTRL4		0x52
-#define TPS65912_LEDB_CTRL5		0x53
-#define TPS65912_LEDB_CTRL6		0x54
-#define TPS65912_LEDB_CTRL7		0x55
-#define TPS65912_LEDB_CTRL8		0x56
-#define TPS65912_LEDC_CTRL1		0x57
-#define TPS65912_LEDC_CTRL2		0x58
-#define TPS65912_LEDC_CTRL3		0x59
-#define TPS65912_LEDC_CTRL4		0x5A
-#define TPS65912_LEDC_CTRL5		0x5B
-#define TPS65912_LEDC_CTRL6		0x5C
-#define TPS65912_LEDC_CTRL7		0x5D
-#define TPS65912_LEDC_CTRL8		0x5E
-#define TPS65912_LED_RAMP_UP_TIME	0x5F
-#define TPS65912_LED_RAMP_DOWN_TIME	0x60
-#define TPS65912_LED_SEQ_EN		0x61
-#define TPS65912_LOADSWITCH		0x62
-#define TPS65912_SPARE			0x63
-#define TPS65912_VERNUM			0x64
-#define TPS6591X_MAX_REGISTER		0x64
-
-/* IRQ Definitions */
-#define TPS65912_IRQ_PWRHOLD_F		0
-#define TPS65912_IRQ_VMON		1
-#define TPS65912_IRQ_PWRON		2
-#define TPS65912_IRQ_PWRON_LP		3
-#define TPS65912_IRQ_PWRHOLD_R		4
-#define TPS65912_IRQ_HOTDIE		5
-#define TPS65912_IRQ_GPIO1_R		6
-#define TPS65912_IRQ_GPIO1_F		7
-#define TPS65912_IRQ_GPIO2_R		8
-#define TPS65912_IRQ_GPIO2_F		9
-#define TPS65912_IRQ_GPIO3_R		10
-#define TPS65912_IRQ_GPIO3_F		11
-#define TPS65912_IRQ_GPIO4_R		12
-#define TPS65912_IRQ_GPIO4_F		13
-#define TPS65912_IRQ_GPIO5_R		14
-#define TPS65912_IRQ_GPIO5_F		15
-#define TPS65912_IRQ_PGOOD_DCDC1	16
-#define TPS65912_IRQ_PGOOD_DCDC2	17
-#define TPS65912_IRQ_PGOOD_DCDC3	18
-#define TPS65912_IRQ_PGOOD_DCDC4	19
-#define TPS65912_IRQ_PGOOD_LDO1		20
-#define TPS65912_IRQ_PGOOD_LDO2		21
-#define TPS65912_IRQ_PGOOD_LDO3		22
-#define TPS65912_IRQ_PGOOD_LDO4		23
-#define TPS65912_IRQ_PGOOD_LDO5		24
-#define TPS65912_IRQ_PGOOD_LDO6		25
-#define TPS65912_IRQ_PGOOD_LDO7		26
-#define TPS65912_IRQ_PGOOD_LD08		27
-#define TPS65912_IRQ_PGOOD_LDO9		28
-#define TPS65912_IRQ_PGOOD_LDO10	29
-
-#define TPS65912_NUM_IRQ		30
-
-/* GPIO 1 and 2 Register Definitions */
-#define GPIO_SLEEP_MASK			0x80
-#define GPIO_SLEEP_SHIFT		7
-#define GPIO_DEB_MASK			0x10
-#define GPIO_DEB_SHIFT			4
-#define GPIO_CFG_MASK			0x04
-#define GPIO_CFG_SHIFT			2
-#define GPIO_STS_MASK			0x02
-#define GPIO_STS_SHIFT			1
-#define GPIO_SET_MASK			0x01
-#define GPIO_SET_SHIFT			0
-
-/* GPIO 3 Register Definitions */
-#define GPIO3_SLEEP_MASK		0x80
-#define GPIO3_SLEEP_SHIFT		7
-#define GPIO3_SEL_MASK			0x40
-#define GPIO3_SEL_SHIFT			6
-#define GPIO3_ODEN_MASK			0x20
-#define GPIO3_ODEN_SHIFT		5
-#define GPIO3_DEB_MASK			0x10
-#define GPIO3_DEB_SHIFT			4
-#define GPIO3_PDEN_MASK			0x08
-#define GPIO3_PDEN_SHIFT		3
-#define GPIO3_CFG_MASK			0x04
-#define GPIO3_CFG_SHIFT			2
-#define GPIO3_STS_MASK			0x02
-#define GPIO3_STS_SHIFT			1
-#define GPIO3_SET_MASK			0x01
-#define GPIO3_SET_SHIFT			0
-
-/* GPIO 4 Register Definitions */
-#define GPIO4_SLEEP_MASK		0x80
-#define GPIO4_SLEEP_SHIFT		7
-#define GPIO4_SEL_MASK			0x40
-#define GPIO4_SEL_SHIFT			6
-#define GPIO4_ODEN_MASK			0x20
-#define GPIO4_ODEN_SHIFT		5
-#define GPIO4_DEB_MASK			0x10
-#define GPIO4_DEB_SHIFT			4
-#define GPIO4_PDEN_MASK			0x08
-#define GPIO4_PDEN_SHIFT		3
-#define GPIO4_CFG_MASK			0x04
-#define GPIO4_CFG_SHIFT			2
-#define GPIO4_STS_MASK			0x02
-#define GPIO4_STS_SHIFT			1
-#define GPIO4_SET_MASK			0x01
-#define GPIO4_SET_SHIFT			0
-
-/* Register THERM  (0x80) register.RegisterDescription */
-#define THERM_THERM_HD_MASK		0x20
-#define THERM_THERM_HD_SHIFT		5
-#define THERM_THERM_TS_MASK		0x10
-#define THERM_THERM_TS_SHIFT		4
-#define THERM_THERM_HDSEL_MASK		0x0C
-#define THERM_THERM_HDSEL_SHIFT		2
-#define THERM_RSVD1_MASK		0x02
-#define THERM_RSVD1_SHIFT		1
-#define THERM_THERM_STATE_MASK		0x01
-#define THERM_THERM_STATE_SHIFT		0
-
-/* Register DCDCCTRL1 register.RegisterDescription */
-#define DCDCCTRL_VCON_ENABLE_MASK	0x80
-#define DCDCCTRL_VCON_ENABLE_SHIFT	7
-#define DCDCCTRL_VCON_RANGE1_MASK	0x40
-#define DCDCCTRL_VCON_RANGE1_SHIFT	6
-#define DCDCCTRL_VCON_RANGE0_MASK	0x20
-#define DCDCCTRL_VCON_RANGE0_SHIFT	5
-#define DCDCCTRL_TSTEP2_MASK		0x10
-#define DCDCCTRL_TSTEP2_SHIFT		4
-#define DCDCCTRL_TSTEP1_MASK		0x08
-#define DCDCCTRL_TSTEP1_SHIFT		3
-#define DCDCCTRL_TSTEP0_MASK		0x04
-#define DCDCCTRL_TSTEP0_SHIFT		2
-#define DCDCCTRL_DCDC1_MODE_MASK	0x02
-#define DCDCCTRL_DCDC1_MODE_SHIFT	1
-
-/* Register DCDCCTRL2 and DCDCCTRL3 register.RegisterDescription */
-#define DCDCCTRL_TSTEP2_MASK		0x10
-#define DCDCCTRL_TSTEP2_SHIFT		4
-#define DCDCCTRL_TSTEP1_MASK		0x08
-#define DCDCCTRL_TSTEP1_SHIFT		3
-#define DCDCCTRL_TSTEP0_MASK		0x04
-#define DCDCCTRL_TSTEP0_SHIFT		2
-#define DCDCCTRL_DCDC_MODE_MASK		0x02
-#define DCDCCTRL_DCDC_MODE_SHIFT	1
-#define DCDCCTRL_RSVD0_MASK		0x01
-#define DCDCCTRL_RSVD0_SHIFT		0
-
-/* Register DCDCCTRL4 register.RegisterDescription */
-#define DCDCCTRL_RAMP_TIME_MASK		0x01
-#define DCDCCTRL_RAMP_TIME_SHIFT	0
-
-/* Register DCDCx_AVS */
-#define DCDC_AVS_ENABLE_MASK		0x80
-#define DCDC_AVS_ENABLE_SHIFT		7
-#define DCDC_AVS_ECO_MASK		0x40
-#define DCDC_AVS_ECO_SHIFT		6
-
-/* Register DCDCx_LIMIT */
-#define DCDC_LIMIT_RANGE_MASK		0xC0
-#define DCDC_LIMIT_RANGE_SHIFT		6
-#define DCDC_LIMIT_MAX_SEL_MASK		0x3F
-#define DCDC_LIMIT_MAX_SEL_SHIFT	0
-
-/**
- * struct tps65912_board
- * Board platform dat may be used to initialize regulators.
- */
-struct tps65912_board {
-	int is_dcdc1_avs;
-	int is_dcdc2_avs;
-	int is_dcdc3_avs;
-	int is_dcdc4_avs;
-	int irq;
-	int irq_base;
-	int gpio_base;
-	struct regulator_init_data *tps65912_pmic_init_data;
-};
-
-/**
- * struct tps65912 - tps65912 sub-driver chip access routines
- */
-
-struct tps65912 {
-	struct device *dev;
-	/* for read/write acces */
-	struct mutex io_mutex;
-
-	/* For device IO interfaces: I2C or SPI */
-	void *control_data;
-
-	int (*read)(struct tps65912 *tps65912, u8 reg, int size, void *dest);
-	int (*write)(struct tps65912 *tps65912, u8 reg, int size, void *src);
-
-	/* Client devices */
-	struct tps65912_pmic *pmic;
-
-	/* GPIO Handling */
-	struct gpio_chip gpio;
-
-	/* IRQ Handling */
-	struct mutex irq_lock;
-	int chip_irq;
-	int irq_base;
-	int irq_num;
-	u32 irq_mask;
-};
-
-struct tps65912_platform_data {
-	int irq;
-	int irq_base;
-};
-
-unsigned int tps_chip(void);
-
-int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask);
-int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask);
-int tps65912_reg_read(struct tps65912 *tps65912, u8 reg);
-int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val);
-int tps65912_device_init(struct tps65912 *tps65912);
-void tps65912_device_exit(struct tps65912 *tps65912);
-int tps65912_irq_init(struct tps65912 *tps65912, int irq,
-			struct tps65912_platform_data *pdata);
-int tps65912_irq_exit(struct tps65912 *tps65912);
-
-#endif /*  __LINUX_MFD_TPS65912_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 2/5] mfd: tps65912: Remove old driver in preparation for new driver
@ 2015-09-24 14:52   ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

The old tps65912 driver is being replaced, delete old driver.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/gpio/Kconfig                   |   6 -
 drivers/gpio/Makefile                  |   1 -
 drivers/gpio/gpio-tps65912.c           | 153 ----------
 drivers/mfd/Kconfig                    |  26 --
 drivers/mfd/Makefile                   |   4 -
 drivers/mfd/tps65912-core.c            | 175 -----------
 drivers/mfd/tps65912-i2c.c             | 139 ---------
 drivers/mfd/tps65912-irq.c             | 217 -------------
 drivers/mfd/tps65912-spi.c             | 141 ---------
 drivers/regulator/Kconfig              |   6 -
 drivers/regulator/Makefile             |   1 -
 drivers/regulator/tps65912-regulator.c | 541 ---------------------------------
 include/linux/mfd/tps65912.h           | 328 --------------------
 13 files changed, 1738 deletions(-)
 delete mode 100644 drivers/gpio/gpio-tps65912.c
 delete mode 100644 drivers/mfd/tps65912-core.c
 delete mode 100644 drivers/mfd/tps65912-i2c.c
 delete mode 100644 drivers/mfd/tps65912-irq.c
 delete mode 100644 drivers/mfd/tps65912-spi.c
 delete mode 100644 drivers/regulator/tps65912-regulator.c
 delete mode 100644 include/linux/mfd/tps65912.h

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b4fc9e4..fb28483 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -838,12 +838,6 @@ config GPIO_TPS65910
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
 
-config GPIO_TPS65912
-	tristate "TI TPS65912 GPIO"
-	depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI)
-	help
-	  This driver supports TPS65912 gpio chip
-
 config GPIO_TWL4030
 	tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
 	depends on TWL4030_CORE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f79a7c4..605bf89 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -96,7 +96,6 @@ obj-$(CONFIG_GPIO_TIMBERDALE)	+= gpio-timberdale.o
 obj-$(CONFIG_GPIO_PALMAS)	+= gpio-palmas.o
 obj-$(CONFIG_GPIO_TPS6586X)	+= gpio-tps6586x.o
 obj-$(CONFIG_GPIO_TPS65910)	+= gpio-tps65910.o
-obj-$(CONFIG_GPIO_TPS65912)	+= gpio-tps65912.o
 obj-$(CONFIG_GPIO_TS5500)	+= gpio-ts5500.o
 obj-$(CONFIG_GPIO_TWL4030)	+= gpio-twl4030.o
 obj-$(CONFIG_GPIO_TWL6040)	+= gpio-twl6040.o
diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
deleted file mode 100644
index 9cdbc0c..0000000
--- a/drivers/gpio/gpio-tps65912.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- * This driver is based on wm8350 implementation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/mfd/core.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/mfd/tps65912.h>
-
-struct tps65912_gpio_data {
-	struct tps65912 *tps65912;
-	struct gpio_chip gpio_chip;
-};
-
-#define to_tgd(gc) container_of(gc, struct tps65912_gpio_data, gpio_chip)
-
-static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-	int val;
-
-	val = tps65912_reg_read(tps65912, TPS65912_GPIO1 + offset);
-
-	if (val & GPIO_STS_MASK)
-		return 1;
-
-	return 0;
-}
-
-static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
-			      int value)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-
-	if (value)
-		tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset,
-							GPIO_SET_MASK);
-	else
-		tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset,
-								GPIO_SET_MASK);
-}
-
-static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
-				int value)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-
-	/* Set the initial value */
-	tps65912_gpio_set(gc, offset, value);
-
-	return tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset,
-								GPIO_CFG_MASK);
-}
-
-static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
-{
-	struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc);
-	struct tps65912 *tps65912 = tps65912_gpio->tps65912;
-
-	return tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset,
-								GPIO_CFG_MASK);
-}
-
-static struct gpio_chip template_chip = {
-	.label			= "tps65912",
-	.owner			= THIS_MODULE,
-	.direction_input	= tps65912_gpio_input,
-	.direction_output	= tps65912_gpio_output,
-	.get			= tps65912_gpio_get,
-	.set			= tps65912_gpio_set,
-	.can_sleep		= true,
-	.ngpio			= 5,
-	.base			= -1,
-};
-
-static int tps65912_gpio_probe(struct platform_device *pdev)
-{
-	struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
-	struct tps65912_board *pdata = dev_get_platdata(tps65912->dev);
-	struct tps65912_gpio_data *tps65912_gpio;
-	int ret;
-
-	tps65912_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65912_gpio),
-				     GFP_KERNEL);
-	if (tps65912_gpio == NULL)
-		return -ENOMEM;
-
-	tps65912_gpio->tps65912 = tps65912;
-	tps65912_gpio->gpio_chip = template_chip;
-	tps65912_gpio->gpio_chip.dev = &pdev->dev;
-	if (pdata && pdata->gpio_base)
-		tps65912_gpio->gpio_chip.base = pdata->gpio_base;
-
-	ret = gpiochip_add(&tps65912_gpio->gpio_chip);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret);
-		return ret;
-	}
-
-	platform_set_drvdata(pdev, tps65912_gpio);
-
-	return ret;
-}
-
-static int tps65912_gpio_remove(struct platform_device *pdev)
-{
-	struct tps65912_gpio_data  *tps65912_gpio = platform_get_drvdata(pdev);
-
-	gpiochip_remove(&tps65912_gpio->gpio_chip);
-	return 0;
-}
-
-static struct platform_driver tps65912_gpio_driver = {
-	.driver = {
-		.name = "tps65912-gpio",
-	},
-	.probe = tps65912_gpio_probe,
-	.remove = tps65912_gpio_remove,
-};
-
-static int __init tps65912_gpio_init(void)
-{
-	return platform_driver_register(&tps65912_gpio_driver);
-}
-subsys_initcall(tps65912_gpio_init);
-
-static void __exit tps65912_gpio_exit(void)
-{
-	platform_driver_unregister(&tps65912_gpio_driver);
-}
-module_exit(tps65912_gpio_exit);
-
-MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("GPIO interface for TPS65912 PMICs");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tps65912-gpio");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 99d6367..9a8df8e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1167,32 +1167,6 @@ config MFD_TPS65910
 	  if you say yes here you get support for the TPS65910 series of
 	  Power Management chips.
 
-config MFD_TPS65912
-	bool "TI TPS65912 Power Management chip"
-	depends on GPIOLIB
-	select MFD_CORE
-	help
-	  If you say yes here you get support for the TPS65912 series of
-	  PM chips.
-
-config MFD_TPS65912_I2C
-	bool "TI TPS65912 Power Management chip with I2C"
-	select MFD_CORE
-	select MFD_TPS65912
-	depends on I2C=y && GPIOLIB
-	help
-	  If you say yes here you get support for the TPS65912 series of
-	  PM chips with I2C interface.
-
-config MFD_TPS65912_SPI
-	bool "TI TPS65912 Power Management chip with SPI"
-	select MFD_CORE
-	select MFD_TPS65912
-	depends on SPI_MASTER && GPIOLIB
-	help
-	  If you say yes here you get support for the TPS65912 series of
-	  PM chips with SPI interface.
-
 config MFD_TPS80031
 	bool "TI TPS80031/TPS80032 Power Management chips"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a59e3fc..004aa76 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -69,10 +69,6 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
-tps65912-objs                   := tps65912-core.o tps65912-irq.o
-obj-$(CONFIG_MFD_TPS65912)	+= tps65912.o
-obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
-obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
 obj-$(CONFIG_MFD_TPS80031)	+= tps80031.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
deleted file mode 100644
index 1f82d60..0000000
--- a/drivers/mfd/tps65912-core.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * tps65912-core.c  --  TI TPS65912x
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This driver is based on wm8350 implementation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/tps65912.h>
-
-static const struct mfd_cell tps65912s[] = {
-	{
-		.name = "tps65912-pmic",
-	},
-};
-
-int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask)
-{
-	u8 data;
-	int err;
-
-	mutex_lock(&tps65912->io_mutex);
-
-	err = tps65912->read(tps65912, reg, 1, &data);
-	if (err) {
-		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
-		goto out;
-	}
-
-	data |= mask;
-	err = tps65912->write(tps65912, reg, 1, &data);
-	if (err)
-		dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);
-
-out:
-	mutex_unlock(&tps65912->io_mutex);
-	return err;
-}
-EXPORT_SYMBOL_GPL(tps65912_set_bits);
-
-int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask)
-{
-	u8 data;
-	int err;
-
-	mutex_lock(&tps65912->io_mutex);
-	err = tps65912->read(tps65912, reg, 1, &data);
-	if (err) {
-		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
-		goto out;
-	}
-
-	data &= ~mask;
-	err = tps65912->write(tps65912, reg, 1, &data);
-	if (err)
-		dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);
-
-out:
-	mutex_unlock(&tps65912->io_mutex);
-	return err;
-}
-EXPORT_SYMBOL_GPL(tps65912_clear_bits);
-
-static inline int tps65912_read(struct tps65912 *tps65912, u8 reg)
-{
-	u8 val;
-	int err;
-
-	err = tps65912->read(tps65912, reg, 1, &val);
-	if (err < 0)
-		return err;
-
-	return val;
-}
-
-static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val)
-{
-	return tps65912->write(tps65912, reg, 1, &val);
-}
-
-int tps65912_reg_read(struct tps65912 *tps65912, u8 reg)
-{
-	int data;
-
-	mutex_lock(&tps65912->io_mutex);
-
-	data = tps65912_read(tps65912, reg);
-	if (data < 0)
-		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
-
-	mutex_unlock(&tps65912->io_mutex);
-	return data;
-}
-EXPORT_SYMBOL_GPL(tps65912_reg_read);
-
-int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val)
-{
-	int err;
-
-	mutex_lock(&tps65912->io_mutex);
-
-	err = tps65912_write(tps65912, reg, val);
-	if (err < 0)
-		dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg);
-
-	mutex_unlock(&tps65912->io_mutex);
-	return err;
-}
-EXPORT_SYMBOL_GPL(tps65912_reg_write);
-
-int tps65912_device_init(struct tps65912 *tps65912)
-{
-	struct tps65912_board *pmic_plat_data = dev_get_platdata(tps65912->dev);
-	struct tps65912_platform_data *init_data;
-	int ret, dcdc_avs, value;
-
-	init_data = kzalloc(sizeof(struct tps65912_platform_data), GFP_KERNEL);
-	if (init_data == NULL)
-		return -ENOMEM;
-
-	mutex_init(&tps65912->io_mutex);
-	dev_set_drvdata(tps65912->dev, tps65912);
-
-	dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 |
-			pmic_plat_data->is_dcdc2_avs  << 1 |
-				pmic_plat_data->is_dcdc3_avs << 2 |
-					pmic_plat_data->is_dcdc4_avs << 3);
-	if (dcdc_avs) {
-		tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value);
-		dcdc_avs |= value;
-		tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs);
-	}
-
-	ret = mfd_add_devices(tps65912->dev, -1,
-			      tps65912s, ARRAY_SIZE(tps65912s),
-			      NULL, 0, NULL);
-	if (ret < 0)
-		goto err;
-
-	init_data->irq = pmic_plat_data->irq;
-	init_data->irq_base = pmic_plat_data->irq_base;
-	ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
-	if (ret < 0)
-		goto err;
-
-	kfree(init_data);
-	return ret;
-
-err:
-	kfree(init_data);
-	mfd_remove_devices(tps65912->dev);
-	return ret;
-}
-
-void tps65912_device_exit(struct tps65912 *tps65912)
-{
-	mfd_remove_devices(tps65912->dev);
-	tps65912_irq_exit(tps65912);
-}
-
-MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("TPS65912x chip family multi-function driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c
deleted file mode 100644
index 7e55640..0000000
--- a/drivers/mfd/tps65912-i2c.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * tps65912-i2c.c  --  I2C access for TI TPS65912x PMIC
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This driver is based on wm8350 implementation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/tps65912.h>
-
-static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg,
-				  int bytes, void *dest)
-{
-	struct i2c_client *i2c = tps65912->control_data;
-	struct i2c_msg xfer[2];
-	int ret;
-
-	/* Write register */
-	xfer[0].addr = i2c->addr;
-	xfer[0].flags = 0;
-	xfer[0].len = 1;
-	xfer[0].buf = &reg;
-
-	/* Read data */
-	xfer[1].addr = i2c->addr;
-	xfer[1].flags = I2C_M_RD;
-	xfer[1].len = bytes;
-	xfer[1].buf = dest;
-
-	ret = i2c_transfer(i2c->adapter, xfer, 2);
-	if (ret == 2)
-		ret = 0;
-	else if (ret >= 0)
-		ret = -EIO;
-	return ret;
-}
-
-static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg,
-				   int bytes, void *src)
-{
-	struct i2c_client *i2c = tps65912->control_data;
-	/* we add 1 byte for device register */
-	u8 msg[TPS6591X_MAX_REGISTER + 1];
-	int ret;
-
-	if (bytes > TPS6591X_MAX_REGISTER)
-		return -EINVAL;
-
-	msg[0] = reg;
-	memcpy(&msg[1], src, bytes);
-
-	ret = i2c_master_send(i2c, msg, bytes + 1);
-	if (ret < 0)
-		return ret;
-	if (ret != bytes + 1)
-		return -EIO;
-
-	return 0;
-}
-
-static int tps65912_i2c_probe(struct i2c_client *i2c,
-			    const struct i2c_device_id *id)
-{
-	struct tps65912 *tps65912;
-
-	tps65912 = devm_kzalloc(&i2c->dev,
-				sizeof(struct tps65912), GFP_KERNEL);
-	if (tps65912 == NULL)
-		return -ENOMEM;
-
-	i2c_set_clientdata(i2c, tps65912);
-	tps65912->dev = &i2c->dev;
-	tps65912->control_data = i2c;
-	tps65912->read = tps65912_i2c_read;
-	tps65912->write = tps65912_i2c_write;
-
-	return tps65912_device_init(tps65912);
-}
-
-static int tps65912_i2c_remove(struct i2c_client *i2c)
-{
-	struct tps65912 *tps65912 = i2c_get_clientdata(i2c);
-
-	tps65912_device_exit(tps65912);
-
-	return 0;
-}
-
-static const struct i2c_device_id tps65912_i2c_id[] = {
-	{"tps65912", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id);
-
-static struct i2c_driver tps65912_i2c_driver = {
-	.driver = {
-		   .name = "tps65912",
-	},
-	.probe = tps65912_i2c_probe,
-	.remove = tps65912_i2c_remove,
-	.id_table = tps65912_i2c_id,
-};
-
-static int __init tps65912_i2c_init(void)
-{
-	int ret;
-
-	ret = i2c_add_driver(&tps65912_i2c_driver);
-	if (ret != 0)
-		pr_err("Failed to register TPS65912 I2C driver: %d\n", ret);
-
-	return ret;
-}
-/* init early so consumer devices can complete system boot */
-subsys_initcall(tps65912_i2c_init);
-
-static void __exit tps65912_i2c_exit(void)
-{
-	i2c_del_driver(&tps65912_i2c_driver);
-}
-module_exit(tps65912_i2c_exit);
-
-MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("TPS6591x chip family multi-function driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps65912-irq.c b/drivers/mfd/tps65912-irq.c
deleted file mode 100644
index db2c29c..0000000
--- a/drivers/mfd/tps65912-irq.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * tps65912-irq.c  --  TI TPS6591x
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- * This driver is based on wm8350 implementation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/mfd/tps65912.h>
-
-static inline int irq_to_tps65912_irq(struct tps65912 *tps65912,
-							int irq)
-{
-	return irq - tps65912->irq_base;
-}
-
-/*
- * This is a threaded IRQ handler so can access I2C/SPI.  Since the
- * IRQ handler explicitly clears the IRQ it handles the IRQ line
- * will be reasserted and the physical IRQ will be handled again if
- * another interrupt is asserted while we run - in the normal course
- * of events this is a rare occurrence so we save I2C/SPI reads. We're
- * also assuming that it's rare to get lots of interrupts firing
- * simultaneously so try to minimise I/O.
- */
-static irqreturn_t tps65912_irq(int irq, void *irq_data)
-{
-	struct tps65912 *tps65912 = irq_data;
-	u32 irq_sts;
-	u32 irq_mask;
-	u8 reg;
-	int i;
-
-
-	tps65912->read(tps65912, TPS65912_INT_STS, 1, &reg);
-	irq_sts = reg;
-	tps65912->read(tps65912, TPS65912_INT_STS2, 1, &reg);
-	irq_sts |= reg << 8;
-	tps65912->read(tps65912, TPS65912_INT_STS3, 1, &reg);
-	irq_sts |= reg << 16;
-	tps65912->read(tps65912, TPS65912_INT_STS4, 1, &reg);
-	irq_sts |= reg << 24;
-
-	tps65912->read(tps65912, TPS65912_INT_MSK, 1, &reg);
-	irq_mask = reg;
-	tps65912->read(tps65912, TPS65912_INT_MSK2, 1, &reg);
-	irq_mask |= reg << 8;
-	tps65912->read(tps65912, TPS65912_INT_MSK3, 1, &reg);
-	irq_mask |= reg << 16;
-	tps65912->read(tps65912, TPS65912_INT_MSK4, 1, &reg);
-	irq_mask |= reg << 24;
-
-	irq_sts &= ~irq_mask;
-	if (!irq_sts)
-		return IRQ_NONE;
-
-	for (i = 0; i < tps65912->irq_num; i++) {
-		if (!(irq_sts & (1 << i)))
-			continue;
-
-		handle_nested_irq(tps65912->irq_base + i);
-	}
-
-	/* Write the STS register back to clear IRQs we handled */
-	reg = irq_sts & 0xFF;
-	irq_sts >>= 8;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS, 1, &reg);
-	reg = irq_sts & 0xFF;
-	irq_sts >>= 8;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS2, 1, &reg);
-	reg = irq_sts & 0xFF;
-	irq_sts >>= 8;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS3, 1, &reg);
-	reg = irq_sts & 0xFF;
-	if (reg)
-		tps65912->write(tps65912, TPS65912_INT_STS4, 1, &reg);
-
-	return IRQ_HANDLED;
-}
-
-static void tps65912_irq_lock(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-
-	mutex_lock(&tps65912->irq_lock);
-}
-
-static void tps65912_irq_sync_unlock(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-	u32 reg_mask;
-	u8 reg;
-
-	tps65912->read(tps65912, TPS65912_INT_MSK, 1, &reg);
-	reg_mask = reg;
-	tps65912->read(tps65912, TPS65912_INT_MSK2, 1, &reg);
-	reg_mask |= reg << 8;
-	tps65912->read(tps65912, TPS65912_INT_MSK3, 1, &reg);
-	reg_mask |= reg << 16;
-	tps65912->read(tps65912, TPS65912_INT_MSK4, 1, &reg);
-	reg_mask |= reg << 24;
-
-	if (tps65912->irq_mask != reg_mask) {
-		reg = tps65912->irq_mask & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK, 1, &reg);
-		reg = tps65912->irq_mask >> 8 & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK2, 1, &reg);
-		reg = tps65912->irq_mask >> 16 & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK3, 1, &reg);
-		reg = tps65912->irq_mask >> 24 & 0xFF;
-		tps65912->write(tps65912, TPS65912_INT_MSK4, 1, &reg);
-	}
-
-	mutex_unlock(&tps65912->irq_lock);
-}
-
-static void tps65912_irq_enable(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-
-	tps65912->irq_mask &= ~(1 << irq_to_tps65912_irq(tps65912, data->irq));
-}
-
-static void tps65912_irq_disable(struct irq_data *data)
-{
-	struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
-
-	tps65912->irq_mask |= (1 << irq_to_tps65912_irq(tps65912, data->irq));
-}
-
-static struct irq_chip tps65912_irq_chip = {
-	.name = "tps65912",
-	.irq_bus_lock = tps65912_irq_lock,
-	.irq_bus_sync_unlock = tps65912_irq_sync_unlock,
-	.irq_disable = tps65912_irq_disable,
-	.irq_enable = tps65912_irq_enable,
-};
-
-int tps65912_irq_init(struct tps65912 *tps65912, int irq,
-			    struct tps65912_platform_data *pdata)
-{
-	int ret, cur_irq;
-	int flags = IRQF_ONESHOT;
-	u8 reg;
-
-	if (!irq) {
-		dev_warn(tps65912->dev, "No interrupt support, no core IRQ\n");
-		return 0;
-	}
-
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(tps65912->dev, "No interrupt support, no IRQ base\n");
-		return 0;
-	}
-
-	/* Clear unattended interrupts */
-	tps65912->read(tps65912, TPS65912_INT_STS, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS, 1, &reg);
-	tps65912->read(tps65912, TPS65912_INT_STS2, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS2, 1, &reg);
-	tps65912->read(tps65912, TPS65912_INT_STS3, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS3, 1, &reg);
-	tps65912->read(tps65912, TPS65912_INT_STS4, 1, &reg);
-	tps65912->write(tps65912, TPS65912_INT_STS4, 1, &reg);
-
-	/* Mask top level interrupts */
-	tps65912->irq_mask = 0xFFFFFFFF;
-
-	mutex_init(&tps65912->irq_lock);
-	tps65912->chip_irq = irq;
-	tps65912->irq_base = pdata->irq_base;
-
-	tps65912->irq_num = TPS65912_NUM_IRQ;
-
-	/* Register with genirq */
-	for (cur_irq = tps65912->irq_base;
-	     cur_irq < tps65912->irq_num + tps65912->irq_base;
-	     cur_irq++) {
-		irq_set_chip_data(cur_irq, tps65912);
-		irq_set_chip_and_handler(cur_irq, &tps65912_irq_chip,
-					 handle_edge_irq);
-		irq_set_nested_thread(cur_irq, 1);
-		irq_clear_status_flags(cur_irq, IRQ_NOREQUEST | IRQ_NOPROBE);
-	}
-
-	ret = request_threaded_irq(irq, NULL, tps65912_irq, flags,
-				   "tps65912", tps65912);
-
-	irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
-	if (ret != 0)
-		dev_err(tps65912->dev, "Failed to request IRQ: %d\n", ret);
-
-	return ret;
-}
-
-int tps65912_irq_exit(struct tps65912 *tps65912)
-{
-	free_irq(tps65912->chip_irq, tps65912);
-	return 0;
-}
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
deleted file mode 100644
index de60ad9..0000000
--- a/drivers/mfd/tps65912-spi.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * tps65912-spi.c  --  SPI access for TI TPS65912x PMIC
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  This driver is based on wm8350 implementation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/tps65912.h>
-
-static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr,
-							int bytes, void *src)
-{
-	struct spi_device *spi = tps65912->control_data;
-	u8 *data = (u8 *) src;
-	int ret;
-	/* bit 23 is the read/write bit */
-	unsigned long spi_data = 1 << 23 | addr << 15 | *data;
-	struct spi_transfer xfer;
-	struct spi_message msg;
-	u32 tx_buf;
-
-	tx_buf = spi_data;
-
-	xfer.tx_buf	= &tx_buf;
-	xfer.rx_buf	= NULL;
-	xfer.len	= sizeof(unsigned long);
-	xfer.bits_per_word = 24;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	ret = spi_sync(spi, &msg);
-	return ret;
-}
-
-static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr,
-							int bytes, void *dest)
-{
-	struct spi_device *spi = tps65912->control_data;
-	/* bit 23 is the read/write bit */
-	unsigned long spi_data = 0 << 23 | addr << 15;
-	struct spi_transfer xfer;
-	struct spi_message msg;
-	int ret;
-	u8 *data = (u8 *) dest;
-	u32 tx_buf, rx_buf;
-
-	tx_buf = spi_data;
-	rx_buf = 0;
-
-	xfer.tx_buf	= &tx_buf;
-	xfer.rx_buf	= &rx_buf;
-	xfer.len	= sizeof(unsigned long);
-	xfer.bits_per_word = 24;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	if (spi == NULL)
-		return 0;
-
-	ret = spi_sync(spi, &msg);
-	if (ret == 0)
-		*data = (u8) (rx_buf & 0xFF);
-	return ret;
-}
-
-static int tps65912_spi_probe(struct spi_device *spi)
-{
-	struct tps65912 *tps65912;
-
-	tps65912 = devm_kzalloc(&spi->dev,
-				sizeof(struct tps65912), GFP_KERNEL);
-	if (tps65912 == NULL)
-		return -ENOMEM;
-
-	tps65912->dev = &spi->dev;
-	tps65912->control_data = spi;
-	tps65912->read = tps65912_spi_read;
-	tps65912->write = tps65912_spi_write;
-
-	spi_set_drvdata(spi, tps65912);
-
-	return tps65912_device_init(tps65912);
-}
-
-static int tps65912_spi_remove(struct spi_device *spi)
-{
-	struct tps65912 *tps65912 = spi_get_drvdata(spi);
-
-	tps65912_device_exit(tps65912);
-
-	return 0;
-}
-
-static struct spi_driver tps65912_spi_driver = {
-	.driver = {
-		.name = "tps65912",
-		.owner = THIS_MODULE,
-	},
-	.probe	= tps65912_spi_probe,
-	.remove = tps65912_spi_remove,
-};
-
-static int __init tps65912_spi_init(void)
-{
-	int ret;
-
-	ret = spi_register_driver(&tps65912_spi_driver);
-	if (ret != 0)
-		pr_err("Failed to register TPS65912 SPI driver: %d\n", ret);
-
-	return 0;
-}
-/* init early so consumer devices can complete system boot */
-subsys_initcall(tps65912_spi_init);
-
-static void __exit tps65912_spi_exit(void)
-{
-	spi_unregister_driver(&tps65912_spi_driver);
-}
-module_exit(tps65912_spi_exit);
-
-MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd");
-MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 64bccff..3cb2de9 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -727,12 +727,6 @@ config REGULATOR_TPS65910
 	help
 	  This driver supports TPS65910/TPS65911 voltage regulator chips.
 
-config REGULATOR_TPS65912
-	tristate "TI TPS65912 Power regulator"
-	depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI)
-	help
-	    This driver supports TPS65912 voltage regulator chip.
-
 config REGULATOR_TPS80031
 	tristate "TI TPS80031/TPS80032 power regualtor driver"
 	depends on MFD_TPS80031
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0f81749..222ff5f 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -91,7 +91,6 @@ obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
-obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
 obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
 obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
deleted file mode 100644
index 9503d54..0000000
--- a/drivers/regulator/tps65912-regulator.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * tps65912.c  --  TI tps65912
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- * This driver is based on wm8350 implementation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/mfd/tps65912.h>
-
-/* DCDC's */
-#define TPS65912_REG_DCDC1	0
-#define TPS65912_REG_DCDC2	1
-#define TPS65912_REG_DCDC3	2
-#define TPS65912_REG_DCDC4	3
-
-/* LDOs */
-#define TPS65912_REG_LDO1	4
-#define TPS65912_REG_LDO2	5
-#define TPS65912_REG_LDO3	6
-#define TPS65912_REG_LDO4	7
-#define TPS65912_REG_LDO5	8
-#define TPS65912_REG_LDO6	9
-#define TPS65912_REG_LDO7	10
-#define TPS65912_REG_LDO8	11
-#define TPS65912_REG_LDO9	12
-#define TPS65912_REG_LDO10	13
-
-/* Number of step-down converters available */
-#define TPS65912_NUM_DCDC	4
-
-/* Number of LDO voltage regulators  available */
-#define TPS65912_NUM_LDO	10
-
-/* Number of total regulators available */
-#define TPS65912_NUM_REGULATOR		(TPS65912_NUM_DCDC + TPS65912_NUM_LDO)
-
-#define TPS65912_REG_ENABLED	0x80
-#define OP_SELREG_MASK		0x40
-#define OP_SELREG_SHIFT		6
-
-struct tps_info {
-	const char *name;
-};
-
-static struct tps_info tps65912_regs[] = {
-	{
-		.name = "DCDC1",
-	},
-	{
-		.name = "DCDC2",
-	},
-	{
-		.name = "DCDC3",
-	},
-	{
-		.name = "DCDC4",
-	},
-	{
-		.name = "LDO1",
-	},
-	{
-		.name = "LDO2",
-	},
-	{
-		.name = "LDO3",
-	},
-	{
-		.name = "LDO4",
-	},
-	{
-		.name = "LDO5",
-	},
-	{
-		.name = "LDO6",
-	},
-	{
-		.name = "LDO7",
-	},
-	{
-		.name = "LDO8",
-	},
-	{
-		.name = "LDO9",
-	},
-	{
-		.name = "LDO10",
-	},
-};
-
-struct tps65912_reg {
-	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
-	struct tps65912 *mfd;
-	struct regulator_dev *rdev[TPS65912_NUM_REGULATOR];
-	struct tps_info *info[TPS65912_NUM_REGULATOR];
-	/* for read/write access */
-	struct mutex io_lock;
-	int mode;
-	int (*get_ctrl_reg)(int);
-	int dcdc_range[TPS65912_NUM_DCDC];
-	int pwm_mode_reg;
-	int eco_reg;
-};
-
-static const struct regulator_linear_range tps65912_ldo_ranges[] = {
-	REGULATOR_LINEAR_RANGE(800000, 0, 32, 25000),
-	REGULATOR_LINEAR_RANGE(1650000, 33, 60, 50000),
-	REGULATOR_LINEAR_RANGE(3100000, 61, 63, 100000),
-};
-
-static int tps65912_get_range(struct tps65912_reg *pmic, int id)
-{
-	struct tps65912 *mfd = pmic->mfd;
-	int range;
-
-	switch (id) {
-	case TPS65912_REG_DCDC1:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC1_LIMIT);
-		break;
-	case TPS65912_REG_DCDC2:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC2_LIMIT);
-		break;
-	case TPS65912_REG_DCDC3:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC3_LIMIT);
-		break;
-	case TPS65912_REG_DCDC4:
-		range = tps65912_reg_read(mfd, TPS65912_DCDC4_LIMIT);
-		break;
-	default:
-		return 0;
-	}
-
-	if (range >= 0)
-		range = (range & DCDC_LIMIT_RANGE_MASK)
-			>> DCDC_LIMIT_RANGE_SHIFT;
-
-	pmic->dcdc_range[id] = range;
-	return range;
-}
-
-static unsigned long tps65912_vsel_to_uv_range0(u8 vsel)
-{
-	unsigned long uv;
-
-	uv = ((vsel * 12500) + 500000);
-	return uv;
-}
-
-static unsigned long tps65912_vsel_to_uv_range1(u8 vsel)
-{
-	unsigned long uv;
-
-	 uv = ((vsel * 12500) + 700000);
-	return uv;
-}
-
-static unsigned long tps65912_vsel_to_uv_range2(u8 vsel)
-{
-	unsigned long uv;
-
-	uv = ((vsel * 25000) + 500000);
-	return uv;
-}
-
-static unsigned long tps65912_vsel_to_uv_range3(u8 vsel)
-{
-	unsigned long uv;
-
-	if (vsel == 0x3f)
-		uv = 3800000;
-	else
-		uv = ((vsel * 50000) + 500000);
-
-	return uv;
-}
-
-static int tps65912_get_ctrl_register(int id)
-{
-	if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4)
-		return id * 3 + TPS65912_DCDC1_AVS;
-	else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10)
-		return id - TPS65912_REG_LDO5 + TPS65912_LDO5;
-	else
-		return -EINVAL;
-}
-
-static int tps65912_get_sel_register(struct tps65912_reg *pmic, int id)
-{
-	struct tps65912 *mfd = pmic->mfd;
-	int opvsel;
-	u8 reg = 0;
-
-	if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4) {
-		opvsel = tps65912_reg_read(mfd, id * 3 + TPS65912_DCDC1_OP);
-		if (opvsel & OP_SELREG_MASK)
-			reg = id * 3 + TPS65912_DCDC1_AVS;
-		else
-			reg = id * 3 + TPS65912_DCDC1_OP;
-	} else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10) {
-		reg = id - TPS65912_REG_LDO5 + TPS65912_LDO5;
-	} else {
-		return -EINVAL;
-	}
-
-	return reg;
-}
-
-static int tps65912_get_mode_regiters(struct tps65912_reg *pmic, int id)
-{
-	switch (id) {
-	case TPS65912_REG_DCDC1:
-		pmic->pwm_mode_reg = TPS65912_DCDC1_CTRL;
-		pmic->eco_reg = TPS65912_DCDC1_AVS;
-		break;
-	case TPS65912_REG_DCDC2:
-		pmic->pwm_mode_reg = TPS65912_DCDC2_CTRL;
-		pmic->eco_reg = TPS65912_DCDC2_AVS;
-		break;
-	case TPS65912_REG_DCDC3:
-		pmic->pwm_mode_reg = TPS65912_DCDC3_CTRL;
-		pmic->eco_reg = TPS65912_DCDC3_AVS;
-		break;
-	case TPS65912_REG_DCDC4:
-		pmic->pwm_mode_reg = TPS65912_DCDC4_CTRL;
-		pmic->eco_reg = TPS65912_DCDC4_AVS;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int tps65912_reg_is_enabled(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int reg, value, id = rdev_get_id(dev);
-
-	if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_LDO10)
-		return -EINVAL;
-
-	reg = pmic->get_ctrl_reg(id);
-	if (reg < 0)
-		return reg;
-
-	value = tps65912_reg_read(mfd, reg);
-	if (value < 0)
-		return value;
-
-	return value & TPS65912_REG_ENABLED;
-}
-
-static int tps65912_reg_enable(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev);
-	int reg;
-
-	if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_LDO10)
-		return -EINVAL;
-
-	reg = pmic->get_ctrl_reg(id);
-	if (reg < 0)
-		return reg;
-
-	return tps65912_set_bits(mfd, reg, TPS65912_REG_ENABLED);
-}
-
-static int tps65912_reg_disable(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev), reg;
-
-	reg = pmic->get_ctrl_reg(id);
-	if (reg < 0)
-		return reg;
-
-	return tps65912_clear_bits(mfd, reg, TPS65912_REG_ENABLED);
-}
-
-static int tps65912_set_mode(struct regulator_dev *dev, unsigned int mode)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int pwm_mode, eco, id = rdev_get_id(dev);
-
-	tps65912_get_mode_regiters(pmic, id);
-
-	pwm_mode = tps65912_reg_read(mfd, pmic->pwm_mode_reg);
-	eco = tps65912_reg_read(mfd, pmic->eco_reg);
-
-	pwm_mode &= DCDCCTRL_DCDC_MODE_MASK;
-	eco &= DCDC_AVS_ECO_MASK;
-
-	switch (mode) {
-	case REGULATOR_MODE_FAST:
-		/* Verify if mode alredy set */
-		if (pwm_mode && !eco)
-			break;
-		tps65912_set_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK);
-		tps65912_clear_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK);
-		break;
-	case REGULATOR_MODE_NORMAL:
-	case REGULATOR_MODE_IDLE:
-		if (!pwm_mode && !eco)
-			break;
-		tps65912_clear_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK);
-		tps65912_clear_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK);
-		break;
-	case REGULATOR_MODE_STANDBY:
-		if (!pwm_mode && eco)
-			break;
-		tps65912_clear_bits(mfd, pmic->pwm_mode_reg, DCDCCTRL_DCDC_MODE_MASK);
-		tps65912_set_bits(mfd, pmic->eco_reg, DCDC_AVS_ECO_MASK);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static unsigned int tps65912_get_mode(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int pwm_mode, eco, mode = 0, id = rdev_get_id(dev);
-
-	tps65912_get_mode_regiters(pmic, id);
-
-	pwm_mode = tps65912_reg_read(mfd, pmic->pwm_mode_reg);
-	eco = tps65912_reg_read(mfd, pmic->eco_reg);
-
-	pwm_mode &= DCDCCTRL_DCDC_MODE_MASK;
-	eco &= DCDC_AVS_ECO_MASK;
-
-	if (pwm_mode && !eco)
-		mode = REGULATOR_MODE_FAST;
-	else if (!pwm_mode && !eco)
-		mode = REGULATOR_MODE_NORMAL;
-	else if (!pwm_mode && eco)
-		mode = REGULATOR_MODE_STANDBY;
-
-	return mode;
-}
-
-static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	int range, voltage = 0, id = rdev_get_id(dev);
-
-	if (id > TPS65912_REG_DCDC4)
-		return -EINVAL;
-
-	range = pmic->dcdc_range[id];
-
-	switch (range) {
-	case 0:
-		/* 0.5 - 1.2875V in 12.5mV steps */
-		voltage = tps65912_vsel_to_uv_range0(selector);
-		break;
-	case 1:
-		/* 0.7 - 1.4875V in 12.5mV steps */
-		voltage = tps65912_vsel_to_uv_range1(selector);
-		break;
-	case 2:
-		/* 0.5 - 2.075V in 25mV steps */
-		voltage = tps65912_vsel_to_uv_range2(selector);
-		break;
-	case 3:
-		/* 0.5 - 3.8V in 50mV steps */
-		voltage = tps65912_vsel_to_uv_range3(selector);
-		break;
-	}
-	return voltage;
-}
-
-static int tps65912_get_voltage_sel(struct regulator_dev *dev)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev);
-	int reg, vsel;
-
-	reg = tps65912_get_sel_register(pmic, id);
-	if (reg < 0)
-		return reg;
-
-	vsel = tps65912_reg_read(mfd, reg);
-	vsel &= 0x3F;
-
-	return vsel;
-}
-
-static int tps65912_set_voltage_sel(struct regulator_dev *dev,
-					 unsigned selector)
-{
-	struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-	struct tps65912 *mfd = pmic->mfd;
-	int id = rdev_get_id(dev);
-	int value;
-	u8 reg;
-
-	reg = tps65912_get_sel_register(pmic, id);
-	value = tps65912_reg_read(mfd, reg);
-	value &= 0xC0;
-	return tps65912_reg_write(mfd, reg, selector | value);
-}
-
-/* Operations permitted on DCDCx */
-static struct regulator_ops tps65912_ops_dcdc = {
-	.is_enabled = tps65912_reg_is_enabled,
-	.enable = tps65912_reg_enable,
-	.disable = tps65912_reg_disable,
-	.set_mode = tps65912_set_mode,
-	.get_mode = tps65912_get_mode,
-	.get_voltage_sel = tps65912_get_voltage_sel,
-	.set_voltage_sel = tps65912_set_voltage_sel,
-	.list_voltage = tps65912_list_voltage,
-};
-
-/* Operations permitted on LDOx */
-static struct regulator_ops tps65912_ops_ldo = {
-	.is_enabled = tps65912_reg_is_enabled,
-	.enable = tps65912_reg_enable,
-	.disable = tps65912_reg_disable,
-	.get_voltage_sel = tps65912_get_voltage_sel,
-	.set_voltage_sel = tps65912_set_voltage_sel,
-	.list_voltage = regulator_list_voltage_linear_range,
-	.map_voltage = regulator_map_voltage_linear_range,
-};
-
-static int tps65912_probe(struct platform_device *pdev)
-{
-	struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
-	struct regulator_config config = { };
-	struct tps_info *info;
-	struct regulator_init_data *reg_data;
-	struct regulator_dev *rdev;
-	struct tps65912_reg *pmic;
-	struct tps65912_board *pmic_plat_data;
-	int i;
-
-	pmic_plat_data = dev_get_platdata(tps65912->dev);
-	if (!pmic_plat_data)
-		return -EINVAL;
-
-	reg_data = pmic_plat_data->tps65912_pmic_init_data;
-
-	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
-	if (!pmic)
-		return -ENOMEM;
-
-	mutex_init(&pmic->io_lock);
-	pmic->mfd = tps65912;
-	platform_set_drvdata(pdev, pmic);
-
-	pmic->get_ctrl_reg = &tps65912_get_ctrl_register;
-	info = tps65912_regs;
-
-	for (i = 0; i < TPS65912_NUM_REGULATOR; i++, info++, reg_data++) {
-		int range = 0;
-		/* Register the regulators */
-		pmic->info[i] = info;
-
-		pmic->desc[i].name = info->name;
-		pmic->desc[i].id = i;
-		pmic->desc[i].n_voltages = 64;
-		if (i > TPS65912_REG_DCDC4) {
-			pmic->desc[i].ops = &tps65912_ops_ldo;
-			pmic->desc[i].linear_ranges = tps65912_ldo_ranges;
-			pmic->desc[i].n_linear_ranges =
-					ARRAY_SIZE(tps65912_ldo_ranges);
-		} else {
-			pmic->desc[i].ops = &tps65912_ops_dcdc;
-		}
-		pmic->desc[i].type = REGULATOR_VOLTAGE;
-		pmic->desc[i].owner = THIS_MODULE;
-		range = tps65912_get_range(pmic, i);
-
-		config.dev = tps65912->dev;
-		config.init_data = reg_data;
-		config.driver_data = pmic;
-
-		rdev = devm_regulator_register(&pdev->dev, &pmic->desc[i],
-					       &config);
-		if (IS_ERR(rdev)) {
-			dev_err(tps65912->dev,
-				"failed to register %s regulator\n",
-				pdev->name);
-			return PTR_ERR(rdev);
-		}
-
-		/* Save regulator for cleanup */
-		pmic->rdev[i] = rdev;
-	}
-	return 0;
-}
-
-static struct platform_driver tps65912_driver = {
-	.driver = {
-		.name = "tps65912-pmic",
-	},
-	.probe = tps65912_probe,
-};
-
-static int __init tps65912_init(void)
-{
-	return platform_driver_register(&tps65912_driver);
-}
-subsys_initcall(tps65912_init);
-
-static void __exit tps65912_cleanup(void)
-{
-	platform_driver_unregister(&tps65912_driver);
-}
-module_exit(tps65912_cleanup);
-
-MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>");
-MODULE_DESCRIPTION("TPS65912 voltage regulator driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tps65912-pmic");
diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h
deleted file mode 100644
index 6d30903..0000000
--- a/include/linux/mfd/tps65912.h
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * tps65912.h  --  TI TPS6591x
- *
- * Copyright 2011 Texas Instruments Inc.
- *
- * Author: Margarita Olaya <magi@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- */
-
-#ifndef __LINUX_MFD_TPS65912_H
-#define __LINUX_MFD_TPS65912_H
-
-/* TPS regulator type list */
-#define REGULATOR_LDO		0
-#define REGULATOR_DCDC		1
-
-/*
- * List of registers for TPS65912
- */
-
-#define TPS65912_DCDC1_CTRL		0x00
-#define TPS65912_DCDC2_CTRL		0x01
-#define TPS65912_DCDC3_CTRL		0x02
-#define TPS65912_DCDC4_CTRL		0x03
-#define TPS65912_DCDC1_OP		0x04
-#define TPS65912_DCDC1_AVS		0x05
-#define TPS65912_DCDC1_LIMIT		0x06
-#define TPS65912_DCDC2_OP		0x07
-#define TPS65912_DCDC2_AVS		0x08
-#define TPS65912_DCDC2_LIMIT		0x09
-#define TPS65912_DCDC3_OP		0x0A
-#define TPS65912_DCDC3_AVS		0x0B
-#define TPS65912_DCDC3_LIMIT		0x0C
-#define TPS65912_DCDC4_OP		0x0D
-#define TPS65912_DCDC4_AVS		0x0E
-#define TPS65912_DCDC4_LIMIT		0x0F
-#define TPS65912_LDO1_OP		0x10
-#define TPS65912_LDO1_AVS		0x11
-#define TPS65912_LDO1_LIMIT		0x12
-#define TPS65912_LDO2_OP		0x13
-#define TPS65912_LDO2_AVS		0x14
-#define TPS65912_LDO2_LIMIT		0x15
-#define TPS65912_LDO3_OP		0x16
-#define TPS65912_LDO3_AVS		0x17
-#define TPS65912_LDO3_LIMIT		0x18
-#define TPS65912_LDO4_OP		0x19
-#define TPS65912_LDO4_AVS		0x1A
-#define TPS65912_LDO4_LIMIT		0x1B
-#define TPS65912_LDO5			0x1C
-#define TPS65912_LDO6			0x1D
-#define TPS65912_LDO7			0x1E
-#define TPS65912_LDO8			0x1F
-#define TPS65912_LDO9			0x20
-#define TPS65912_LDO10			0x21
-#define TPS65912_THRM			0x22
-#define TPS65912_CLK32OUT		0x23
-#define TPS65912_DEVCTRL		0x24
-#define TPS65912_DEVCTRL2		0x25
-#define TPS65912_I2C_SPI_CFG		0x26
-#define TPS65912_KEEP_ON		0x27
-#define TPS65912_KEEP_ON2		0x28
-#define TPS65912_SET_OFF1		0x29
-#define TPS65912_SET_OFF2		0x2A
-#define TPS65912_DEF_VOLT		0x2B
-#define TPS65912_DEF_VOLT_MAPPING	0x2C
-#define TPS65912_DISCHARGE		0x2D
-#define TPS65912_DISCHARGE2		0x2E
-#define TPS65912_EN1_SET1		0x2F
-#define TPS65912_EN1_SET2		0x30
-#define TPS65912_EN2_SET1		0x31
-#define TPS65912_EN2_SET2		0x32
-#define TPS65912_EN3_SET1		0x33
-#define TPS65912_EN3_SET2		0x34
-#define TPS65912_EN4_SET1		0x35
-#define TPS65912_EN4_SET2		0x36
-#define TPS65912_PGOOD			0x37
-#define TPS65912_PGOOD2			0x38
-#define TPS65912_INT_STS		0x39
-#define TPS65912_INT_MSK		0x3A
-#define TPS65912_INT_STS2		0x3B
-#define TPS65912_INT_MSK2		0x3C
-#define TPS65912_INT_STS3		0x3D
-#define TPS65912_INT_MSK3		0x3E
-#define TPS65912_INT_STS4		0x3F
-#define TPS65912_INT_MSK4		0x40
-#define TPS65912_GPIO1			0x41
-#define TPS65912_GPIO2			0x42
-#define TPS65912_GPIO3			0x43
-#define TPS65912_GPIO4			0x44
-#define TPS65912_GPIO5			0x45
-#define TPS65912_VMON			0x46
-#define TPS65912_LEDA_CTRL1		0x47
-#define TPS65912_LEDA_CTRL2		0x48
-#define TPS65912_LEDA_CTRL3		0x49
-#define TPS65912_LEDA_CTRL4		0x4A
-#define TPS65912_LEDA_CTRL5		0x4B
-#define TPS65912_LEDA_CTRL6		0x4C
-#define TPS65912_LEDA_CTRL7		0x4D
-#define TPS65912_LEDA_CTRL8		0x4E
-#define TPS65912_LEDB_CTRL1		0x4F
-#define TPS65912_LEDB_CTRL2		0x50
-#define TPS65912_LEDB_CTRL3		0x51
-#define TPS65912_LEDB_CTRL4		0x52
-#define TPS65912_LEDB_CTRL5		0x53
-#define TPS65912_LEDB_CTRL6		0x54
-#define TPS65912_LEDB_CTRL7		0x55
-#define TPS65912_LEDB_CTRL8		0x56
-#define TPS65912_LEDC_CTRL1		0x57
-#define TPS65912_LEDC_CTRL2		0x58
-#define TPS65912_LEDC_CTRL3		0x59
-#define TPS65912_LEDC_CTRL4		0x5A
-#define TPS65912_LEDC_CTRL5		0x5B
-#define TPS65912_LEDC_CTRL6		0x5C
-#define TPS65912_LEDC_CTRL7		0x5D
-#define TPS65912_LEDC_CTRL8		0x5E
-#define TPS65912_LED_RAMP_UP_TIME	0x5F
-#define TPS65912_LED_RAMP_DOWN_TIME	0x60
-#define TPS65912_LED_SEQ_EN		0x61
-#define TPS65912_LOADSWITCH		0x62
-#define TPS65912_SPARE			0x63
-#define TPS65912_VERNUM			0x64
-#define TPS6591X_MAX_REGISTER		0x64
-
-/* IRQ Definitions */
-#define TPS65912_IRQ_PWRHOLD_F		0
-#define TPS65912_IRQ_VMON		1
-#define TPS65912_IRQ_PWRON		2
-#define TPS65912_IRQ_PWRON_LP		3
-#define TPS65912_IRQ_PWRHOLD_R		4
-#define TPS65912_IRQ_HOTDIE		5
-#define TPS65912_IRQ_GPIO1_R		6
-#define TPS65912_IRQ_GPIO1_F		7
-#define TPS65912_IRQ_GPIO2_R		8
-#define TPS65912_IRQ_GPIO2_F		9
-#define TPS65912_IRQ_GPIO3_R		10
-#define TPS65912_IRQ_GPIO3_F		11
-#define TPS65912_IRQ_GPIO4_R		12
-#define TPS65912_IRQ_GPIO4_F		13
-#define TPS65912_IRQ_GPIO5_R		14
-#define TPS65912_IRQ_GPIO5_F		15
-#define TPS65912_IRQ_PGOOD_DCDC1	16
-#define TPS65912_IRQ_PGOOD_DCDC2	17
-#define TPS65912_IRQ_PGOOD_DCDC3	18
-#define TPS65912_IRQ_PGOOD_DCDC4	19
-#define TPS65912_IRQ_PGOOD_LDO1		20
-#define TPS65912_IRQ_PGOOD_LDO2		21
-#define TPS65912_IRQ_PGOOD_LDO3		22
-#define TPS65912_IRQ_PGOOD_LDO4		23
-#define TPS65912_IRQ_PGOOD_LDO5		24
-#define TPS65912_IRQ_PGOOD_LDO6		25
-#define TPS65912_IRQ_PGOOD_LDO7		26
-#define TPS65912_IRQ_PGOOD_LD08		27
-#define TPS65912_IRQ_PGOOD_LDO9		28
-#define TPS65912_IRQ_PGOOD_LDO10	29
-
-#define TPS65912_NUM_IRQ		30
-
-/* GPIO 1 and 2 Register Definitions */
-#define GPIO_SLEEP_MASK			0x80
-#define GPIO_SLEEP_SHIFT		7
-#define GPIO_DEB_MASK			0x10
-#define GPIO_DEB_SHIFT			4
-#define GPIO_CFG_MASK			0x04
-#define GPIO_CFG_SHIFT			2
-#define GPIO_STS_MASK			0x02
-#define GPIO_STS_SHIFT			1
-#define GPIO_SET_MASK			0x01
-#define GPIO_SET_SHIFT			0
-
-/* GPIO 3 Register Definitions */
-#define GPIO3_SLEEP_MASK		0x80
-#define GPIO3_SLEEP_SHIFT		7
-#define GPIO3_SEL_MASK			0x40
-#define GPIO3_SEL_SHIFT			6
-#define GPIO3_ODEN_MASK			0x20
-#define GPIO3_ODEN_SHIFT		5
-#define GPIO3_DEB_MASK			0x10
-#define GPIO3_DEB_SHIFT			4
-#define GPIO3_PDEN_MASK			0x08
-#define GPIO3_PDEN_SHIFT		3
-#define GPIO3_CFG_MASK			0x04
-#define GPIO3_CFG_SHIFT			2
-#define GPIO3_STS_MASK			0x02
-#define GPIO3_STS_SHIFT			1
-#define GPIO3_SET_MASK			0x01
-#define GPIO3_SET_SHIFT			0
-
-/* GPIO 4 Register Definitions */
-#define GPIO4_SLEEP_MASK		0x80
-#define GPIO4_SLEEP_SHIFT		7
-#define GPIO4_SEL_MASK			0x40
-#define GPIO4_SEL_SHIFT			6
-#define GPIO4_ODEN_MASK			0x20
-#define GPIO4_ODEN_SHIFT		5
-#define GPIO4_DEB_MASK			0x10
-#define GPIO4_DEB_SHIFT			4
-#define GPIO4_PDEN_MASK			0x08
-#define GPIO4_PDEN_SHIFT		3
-#define GPIO4_CFG_MASK			0x04
-#define GPIO4_CFG_SHIFT			2
-#define GPIO4_STS_MASK			0x02
-#define GPIO4_STS_SHIFT			1
-#define GPIO4_SET_MASK			0x01
-#define GPIO4_SET_SHIFT			0
-
-/* Register THERM  (0x80) register.RegisterDescription */
-#define THERM_THERM_HD_MASK		0x20
-#define THERM_THERM_HD_SHIFT		5
-#define THERM_THERM_TS_MASK		0x10
-#define THERM_THERM_TS_SHIFT		4
-#define THERM_THERM_HDSEL_MASK		0x0C
-#define THERM_THERM_HDSEL_SHIFT		2
-#define THERM_RSVD1_MASK		0x02
-#define THERM_RSVD1_SHIFT		1
-#define THERM_THERM_STATE_MASK		0x01
-#define THERM_THERM_STATE_SHIFT		0
-
-/* Register DCDCCTRL1 register.RegisterDescription */
-#define DCDCCTRL_VCON_ENABLE_MASK	0x80
-#define DCDCCTRL_VCON_ENABLE_SHIFT	7
-#define DCDCCTRL_VCON_RANGE1_MASK	0x40
-#define DCDCCTRL_VCON_RANGE1_SHIFT	6
-#define DCDCCTRL_VCON_RANGE0_MASK	0x20
-#define DCDCCTRL_VCON_RANGE0_SHIFT	5
-#define DCDCCTRL_TSTEP2_MASK		0x10
-#define DCDCCTRL_TSTEP2_SHIFT		4
-#define DCDCCTRL_TSTEP1_MASK		0x08
-#define DCDCCTRL_TSTEP1_SHIFT		3
-#define DCDCCTRL_TSTEP0_MASK		0x04
-#define DCDCCTRL_TSTEP0_SHIFT		2
-#define DCDCCTRL_DCDC1_MODE_MASK	0x02
-#define DCDCCTRL_DCDC1_MODE_SHIFT	1
-
-/* Register DCDCCTRL2 and DCDCCTRL3 register.RegisterDescription */
-#define DCDCCTRL_TSTEP2_MASK		0x10
-#define DCDCCTRL_TSTEP2_SHIFT		4
-#define DCDCCTRL_TSTEP1_MASK		0x08
-#define DCDCCTRL_TSTEP1_SHIFT		3
-#define DCDCCTRL_TSTEP0_MASK		0x04
-#define DCDCCTRL_TSTEP0_SHIFT		2
-#define DCDCCTRL_DCDC_MODE_MASK		0x02
-#define DCDCCTRL_DCDC_MODE_SHIFT	1
-#define DCDCCTRL_RSVD0_MASK		0x01
-#define DCDCCTRL_RSVD0_SHIFT		0
-
-/* Register DCDCCTRL4 register.RegisterDescription */
-#define DCDCCTRL_RAMP_TIME_MASK		0x01
-#define DCDCCTRL_RAMP_TIME_SHIFT	0
-
-/* Register DCDCx_AVS */
-#define DCDC_AVS_ENABLE_MASK		0x80
-#define DCDC_AVS_ENABLE_SHIFT		7
-#define DCDC_AVS_ECO_MASK		0x40
-#define DCDC_AVS_ECO_SHIFT		6
-
-/* Register DCDCx_LIMIT */
-#define DCDC_LIMIT_RANGE_MASK		0xC0
-#define DCDC_LIMIT_RANGE_SHIFT		6
-#define DCDC_LIMIT_MAX_SEL_MASK		0x3F
-#define DCDC_LIMIT_MAX_SEL_SHIFT	0
-
-/**
- * struct tps65912_board
- * Board platform dat may be used to initialize regulators.
- */
-struct tps65912_board {
-	int is_dcdc1_avs;
-	int is_dcdc2_avs;
-	int is_dcdc3_avs;
-	int is_dcdc4_avs;
-	int irq;
-	int irq_base;
-	int gpio_base;
-	struct regulator_init_data *tps65912_pmic_init_data;
-};
-
-/**
- * struct tps65912 - tps65912 sub-driver chip access routines
- */
-
-struct tps65912 {
-	struct device *dev;
-	/* for read/write acces */
-	struct mutex io_mutex;
-
-	/* For device IO interfaces: I2C or SPI */
-	void *control_data;
-
-	int (*read)(struct tps65912 *tps65912, u8 reg, int size, void *dest);
-	int (*write)(struct tps65912 *tps65912, u8 reg, int size, void *src);
-
-	/* Client devices */
-	struct tps65912_pmic *pmic;
-
-	/* GPIO Handling */
-	struct gpio_chip gpio;
-
-	/* IRQ Handling */
-	struct mutex irq_lock;
-	int chip_irq;
-	int irq_base;
-	int irq_num;
-	u32 irq_mask;
-};
-
-struct tps65912_platform_data {
-	int irq;
-	int irq_base;
-};
-
-unsigned int tps_chip(void);
-
-int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask);
-int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask);
-int tps65912_reg_read(struct tps65912 *tps65912, u8 reg);
-int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val);
-int tps65912_device_init(struct tps65912 *tps65912);
-void tps65912_device_exit(struct tps65912 *tps65912);
-int tps65912_irq_init(struct tps65912 *tps65912, int irq,
-			struct tps65912_platform_data *pdata);
-int tps65912_irq_exit(struct tps65912 *tps65912);
-
-#endif /*  __LINUX_MFD_TPS65912_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-24 14:52 ` Andrew F. Davis
@ 2015-09-24 14:52   ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

This patch adds support for TPS65912 mfd device. It provides
communication through the I2C and SPI interfaces. It contains
the following components:

 - Regulators
 - GPIO controller

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/mfd/Kconfig          |  24 +++
 drivers/mfd/Makefile         |   3 +
 drivers/mfd/tps65912-core.c  | 114 +++++++++++++
 drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
 drivers/mfd/tps65912-spi.c   |  85 ++++++++++
 include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 705 insertions(+)
 create mode 100644 drivers/mfd/tps65912-core.c
 create mode 100644 drivers/mfd/tps65912-i2c.c
 create mode 100644 drivers/mfd/tps65912-spi.c
 create mode 100644 include/linux/mfd/tps65912.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 9a8df8e..4663658 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1167,6 +1167,30 @@ config MFD_TPS65910
 	  if you say yes here you get support for the TPS65910 series of
 	  Power Management chips.
 
+config MFD_TPS65912
+	tristate
+	select REGMAP
+	select REGMAP_IRQ
+	select MFD_CORE
+
+config MFD_TPS65912_I2C
+	tristate "TI TPS65912 Power Management chip with I2C"
+	select MFD_TPS65912
+	select REGMAP_I2C
+	depends on I2C
+	help
+	  If you say yes here you get support for the TPS65912 series of
+	  PM chips with I2C interface.
+
+config MFD_TPS65912_SPI
+	tristate "TI TPS65912 Power Management chip with SPI"
+	select MFD_TPS65912
+	select REGMAP_SPI
+	depends on SPI_MASTER
+	help
+	  If you say yes here you get support for the TPS65912 series of
+	  PM chips with SPI interface.
+
 config MFD_TPS80031
 	bool "TI TPS80031/TPS80032 Power Management chips"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 004aa76..49c3530 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -69,6 +69,9 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
+obj-$(CONFIG_MFD_TPS65912)	+= tps65912-core.o
+obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
+obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
 obj-$(CONFIG_MFD_TPS80031)	+= tps80031.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
new file mode 100644
index 0000000..8dd1aac
--- /dev/null
+++ b/drivers/mfd/tps65912-core.c
@@ -0,0 +1,114 @@
+/*
+ * Core functions for TI TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+#include <linux/mfd/tps65912.h>
+
+#define TPS65912_IRQ(_name, _reg, _offset)			\
+	[TPS65912_IRQ_ ## _name] = {				\
+		.mask = TPS65912_ ## _reg ## _ ## _name,	\
+		.reg_offset = _offset,				\
+	}
+
+static const struct regmap_irq tps65912_irqs[] = {
+	/* INT_STS IRQs */
+	TPS65912_IRQ(PWRHOLD_F, INT_STS, 0),
+	TPS65912_IRQ(VMON, INT_STS, 0),
+	TPS65912_IRQ(PWRON, INT_STS, 0),
+	TPS65912_IRQ(PWRON_LP, INT_STS, 0),
+	TPS65912_IRQ(PWRHOLD_R, INT_STS, 0),
+	TPS65912_IRQ(HOTDIE, INT_STS, 0),
+	TPS65912_IRQ(GPIO1_R, INT_STS, 0),
+	TPS65912_IRQ(GPIO1_F, INT_STS, 0),
+	/* INT_STS2 IRQs */
+	TPS65912_IRQ(GPIO2_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO2_F, INT_STS2, 1),
+	TPS65912_IRQ(GPIO3_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO3_F, INT_STS2, 1),
+	TPS65912_IRQ(GPIO4_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO4_F, INT_STS2, 1),
+	TPS65912_IRQ(GPIO5_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO5_F, INT_STS2, 1),
+	/* INT_STS3 IRQs */
+	TPS65912_IRQ(PGOOD_DCDC1, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_DCDC2, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_DCDC3, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_DCDC4, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO1, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO2, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO3, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO4, INT_STS3, 2),
+	/* INT_STS4 IRQs */
+	TPS65912_IRQ(PGOOD_LDO5, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO6, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO7, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO8, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO9, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO10, INT_STS4, 3),
+};
+
+static struct regmap_irq_chip tps65912_irq_chip = {
+	.name = "tps65912",
+	.irqs = tps65912_irqs,
+	.num_irqs = ARRAY_SIZE(tps65912_irqs),
+	.num_regs = 4,
+	.irq_reg_stride = 2,
+	.mask_base = TPS65912_INT_MSK,
+	.status_base = TPS65912_INT_STS,
+	.ack_base = TPS65912_INT_STS,
+	.init_ack_masked = true,
+};
+
+int tps65912_device_init(struct tps65912 *tps)
+{
+	int ret;
+
+	ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
+				  &tps65912_irq_chip, &tps->irq_data);
+	if (ret < 0)
+		return ret;
+
+	ret = of_platform_populate(tps->dev->of_node, NULL, NULL, tps->dev);
+	if (ret < 0)
+		goto err_irq;
+
+	return 0;
+
+err_irq:
+	regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tps65912_device_init);
+
+int tps65912_device_exit(struct tps65912 *tps)
+{
+	regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tps65912_device_exit);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912x MFD Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c
new file mode 100644
index 0000000..ca640c4
--- /dev/null
+++ b/drivers/mfd/tps65912-i2c.c
@@ -0,0 +1,86 @@
+/*
+ * I2C access driver for TI TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/tps65912.h>
+
+static const struct of_device_id tps65912_i2c_of_match_table[] = {
+	{ .compatible = "ti,tps65912", },
+	{ /* sentinel */ }
+};
+
+static int tps65912_i2c_probe(struct i2c_client *client,
+			      const struct i2c_device_id *ids)
+{
+	struct tps65912 *tps;
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, tps);
+	tps->dev = &client->dev;
+	tps->irq = client->irq;
+
+	tps->regmap = devm_regmap_init_i2c(client, &tps65912_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		int ret = PTR_ERR(tps->regmap);
+
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+
+		return ret;
+	}
+
+	return tps65912_device_init(tps);
+}
+
+static int tps65912_i2c_remove(struct i2c_client *client)
+{
+	struct tps65912 *tps = i2c_get_clientdata(client);
+
+	return tps65912_device_exit(tps);
+}
+
+static const struct i2c_device_id tps65912_i2c_id_table[] = {
+	{ "tps65912", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id_table);
+
+static struct i2c_driver tps65912_i2c_driver = {
+	.driver		= {
+		.name	= "tps65912",
+		.of_match_table = tps65912_i2c_of_match_table,
+	},
+	.probe		= tps65912_i2c_probe,
+	.remove		= tps65912_i2c_remove,
+	.id_table       = tps65912_i2c_id_table,
+};
+
+module_i2c_driver(tps65912_i2c_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912x I2C Interface Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
new file mode 100644
index 0000000..799f835
--- /dev/null
+++ b/drivers/mfd/tps65912-spi.c
@@ -0,0 +1,85 @@
+/*
+ * SPI access driver for TI TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mfd/tps65912.h>
+
+static const struct of_device_id tps65912_spi_of_match_table[] = {
+	{ .compatible = "ti,tps65912", },
+	{ /* sentinel */ }
+};
+
+static int tps65912_spi_probe(struct spi_device *spi)
+{
+	struct tps65912 *tps;
+
+	tps = devm_kzalloc(&spi->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, tps);
+	tps->dev = &spi->dev;
+	tps->irq = spi->irq;
+
+	tps->regmap = devm_regmap_init_spi(spi, &tps65912_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		int ret = PTR_ERR(tps->regmap);
+
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+
+		return ret;
+	}
+
+	return tps65912_device_init(tps);
+}
+
+static int tps65912_spi_remove(struct spi_device *client)
+{
+	struct tps65912 *tps = spi_get_drvdata(client);
+
+	return tps65912_device_exit(tps);
+}
+
+static const struct spi_device_id tps65912_spi_id_table[] = {
+	{ "tps65912", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(spi, tps65912_spi_id_table);
+
+static struct spi_driver tps65912_spi_driver = {
+	.driver		= {
+		.name	= "tps65912",
+		.of_match_table = tps65912_spi_of_match_table,
+	},
+	.probe		= tps65912_spi_probe,
+	.remove		= tps65912_spi_remove,
+	.id_table       = tps65912_spi_id_table,
+};
+
+module_spi_driver(tps65912_spi_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912x SPI Interface Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h
new file mode 100644
index 0000000..e5ebd48
--- /dev/null
+++ b/include/linux/mfd/tps65912.h
@@ -0,0 +1,393 @@
+/*
+ * TI TPS65912x
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#ifndef __LINUX_MFD_TPS65912_H
+#define __LINUX_MFD_TPS65912_H
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+/* List of registers for TPS65912 */
+#define TPS65912_DCDC1_CTRL		0x00
+#define TPS65912_DCDC2_CTRL		0x01
+#define TPS65912_DCDC3_CTRL		0x02
+#define TPS65912_DCDC4_CTRL		0x03
+#define TPS65912_DCDC1_OP		0x04
+#define TPS65912_DCDC1_AVS		0x05
+#define TPS65912_DCDC1_LIMIT		0x06
+#define TPS65912_DCDC2_OP		0x07
+#define TPS65912_DCDC2_AVS		0x08
+#define TPS65912_DCDC2_LIMIT		0x09
+#define TPS65912_DCDC3_OP		0x0A
+#define TPS65912_DCDC3_AVS		0x0B
+#define TPS65912_DCDC3_LIMIT		0x0C
+#define TPS65912_DCDC4_OP		0x0D
+#define TPS65912_DCDC4_AVS		0x0E
+#define TPS65912_DCDC4_LIMIT		0x0F
+#define TPS65912_LDO1_OP		0x10
+#define TPS65912_LDO1_AVS		0x11
+#define TPS65912_LDO1_LIMIT		0x12
+#define TPS65912_LDO2_OP		0x13
+#define TPS65912_LDO2_AVS		0x14
+#define TPS65912_LDO2_LIMIT		0x15
+#define TPS65912_LDO3_OP		0x16
+#define TPS65912_LDO3_AVS		0x17
+#define TPS65912_LDO3_LIMIT		0x18
+#define TPS65912_LDO4_OP		0x19
+#define TPS65912_LDO4_AVS		0x1A
+#define TPS65912_LDO4_LIMIT		0x1B
+#define TPS65912_LDO5			0x1C
+#define TPS65912_LDO6			0x1D
+#define TPS65912_LDO7			0x1E
+#define TPS65912_LDO8			0x1F
+#define TPS65912_LDO9			0x20
+#define TPS65912_LDO10			0x21
+#define TPS65912_THRM			0x22
+#define TPS65912_CLK32OUT		0x23
+#define TPS65912_DEVCTRL		0x24
+#define TPS65912_DEVCTRL2		0x25
+#define TPS65912_I2C_SPI_CFG		0x26
+#define TPS65912_KEEP_ON		0x27
+#define TPS65912_KEEP_ON2		0x28
+#define TPS65912_SET_OFF1		0x29
+#define TPS65912_SET_OFF2		0x2A
+#define TPS65912_DEF_VOLT		0x2B
+#define TPS65912_DEF_VOLT_MAPPING	0x2C
+#define TPS65912_DISCHARGE		0x2D
+#define TPS65912_DISCHARGE2		0x2E
+#define TPS65912_EN1_SET1		0x2F
+#define TPS65912_EN1_SET2		0x30
+#define TPS65912_EN2_SET1		0x31
+#define TPS65912_EN2_SET2		0x32
+#define TPS65912_EN3_SET1		0x33
+#define TPS65912_EN3_SET2		0x34
+#define TPS65912_EN4_SET1		0x35
+#define TPS65912_EN4_SET2		0x36
+#define TPS65912_PGOOD			0x37
+#define TPS65912_PGOOD2			0x38
+#define TPS65912_INT_STS		0x39
+#define TPS65912_INT_MSK		0x3A
+#define TPS65912_INT_STS2		0x3B
+#define TPS65912_INT_MSK2		0x3C
+#define TPS65912_INT_STS3		0x3D
+#define TPS65912_INT_MSK3		0x3E
+#define TPS65912_INT_STS4		0x3F
+#define TPS65912_INT_MSK4		0x40
+#define TPS65912_GPIO1			0x41
+#define TPS65912_GPIO2			0x42
+#define TPS65912_GPIO3			0x43
+#define TPS65912_GPIO4			0x44
+#define TPS65912_GPIO5			0x45
+#define TPS65912_VMON			0x46
+#define TPS65912_LEDA_CTRL1		0x47
+#define TPS65912_LEDA_CTRL2		0x48
+#define TPS65912_LEDA_CTRL3		0x49
+#define TPS65912_LEDA_CTRL4		0x4A
+#define TPS65912_LEDA_CTRL5		0x4B
+#define TPS65912_LEDA_CTRL6		0x4C
+#define TPS65912_LEDA_CTRL7		0x4D
+#define TPS65912_LEDA_CTRL8		0x4E
+#define TPS65912_LEDB_CTRL1		0x4F
+#define TPS65912_LEDB_CTRL2		0x50
+#define TPS65912_LEDB_CTRL3		0x51
+#define TPS65912_LEDB_CTRL4		0x52
+#define TPS65912_LEDB_CTRL5		0x53
+#define TPS65912_LEDB_CTRL6		0x54
+#define TPS65912_LEDB_CTRL7		0x55
+#define TPS65912_LEDB_CTRL8		0x56
+#define TPS65912_LEDC_CTRL1		0x57
+#define TPS65912_LEDC_CTRL2		0x58
+#define TPS65912_LEDC_CTRL3		0x59
+#define TPS65912_LEDC_CTRL4		0x5A
+#define TPS65912_LEDC_CTRL5		0x5B
+#define TPS65912_LEDC_CTRL6		0x5C
+#define TPS65912_LEDC_CTRL7		0x5D
+#define TPS65912_LEDC_CTRL8		0x5E
+#define TPS65912_LED_RAMP_UP_TIME	0x5F
+#define TPS65912_LED_RAMP_DOWN_TIME	0x60
+#define TPS65912_LED_SEQ_EN		0x61
+#define TPS65912_LOADSWITCH		0x62
+#define TPS65912_SPARE			0x63
+#define TPS65912_VERNUM			0x64
+#define TPS6591X_MAX_REGISTER		0x64
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS_PWRHOLD_F	BIT(0)
+#define TPS65912_INT_STS_VMON		BIT(1)
+#define TPS65912_INT_STS_PWRON		BIT(2)
+#define TPS65912_INT_STS_PWRON_LP	BIT(3)
+#define TPS65912_INT_STS_PWRHOLD_R	BIT(4)
+#define TPS65912_INT_STS_HOTDIE		BIT(5)
+#define TPS65912_INT_STS_GPIO1_R	BIT(6)
+#define TPS65912_INT_STS_GPIO1_F	BIT(7)
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS2_GPIO2_R	BIT(0)
+#define TPS65912_INT_STS2_GPIO2_F	BIT(1)
+#define TPS65912_INT_STS2_GPIO3_R	BIT(2)
+#define TPS65912_INT_STS2_GPIO3_F	BIT(3)
+#define TPS65912_INT_STS2_GPIO4_R	BIT(4)
+#define TPS65912_INT_STS2_GPIO4_F	BIT(5)
+#define TPS65912_INT_STS2_GPIO5_R	BIT(6)
+#define TPS65912_INT_STS2_GPIO5_F	BIT(7)
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS3_PGOOD_DCDC1	BIT(0)
+#define TPS65912_INT_STS3_PGOOD_DCDC2	BIT(1)
+#define TPS65912_INT_STS3_PGOOD_DCDC3	BIT(2)
+#define TPS65912_INT_STS3_PGOOD_DCDC4	BIT(3)
+#define TPS65912_INT_STS3_PGOOD_LDO1	BIT(4)
+#define TPS65912_INT_STS3_PGOOD_LDO2	BIT(5)
+#define TPS65912_INT_STS3_PGOOD_LDO3	BIT(6)
+#define TPS65912_INT_STS3_PGOOD_LDO4	BIT(7)
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS4_PGOOD_LDO5	BIT(0)
+#define TPS65912_INT_STS4_PGOOD_LDO6	BIT(1)
+#define TPS65912_INT_STS4_PGOOD_LDO7	BIT(2)
+#define TPS65912_INT_STS4_PGOOD_LDO8	BIT(3)
+#define TPS65912_INT_STS4_PGOOD_LDO9	BIT(4)
+#define TPS65912_INT_STS4_PGOOD_LDO10	BIT(5)
+
+/* GPIO 1 and 2 Register field definitions */
+#define GPIO_SLEEP_MASK			0x80
+#define GPIO_SLEEP_SHIFT		7
+#define GPIO_DEB_MASK			0x10
+#define GPIO_DEB_SHIFT			4
+#define GPIO_CFG_MASK			0x04
+#define GPIO_CFG_SHIFT			2
+#define GPIO_STS_MASK			0x02
+#define GPIO_STS_SHIFT			1
+#define GPIO_SET_MASK			0x01
+#define GPIO_SET_SHIFT			0
+
+/* GPIO 3 Register field definitions */
+#define GPIO3_SLEEP_MASK		0x80
+#define GPIO3_SLEEP_SHIFT		7
+#define GPIO3_SEL_MASK			0x40
+#define GPIO3_SEL_SHIFT			6
+#define GPIO3_ODEN_MASK			0x20
+#define GPIO3_ODEN_SHIFT		5
+#define GPIO3_DEB_MASK			0x10
+#define GPIO3_DEB_SHIFT			4
+#define GPIO3_PDEN_MASK			0x08
+#define GPIO3_PDEN_SHIFT		3
+#define GPIO3_CFG_MASK			0x04
+#define GPIO3_CFG_SHIFT			2
+#define GPIO3_STS_MASK			0x02
+#define GPIO3_STS_SHIFT			1
+#define GPIO3_SET_MASK			0x01
+#define GPIO3_SET_SHIFT			0
+
+/* GPIO 4 Register field definitions */
+#define GPIO4_SLEEP_MASK		0x80
+#define GPIO4_SLEEP_SHIFT		7
+#define GPIO4_SEL_MASK			0x40
+#define GPIO4_SEL_SHIFT			6
+#define GPIO4_ODEN_MASK			0x20
+#define GPIO4_ODEN_SHIFT		5
+#define GPIO4_DEB_MASK			0x10
+#define GPIO4_DEB_SHIFT			4
+#define GPIO4_PDEN_MASK			0x08
+#define GPIO4_PDEN_SHIFT		3
+#define GPIO4_CFG_MASK			0x04
+#define GPIO4_CFG_SHIFT			2
+#define GPIO4_STS_MASK			0x02
+#define GPIO4_STS_SHIFT			1
+#define GPIO4_SET_MASK			0x01
+#define GPIO4_SET_SHIFT			0
+
+/* Register THERM  (0x80) register.RegisterDescription */
+#define THERM_THERM_HD_MASK		0x20
+#define THERM_THERM_HD_SHIFT		5
+#define THERM_THERM_TS_MASK		0x10
+#define THERM_THERM_TS_SHIFT		4
+#define THERM_THERM_HDSEL_MASK		0x0C
+#define THERM_THERM_HDSEL_SHIFT		2
+#define THERM_RSVD1_MASK		0x02
+#define THERM_RSVD1_SHIFT		1
+#define THERM_THERM_STATE_MASK		0x01
+#define THERM_THERM_STATE_SHIFT		0
+
+/* Register DCDCCTRL1 register.RegisterDescription */
+#define DCDCCTRL_VCON_ENABLE_MASK	0x80
+#define DCDCCTRL_VCON_ENABLE_SHIFT	7
+#define DCDCCTRL_VCON_RANGE1_MASK	0x40
+#define DCDCCTRL_VCON_RANGE1_SHIFT	6
+#define DCDCCTRL_VCON_RANGE0_MASK	0x20
+#define DCDCCTRL_VCON_RANGE0_SHIFT	5
+#define DCDCCTRL_TSTEP2_MASK		0x10
+#define DCDCCTRL_TSTEP2_SHIFT		4
+#define DCDCCTRL_TSTEP1_MASK		0x08
+#define DCDCCTRL_TSTEP1_SHIFT		3
+#define DCDCCTRL_TSTEP0_MASK		0x04
+#define DCDCCTRL_TSTEP0_SHIFT		2
+#define DCDCCTRL_DCDC1_MODE_MASK	0x02
+#define DCDCCTRL_DCDC1_MODE_SHIFT	1
+
+/* Register DCDCCTRL2 and DCDCCTRL3 register.RegisterDescription */
+#define DCDCCTRL_TSTEP2_MASK		0x10
+#define DCDCCTRL_TSTEP2_SHIFT		4
+#define DCDCCTRL_TSTEP1_MASK		0x08
+#define DCDCCTRL_TSTEP1_SHIFT		3
+#define DCDCCTRL_TSTEP0_MASK		0x04
+#define DCDCCTRL_TSTEP0_SHIFT		2
+#define DCDCCTRL_DCDC_MODE_MASK		0x02
+#define DCDCCTRL_DCDC_MODE_SHIFT	1
+#define DCDCCTRL_RSVD0_MASK		0x01
+#define DCDCCTRL_RSVD0_SHIFT		0
+
+/* Register DCDCCTRL4 register.RegisterDescription */
+#define DCDCCTRL_RAMP_TIME_MASK		0x01
+#define DCDCCTRL_RAMP_TIME_SHIFT	0
+
+/* Register DCDCx_AVS */
+#define DCDC_AVS_ENABLE_MASK		0x80
+#define DCDC_AVS_ENABLE_SHIFT		7
+#define DCDC_AVS_ECO_MASK		0x40
+#define DCDC_AVS_ECO_SHIFT		6
+
+/* Register DCDCx_LIMIT */
+#define DCDC_LIMIT_RANGE_MASK		0xC0
+#define DCDC_LIMIT_RANGE_SHIFT		6
+#define DCDC_LIMIT_MAX_SEL_MASK		0x3F
+#define DCDC_LIMIT_MAX_SEL_SHIFT	0
+
+enum tps65912_regulator_id {
+	/* DCDC's */
+	TPS65912_DCDC_1,
+	TPS65912_DCDC_2,
+	TPS65912_DCDC_3,
+	TPS65912_DCDC_4,
+	/* LDOs */
+	TPS65912_LDO_1,
+	TPS65912_LDO_2,
+	TPS65912_LDO_3,
+	TPS65912_LDO_4,
+	TPS65912_LDO_5,
+	TPS65912_LDO_6,
+	TPS65912_LDO_7,
+	TPS65912_LDO_8,
+	TPS65912_LDO_9,
+	TPS65912_LDO_10,
+};
+
+#define TPS65912_MAX_REG_ID		TPS65912_LDO_10
+
+/* Number of step-down converters available */
+#define TPS65912_NUM_DCDC		4
+/* Number of LDO voltage regulators available */
+#define TPS65912_NUM_LDO		10
+/* Number of total regulators available */
+#define TPS65912_NUM_REGULATOR		(TPS65912_NUM_DCDC + TPS65912_NUM_LDO)
+
+/* Define the TPS65912 IRQ numbers */
+enum tps65912_irqs {
+	/* INT_STS registers */
+	TPS65912_IRQ_PWRHOLD_F,
+	TPS65912_IRQ_VMON,
+	TPS65912_IRQ_PWRON,
+	TPS65912_IRQ_PWRON_LP,
+	TPS65912_IRQ_PWRHOLD_R,
+	TPS65912_IRQ_HOTDIE,
+	TPS65912_IRQ_GPIO1_R,
+	TPS65912_IRQ_GPIO1_F,
+	/* INT_STS2 registers */
+	TPS65912_IRQ_GPIO2_R,
+	TPS65912_IRQ_GPIO2_F,
+	TPS65912_IRQ_GPIO3_R,
+	TPS65912_IRQ_GPIO3_F,
+	TPS65912_IRQ_GPIO4_R,
+	TPS65912_IRQ_GPIO4_F,
+	TPS65912_IRQ_GPIO5_R,
+	TPS65912_IRQ_GPIO5_F,
+	/* INT_STS3 registers */
+	TPS65912_IRQ_PGOOD_DCDC1,
+	TPS65912_IRQ_PGOOD_DCDC2,
+	TPS65912_IRQ_PGOOD_DCDC3,
+	TPS65912_IRQ_PGOOD_DCDC4,
+	TPS65912_IRQ_PGOOD_LDO1,
+	TPS65912_IRQ_PGOOD_LDO2,
+	TPS65912_IRQ_PGOOD_LDO3,
+	TPS65912_IRQ_PGOOD_LDO4,
+	/* INT_STS4 registers */
+	TPS65912_IRQ_PGOOD_LDO5,
+	TPS65912_IRQ_PGOOD_LDO6,
+	TPS65912_IRQ_PGOOD_LDO7,
+	TPS65912_IRQ_PGOOD_LDO8,
+	TPS65912_IRQ_PGOOD_LDO9,
+	TPS65912_IRQ_PGOOD_LDO10,
+};
+
+/*
+ * struct tps_info - packages regulator constraints
+ * @id: Id of the regulator
+ * @name: Voltage regulator name
+ * @min_uV: Minimum micro volts
+ * @max_uV: Minimum micro volts
+ *
+ * This data is used to check the regulator voltage limits while setting.
+ */
+struct tps_info {
+	int id;
+	const char *name;
+	int min_uV;
+	int max_uV;
+};
+
+/*
+ * struct tps65912 - state holder for the tps65912 driver
+ *
+ * Device data may be used to access the TPS65912 chip
+ */
+struct tps65912 {
+	struct device *dev;
+	unsigned int id;
+
+	/* IRQ Data */
+	int irq;
+	struct regmap_irq_chip_data *irq_data;
+
+	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
+	struct tps_info *info[TPS65912_NUM_REGULATOR];
+	struct regmap *regmap;
+};
+
+static const struct regmap_range tps65912_yes_ranges[] = {
+	regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
+};
+
+static const struct regmap_access_table tps65912_volatile_table = {
+	.yes_ranges = tps65912_yes_ranges,
+	.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
+};
+
+static const struct regmap_config tps65912_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_table = &tps65912_volatile_table,
+};
+
+int tps65912_device_init(struct tps65912 *tps);
+int tps65912_device_exit(struct tps65912 *tps);
+
+#endif /*  __LINUX_MFD_TPS65912_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-24 14:52   ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

This patch adds support for TPS65912 mfd device. It provides
communication through the I2C and SPI interfaces. It contains
the following components:

 - Regulators
 - GPIO controller

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/mfd/Kconfig          |  24 +++
 drivers/mfd/Makefile         |   3 +
 drivers/mfd/tps65912-core.c  | 114 +++++++++++++
 drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
 drivers/mfd/tps65912-spi.c   |  85 ++++++++++
 include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 705 insertions(+)
 create mode 100644 drivers/mfd/tps65912-core.c
 create mode 100644 drivers/mfd/tps65912-i2c.c
 create mode 100644 drivers/mfd/tps65912-spi.c
 create mode 100644 include/linux/mfd/tps65912.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 9a8df8e..4663658 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1167,6 +1167,30 @@ config MFD_TPS65910
 	  if you say yes here you get support for the TPS65910 series of
 	  Power Management chips.
 
+config MFD_TPS65912
+	tristate
+	select REGMAP
+	select REGMAP_IRQ
+	select MFD_CORE
+
+config MFD_TPS65912_I2C
+	tristate "TI TPS65912 Power Management chip with I2C"
+	select MFD_TPS65912
+	select REGMAP_I2C
+	depends on I2C
+	help
+	  If you say yes here you get support for the TPS65912 series of
+	  PM chips with I2C interface.
+
+config MFD_TPS65912_SPI
+	tristate "TI TPS65912 Power Management chip with SPI"
+	select MFD_TPS65912
+	select REGMAP_SPI
+	depends on SPI_MASTER
+	help
+	  If you say yes here you get support for the TPS65912 series of
+	  PM chips with SPI interface.
+
 config MFD_TPS80031
 	bool "TI TPS80031/TPS80032 Power Management chips"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 004aa76..49c3530 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -69,6 +69,9 @@ obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
+obj-$(CONFIG_MFD_TPS65912)	+= tps65912-core.o
+obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
+obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
 obj-$(CONFIG_MFD_TPS80031)	+= tps80031.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
new file mode 100644
index 0000000..8dd1aac
--- /dev/null
+++ b/drivers/mfd/tps65912-core.c
@@ -0,0 +1,114 @@
+/*
+ * Core functions for TI TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+#include <linux/mfd/tps65912.h>
+
+#define TPS65912_IRQ(_name, _reg, _offset)			\
+	[TPS65912_IRQ_ ## _name] = {				\
+		.mask = TPS65912_ ## _reg ## _ ## _name,	\
+		.reg_offset = _offset,				\
+	}
+
+static const struct regmap_irq tps65912_irqs[] = {
+	/* INT_STS IRQs */
+	TPS65912_IRQ(PWRHOLD_F, INT_STS, 0),
+	TPS65912_IRQ(VMON, INT_STS, 0),
+	TPS65912_IRQ(PWRON, INT_STS, 0),
+	TPS65912_IRQ(PWRON_LP, INT_STS, 0),
+	TPS65912_IRQ(PWRHOLD_R, INT_STS, 0),
+	TPS65912_IRQ(HOTDIE, INT_STS, 0),
+	TPS65912_IRQ(GPIO1_R, INT_STS, 0),
+	TPS65912_IRQ(GPIO1_F, INT_STS, 0),
+	/* INT_STS2 IRQs */
+	TPS65912_IRQ(GPIO2_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO2_F, INT_STS2, 1),
+	TPS65912_IRQ(GPIO3_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO3_F, INT_STS2, 1),
+	TPS65912_IRQ(GPIO4_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO4_F, INT_STS2, 1),
+	TPS65912_IRQ(GPIO5_R, INT_STS2, 1),
+	TPS65912_IRQ(GPIO5_F, INT_STS2, 1),
+	/* INT_STS3 IRQs */
+	TPS65912_IRQ(PGOOD_DCDC1, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_DCDC2, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_DCDC3, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_DCDC4, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO1, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO2, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO3, INT_STS3, 2),
+	TPS65912_IRQ(PGOOD_LDO4, INT_STS3, 2),
+	/* INT_STS4 IRQs */
+	TPS65912_IRQ(PGOOD_LDO5, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO6, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO7, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO8, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO9, INT_STS4, 3),
+	TPS65912_IRQ(PGOOD_LDO10, INT_STS4, 3),
+};
+
+static struct regmap_irq_chip tps65912_irq_chip = {
+	.name = "tps65912",
+	.irqs = tps65912_irqs,
+	.num_irqs = ARRAY_SIZE(tps65912_irqs),
+	.num_regs = 4,
+	.irq_reg_stride = 2,
+	.mask_base = TPS65912_INT_MSK,
+	.status_base = TPS65912_INT_STS,
+	.ack_base = TPS65912_INT_STS,
+	.init_ack_masked = true,
+};
+
+int tps65912_device_init(struct tps65912 *tps)
+{
+	int ret;
+
+	ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
+				  &tps65912_irq_chip, &tps->irq_data);
+	if (ret < 0)
+		return ret;
+
+	ret = of_platform_populate(tps->dev->of_node, NULL, NULL, tps->dev);
+	if (ret < 0)
+		goto err_irq;
+
+	return 0;
+
+err_irq:
+	regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tps65912_device_init);
+
+int tps65912_device_exit(struct tps65912 *tps)
+{
+	regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tps65912_device_exit);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912x MFD Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c
new file mode 100644
index 0000000..ca640c4
--- /dev/null
+++ b/drivers/mfd/tps65912-i2c.c
@@ -0,0 +1,86 @@
+/*
+ * I2C access driver for TI TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/tps65912.h>
+
+static const struct of_device_id tps65912_i2c_of_match_table[] = {
+	{ .compatible = "ti,tps65912", },
+	{ /* sentinel */ }
+};
+
+static int tps65912_i2c_probe(struct i2c_client *client,
+			      const struct i2c_device_id *ids)
+{
+	struct tps65912 *tps;
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, tps);
+	tps->dev = &client->dev;
+	tps->irq = client->irq;
+
+	tps->regmap = devm_regmap_init_i2c(client, &tps65912_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		int ret = PTR_ERR(tps->regmap);
+
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+
+		return ret;
+	}
+
+	return tps65912_device_init(tps);
+}
+
+static int tps65912_i2c_remove(struct i2c_client *client)
+{
+	struct tps65912 *tps = i2c_get_clientdata(client);
+
+	return tps65912_device_exit(tps);
+}
+
+static const struct i2c_device_id tps65912_i2c_id_table[] = {
+	{ "tps65912", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id_table);
+
+static struct i2c_driver tps65912_i2c_driver = {
+	.driver		= {
+		.name	= "tps65912",
+		.of_match_table = tps65912_i2c_of_match_table,
+	},
+	.probe		= tps65912_i2c_probe,
+	.remove		= tps65912_i2c_remove,
+	.id_table       = tps65912_i2c_id_table,
+};
+
+module_i2c_driver(tps65912_i2c_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912x I2C Interface Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
new file mode 100644
index 0000000..799f835
--- /dev/null
+++ b/drivers/mfd/tps65912-spi.c
@@ -0,0 +1,85 @@
+/*
+ * SPI access driver for TI TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mfd/tps65912.h>
+
+static const struct of_device_id tps65912_spi_of_match_table[] = {
+	{ .compatible = "ti,tps65912", },
+	{ /* sentinel */ }
+};
+
+static int tps65912_spi_probe(struct spi_device *spi)
+{
+	struct tps65912 *tps;
+
+	tps = devm_kzalloc(&spi->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, tps);
+	tps->dev = &spi->dev;
+	tps->irq = spi->irq;
+
+	tps->regmap = devm_regmap_init_spi(spi, &tps65912_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		int ret = PTR_ERR(tps->regmap);
+
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+
+		return ret;
+	}
+
+	return tps65912_device_init(tps);
+}
+
+static int tps65912_spi_remove(struct spi_device *client)
+{
+	struct tps65912 *tps = spi_get_drvdata(client);
+
+	return tps65912_device_exit(tps);
+}
+
+static const struct spi_device_id tps65912_spi_id_table[] = {
+	{ "tps65912", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(spi, tps65912_spi_id_table);
+
+static struct spi_driver tps65912_spi_driver = {
+	.driver		= {
+		.name	= "tps65912",
+		.of_match_table = tps65912_spi_of_match_table,
+	},
+	.probe		= tps65912_spi_probe,
+	.remove		= tps65912_spi_remove,
+	.id_table       = tps65912_spi_id_table,
+};
+
+module_spi_driver(tps65912_spi_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912x SPI Interface Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h
new file mode 100644
index 0000000..e5ebd48
--- /dev/null
+++ b/include/linux/mfd/tps65912.h
@@ -0,0 +1,393 @@
+/*
+ * TI TPS65912x
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#ifndef __LINUX_MFD_TPS65912_H
+#define __LINUX_MFD_TPS65912_H
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+/* List of registers for TPS65912 */
+#define TPS65912_DCDC1_CTRL		0x00
+#define TPS65912_DCDC2_CTRL		0x01
+#define TPS65912_DCDC3_CTRL		0x02
+#define TPS65912_DCDC4_CTRL		0x03
+#define TPS65912_DCDC1_OP		0x04
+#define TPS65912_DCDC1_AVS		0x05
+#define TPS65912_DCDC1_LIMIT		0x06
+#define TPS65912_DCDC2_OP		0x07
+#define TPS65912_DCDC2_AVS		0x08
+#define TPS65912_DCDC2_LIMIT		0x09
+#define TPS65912_DCDC3_OP		0x0A
+#define TPS65912_DCDC3_AVS		0x0B
+#define TPS65912_DCDC3_LIMIT		0x0C
+#define TPS65912_DCDC4_OP		0x0D
+#define TPS65912_DCDC4_AVS		0x0E
+#define TPS65912_DCDC4_LIMIT		0x0F
+#define TPS65912_LDO1_OP		0x10
+#define TPS65912_LDO1_AVS		0x11
+#define TPS65912_LDO1_LIMIT		0x12
+#define TPS65912_LDO2_OP		0x13
+#define TPS65912_LDO2_AVS		0x14
+#define TPS65912_LDO2_LIMIT		0x15
+#define TPS65912_LDO3_OP		0x16
+#define TPS65912_LDO3_AVS		0x17
+#define TPS65912_LDO3_LIMIT		0x18
+#define TPS65912_LDO4_OP		0x19
+#define TPS65912_LDO4_AVS		0x1A
+#define TPS65912_LDO4_LIMIT		0x1B
+#define TPS65912_LDO5			0x1C
+#define TPS65912_LDO6			0x1D
+#define TPS65912_LDO7			0x1E
+#define TPS65912_LDO8			0x1F
+#define TPS65912_LDO9			0x20
+#define TPS65912_LDO10			0x21
+#define TPS65912_THRM			0x22
+#define TPS65912_CLK32OUT		0x23
+#define TPS65912_DEVCTRL		0x24
+#define TPS65912_DEVCTRL2		0x25
+#define TPS65912_I2C_SPI_CFG		0x26
+#define TPS65912_KEEP_ON		0x27
+#define TPS65912_KEEP_ON2		0x28
+#define TPS65912_SET_OFF1		0x29
+#define TPS65912_SET_OFF2		0x2A
+#define TPS65912_DEF_VOLT		0x2B
+#define TPS65912_DEF_VOLT_MAPPING	0x2C
+#define TPS65912_DISCHARGE		0x2D
+#define TPS65912_DISCHARGE2		0x2E
+#define TPS65912_EN1_SET1		0x2F
+#define TPS65912_EN1_SET2		0x30
+#define TPS65912_EN2_SET1		0x31
+#define TPS65912_EN2_SET2		0x32
+#define TPS65912_EN3_SET1		0x33
+#define TPS65912_EN3_SET2		0x34
+#define TPS65912_EN4_SET1		0x35
+#define TPS65912_EN4_SET2		0x36
+#define TPS65912_PGOOD			0x37
+#define TPS65912_PGOOD2			0x38
+#define TPS65912_INT_STS		0x39
+#define TPS65912_INT_MSK		0x3A
+#define TPS65912_INT_STS2		0x3B
+#define TPS65912_INT_MSK2		0x3C
+#define TPS65912_INT_STS3		0x3D
+#define TPS65912_INT_MSK3		0x3E
+#define TPS65912_INT_STS4		0x3F
+#define TPS65912_INT_MSK4		0x40
+#define TPS65912_GPIO1			0x41
+#define TPS65912_GPIO2			0x42
+#define TPS65912_GPIO3			0x43
+#define TPS65912_GPIO4			0x44
+#define TPS65912_GPIO5			0x45
+#define TPS65912_VMON			0x46
+#define TPS65912_LEDA_CTRL1		0x47
+#define TPS65912_LEDA_CTRL2		0x48
+#define TPS65912_LEDA_CTRL3		0x49
+#define TPS65912_LEDA_CTRL4		0x4A
+#define TPS65912_LEDA_CTRL5		0x4B
+#define TPS65912_LEDA_CTRL6		0x4C
+#define TPS65912_LEDA_CTRL7		0x4D
+#define TPS65912_LEDA_CTRL8		0x4E
+#define TPS65912_LEDB_CTRL1		0x4F
+#define TPS65912_LEDB_CTRL2		0x50
+#define TPS65912_LEDB_CTRL3		0x51
+#define TPS65912_LEDB_CTRL4		0x52
+#define TPS65912_LEDB_CTRL5		0x53
+#define TPS65912_LEDB_CTRL6		0x54
+#define TPS65912_LEDB_CTRL7		0x55
+#define TPS65912_LEDB_CTRL8		0x56
+#define TPS65912_LEDC_CTRL1		0x57
+#define TPS65912_LEDC_CTRL2		0x58
+#define TPS65912_LEDC_CTRL3		0x59
+#define TPS65912_LEDC_CTRL4		0x5A
+#define TPS65912_LEDC_CTRL5		0x5B
+#define TPS65912_LEDC_CTRL6		0x5C
+#define TPS65912_LEDC_CTRL7		0x5D
+#define TPS65912_LEDC_CTRL8		0x5E
+#define TPS65912_LED_RAMP_UP_TIME	0x5F
+#define TPS65912_LED_RAMP_DOWN_TIME	0x60
+#define TPS65912_LED_SEQ_EN		0x61
+#define TPS65912_LOADSWITCH		0x62
+#define TPS65912_SPARE			0x63
+#define TPS65912_VERNUM			0x64
+#define TPS6591X_MAX_REGISTER		0x64
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS_PWRHOLD_F	BIT(0)
+#define TPS65912_INT_STS_VMON		BIT(1)
+#define TPS65912_INT_STS_PWRON		BIT(2)
+#define TPS65912_INT_STS_PWRON_LP	BIT(3)
+#define TPS65912_INT_STS_PWRHOLD_R	BIT(4)
+#define TPS65912_INT_STS_HOTDIE		BIT(5)
+#define TPS65912_INT_STS_GPIO1_R	BIT(6)
+#define TPS65912_INT_STS_GPIO1_F	BIT(7)
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS2_GPIO2_R	BIT(0)
+#define TPS65912_INT_STS2_GPIO2_F	BIT(1)
+#define TPS65912_INT_STS2_GPIO3_R	BIT(2)
+#define TPS65912_INT_STS2_GPIO3_F	BIT(3)
+#define TPS65912_INT_STS2_GPIO4_R	BIT(4)
+#define TPS65912_INT_STS2_GPIO4_F	BIT(5)
+#define TPS65912_INT_STS2_GPIO5_R	BIT(6)
+#define TPS65912_INT_STS2_GPIO5_F	BIT(7)
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS3_PGOOD_DCDC1	BIT(0)
+#define TPS65912_INT_STS3_PGOOD_DCDC2	BIT(1)
+#define TPS65912_INT_STS3_PGOOD_DCDC3	BIT(2)
+#define TPS65912_INT_STS3_PGOOD_DCDC4	BIT(3)
+#define TPS65912_INT_STS3_PGOOD_LDO1	BIT(4)
+#define TPS65912_INT_STS3_PGOOD_LDO2	BIT(5)
+#define TPS65912_INT_STS3_PGOOD_LDO3	BIT(6)
+#define TPS65912_INT_STS3_PGOOD_LDO4	BIT(7)
+
+/* INT_STS Register field definitions */
+#define TPS65912_INT_STS4_PGOOD_LDO5	BIT(0)
+#define TPS65912_INT_STS4_PGOOD_LDO6	BIT(1)
+#define TPS65912_INT_STS4_PGOOD_LDO7	BIT(2)
+#define TPS65912_INT_STS4_PGOOD_LDO8	BIT(3)
+#define TPS65912_INT_STS4_PGOOD_LDO9	BIT(4)
+#define TPS65912_INT_STS4_PGOOD_LDO10	BIT(5)
+
+/* GPIO 1 and 2 Register field definitions */
+#define GPIO_SLEEP_MASK			0x80
+#define GPIO_SLEEP_SHIFT		7
+#define GPIO_DEB_MASK			0x10
+#define GPIO_DEB_SHIFT			4
+#define GPIO_CFG_MASK			0x04
+#define GPIO_CFG_SHIFT			2
+#define GPIO_STS_MASK			0x02
+#define GPIO_STS_SHIFT			1
+#define GPIO_SET_MASK			0x01
+#define GPIO_SET_SHIFT			0
+
+/* GPIO 3 Register field definitions */
+#define GPIO3_SLEEP_MASK		0x80
+#define GPIO3_SLEEP_SHIFT		7
+#define GPIO3_SEL_MASK			0x40
+#define GPIO3_SEL_SHIFT			6
+#define GPIO3_ODEN_MASK			0x20
+#define GPIO3_ODEN_SHIFT		5
+#define GPIO3_DEB_MASK			0x10
+#define GPIO3_DEB_SHIFT			4
+#define GPIO3_PDEN_MASK			0x08
+#define GPIO3_PDEN_SHIFT		3
+#define GPIO3_CFG_MASK			0x04
+#define GPIO3_CFG_SHIFT			2
+#define GPIO3_STS_MASK			0x02
+#define GPIO3_STS_SHIFT			1
+#define GPIO3_SET_MASK			0x01
+#define GPIO3_SET_SHIFT			0
+
+/* GPIO 4 Register field definitions */
+#define GPIO4_SLEEP_MASK		0x80
+#define GPIO4_SLEEP_SHIFT		7
+#define GPIO4_SEL_MASK			0x40
+#define GPIO4_SEL_SHIFT			6
+#define GPIO4_ODEN_MASK			0x20
+#define GPIO4_ODEN_SHIFT		5
+#define GPIO4_DEB_MASK			0x10
+#define GPIO4_DEB_SHIFT			4
+#define GPIO4_PDEN_MASK			0x08
+#define GPIO4_PDEN_SHIFT		3
+#define GPIO4_CFG_MASK			0x04
+#define GPIO4_CFG_SHIFT			2
+#define GPIO4_STS_MASK			0x02
+#define GPIO4_STS_SHIFT			1
+#define GPIO4_SET_MASK			0x01
+#define GPIO4_SET_SHIFT			0
+
+/* Register THERM  (0x80) register.RegisterDescription */
+#define THERM_THERM_HD_MASK		0x20
+#define THERM_THERM_HD_SHIFT		5
+#define THERM_THERM_TS_MASK		0x10
+#define THERM_THERM_TS_SHIFT		4
+#define THERM_THERM_HDSEL_MASK		0x0C
+#define THERM_THERM_HDSEL_SHIFT		2
+#define THERM_RSVD1_MASK		0x02
+#define THERM_RSVD1_SHIFT		1
+#define THERM_THERM_STATE_MASK		0x01
+#define THERM_THERM_STATE_SHIFT		0
+
+/* Register DCDCCTRL1 register.RegisterDescription */
+#define DCDCCTRL_VCON_ENABLE_MASK	0x80
+#define DCDCCTRL_VCON_ENABLE_SHIFT	7
+#define DCDCCTRL_VCON_RANGE1_MASK	0x40
+#define DCDCCTRL_VCON_RANGE1_SHIFT	6
+#define DCDCCTRL_VCON_RANGE0_MASK	0x20
+#define DCDCCTRL_VCON_RANGE0_SHIFT	5
+#define DCDCCTRL_TSTEP2_MASK		0x10
+#define DCDCCTRL_TSTEP2_SHIFT		4
+#define DCDCCTRL_TSTEP1_MASK		0x08
+#define DCDCCTRL_TSTEP1_SHIFT		3
+#define DCDCCTRL_TSTEP0_MASK		0x04
+#define DCDCCTRL_TSTEP0_SHIFT		2
+#define DCDCCTRL_DCDC1_MODE_MASK	0x02
+#define DCDCCTRL_DCDC1_MODE_SHIFT	1
+
+/* Register DCDCCTRL2 and DCDCCTRL3 register.RegisterDescription */
+#define DCDCCTRL_TSTEP2_MASK		0x10
+#define DCDCCTRL_TSTEP2_SHIFT		4
+#define DCDCCTRL_TSTEP1_MASK		0x08
+#define DCDCCTRL_TSTEP1_SHIFT		3
+#define DCDCCTRL_TSTEP0_MASK		0x04
+#define DCDCCTRL_TSTEP0_SHIFT		2
+#define DCDCCTRL_DCDC_MODE_MASK		0x02
+#define DCDCCTRL_DCDC_MODE_SHIFT	1
+#define DCDCCTRL_RSVD0_MASK		0x01
+#define DCDCCTRL_RSVD0_SHIFT		0
+
+/* Register DCDCCTRL4 register.RegisterDescription */
+#define DCDCCTRL_RAMP_TIME_MASK		0x01
+#define DCDCCTRL_RAMP_TIME_SHIFT	0
+
+/* Register DCDCx_AVS */
+#define DCDC_AVS_ENABLE_MASK		0x80
+#define DCDC_AVS_ENABLE_SHIFT		7
+#define DCDC_AVS_ECO_MASK		0x40
+#define DCDC_AVS_ECO_SHIFT		6
+
+/* Register DCDCx_LIMIT */
+#define DCDC_LIMIT_RANGE_MASK		0xC0
+#define DCDC_LIMIT_RANGE_SHIFT		6
+#define DCDC_LIMIT_MAX_SEL_MASK		0x3F
+#define DCDC_LIMIT_MAX_SEL_SHIFT	0
+
+enum tps65912_regulator_id {
+	/* DCDC's */
+	TPS65912_DCDC_1,
+	TPS65912_DCDC_2,
+	TPS65912_DCDC_3,
+	TPS65912_DCDC_4,
+	/* LDOs */
+	TPS65912_LDO_1,
+	TPS65912_LDO_2,
+	TPS65912_LDO_3,
+	TPS65912_LDO_4,
+	TPS65912_LDO_5,
+	TPS65912_LDO_6,
+	TPS65912_LDO_7,
+	TPS65912_LDO_8,
+	TPS65912_LDO_9,
+	TPS65912_LDO_10,
+};
+
+#define TPS65912_MAX_REG_ID		TPS65912_LDO_10
+
+/* Number of step-down converters available */
+#define TPS65912_NUM_DCDC		4
+/* Number of LDO voltage regulators available */
+#define TPS65912_NUM_LDO		10
+/* Number of total regulators available */
+#define TPS65912_NUM_REGULATOR		(TPS65912_NUM_DCDC + TPS65912_NUM_LDO)
+
+/* Define the TPS65912 IRQ numbers */
+enum tps65912_irqs {
+	/* INT_STS registers */
+	TPS65912_IRQ_PWRHOLD_F,
+	TPS65912_IRQ_VMON,
+	TPS65912_IRQ_PWRON,
+	TPS65912_IRQ_PWRON_LP,
+	TPS65912_IRQ_PWRHOLD_R,
+	TPS65912_IRQ_HOTDIE,
+	TPS65912_IRQ_GPIO1_R,
+	TPS65912_IRQ_GPIO1_F,
+	/* INT_STS2 registers */
+	TPS65912_IRQ_GPIO2_R,
+	TPS65912_IRQ_GPIO2_F,
+	TPS65912_IRQ_GPIO3_R,
+	TPS65912_IRQ_GPIO3_F,
+	TPS65912_IRQ_GPIO4_R,
+	TPS65912_IRQ_GPIO4_F,
+	TPS65912_IRQ_GPIO5_R,
+	TPS65912_IRQ_GPIO5_F,
+	/* INT_STS3 registers */
+	TPS65912_IRQ_PGOOD_DCDC1,
+	TPS65912_IRQ_PGOOD_DCDC2,
+	TPS65912_IRQ_PGOOD_DCDC3,
+	TPS65912_IRQ_PGOOD_DCDC4,
+	TPS65912_IRQ_PGOOD_LDO1,
+	TPS65912_IRQ_PGOOD_LDO2,
+	TPS65912_IRQ_PGOOD_LDO3,
+	TPS65912_IRQ_PGOOD_LDO4,
+	/* INT_STS4 registers */
+	TPS65912_IRQ_PGOOD_LDO5,
+	TPS65912_IRQ_PGOOD_LDO6,
+	TPS65912_IRQ_PGOOD_LDO7,
+	TPS65912_IRQ_PGOOD_LDO8,
+	TPS65912_IRQ_PGOOD_LDO9,
+	TPS65912_IRQ_PGOOD_LDO10,
+};
+
+/*
+ * struct tps_info - packages regulator constraints
+ * @id: Id of the regulator
+ * @name: Voltage regulator name
+ * @min_uV: Minimum micro volts
+ * @max_uV: Minimum micro volts
+ *
+ * This data is used to check the regulator voltage limits while setting.
+ */
+struct tps_info {
+	int id;
+	const char *name;
+	int min_uV;
+	int max_uV;
+};
+
+/*
+ * struct tps65912 - state holder for the tps65912 driver
+ *
+ * Device data may be used to access the TPS65912 chip
+ */
+struct tps65912 {
+	struct device *dev;
+	unsigned int id;
+
+	/* IRQ Data */
+	int irq;
+	struct regmap_irq_chip_data *irq_data;
+
+	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
+	struct tps_info *info[TPS65912_NUM_REGULATOR];
+	struct regmap *regmap;
+};
+
+static const struct regmap_range tps65912_yes_ranges[] = {
+	regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
+};
+
+static const struct regmap_access_table tps65912_volatile_table = {
+	.yes_ranges = tps65912_yes_ranges,
+	.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
+};
+
+static const struct regmap_config tps65912_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_table = &tps65912_volatile_table,
+};
+
+int tps65912_device_init(struct tps65912 *tps);
+int tps65912_device_exit(struct tps65912 *tps);
+
+#endif /*  __LINUX_MFD_TPS65912_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-24 14:52 ` Andrew F. Davis
@ 2015-09-24 14:52   ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

This patch adds support for TPS65912 PMIC regulators.

The regulators set consists of 4 DCDCs and 10 LDOs. The output
voltages are configurable and are meant to supply power to the
main processor and other components.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/regulator/Kconfig              |   6 +
 drivers/regulator/Makefile             |   1 +
 drivers/regulator/tps65912-regulator.c | 240 +++++++++++++++++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 drivers/regulator/tps65912-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 3cb2de9..1dec96a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -727,6 +727,12 @@ config REGULATOR_TPS65910
 	help
 	  This driver supports TPS65910/TPS65911 voltage regulator chips.
 
+config REGULATOR_TPS65912
+	tristate "TI TPS65912 Power regulator"
+	depends on MFD_TPS65912
+	help
+	    This driver supports TPS65912 voltage regulator chip.
+
 config REGULATOR_TPS80031
 	tristate "TI TPS80031/TPS80032 power regualtor driver"
 	depends on MFD_TPS80031
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 222ff5f..0f81749 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
+obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
 obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
 obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
new file mode 100644
index 0000000..343dae1
--- /dev/null
+++ b/drivers/regulator/tps65912-regulator.c
@@ -0,0 +1,240 @@
+/*
+ * Regulator driver for TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#include <linux/mfd/tps65912.h>
+
+enum tps65912_regulators { DCDC1, DCDC2, DCDC3, DCDC4, LDO1, LDO2, LDO3,
+	LDO4, LDO5, LDO6, LDO7, LDO8, LDO9, LDO10 };
+
+#define TPS65912_REGULATOR(_name, _id, _ops, _vr, _er, _lr, _nlr)	\
+	{								\
+		.name			= _name,			\
+		.id			= _id,				\
+		.ops			= &_ops,			\
+		.n_voltages		= 64,				\
+		.type			= REGULATOR_VOLTAGE,		\
+		.owner			= THIS_MODULE,			\
+		.vsel_reg		= _vr,				\
+		.vsel_mask		= 0x3f,				\
+		.enable_reg		= _er,				\
+		.enable_mask		= BIT(7),			\
+		.volt_table		= NULL,				\
+		.linear_ranges		= _lr,				\
+		.n_linear_ranges	= _nlr,				\
+	}								\
+
+#define TPS65912_INFO(_id, _nm, _min, _max)	\
+	[_id] = {				\
+		.id		= _id,		\
+		.name		= _nm,		\
+		.min_uV		= _min,		\
+		.max_uV		= _max,		\
+	}
+
+static const struct regulator_linear_range tps65912_dcdc_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0x0, 0x3f, 50000),
+};
+
+static const struct regulator_linear_range tps65912_ldo_ranges[] = {
+	REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 25000),
+	REGULATOR_LINEAR_RANGE(1650000, 0x21, 0x3c, 50000),
+	REGULATOR_LINEAR_RANGE(3100000, 0x3d, 0x3f, 100000),
+};
+
+static struct tps_info tps65912_pmic_regs[] = {
+	TPS65912_INFO(DCDC1, "DCDC1", 500000, 3800000),
+	TPS65912_INFO(DCDC2, "DCDC2", 500000, 3800000),
+	TPS65912_INFO(DCDC3, "DCDC3", 500000, 3800000),
+	TPS65912_INFO(DCDC4, "DCDC4", 500000, 3800000),
+	TPS65912_INFO(LDO1, "LDO1", 800000, 3300000),
+	TPS65912_INFO(LDO2, "LDO2", 800000, 3300000),
+	TPS65912_INFO(LDO3, "LDO3", 800000, 3300000),
+	TPS65912_INFO(LDO4, "LDO4", 1600000, 3300000),
+	TPS65912_INFO(LDO5, "LDO5", 1600000, 3300000),
+	TPS65912_INFO(LDO6, "LDO6", 800000, 3300000),
+	TPS65912_INFO(LDO7, "LDO7", 800000, 3300000),
+	TPS65912_INFO(LDO8, "LDO8", 800000, 3300000),
+	TPS65912_INFO(LDO9, "LDO9", 800000, 3300000),
+	TPS65912_INFO(LDO10, "LDO10", 800000, 3300000),
+};
+
+#define TPS65912_OF_MATCH(comp, label)	\
+	{				\
+		.compatible = comp,	\
+		.data = &label,		\
+	}
+
+static const struct of_device_id tps65912_regulator_of_match_table[] = {
+	TPS65912_OF_MATCH("ti,tps65912-dcdc1", tps65912_pmic_regs[DCDC1]),
+	TPS65912_OF_MATCH("ti,tps65912-dcdc2", tps65912_pmic_regs[DCDC2]),
+	TPS65912_OF_MATCH("ti,tps65912-dcdc3", tps65912_pmic_regs[DCDC3]),
+	TPS65912_OF_MATCH("ti,tps65912-dcdc4", tps65912_pmic_regs[DCDC4]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo1", tps65912_pmic_regs[LDO1]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo2", tps65912_pmic_regs[LDO2]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo3", tps65912_pmic_regs[LDO3]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo4", tps65912_pmic_regs[LDO4]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo5", tps65912_pmic_regs[LDO5]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo6", tps65912_pmic_regs[LDO6]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo7", tps65912_pmic_regs[LDO7]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo8", tps65912_pmic_regs[LDO8]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo9", tps65912_pmic_regs[LDO9]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo10", tps65912_pmic_regs[LDO10]),
+	{ /*sentinel*/ },
+};
+MODULE_DEVICE_TABLE(of, tps65912_regulator_of_match_table);
+
+/* Operations permitted on DCDCx */
+static struct regulator_ops tps65912_ops_dcdc = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+};
+
+/* Operations permitted on LDOx */
+static struct regulator_ops tps65912_ops_ldo = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_desc regulators[] = {
+	TPS65912_REGULATOR("DCDC1", TPS65912_DCDC_1, tps65912_ops_dcdc,
+			   TPS65912_DCDC1_OP, TPS65912_DCDC1_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("DCDC2", TPS65912_DCDC_2, tps65912_ops_dcdc,
+			   TPS65912_DCDC2_OP, TPS65912_DCDC2_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("DCDC3", TPS65912_DCDC_3, tps65912_ops_dcdc,
+			   TPS65912_DCDC3_OP, TPS65912_DCDC3_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("DCDC4", TPS65912_DCDC_4, tps65912_ops_dcdc,
+			   TPS65912_DCDC4_OP, TPS65912_DCDC4_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("LDO1", TPS65912_LDO_1, tps65912_ops_ldo,
+			   TPS65912_LDO1_OP, TPS65912_LDO1_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO2", TPS65912_LDO_2, tps65912_ops_ldo,
+			   TPS65912_LDO2_OP, TPS65912_LDO2_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO3", TPS65912_LDO_3, tps65912_ops_ldo,
+			   TPS65912_LDO3_OP, TPS65912_LDO3_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO4", TPS65912_LDO_4, tps65912_ops_ldo,
+			   TPS65912_LDO4_OP, TPS65912_LDO4_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO5", TPS65912_LDO_5, tps65912_ops_ldo,
+			   TPS65912_LDO5, TPS65912_LDO5,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO6", TPS65912_LDO_6, tps65912_ops_ldo,
+			   TPS65912_LDO6, TPS65912_LDO6,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO7", TPS65912_LDO_7, tps65912_ops_ldo,
+			   TPS65912_LDO7, TPS65912_LDO7,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO8", TPS65912_LDO_8, tps65912_ops_ldo,
+			   TPS65912_LDO8, TPS65912_LDO8,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO9", TPS65912_LDO_9, tps65912_ops_ldo,
+			   TPS65912_LDO9, TPS65912_LDO9,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO10", TPS65912_LDO_10, tps65912_ops_ldo,
+			   TPS65912_LDO10, TPS65912_LDO10,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+};
+
+static int tps65912_regulator_probe(struct platform_device *pdev)
+{
+	struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_init_data *init_data;
+	const struct tps_info *template;
+	struct regulator_dev *rdev;
+	const struct of_device_id *match;
+	struct regulator_config config = { };
+	int id;
+
+	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
+	if (!match)
+		return -ENODEV;
+
+	template = match->data;
+	id = template->id;
+	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
+					       &regulators[id]);
+
+	platform_set_drvdata(pdev, tps);
+
+	tps->info[id] = &tps65912_pmic_regs[id];
+	config.dev = &pdev->dev;
+	config.init_data = init_data;
+	config.driver_data = tps;
+	config.regmap = tps->regmap;
+	config.of_node = pdev->dev.of_node;
+
+	rdev = devm_regulator_register(&pdev->dev, &regulators[id], &config);
+	if (IS_ERR(rdev)) {
+		dev_err(tps->dev, "failed to register %s regulator\n",
+			pdev->name);
+		return PTR_ERR(rdev);
+	}
+
+	return 0;
+}
+
+static struct platform_driver tps65912_regulator_driver = {
+	.driver = {
+		.name = "tps65912-pmic",
+		.of_match_table = tps65912_regulator_of_match_table,
+	},
+	.probe = tps65912_regulator_probe,
+};
+
+module_platform_driver(tps65912_regulator_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912 voltage regulator driver");
+MODULE_ALIAS("platform:tps65912-pmic");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-09-24 14:52   ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

This patch adds support for TPS65912 PMIC regulators.

The regulators set consists of 4 DCDCs and 10 LDOs. The output
voltages are configurable and are meant to supply power to the
main processor and other components.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/regulator/Kconfig              |   6 +
 drivers/regulator/Makefile             |   1 +
 drivers/regulator/tps65912-regulator.c | 240 +++++++++++++++++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 drivers/regulator/tps65912-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 3cb2de9..1dec96a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -727,6 +727,12 @@ config REGULATOR_TPS65910
 	help
 	  This driver supports TPS65910/TPS65911 voltage regulator chips.
 
+config REGULATOR_TPS65912
+	tristate "TI TPS65912 Power regulator"
+	depends on MFD_TPS65912
+	help
+	    This driver supports TPS65912 voltage regulator chip.
+
 config REGULATOR_TPS80031
 	tristate "TI TPS80031/TPS80032 power regualtor driver"
 	depends on MFD_TPS80031
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 222ff5f..0f81749 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
+obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
 obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
 obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
new file mode 100644
index 0000000..343dae1
--- /dev/null
+++ b/drivers/regulator/tps65912-regulator.c
@@ -0,0 +1,240 @@
+/*
+ * Regulator driver for TPS65912x PMIC
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the TPS65218 driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#include <linux/mfd/tps65912.h>
+
+enum tps65912_regulators { DCDC1, DCDC2, DCDC3, DCDC4, LDO1, LDO2, LDO3,
+	LDO4, LDO5, LDO6, LDO7, LDO8, LDO9, LDO10 };
+
+#define TPS65912_REGULATOR(_name, _id, _ops, _vr, _er, _lr, _nlr)	\
+	{								\
+		.name			= _name,			\
+		.id			= _id,				\
+		.ops			= &_ops,			\
+		.n_voltages		= 64,				\
+		.type			= REGULATOR_VOLTAGE,		\
+		.owner			= THIS_MODULE,			\
+		.vsel_reg		= _vr,				\
+		.vsel_mask		= 0x3f,				\
+		.enable_reg		= _er,				\
+		.enable_mask		= BIT(7),			\
+		.volt_table		= NULL,				\
+		.linear_ranges		= _lr,				\
+		.n_linear_ranges	= _nlr,				\
+	}								\
+
+#define TPS65912_INFO(_id, _nm, _min, _max)	\
+	[_id] = {				\
+		.id		= _id,		\
+		.name		= _nm,		\
+		.min_uV		= _min,		\
+		.max_uV		= _max,		\
+	}
+
+static const struct regulator_linear_range tps65912_dcdc_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0x0, 0x3f, 50000),
+};
+
+static const struct regulator_linear_range tps65912_ldo_ranges[] = {
+	REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 25000),
+	REGULATOR_LINEAR_RANGE(1650000, 0x21, 0x3c, 50000),
+	REGULATOR_LINEAR_RANGE(3100000, 0x3d, 0x3f, 100000),
+};
+
+static struct tps_info tps65912_pmic_regs[] = {
+	TPS65912_INFO(DCDC1, "DCDC1", 500000, 3800000),
+	TPS65912_INFO(DCDC2, "DCDC2", 500000, 3800000),
+	TPS65912_INFO(DCDC3, "DCDC3", 500000, 3800000),
+	TPS65912_INFO(DCDC4, "DCDC4", 500000, 3800000),
+	TPS65912_INFO(LDO1, "LDO1", 800000, 3300000),
+	TPS65912_INFO(LDO2, "LDO2", 800000, 3300000),
+	TPS65912_INFO(LDO3, "LDO3", 800000, 3300000),
+	TPS65912_INFO(LDO4, "LDO4", 1600000, 3300000),
+	TPS65912_INFO(LDO5, "LDO5", 1600000, 3300000),
+	TPS65912_INFO(LDO6, "LDO6", 800000, 3300000),
+	TPS65912_INFO(LDO7, "LDO7", 800000, 3300000),
+	TPS65912_INFO(LDO8, "LDO8", 800000, 3300000),
+	TPS65912_INFO(LDO9, "LDO9", 800000, 3300000),
+	TPS65912_INFO(LDO10, "LDO10", 800000, 3300000),
+};
+
+#define TPS65912_OF_MATCH(comp, label)	\
+	{				\
+		.compatible = comp,	\
+		.data = &label,		\
+	}
+
+static const struct of_device_id tps65912_regulator_of_match_table[] = {
+	TPS65912_OF_MATCH("ti,tps65912-dcdc1", tps65912_pmic_regs[DCDC1]),
+	TPS65912_OF_MATCH("ti,tps65912-dcdc2", tps65912_pmic_regs[DCDC2]),
+	TPS65912_OF_MATCH("ti,tps65912-dcdc3", tps65912_pmic_regs[DCDC3]),
+	TPS65912_OF_MATCH("ti,tps65912-dcdc4", tps65912_pmic_regs[DCDC4]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo1", tps65912_pmic_regs[LDO1]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo2", tps65912_pmic_regs[LDO2]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo3", tps65912_pmic_regs[LDO3]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo4", tps65912_pmic_regs[LDO4]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo5", tps65912_pmic_regs[LDO5]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo6", tps65912_pmic_regs[LDO6]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo7", tps65912_pmic_regs[LDO7]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo8", tps65912_pmic_regs[LDO8]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo9", tps65912_pmic_regs[LDO9]),
+	TPS65912_OF_MATCH("ti,tps65912-ldo10", tps65912_pmic_regs[LDO10]),
+	{ /*sentinel*/ },
+};
+MODULE_DEVICE_TABLE(of, tps65912_regulator_of_match_table);
+
+/* Operations permitted on DCDCx */
+static struct regulator_ops tps65912_ops_dcdc = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+};
+
+/* Operations permitted on LDOx */
+static struct regulator_ops tps65912_ops_ldo = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_desc regulators[] = {
+	TPS65912_REGULATOR("DCDC1", TPS65912_DCDC_1, tps65912_ops_dcdc,
+			   TPS65912_DCDC1_OP, TPS65912_DCDC1_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("DCDC2", TPS65912_DCDC_2, tps65912_ops_dcdc,
+			   TPS65912_DCDC2_OP, TPS65912_DCDC2_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("DCDC3", TPS65912_DCDC_3, tps65912_ops_dcdc,
+			   TPS65912_DCDC3_OP, TPS65912_DCDC3_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("DCDC4", TPS65912_DCDC_4, tps65912_ops_dcdc,
+			   TPS65912_DCDC4_OP, TPS65912_DCDC4_CTRL,
+			   tps65912_dcdc_ranges,
+			   ARRAY_SIZE(tps65912_dcdc_ranges)),
+	TPS65912_REGULATOR("LDO1", TPS65912_LDO_1, tps65912_ops_ldo,
+			   TPS65912_LDO1_OP, TPS65912_LDO1_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO2", TPS65912_LDO_2, tps65912_ops_ldo,
+			   TPS65912_LDO2_OP, TPS65912_LDO2_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO3", TPS65912_LDO_3, tps65912_ops_ldo,
+			   TPS65912_LDO3_OP, TPS65912_LDO3_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO4", TPS65912_LDO_4, tps65912_ops_ldo,
+			   TPS65912_LDO4_OP, TPS65912_LDO4_AVS,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO5", TPS65912_LDO_5, tps65912_ops_ldo,
+			   TPS65912_LDO5, TPS65912_LDO5,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO6", TPS65912_LDO_6, tps65912_ops_ldo,
+			   TPS65912_LDO6, TPS65912_LDO6,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO7", TPS65912_LDO_7, tps65912_ops_ldo,
+			   TPS65912_LDO7, TPS65912_LDO7,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO8", TPS65912_LDO_8, tps65912_ops_ldo,
+			   TPS65912_LDO8, TPS65912_LDO8,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO9", TPS65912_LDO_9, tps65912_ops_ldo,
+			   TPS65912_LDO9, TPS65912_LDO9,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+	TPS65912_REGULATOR("LDO10", TPS65912_LDO_10, tps65912_ops_ldo,
+			   TPS65912_LDO10, TPS65912_LDO10,
+			   tps65912_ldo_ranges,
+			   ARRAY_SIZE(tps65912_ldo_ranges)),
+};
+
+static int tps65912_regulator_probe(struct platform_device *pdev)
+{
+	struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_init_data *init_data;
+	const struct tps_info *template;
+	struct regulator_dev *rdev;
+	const struct of_device_id *match;
+	struct regulator_config config = { };
+	int id;
+
+	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
+	if (!match)
+		return -ENODEV;
+
+	template = match->data;
+	id = template->id;
+	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
+					       &regulators[id]);
+
+	platform_set_drvdata(pdev, tps);
+
+	tps->info[id] = &tps65912_pmic_regs[id];
+	config.dev = &pdev->dev;
+	config.init_data = init_data;
+	config.driver_data = tps;
+	config.regmap = tps->regmap;
+	config.of_node = pdev->dev.of_node;
+
+	rdev = devm_regulator_register(&pdev->dev, &regulators[id], &config);
+	if (IS_ERR(rdev)) {
+		dev_err(tps->dev, "failed to register %s regulator\n",
+			pdev->name);
+		return PTR_ERR(rdev);
+	}
+
+	return 0;
+}
+
+static struct platform_driver tps65912_regulator_driver = {
+	.driver = {
+		.name = "tps65912-pmic",
+		.of_match_table = tps65912_regulator_of_match_table,
+	},
+	.probe = tps65912_regulator_probe,
+};
+
+module_platform_driver(tps65912_regulator_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912 voltage regulator driver");
+MODULE_ALIAS("platform:tps65912-pmic");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 5/5] gpio: tps65912: Add GPIO driver for the TPS65912 PMIC
  2015-09-24 14:52 ` Andrew F. Davis
@ 2015-09-24 14:52   ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

This patch adds support for the TPS65912 PMIC GPIOs.

TPS65912 has five configurable GPIOs that can be used for several
purposes.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/gpio/Kconfig         |   6 ++
 drivers/gpio/Makefile        |   1 +
 drivers/gpio/gpio-tps65912.c | 138 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+)
 create mode 100644 drivers/gpio/gpio-tps65912.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index fb28483..82218fa 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -838,6 +838,12 @@ config GPIO_TPS65910
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
 
+config GPIO_TPS65912
+	tristate "TI TPS65912 GPIO"
+	depends on MFD_TPS65912
+	help
+	  This driver supports TPS65912 gpio chip
+
 config GPIO_TWL4030
 	tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
 	depends on TWL4030_CORE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 605bf89..f79a7c4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_GPIO_TIMBERDALE)	+= gpio-timberdale.o
 obj-$(CONFIG_GPIO_PALMAS)	+= gpio-palmas.o
 obj-$(CONFIG_GPIO_TPS6586X)	+= gpio-tps6586x.o
 obj-$(CONFIG_GPIO_TPS65910)	+= gpio-tps65910.o
+obj-$(CONFIG_GPIO_TPS65912)	+= gpio-tps65912.o
 obj-$(CONFIG_GPIO_TS5500)	+= gpio-ts5500.o
 obj-$(CONFIG_GPIO_TWL4030)	+= gpio-twl4030.o
 obj-$(CONFIG_GPIO_TWL6040)	+= gpio-twl6040.o
diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
new file mode 100644
index 0000000..4707e62
--- /dev/null
+++ b/drivers/gpio/gpio-tps65912.c
@@ -0,0 +1,138 @@
+/*
+ * TI TPS65912x GPIO Driver
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the Arizona GPIO driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+#include <linux/mfd/tps65912.h>
+
+struct tps65912_gpio {
+	struct tps65912 *tps;
+	struct gpio_chip gpio_chip;
+};
+
+#define to_gpio(gc) container_of(gc, struct tps65912_gpio, gpio_chip)
+
+static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+	int ret, val;
+
+	ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val);
+	if (ret < 0)
+		return ret;
+
+	return val & GPIO_STS_MASK;
+}
+
+static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
+			      int value)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+
+	regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
+			   GPIO_SET_MASK, value ? GPIO_SET_MASK : 0);
+}
+
+static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
+				int value)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+
+	/* Set the initial value */
+	tps65912_gpio_set(gc, offset, value);
+
+	return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
+				  GPIO_CFG_MASK, GPIO_CFG_MASK);
+}
+
+static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+
+	return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
+				  GPIO_CFG_MASK, 0);
+}
+
+static const struct of_device_id tps65912_gpio_of_match_table[] = {
+	{ .compatible = "ti,tps65912-gpio", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tps65912_gpio_of_match_table);
+
+static struct gpio_chip template_chip = {
+	.label			= "tps65912-gpio",
+	.owner			= THIS_MODULE,
+	.direction_input	= tps65912_gpio_input,
+	.direction_output	= tps65912_gpio_output,
+	.get			= tps65912_gpio_get,
+	.set			= tps65912_gpio_set,
+	.can_sleep		= true,
+	.ngpio			= 5,
+	.base			= -1,
+};
+
+static int tps65912_gpio_probe(struct platform_device *pdev)
+{
+	struct tps65912_gpio *gpio;
+	int ret;
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+	if (!gpio)
+		return -ENOMEM;
+
+	gpio->tps = dev_get_drvdata(pdev->dev.parent);
+	gpio->gpio_chip = template_chip;
+	ret = gpiochip_add(&gpio->gpio_chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, gpio);
+
+	return 0;
+}
+
+static int tps65912_gpio_remove(struct platform_device *pdev)
+{
+	struct tps65912_gpio *gpio = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&gpio->gpio_chip);
+
+	return 0;
+}
+
+static struct platform_driver tps65912_gpio_driver = {
+	.driver = {
+		.name = "tps65912-gpio",
+		.of_match_table = tps65912_gpio_of_match_table,
+	},
+	.probe = tps65912_gpio_probe,
+	.remove = tps65912_gpio_remove,
+};
+
+module_platform_driver(tps65912_gpio_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912 GPIO driver");
+MODULE_ALIAS("platform:tps65912-gpio");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH v3 5/5] gpio: tps65912: Add GPIO driver for the TPS65912 PMIC
@ 2015-09-24 14:52   ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-24 14:52 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Alexandre Courbot,
	Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel, Andrew F. Davis

This patch adds support for the TPS65912 PMIC GPIOs.

TPS65912 has five configurable GPIOs that can be used for several
purposes.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/gpio/Kconfig         |   6 ++
 drivers/gpio/Makefile        |   1 +
 drivers/gpio/gpio-tps65912.c | 138 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+)
 create mode 100644 drivers/gpio/gpio-tps65912.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index fb28483..82218fa 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -838,6 +838,12 @@ config GPIO_TPS65910
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
 
+config GPIO_TPS65912
+	tristate "TI TPS65912 GPIO"
+	depends on MFD_TPS65912
+	help
+	  This driver supports TPS65912 gpio chip
+
 config GPIO_TWL4030
 	tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
 	depends on TWL4030_CORE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 605bf89..f79a7c4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_GPIO_TIMBERDALE)	+= gpio-timberdale.o
 obj-$(CONFIG_GPIO_PALMAS)	+= gpio-palmas.o
 obj-$(CONFIG_GPIO_TPS6586X)	+= gpio-tps6586x.o
 obj-$(CONFIG_GPIO_TPS65910)	+= gpio-tps65910.o
+obj-$(CONFIG_GPIO_TPS65912)	+= gpio-tps65912.o
 obj-$(CONFIG_GPIO_TS5500)	+= gpio-ts5500.o
 obj-$(CONFIG_GPIO_TWL4030)	+= gpio-twl4030.o
 obj-$(CONFIG_GPIO_TWL6040)	+= gpio-twl6040.o
diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
new file mode 100644
index 0000000..4707e62
--- /dev/null
+++ b/drivers/gpio/gpio-tps65912.c
@@ -0,0 +1,138 @@
+/*
+ * TI TPS65912x GPIO Driver
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ *
+ * Based on the Arizona GPIO driver and the previous TPS65912 driver by
+ * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
+ */
+
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+#include <linux/mfd/tps65912.h>
+
+struct tps65912_gpio {
+	struct tps65912 *tps;
+	struct gpio_chip gpio_chip;
+};
+
+#define to_gpio(gc) container_of(gc, struct tps65912_gpio, gpio_chip)
+
+static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+	int ret, val;
+
+	ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val);
+	if (ret < 0)
+		return ret;
+
+	return val & GPIO_STS_MASK;
+}
+
+static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
+			      int value)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+
+	regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
+			   GPIO_SET_MASK, value ? GPIO_SET_MASK : 0);
+}
+
+static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
+				int value)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+
+	/* Set the initial value */
+	tps65912_gpio_set(gc, offset, value);
+
+	return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
+				  GPIO_CFG_MASK, GPIO_CFG_MASK);
+}
+
+static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct tps65912_gpio *gpio = to_gpio(gc);
+
+	return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
+				  GPIO_CFG_MASK, 0);
+}
+
+static const struct of_device_id tps65912_gpio_of_match_table[] = {
+	{ .compatible = "ti,tps65912-gpio", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tps65912_gpio_of_match_table);
+
+static struct gpio_chip template_chip = {
+	.label			= "tps65912-gpio",
+	.owner			= THIS_MODULE,
+	.direction_input	= tps65912_gpio_input,
+	.direction_output	= tps65912_gpio_output,
+	.get			= tps65912_gpio_get,
+	.set			= tps65912_gpio_set,
+	.can_sleep		= true,
+	.ngpio			= 5,
+	.base			= -1,
+};
+
+static int tps65912_gpio_probe(struct platform_device *pdev)
+{
+	struct tps65912_gpio *gpio;
+	int ret;
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+	if (!gpio)
+		return -ENOMEM;
+
+	gpio->tps = dev_get_drvdata(pdev->dev.parent);
+	gpio->gpio_chip = template_chip;
+	ret = gpiochip_add(&gpio->gpio_chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, gpio);
+
+	return 0;
+}
+
+static int tps65912_gpio_remove(struct platform_device *pdev)
+{
+	struct tps65912_gpio *gpio = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&gpio->gpio_chip);
+
+	return 0;
+}
+
+static struct platform_driver tps65912_gpio_driver = {
+	.driver = {
+		.name = "tps65912-gpio",
+		.of_match_table = tps65912_gpio_of_match_table,
+	},
+	.probe = tps65912_gpio_probe,
+	.remove = tps65912_gpio_remove,
+};
+
+module_platform_driver(tps65912_gpio_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65912 GPIO driver");
+MODULE_ALIAS("platform:tps65912-gpio");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-24 14:52   ` Andrew F. Davis
@ 2015-09-25 16:50       ` Lee Jones
  -1 siblings, 0 replies; 56+ messages in thread
From: Lee Jones @ 2015-09-25 16:50 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Thu, 24 Sep 2015, Andrew F. Davis wrote:

> This patch adds support for TPS65912 mfd device. It provides
> communication through the I2C and SPI interfaces. It contains
> the following components:
> 
>  - Regulators
>  - GPIO controller
> 
> Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
> ---
>  drivers/mfd/Kconfig          |  24 +++
>  drivers/mfd/Makefile         |   3 +
>  drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>  drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>  drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>  include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 705 insertions(+)
>  create mode 100644 drivers/mfd/tps65912-core.c
>  create mode 100644 drivers/mfd/tps65912-i2c.c
>  create mode 100644 drivers/mfd/tps65912-spi.c
>  create mode 100644 include/linux/mfd/tps65912.h

[...]

> +#define TPS65912_IRQ(_name, _reg, _offset)			\
> +	[TPS65912_IRQ_ ## _name] = {				\
> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
> +		.reg_offset = _offset,				\
> +	}

I told you about this already.

If you want this set to be merged for v4.3 then you'll need commit
b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
tree.

[...]

> +static struct i2c_driver tps65912_i2c_driver = {
> +	.driver		= {
> +		.name	= "tps65912",
> +		.of_match_table = tps65912_i2c_of_match_table,

of_match_ptr()

[...]

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-25 16:50       ` Lee Jones
  0 siblings, 0 replies; 56+ messages in thread
From: Lee Jones @ 2015-09-25 16:50 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On Thu, 24 Sep 2015, Andrew F. Davis wrote:

> This patch adds support for TPS65912 mfd device. It provides
> communication through the I2C and SPI interfaces. It contains
> the following components:
> 
>  - Regulators
>  - GPIO controller
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  drivers/mfd/Kconfig          |  24 +++
>  drivers/mfd/Makefile         |   3 +
>  drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>  drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>  drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>  include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 705 insertions(+)
>  create mode 100644 drivers/mfd/tps65912-core.c
>  create mode 100644 drivers/mfd/tps65912-i2c.c
>  create mode 100644 drivers/mfd/tps65912-spi.c
>  create mode 100644 include/linux/mfd/tps65912.h

[...]

> +#define TPS65912_IRQ(_name, _reg, _offset)			\
> +	[TPS65912_IRQ_ ## _name] = {				\
> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
> +		.reg_offset = _offset,				\
> +	}

I told you about this already.

If you want this set to be merged for v4.3 then you'll need commit
b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
tree.

[...]

> +static struct i2c_driver tps65912_i2c_driver = {
> +	.driver		= {
> +		.name	= "tps65912",
> +		.of_match_table = tps65912_i2c_of_match_table,

of_match_ptr()

[...]

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 2/5] mfd: tps65912: Remove old driver in preparation for new driver
  2015-09-24 14:52   ` Andrew F. Davis
@ 2015-09-25 16:52       ` Lee Jones
  -1 siblings, 0 replies; 56+ messages in thread
From: Lee Jones @ 2015-09-25 16:52 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Thu, 24 Sep 2015, Andrew F. Davis wrote:

> The old tps65912 driver is being replaced, delete old driver.
> 
> Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
> ---
>  drivers/gpio/Kconfig                   |   6 -
>  drivers/gpio/Makefile                  |   1 -
>  drivers/gpio/gpio-tps65912.c           | 153 ----------
>  drivers/mfd/Kconfig                    |  26 --
>  drivers/mfd/Makefile                   |   4 -
>  drivers/mfd/tps65912-core.c            | 175 -----------
>  drivers/mfd/tps65912-i2c.c             | 139 ---------
>  drivers/mfd/tps65912-irq.c             | 217 -------------
>  drivers/mfd/tps65912-spi.c             | 141 ---------
>  drivers/regulator/Kconfig              |   6 -
>  drivers/regulator/Makefile             |   1 -
>  drivers/regulator/tps65912-regulator.c | 541 ---------------------------------
>  include/linux/mfd/tps65912.h           | 328 --------------------
>  13 files changed, 1738 deletions(-)
>  delete mode 100644 drivers/gpio/gpio-tps65912.c
>  delete mode 100644 drivers/mfd/tps65912-core.c
>  delete mode 100644 drivers/mfd/tps65912-i2c.c
>  delete mode 100644 drivers/mfd/tps65912-irq.c
>  delete mode 100644 drivers/mfd/tps65912-spi.c
>  delete mode 100644 drivers/regulator/tps65912-regulator.c
>  delete mode 100644 include/linux/mfd/tps65912.h

I initially thought it was a bad idea due to bisectability blah blah
blah, but as the next patch adds a completely new incarnation I
thought this point to be moot.

Acked-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 2/5] mfd: tps65912: Remove old driver in preparation for new driver
@ 2015-09-25 16:52       ` Lee Jones
  0 siblings, 0 replies; 56+ messages in thread
From: Lee Jones @ 2015-09-25 16:52 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On Thu, 24 Sep 2015, Andrew F. Davis wrote:

> The old tps65912 driver is being replaced, delete old driver.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  drivers/gpio/Kconfig                   |   6 -
>  drivers/gpio/Makefile                  |   1 -
>  drivers/gpio/gpio-tps65912.c           | 153 ----------
>  drivers/mfd/Kconfig                    |  26 --
>  drivers/mfd/Makefile                   |   4 -
>  drivers/mfd/tps65912-core.c            | 175 -----------
>  drivers/mfd/tps65912-i2c.c             | 139 ---------
>  drivers/mfd/tps65912-irq.c             | 217 -------------
>  drivers/mfd/tps65912-spi.c             | 141 ---------
>  drivers/regulator/Kconfig              |   6 -
>  drivers/regulator/Makefile             |   1 -
>  drivers/regulator/tps65912-regulator.c | 541 ---------------------------------
>  include/linux/mfd/tps65912.h           | 328 --------------------
>  13 files changed, 1738 deletions(-)
>  delete mode 100644 drivers/gpio/gpio-tps65912.c
>  delete mode 100644 drivers/mfd/tps65912-core.c
>  delete mode 100644 drivers/mfd/tps65912-i2c.c
>  delete mode 100644 drivers/mfd/tps65912-irq.c
>  delete mode 100644 drivers/mfd/tps65912-spi.c
>  delete mode 100644 drivers/regulator/tps65912-regulator.c
>  delete mode 100644 include/linux/mfd/tps65912.h

I initially thought it was a bad idea due to bisectability blah blah
blah, but as the next patch adds a completely new incarnation I
thought this point to be moot.

Acked-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-24 14:52   ` Andrew F. Davis
@ 2015-09-25 18:05       ` Mark Brown
  -1 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2015-09-25 18:05 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 839 bytes --]

On Thu, Sep 24, 2015 at 09:52:53AM -0500, Andrew F. Davis wrote:

> +static int tps65912_regulator_probe(struct platform_device *pdev)
> +{
> +	struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
> +	struct regulator_init_data *init_data;
> +	const struct tps_info *template;
> +	struct regulator_dev *rdev;
> +	const struct of_device_id *match;
> +	struct regulator_config config = { };
> +	int id;
> +
> +	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
> +	if (!match)
> +		return -ENODEV;
> +
> +	template = match->data;
> +	id = template->id;
> +	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
> +					       &regulators[id]);

Don't open code this stuff, use the core DT matching in the
regulator_desc instead.

Please also use subject lines mathcing the style for the subsystem.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-09-25 18:05       ` Mark Brown
  0 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2015-09-25 18:05 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 839 bytes --]

On Thu, Sep 24, 2015 at 09:52:53AM -0500, Andrew F. Davis wrote:

> +static int tps65912_regulator_probe(struct platform_device *pdev)
> +{
> +	struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
> +	struct regulator_init_data *init_data;
> +	const struct tps_info *template;
> +	struct regulator_dev *rdev;
> +	const struct of_device_id *match;
> +	struct regulator_config config = { };
> +	int id;
> +
> +	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
> +	if (!match)
> +		return -ENODEV;
> +
> +	template = match->data;
> +	id = template->id;
> +	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
> +					       &regulators[id]);

Don't open code this stuff, use the core DT matching in the
regulator_desc instead.

Please also use subject lines mathcing the style for the subsystem.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-25 16:50       ` Lee Jones
@ 2015-09-25 19:13         ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-25 19:13 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/25/2015 11:50 AM, Lee Jones wrote:
> On Thu, 24 Sep 2015, Andrew F. Davis wrote:
>
>> This patch adds support for TPS65912 mfd device. It provides
>> communication through the I2C and SPI interfaces. It contains
>> the following components:
>>
>>   - Regulators
>>   - GPIO controller
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/mfd/Kconfig          |  24 +++
>>   drivers/mfd/Makefile         |   3 +
>>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>   6 files changed, 705 insertions(+)
>>   create mode 100644 drivers/mfd/tps65912-core.c
>>   create mode 100644 drivers/mfd/tps65912-i2c.c
>>   create mode 100644 drivers/mfd/tps65912-spi.c
>>   create mode 100644 include/linux/mfd/tps65912.h
>
> [...]
>
>> +#define TPS65912_IRQ(_name, _reg, _offset)			\
>> +	[TPS65912_IRQ_ ## _name] = {				\
>> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
>> +		.reg_offset = _offset,				\
>> +	}
>
> I told you about this already.
>
> If you want this set to be merged for v4.3 then you'll need commit
> b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
> tree.
>

You asked me to submit this to Mark Brown, I didn't realize you also
wanted me to use the one in your tree. Using yours will make my lines
over 80 chars and so it kind of defeats the purpose but I'll do it
for v4.

> [...]
>
>> +static struct i2c_driver tps65912_i2c_driver = {
>> +	.driver		= {
>> +		.name	= "tps65912",
>> +		.of_match_table = tps65912_i2c_of_match_table,
>
> of_match_ptr()
>

Why? tps65912_i2c_of_match_table is always compiled in.

> [...]
>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-25 19:13         ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-25 19:13 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/25/2015 11:50 AM, Lee Jones wrote:
> On Thu, 24 Sep 2015, Andrew F. Davis wrote:
>
>> This patch adds support for TPS65912 mfd device. It provides
>> communication through the I2C and SPI interfaces. It contains
>> the following components:
>>
>>   - Regulators
>>   - GPIO controller
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/mfd/Kconfig          |  24 +++
>>   drivers/mfd/Makefile         |   3 +
>>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>   6 files changed, 705 insertions(+)
>>   create mode 100644 drivers/mfd/tps65912-core.c
>>   create mode 100644 drivers/mfd/tps65912-i2c.c
>>   create mode 100644 drivers/mfd/tps65912-spi.c
>>   create mode 100644 include/linux/mfd/tps65912.h
>
> [...]
>
>> +#define TPS65912_IRQ(_name, _reg, _offset)			\
>> +	[TPS65912_IRQ_ ## _name] = {				\
>> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
>> +		.reg_offset = _offset,				\
>> +	}
>
> I told you about this already.
>
> If you want this set to be merged for v4.3 then you'll need commit
> b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
> tree.
>

You asked me to submit this to Mark Brown, I didn't realize you also
wanted me to use the one in your tree. Using yours will make my lines
over 80 chars and so it kind of defeats the purpose but I'll do it
for v4.

> [...]
>
>> +static struct i2c_driver tps65912_i2c_driver = {
>> +	.driver		= {
>> +		.name	= "tps65912",
>> +		.of_match_table = tps65912_i2c_of_match_table,
>
> of_match_ptr()
>

Why? tps65912_i2c_of_match_table is always compiled in.

> [...]
>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-25 18:05       ` Mark Brown
@ 2015-09-25 20:10         ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-25 20:10 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/25/2015 01:05 PM, Mark Brown wrote:
> On Thu, Sep 24, 2015 at 09:52:53AM -0500, Andrew F. Davis wrote:
>
>> +static int tps65912_regulator_probe(struct platform_device *pdev)
>> +{
>> +	struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
>> +	struct regulator_init_data *init_data;
>> +	const struct tps_info *template;
>> +	struct regulator_dev *rdev;
>> +	const struct of_device_id *match;
>> +	struct regulator_config config = { };
>> +	int id;
>> +
>> +	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
>> +	if (!match)
>> +		return -ENODEV;
>> +
>> +	template = match->data;
>> +	id = template->id;
>> +	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
>> +					       &regulators[id]);
>
> Don't open code this stuff, use the core DT matching in the
> regulator_desc instead.
>

I assume you are referring to your additions in a0c7b164ad11? If so I'm not
sure that will save me anything as my probe function is called with a DT
match already, so no searching is needed.

> Please also use subject lines mathcing the style for the subsystem.
>

I'm not sure I know what you mean? What is wrong with my subject line, it looks
like the others I've looked at?

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-09-25 20:10         ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-25 20:10 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/25/2015 01:05 PM, Mark Brown wrote:
> On Thu, Sep 24, 2015 at 09:52:53AM -0500, Andrew F. Davis wrote:
>
>> +static int tps65912_regulator_probe(struct platform_device *pdev)
>> +{
>> +	struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
>> +	struct regulator_init_data *init_data;
>> +	const struct tps_info *template;
>> +	struct regulator_dev *rdev;
>> +	const struct of_device_id *match;
>> +	struct regulator_config config = { };
>> +	int id;
>> +
>> +	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
>> +	if (!match)
>> +		return -ENODEV;
>> +
>> +	template = match->data;
>> +	id = template->id;
>> +	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
>> +					       &regulators[id]);
>
> Don't open code this stuff, use the core DT matching in the
> regulator_desc instead.
>

I assume you are referring to your additions in a0c7b164ad11? If so I'm not
sure that will save me anything as my probe function is called with a DT
match already, so no searching is needed.

> Please also use subject lines mathcing the style for the subsystem.
>

I'm not sure I know what you mean? What is wrong with my subject line, it looks
like the others I've looked at?

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-25 19:13         ` Andrew F. Davis
@ 2015-09-25 21:24             ` Lee Jones
  -1 siblings, 0 replies; 56+ messages in thread
From: Lee Jones @ 2015-09-25 21:24 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, 25 Sep 2015, Andrew F. Davis wrote:

> On 09/25/2015 11:50 AM, Lee Jones wrote:
> >On Thu, 24 Sep 2015, Andrew F. Davis wrote:
> >
> >>This patch adds support for TPS65912 mfd device. It provides
> >>communication through the I2C and SPI interfaces. It contains
> >>the following components:
> >>
> >>  - Regulators
> >>  - GPIO controller
> >>
> >>Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
> >>---
> >>  drivers/mfd/Kconfig          |  24 +++
> >>  drivers/mfd/Makefile         |   3 +
> >>  drivers/mfd/tps65912-core.c  | 114 +++++++++++++
> >>  drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
> >>  drivers/mfd/tps65912-spi.c   |  85 ++++++++++
> >>  include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
> >>  6 files changed, 705 insertions(+)
> >>  create mode 100644 drivers/mfd/tps65912-core.c
> >>  create mode 100644 drivers/mfd/tps65912-i2c.c
> >>  create mode 100644 drivers/mfd/tps65912-spi.c
> >>  create mode 100644 include/linux/mfd/tps65912.h
> >
> >[...]
> >
> >>+#define TPS65912_IRQ(_name, _reg, _offset)			\
> >>+	[TPS65912_IRQ_ ## _name] = {				\
> >>+		.mask = TPS65912_ ## _reg ## _ ## _name,	\
> >>+		.reg_offset = _offset,				\
> >>+	}
> >
> >I told you about this already.
> >
> >If you want this set to be merged for v4.3 then you'll need commit
> >b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
> >tree.
> 
> You asked me to submit this to Mark Brown, I didn't realize you also
> wanted me to use the one in your tree. Using yours will make my lines
> over 80 chars and so it kind of defeats the purpose but I'll do it
> for v4.

I asked two of you to upstream a generic incarnation of your
implementation.  The other guy got there first.  Now I want everyone
to use it instead of hand-rolling their own.

> >[...]
> >
> >>+static struct i2c_driver tps65912_i2c_driver = {
> >>+	.driver		= {
> >>+		.name	= "tps65912",
> >>+		.of_match_table = tps65912_i2c_of_match_table,
> >
> >of_match_ptr()
> >
> 
> Why? tps65912_i2c_of_match_table is always compiled in.

But it needn't be.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-25 21:24             ` Lee Jones
  0 siblings, 0 replies; 56+ messages in thread
From: Lee Jones @ 2015-09-25 21:24 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On Fri, 25 Sep 2015, Andrew F. Davis wrote:

> On 09/25/2015 11:50 AM, Lee Jones wrote:
> >On Thu, 24 Sep 2015, Andrew F. Davis wrote:
> >
> >>This patch adds support for TPS65912 mfd device. It provides
> >>communication through the I2C and SPI interfaces. It contains
> >>the following components:
> >>
> >>  - Regulators
> >>  - GPIO controller
> >>
> >>Signed-off-by: Andrew F. Davis <afd@ti.com>
> >>---
> >>  drivers/mfd/Kconfig          |  24 +++
> >>  drivers/mfd/Makefile         |   3 +
> >>  drivers/mfd/tps65912-core.c  | 114 +++++++++++++
> >>  drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
> >>  drivers/mfd/tps65912-spi.c   |  85 ++++++++++
> >>  include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
> >>  6 files changed, 705 insertions(+)
> >>  create mode 100644 drivers/mfd/tps65912-core.c
> >>  create mode 100644 drivers/mfd/tps65912-i2c.c
> >>  create mode 100644 drivers/mfd/tps65912-spi.c
> >>  create mode 100644 include/linux/mfd/tps65912.h
> >
> >[...]
> >
> >>+#define TPS65912_IRQ(_name, _reg, _offset)			\
> >>+	[TPS65912_IRQ_ ## _name] = {				\
> >>+		.mask = TPS65912_ ## _reg ## _ ## _name,	\
> >>+		.reg_offset = _offset,				\
> >>+	}
> >
> >I told you about this already.
> >
> >If you want this set to be merged for v4.3 then you'll need commit
> >b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
> >tree.
> 
> You asked me to submit this to Mark Brown, I didn't realize you also
> wanted me to use the one in your tree. Using yours will make my lines
> over 80 chars and so it kind of defeats the purpose but I'll do it
> for v4.

I asked two of you to upstream a generic incarnation of your
implementation.  The other guy got there first.  Now I want everyone
to use it instead of hand-rolling their own.

> >[...]
> >
> >>+static struct i2c_driver tps65912_i2c_driver = {
> >>+	.driver		= {
> >>+		.name	= "tps65912",
> >>+		.of_match_table = tps65912_i2c_of_match_table,
> >
> >of_match_ptr()
> >
> 
> Why? tps65912_i2c_of_match_table is always compiled in.

But it needn't be.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 5/5] gpio: tps65912: Add GPIO driver for the TPS65912 PMIC
  2015-09-24 14:52   ` Andrew F. Davis
  (?)
@ 2015-09-28  2:54   ` Alexandre Courbot
       [not found]     ` <CAAVeFuKu8R5GCQo3NySCOVLUew4_1qpYydHPAz9tfNorj27-NA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  -1 siblings, 1 reply; 56+ messages in thread
From: Alexandre Courbot @ 2015-09-28  2:54 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, Linux Kernel Mailing List

On Thu, Sep 24, 2015 at 11:52 PM, Andrew F. Davis <afd@ti.com> wrote:
> This patch adds support for the TPS65912 PMIC GPIOs.
>
> TPS65912 has five configurable GPIOs that can be used for several
> purposes.
>
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  drivers/gpio/Kconfig         |   6 ++
>  drivers/gpio/Makefile        |   1 +
>  drivers/gpio/gpio-tps65912.c | 138 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 145 insertions(+)
>  create mode 100644 drivers/gpio/gpio-tps65912.c
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index fb28483..82218fa 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -838,6 +838,12 @@ config GPIO_TPS65910
>           Select this option to enable GPIO driver for the TPS65910
>           chip family.
>
> +config GPIO_TPS65912
> +       tristate "TI TPS65912 GPIO"
> +       depends on MFD_TPS65912
> +       help
> +         This driver supports TPS65912 gpio chip
> +
>  config GPIO_TWL4030
>         tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
>         depends on TWL4030_CORE
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 605bf89..f79a7c4 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -96,6 +96,7 @@ obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
>  obj-$(CONFIG_GPIO_PALMAS)      += gpio-palmas.o
>  obj-$(CONFIG_GPIO_TPS6586X)    += gpio-tps6586x.o
>  obj-$(CONFIG_GPIO_TPS65910)    += gpio-tps65910.o
> +obj-$(CONFIG_GPIO_TPS65912)    += gpio-tps65912.o
>  obj-$(CONFIG_GPIO_TS5500)      += gpio-ts5500.o
>  obj-$(CONFIG_GPIO_TWL4030)     += gpio-twl4030.o
>  obj-$(CONFIG_GPIO_TWL6040)     += gpio-twl6040.o
> diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
> new file mode 100644
> index 0000000..4707e62
> --- /dev/null
> +++ b/drivers/gpio/gpio-tps65912.c
> @@ -0,0 +1,138 @@
> +/*
> + * TI TPS65912x GPIO Driver
> + *
> + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
> + *
> + * Author: Andrew F. Davis <afd@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether expressed or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License version 2 for more details.
> + *
> + * Based on the Arizona GPIO driver and the previous TPS65912 driver by
> + * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
> + */
> +
> +#include <linux/gpio.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +
> +#include <linux/mfd/tps65912.h>
> +
> +struct tps65912_gpio {
> +       struct tps65912 *tps;
> +       struct gpio_chip gpio_chip;

Nit: I'd suggest to put gpio_chip as the first member of your struct
so that to_gpio() resolves to the same address. This may make the
generated code neglectably smaller and faster.

> +};
> +
> +#define to_gpio(gc) container_of(gc, struct tps65912_gpio, gpio_chip)

Nit2: Maybe a more specific name (like tps_gpio()) would be better?
It's local to this file though, so not a big deal.

> +
> +static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct tps65912_gpio *gpio = to_gpio(gc);
> +       int ret, val;
> +
> +       ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val);
> +       if (ret < 0)
> +               return ret;
> +
> +       return val & GPIO_STS_MASK;
> +}
> +
> +static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
> +                             int value)
> +{
> +       struct tps65912_gpio *gpio = to_gpio(gc);
> +
> +       regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
> +                          GPIO_SET_MASK, value ? GPIO_SET_MASK : 0);
> +}
> +
> +static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
> +                               int value)
> +{
> +       struct tps65912_gpio *gpio = to_gpio(gc);
> +
> +       /* Set the initial value */
> +       tps65912_gpio_set(gc, offset, value);
> +
> +       return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
> +                                 GPIO_CFG_MASK, GPIO_CFG_MASK);
> +}
> +
> +static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct tps65912_gpio *gpio = to_gpio(gc);
> +
> +       return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
> +                                 GPIO_CFG_MASK, 0);
> +}
> +
> +static const struct of_device_id tps65912_gpio_of_match_table[] = {
> +       { .compatible = "ti,tps65912-gpio", },
> +       { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, tps65912_gpio_of_match_table);
> +
> +static struct gpio_chip template_chip = {
> +       .label                  = "tps65912-gpio",
> +       .owner                  = THIS_MODULE,
> +       .direction_input        = tps65912_gpio_input,
> +       .direction_output       = tps65912_gpio_output,
> +       .get                    = tps65912_gpio_get,
> +       .set                    = tps65912_gpio_set,
> +       .can_sleep              = true,
> +       .ngpio                  = 5,
> +       .base                   = -1,
> +};
> +
> +static int tps65912_gpio_probe(struct platform_device *pdev)
> +{
> +       struct tps65912_gpio *gpio;
> +       int ret;
> +
> +       gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
> +       if (!gpio)
> +               return -ENOMEM;
> +
> +       gpio->tps = dev_get_drvdata(pdev->dev.parent);
> +       gpio->gpio_chip = template_chip;
> +       ret = gpiochip_add(&gpio->gpio_chip);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
> +               return ret;
> +       }
> +
> +       platform_set_drvdata(pdev, gpio);
> +
> +       return 0;
> +}
> +
> +static int tps65912_gpio_remove(struct platform_device *pdev)
> +{
> +       struct tps65912_gpio *gpio = platform_get_drvdata(pdev);
> +
> +       gpiochip_remove(&gpio->gpio_chip);
> +
> +       return 0;
> +}
> +
> +static struct platform_driver tps65912_gpio_driver = {
> +       .driver = {
> +               .name = "tps65912-gpio",
> +               .of_match_table = tps65912_gpio_of_match_table,
> +       },
> +       .probe = tps65912_gpio_probe,
> +       .remove = tps65912_gpio_remove,
> +};
> +
> +module_platform_driver(tps65912_gpio_driver);
> +
> +MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
> +MODULE_DESCRIPTION("TPS65912 GPIO driver");
> +MODULE_ALIAS("platform:tps65912-gpio");
> +MODULE_LICENSE("GPL v2");

Nice and simple driver - my remarks above should not be taken as a
call to re-spin, just consider them if you need to send another
version of this patchset.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-25 21:24             ` Lee Jones
@ 2015-09-28 15:43               ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-28 15:43 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 09/25/2015 04:24 PM, Lee Jones wrote:
> On Fri, 25 Sep 2015, Andrew F. Davis wrote:
>
>> On 09/25/2015 11:50 AM, Lee Jones wrote:
>>> On Thu, 24 Sep 2015, Andrew F. Davis wrote:
>>>
>>>> This patch adds support for TPS65912 mfd device. It provides
>>>> communication through the I2C and SPI interfaces. It contains
>>>> the following components:
>>>>
>>>>   - Regulators
>>>>   - GPIO controller
>>>>
>>>> Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
>>>> ---
>>>>   drivers/mfd/Kconfig          |  24 +++
>>>>   drivers/mfd/Makefile         |   3 +
>>>>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>>>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>>>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>>>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>>>   6 files changed, 705 insertions(+)
>>>>   create mode 100644 drivers/mfd/tps65912-core.c
>>>>   create mode 100644 drivers/mfd/tps65912-i2c.c
>>>>   create mode 100644 drivers/mfd/tps65912-spi.c
>>>>   create mode 100644 include/linux/mfd/tps65912.h
>>>
>>> [...]
>>>
>>>> +#define TPS65912_IRQ(_name, _reg, _offset)			\
>>>> +	[TPS65912_IRQ_ ## _name] = {				\
>>>> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
>>>> +		.reg_offset = _offset,				\
>>>> +	}
>>>
>>> I told you about this already.
>>>
>>> If you want this set to be merged for v4.3 then you'll need commit
>>> b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
>>> tree.
>>
>> You asked me to submit this to Mark Brown, I didn't realize you also
>> wanted me to use the one in your tree. Using yours will make my lines
>> over 80 chars and so it kind of defeats the purpose but I'll do it
>> for v4.
>
> I asked two of you to upstream a generic incarnation of your
> implementation.  The other guy got there first.  Now I want everyone
> to use it instead of hand-rolling their own.
>

Got it.

>>> [...]
>>>
>>>> +static struct i2c_driver tps65912_i2c_driver = {
>>>> +	.driver		= {
>>>> +		.name	= "tps65912",
>>>> +		.of_match_table = tps65912_i2c_of_match_table,
>>>
>>> of_match_ptr()
>>>
>>
>> Why? tps65912_i2c_of_match_table is always compiled in.
>
> But it needn't be.
>

This driver is DT only, would it make more sense to just add a dependency
on CONFIG_OF in the Kconfig? I don't see many other drivers that are DT
only doing this, the driver should compile just fine without OF enabled,
it just wont have DT functionality, so is it really dependent on OF?
The of_match_ptr(x) macro looks to be useful when the x is conditionally
compiled in, but in my case the x (my of_device_id table) is always compiled.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-28 15:43               ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-28 15:43 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/25/2015 04:24 PM, Lee Jones wrote:
> On Fri, 25 Sep 2015, Andrew F. Davis wrote:
>
>> On 09/25/2015 11:50 AM, Lee Jones wrote:
>>> On Thu, 24 Sep 2015, Andrew F. Davis wrote:
>>>
>>>> This patch adds support for TPS65912 mfd device. It provides
>>>> communication through the I2C and SPI interfaces. It contains
>>>> the following components:
>>>>
>>>>   - Regulators
>>>>   - GPIO controller
>>>>
>>>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>>>> ---
>>>>   drivers/mfd/Kconfig          |  24 +++
>>>>   drivers/mfd/Makefile         |   3 +
>>>>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>>>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>>>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>>>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>>>   6 files changed, 705 insertions(+)
>>>>   create mode 100644 drivers/mfd/tps65912-core.c
>>>>   create mode 100644 drivers/mfd/tps65912-i2c.c
>>>>   create mode 100644 drivers/mfd/tps65912-spi.c
>>>>   create mode 100644 include/linux/mfd/tps65912.h
>>>
>>> [...]
>>>
>>>> +#define TPS65912_IRQ(_name, _reg, _offset)			\
>>>> +	[TPS65912_IRQ_ ## _name] = {				\
>>>> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
>>>> +		.reg_offset = _offset,				\
>>>> +	}
>>>
>>> I told you about this already.
>>>
>>> If you want this set to be merged for v4.3 then you'll need commit
>>> b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
>>> tree.
>>
>> You asked me to submit this to Mark Brown, I didn't realize you also
>> wanted me to use the one in your tree. Using yours will make my lines
>> over 80 chars and so it kind of defeats the purpose but I'll do it
>> for v4.
>
> I asked two of you to upstream a generic incarnation of your
> implementation.  The other guy got there first.  Now I want everyone
> to use it instead of hand-rolling their own.
>

Got it.

>>> [...]
>>>
>>>> +static struct i2c_driver tps65912_i2c_driver = {
>>>> +	.driver		= {
>>>> +		.name	= "tps65912",
>>>> +		.of_match_table = tps65912_i2c_of_match_table,
>>>
>>> of_match_ptr()
>>>
>>
>> Why? tps65912_i2c_of_match_table is always compiled in.
>
> But it needn't be.
>

This driver is DT only, would it make more sense to just add a dependency
on CONFIG_OF in the Kconfig? I don't see many other drivers that are DT
only doing this, the driver should compile just fine without OF enabled,
it just wont have DT functionality, so is it really dependent on OF?
The of_match_ptr(x) macro looks to be useful when the x is conditionally
compiled in, but in my case the x (my of_device_id table) is always compiled.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 5/5] gpio: tps65912: Add GPIO driver for the TPS65912 PMIC
  2015-09-28  2:54   ` Alexandre Courbot
@ 2015-09-28 15:52         ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-28 15:52 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Samuel Ortiz,
	Liam Girdwood, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Linux Kernel Mailing List

On 09/27/2015 09:54 PM, Alexandre Courbot wrote:
> On Thu, Sep 24, 2015 at 11:52 PM, Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org> wrote:
>> This patch adds support for the TPS65912 PMIC GPIOs.
>>
>> TPS65912 has five configurable GPIOs that can be used for several
>> purposes.
>>
>> Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
>> ---
>>   drivers/gpio/Kconfig         |   6 ++
>>   drivers/gpio/Makefile        |   1 +
>>   drivers/gpio/gpio-tps65912.c | 138 +++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 145 insertions(+)
>>   create mode 100644 drivers/gpio/gpio-tps65912.c
>>
>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
>> index fb28483..82218fa 100644
>> --- a/drivers/gpio/Kconfig
>> +++ b/drivers/gpio/Kconfig
>> @@ -838,6 +838,12 @@ config GPIO_TPS65910
>>            Select this option to enable GPIO driver for the TPS65910
>>            chip family.
>>
>> +config GPIO_TPS65912
>> +       tristate "TI TPS65912 GPIO"
>> +       depends on MFD_TPS65912
>> +       help
>> +         This driver supports TPS65912 gpio chip
>> +
>>   config GPIO_TWL4030
>>          tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
>>          depends on TWL4030_CORE
>> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
>> index 605bf89..f79a7c4 100644
>> --- a/drivers/gpio/Makefile
>> +++ b/drivers/gpio/Makefile
>> @@ -96,6 +96,7 @@ obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
>>   obj-$(CONFIG_GPIO_PALMAS)      += gpio-palmas.o
>>   obj-$(CONFIG_GPIO_TPS6586X)    += gpio-tps6586x.o
>>   obj-$(CONFIG_GPIO_TPS65910)    += gpio-tps65910.o
>> +obj-$(CONFIG_GPIO_TPS65912)    += gpio-tps65912.o
>>   obj-$(CONFIG_GPIO_TS5500)      += gpio-ts5500.o
>>   obj-$(CONFIG_GPIO_TWL4030)     += gpio-twl4030.o
>>   obj-$(CONFIG_GPIO_TWL6040)     += gpio-twl6040.o
>> diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
>> new file mode 100644
>> index 0000000..4707e62
>> --- /dev/null
>> +++ b/drivers/gpio/gpio-tps65912.c
>> @@ -0,0 +1,138 @@
>> +/*
>> + * TI TPS65912x GPIO Driver
>> + *
>> + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
>> + *
>> + * Author: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>> + * kind, whether expressed or implied; without even the implied warranty
>> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License version 2 for more details.
>> + *
>> + * Based on the Arizona GPIO driver and the previous TPS65912 driver by
>> + * Margarita Olaya Cabrera <magi-kDsPt+C1G03kYMGBc/C6ZA@public.gmane.org>
>> + */
>> +
>> +#include <linux/gpio.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +
>> +#include <linux/mfd/tps65912.h>
>> +
>> +struct tps65912_gpio {
>> +       struct tps65912 *tps;
>> +       struct gpio_chip gpio_chip;
>
> Nit: I'd suggest to put gpio_chip as the first member of your struct
> so that to_gpio() resolves to the same address. This may make the
> generated code neglectably smaller and faster.
>

ACK

>> +};
>> +
>> +#define to_gpio(gc) container_of(gc, struct tps65912_gpio, gpio_chip)
>
> Nit2: Maybe a more specific name (like tps_gpio()) would be better?
> It's local to this file though, so not a big deal.
>

ACK

>> +
>> +static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +       int ret, val;
>> +
>> +       ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val);
>> +       if (ret < 0)
>> +               return ret;
>> +
>> +       return val & GPIO_STS_MASK;
>> +}
>> +
>> +static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
>> +                             int value)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +
>> +       regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
>> +                          GPIO_SET_MASK, value ? GPIO_SET_MASK : 0);
>> +}
>> +
>> +static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
>> +                               int value)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +
>> +       /* Set the initial value */
>> +       tps65912_gpio_set(gc, offset, value);
>> +
>> +       return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
>> +                                 GPIO_CFG_MASK, GPIO_CFG_MASK);
>> +}
>> +
>> +static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +
>> +       return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
>> +                                 GPIO_CFG_MASK, 0);
>> +}
>> +
>> +static const struct of_device_id tps65912_gpio_of_match_table[] = {
>> +       { .compatible = "ti,tps65912-gpio", },
>> +       { /* sentinel */ },
>> +};
>> +MODULE_DEVICE_TABLE(of, tps65912_gpio_of_match_table);
>> +
>> +static struct gpio_chip template_chip = {
>> +       .label                  = "tps65912-gpio",
>> +       .owner                  = THIS_MODULE,
>> +       .direction_input        = tps65912_gpio_input,
>> +       .direction_output       = tps65912_gpio_output,
>> +       .get                    = tps65912_gpio_get,
>> +       .set                    = tps65912_gpio_set,
>> +       .can_sleep              = true,
>> +       .ngpio                  = 5,
>> +       .base                   = -1,
>> +};
>> +
>> +static int tps65912_gpio_probe(struct platform_device *pdev)
>> +{
>> +       struct tps65912_gpio *gpio;
>> +       int ret;
>> +
>> +       gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
>> +       if (!gpio)
>> +               return -ENOMEM;
>> +
>> +       gpio->tps = dev_get_drvdata(pdev->dev.parent);
>> +       gpio->gpio_chip = template_chip;
>> +       ret = gpiochip_add(&gpio->gpio_chip);
>> +       if (ret < 0) {
>> +               dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       platform_set_drvdata(pdev, gpio);
>> +
>> +       return 0;
>> +}
>> +
>> +static int tps65912_gpio_remove(struct platform_device *pdev)
>> +{
>> +       struct tps65912_gpio *gpio = platform_get_drvdata(pdev);
>> +
>> +       gpiochip_remove(&gpio->gpio_chip);
>> +
>> +       return 0;
>> +}
>> +
>> +static struct platform_driver tps65912_gpio_driver = {
>> +       .driver = {
>> +               .name = "tps65912-gpio",
>> +               .of_match_table = tps65912_gpio_of_match_table,
>> +       },
>> +       .probe = tps65912_gpio_probe,
>> +       .remove = tps65912_gpio_remove,
>> +};
>> +
>> +module_platform_driver(tps65912_gpio_driver);
>> +
>> +MODULE_AUTHOR("Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>");
>> +MODULE_DESCRIPTION("TPS65912 GPIO driver");
>> +MODULE_ALIAS("platform:tps65912-gpio");
>> +MODULE_LICENSE("GPL v2");
>
> Nice and simple driver - my remarks above should not be taken as a
> call to re-spin, just consider them if you need to send another
> version of this patchset.
>
> Reviewed-by: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>

I'm going to have to send another spin of this patchset anyway so I'll
take them.

Thanks for the review,
Andrew
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 5/5] gpio: tps65912: Add GPIO driver for the TPS65912 PMIC
@ 2015-09-28 15:52         ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-28 15:52 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Linus Walleij, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, Linux Kernel Mailing List

On 09/27/2015 09:54 PM, Alexandre Courbot wrote:
> On Thu, Sep 24, 2015 at 11:52 PM, Andrew F. Davis <afd@ti.com> wrote:
>> This patch adds support for the TPS65912 PMIC GPIOs.
>>
>> TPS65912 has five configurable GPIOs that can be used for several
>> purposes.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/gpio/Kconfig         |   6 ++
>>   drivers/gpio/Makefile        |   1 +
>>   drivers/gpio/gpio-tps65912.c | 138 +++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 145 insertions(+)
>>   create mode 100644 drivers/gpio/gpio-tps65912.c
>>
>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
>> index fb28483..82218fa 100644
>> --- a/drivers/gpio/Kconfig
>> +++ b/drivers/gpio/Kconfig
>> @@ -838,6 +838,12 @@ config GPIO_TPS65910
>>            Select this option to enable GPIO driver for the TPS65910
>>            chip family.
>>
>> +config GPIO_TPS65912
>> +       tristate "TI TPS65912 GPIO"
>> +       depends on MFD_TPS65912
>> +       help
>> +         This driver supports TPS65912 gpio chip
>> +
>>   config GPIO_TWL4030
>>          tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
>>          depends on TWL4030_CORE
>> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
>> index 605bf89..f79a7c4 100644
>> --- a/drivers/gpio/Makefile
>> +++ b/drivers/gpio/Makefile
>> @@ -96,6 +96,7 @@ obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
>>   obj-$(CONFIG_GPIO_PALMAS)      += gpio-palmas.o
>>   obj-$(CONFIG_GPIO_TPS6586X)    += gpio-tps6586x.o
>>   obj-$(CONFIG_GPIO_TPS65910)    += gpio-tps65910.o
>> +obj-$(CONFIG_GPIO_TPS65912)    += gpio-tps65912.o
>>   obj-$(CONFIG_GPIO_TS5500)      += gpio-ts5500.o
>>   obj-$(CONFIG_GPIO_TWL4030)     += gpio-twl4030.o
>>   obj-$(CONFIG_GPIO_TWL6040)     += gpio-twl6040.o
>> diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c
>> new file mode 100644
>> index 0000000..4707e62
>> --- /dev/null
>> +++ b/drivers/gpio/gpio-tps65912.c
>> @@ -0,0 +1,138 @@
>> +/*
>> + * TI TPS65912x GPIO Driver
>> + *
>> + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
>> + *
>> + * Author: Andrew F. Davis <afd@ti.com>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>> + * kind, whether expressed or implied; without even the implied warranty
>> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License version 2 for more details.
>> + *
>> + * Based on the Arizona GPIO driver and the previous TPS65912 driver by
>> + * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
>> + */
>> +
>> +#include <linux/gpio.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +
>> +#include <linux/mfd/tps65912.h>
>> +
>> +struct tps65912_gpio {
>> +       struct tps65912 *tps;
>> +       struct gpio_chip gpio_chip;
>
> Nit: I'd suggest to put gpio_chip as the first member of your struct
> so that to_gpio() resolves to the same address. This may make the
> generated code neglectably smaller and faster.
>

ACK

>> +};
>> +
>> +#define to_gpio(gc) container_of(gc, struct tps65912_gpio, gpio_chip)
>
> Nit2: Maybe a more specific name (like tps_gpio()) would be better?
> It's local to this file though, so not a big deal.
>

ACK

>> +
>> +static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +       int ret, val;
>> +
>> +       ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val);
>> +       if (ret < 0)
>> +               return ret;
>> +
>> +       return val & GPIO_STS_MASK;
>> +}
>> +
>> +static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
>> +                             int value)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +
>> +       regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
>> +                          GPIO_SET_MASK, value ? GPIO_SET_MASK : 0);
>> +}
>> +
>> +static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
>> +                               int value)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +
>> +       /* Set the initial value */
>> +       tps65912_gpio_set(gc, offset, value);
>> +
>> +       return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
>> +                                 GPIO_CFG_MASK, GPIO_CFG_MASK);
>> +}
>> +
>> +static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct tps65912_gpio *gpio = to_gpio(gc);
>> +
>> +       return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
>> +                                 GPIO_CFG_MASK, 0);
>> +}
>> +
>> +static const struct of_device_id tps65912_gpio_of_match_table[] = {
>> +       { .compatible = "ti,tps65912-gpio", },
>> +       { /* sentinel */ },
>> +};
>> +MODULE_DEVICE_TABLE(of, tps65912_gpio_of_match_table);
>> +
>> +static struct gpio_chip template_chip = {
>> +       .label                  = "tps65912-gpio",
>> +       .owner                  = THIS_MODULE,
>> +       .direction_input        = tps65912_gpio_input,
>> +       .direction_output       = tps65912_gpio_output,
>> +       .get                    = tps65912_gpio_get,
>> +       .set                    = tps65912_gpio_set,
>> +       .can_sleep              = true,
>> +       .ngpio                  = 5,
>> +       .base                   = -1,
>> +};
>> +
>> +static int tps65912_gpio_probe(struct platform_device *pdev)
>> +{
>> +       struct tps65912_gpio *gpio;
>> +       int ret;
>> +
>> +       gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
>> +       if (!gpio)
>> +               return -ENOMEM;
>> +
>> +       gpio->tps = dev_get_drvdata(pdev->dev.parent);
>> +       gpio->gpio_chip = template_chip;
>> +       ret = gpiochip_add(&gpio->gpio_chip);
>> +       if (ret < 0) {
>> +               dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       platform_set_drvdata(pdev, gpio);
>> +
>> +       return 0;
>> +}
>> +
>> +static int tps65912_gpio_remove(struct platform_device *pdev)
>> +{
>> +       struct tps65912_gpio *gpio = platform_get_drvdata(pdev);
>> +
>> +       gpiochip_remove(&gpio->gpio_chip);
>> +
>> +       return 0;
>> +}
>> +
>> +static struct platform_driver tps65912_gpio_driver = {
>> +       .driver = {
>> +               .name = "tps65912-gpio",
>> +               .of_match_table = tps65912_gpio_of_match_table,
>> +       },
>> +       .probe = tps65912_gpio_probe,
>> +       .remove = tps65912_gpio_remove,
>> +};
>> +
>> +module_platform_driver(tps65912_gpio_driver);
>> +
>> +MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
>> +MODULE_DESCRIPTION("TPS65912 GPIO driver");
>> +MODULE_ALIAS("platform:tps65912-gpio");
>> +MODULE_LICENSE("GPL v2");
>
> Nice and simple driver - my remarks above should not be taken as a
> call to re-spin, just consider them if you need to send another
> version of this patchset.
>
> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
>

I'm going to have to send another spin of this patchset anyway so I'll
take them.

Thanks for the review,
Andrew

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-24 14:52   ` Andrew F. Davis
@ 2015-09-28 16:01     ` Grygorii Strashko
  -1 siblings, 0 replies; 56+ messages in thread
From: Grygorii Strashko @ 2015-09-28 16:01 UTC (permalink / raw)
  To: Andrew F. Davis, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Lee Jones, Mark Brown, Linus Walleij,
	Alexandre Courbot, Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel

On 09/24/2015 09:52 AM, Andrew F. Davis wrote:
> This patch adds support for TPS65912 mfd device. It provides
> communication through the I2C and SPI interfaces. It contains
> the following components:
> 
>   - Regulators
>   - GPIO controller
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>   drivers/mfd/Kconfig          |  24 +++
>   drivers/mfd/Makefile         |   3 +
>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>   6 files changed, 705 insertions(+)
>   create mode 100644 drivers/mfd/tps65912-core.c
>   create mode 100644 drivers/mfd/tps65912-i2c.c
>   create mode 100644 drivers/mfd/tps65912-spi.c
>   create mode 100644 include/linux/mfd/tps65912.h
> 

[...]

> +
> +/*
> + * struct tps_info - packages regulator constraints
> + * @id: Id of the regulator
> + * @name: Voltage regulator name
> + * @min_uV: Minimum micro volts
> + * @max_uV: Minimum micro volts
> + *
> + * This data is used to check the regulator voltage limits while setting.
> + */
> +struct tps_info {
> +	int id;
> +	const char *name;
> +	int min_uV;
> +	int max_uV;
> +};

Could you move structure's definitions to the corresponding c-files
if they are used only locally in this files, pls? 

> +
> +/*
> + * struct tps65912 - state holder for the tps65912 driver
> + *
> + * Device data may be used to access the TPS65912 chip
> + */
> +struct tps65912 {
> +	struct device *dev;
> +	unsigned int id;
> +
> +	/* IRQ Data */
> +	int irq;
> +	struct regmap_irq_chip_data *irq_data;
> +
> +	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
> +	struct tps_info *info[TPS65912_NUM_REGULATOR];

seems above two field are not used (and id?).

> +	struct regmap *regmap;
> +};
> +
> +static const struct regmap_range tps65912_yes_ranges[] = {
> +	regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
> +};
> +
> +static const struct regmap_access_table tps65912_volatile_table = {
> +	.yes_ranges = tps65912_yes_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
> +};
> +
> +static const struct regmap_config tps65912_regmap_co	nfig = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_table = &tps65912_volatile_table,
> +};
> +
> +int tps65912_device_init(struct tps65912 *tps);
> +int tps65912_device_exit(struct tps65912 *tps);
> +
> +#endif /*  __LINUX_MFD_TPS65912_H */
> 


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-28 16:01     ` Grygorii Strashko
  0 siblings, 0 replies; 56+ messages in thread
From: Grygorii Strashko @ 2015-09-28 16:01 UTC (permalink / raw)
  To: Andrew F. Davis, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Lee Jones, Mark Brown, Linus Walleij,
	Alexandre Courbot, Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel

On 09/24/2015 09:52 AM, Andrew F. Davis wrote:
> This patch adds support for TPS65912 mfd device. It provides
> communication through the I2C and SPI interfaces. It contains
> the following components:
> 
>   - Regulators
>   - GPIO controller
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>   drivers/mfd/Kconfig          |  24 +++
>   drivers/mfd/Makefile         |   3 +
>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>   6 files changed, 705 insertions(+)
>   create mode 100644 drivers/mfd/tps65912-core.c
>   create mode 100644 drivers/mfd/tps65912-i2c.c
>   create mode 100644 drivers/mfd/tps65912-spi.c
>   create mode 100644 include/linux/mfd/tps65912.h
> 

[...]

> +
> +/*
> + * struct tps_info - packages regulator constraints
> + * @id: Id of the regulator
> + * @name: Voltage regulator name
> + * @min_uV: Minimum micro volts
> + * @max_uV: Minimum micro volts
> + *
> + * This data is used to check the regulator voltage limits while setting.
> + */
> +struct tps_info {
> +	int id;
> +	const char *name;
> +	int min_uV;
> +	int max_uV;
> +};

Could you move structure's definitions to the corresponding c-files
if they are used only locally in this files, pls? 

> +
> +/*
> + * struct tps65912 - state holder for the tps65912 driver
> + *
> + * Device data may be used to access the TPS65912 chip
> + */
> +struct tps65912 {
> +	struct device *dev;
> +	unsigned int id;
> +
> +	/* IRQ Data */
> +	int irq;
> +	struct regmap_irq_chip_data *irq_data;
> +
> +	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
> +	struct tps_info *info[TPS65912_NUM_REGULATOR];

seems above two field are not used (and id?).

> +	struct regmap *regmap;
> +};
> +
> +static const struct regmap_range tps65912_yes_ranges[] = {
> +	regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
> +};
> +
> +static const struct regmap_access_table tps65912_volatile_table = {
> +	.yes_ranges = tps65912_yes_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
> +};
> +
> +static const struct regmap_config tps65912_regmap_co	nfig = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_table = &tps65912_volatile_table,
> +};
> +
> +int tps65912_device_init(struct tps65912 *tps);
> +int tps65912_device_exit(struct tps65912 *tps);
> +
> +#endif /*  __LINUX_MFD_TPS65912_H */
> 


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-28 15:43               ` Andrew F. Davis
  (?)
@ 2015-09-29  7:19               ` Lee Jones
  2015-09-29 15:50                   ` Andrew F. Davis
  -1 siblings, 1 reply; 56+ messages in thread
From: Lee Jones @ 2015-09-29  7:19 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On Mon, 28 Sep 2015, Andrew F. Davis wrote:

> On 09/25/2015 04:24 PM, Lee Jones wrote:
> >On Fri, 25 Sep 2015, Andrew F. Davis wrote:
> >
> >>On 09/25/2015 11:50 AM, Lee Jones wrote:
> >>>On Thu, 24 Sep 2015, Andrew F. Davis wrote:
> >>>
> >>>>This patch adds support for TPS65912 mfd device. It provides
> >>>>communication through the I2C and SPI interfaces. It contains
> >>>>the following components:
> >>>>
> >>>>  - Regulators
> >>>>  - GPIO controller
> >>>>
> >>>>Signed-off-by: Andrew F. Davis <afd@ti.com>
> >>>>---
> >>>>  drivers/mfd/Kconfig          |  24 +++
> >>>>  drivers/mfd/Makefile         |   3 +
> >>>>  drivers/mfd/tps65912-core.c  | 114 +++++++++++++
> >>>>  drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
> >>>>  drivers/mfd/tps65912-spi.c   |  85 ++++++++++
> >>>>  include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
> >>>>  6 files changed, 705 insertions(+)
> >>>>  create mode 100644 drivers/mfd/tps65912-core.c
> >>>>  create mode 100644 drivers/mfd/tps65912-i2c.c
> >>>>  create mode 100644 drivers/mfd/tps65912-spi.c
> >>>>  create mode 100644 include/linux/mfd/tps65912.h
> >>>
> >>>[...]
> >>>
> >>>>+#define TPS65912_IRQ(_name, _reg, _offset)			\
> >>>>+	[TPS65912_IRQ_ ## _name] = {				\
> >>>>+		.mask = TPS65912_ ## _reg ## _ ## _name,	\
> >>>>+		.reg_offset = _offset,				\
> >>>>+	}
> >>>
> >>>I told you about this already.
> >>>
> >>>If you want this set to be merged for v4.3 then you'll need commit
> >>>b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
> >>>tree.
> >>
> >>You asked me to submit this to Mark Brown, I didn't realize you also
> >>wanted me to use the one in your tree. Using yours will make my lines
> >>over 80 chars and so it kind of defeats the purpose but I'll do it
> >>for v4.
> >
> >I asked two of you to upstream a generic incarnation of your
> >implementation.  The other guy got there first.  Now I want everyone
> >to use it instead of hand-rolling their own.
> >
> 
> Got it.
> 
> >>>[...]
> >>>
> >>>>+static struct i2c_driver tps65912_i2c_driver = {
> >>>>+	.driver		= {
> >>>>+		.name	= "tps65912",
> >>>>+		.of_match_table = tps65912_i2c_of_match_table,
> >>>
> >>>of_match_ptr()
> >>>
> >>
> >>Why? tps65912_i2c_of_match_table is always compiled in.
> >
> >But it needn't be.
> >
> 
> This driver is DT only, would it make more sense to just add a dependency
> on CONFIG_OF in the Kconfig?

Yes, that is the alternitive.

> I don't see many other drivers that are DT
> only doing this, the driver should compile just fine without OF enabled,
> it just wont have DT functionality, so is it really dependent on OF?

Then it should be "depends on OF || COMPILE_TEST"

> The of_match_ptr(x) macro looks to be useful when the x is conditionally
> compiled in, but in my case the x (my of_device_id table) is always compiled.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-25 20:10         ` Andrew F. Davis
  (?)
@ 2015-09-29 15:13         ` Mark Brown
  2015-09-29 18:08             ` Andrew F. Davis
  -1 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2015-09-29 15:13 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1389 bytes --]

On Fri, Sep 25, 2015 at 03:10:04PM -0500, Andrew F. Davis wrote:
> On 09/25/2015 01:05 PM, Mark Brown wrote:
> >On Thu, Sep 24, 2015 at 09:52:53AM -0500, Andrew F. Davis wrote:

> >>+	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
> >>+	if (!match)
> >>+		return -ENODEV;

> >>+	template = match->data;
> >>+	id = template->id;
> >>+	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
> >>+					       &regulators[id]);

> >Don't open code this stuff, use the core DT matching in the
> >regulator_desc instead.

> I assume you are referring to your additions in a0c7b164ad11? If so I'm not

Please don't refer to commits by ID only, include a human readable
description of the commit for the benefit of any humans who might read
your mail.

> sure that will save me anything as my probe function is called with a DT
> match already, so no searching is needed.

You've not understood what that change is replacing, the code I'm
quoting above is exactly that code.  Check out some of the existing
drivers using this API.

> >Please also use subject lines mathcing the style for the subsystem.

> I'm not sure I know what you mean? What is wrong with my subject line, it looks
> like the others I've looked at?

You are using "regulators:", the regulator API uses "regulator:" - this
should be really clear if you do something like a git shortlog.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-29  7:19               ` Lee Jones
@ 2015-09-29 15:50                   ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 15:50 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/29/2015 02:19 AM, Lee Jones wrote:
> On Mon, 28 Sep 2015, Andrew F. Davis wrote:
>
>> On 09/25/2015 04:24 PM, Lee Jones wrote:
>>> On Fri, 25 Sep 2015, Andrew F. Davis wrote:
>>>
>>>> On 09/25/2015 11:50 AM, Lee Jones wrote:
>>>>> On Thu, 24 Sep 2015, Andrew F. Davis wrote:
>>>>>
>>>>>> This patch adds support for TPS65912 mfd device. It provides
>>>>>> communication through the I2C and SPI interfaces. It contains
>>>>>> the following components:
>>>>>>
>>>>>>   - Regulators
>>>>>>   - GPIO controller
>>>>>>
>>>>>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>>>>>> ---
>>>>>>   drivers/mfd/Kconfig          |  24 +++
>>>>>>   drivers/mfd/Makefile         |   3 +
>>>>>>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>>>>>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>>>>>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>>>>>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>>>>>   6 files changed, 705 insertions(+)
>>>>>>   create mode 100644 drivers/mfd/tps65912-core.c
>>>>>>   create mode 100644 drivers/mfd/tps65912-i2c.c
>>>>>>   create mode 100644 drivers/mfd/tps65912-spi.c
>>>>>>   create mode 100644 include/linux/mfd/tps65912.h
>>>>>
>>>>> [...]
>>>>>
>>>>>> +#define TPS65912_IRQ(_name, _reg, _offset)			\
>>>>>> +	[TPS65912_IRQ_ ## _name] = {				\
>>>>>> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
>>>>>> +		.reg_offset = _offset,				\
>>>>>> +	}
>>>>>
>>>>> I told you about this already.
>>>>>
>>>>> If you want this set to be merged for v4.3 then you'll need commit
>>>>> b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
>>>>> tree.
>>>>
>>>> You asked me to submit this to Mark Brown, I didn't realize you also
>>>> wanted me to use the one in your tree. Using yours will make my lines
>>>> over 80 chars and so it kind of defeats the purpose but I'll do it
>>>> for v4.
>>>
>>> I asked two of you to upstream a generic incarnation of your
>>> implementation.  The other guy got there first.  Now I want everyone
>>> to use it instead of hand-rolling their own.
>>>
>>
>> Got it.
>>
>>>>> [...]
>>>>>
>>>>>> +static struct i2c_driver tps65912_i2c_driver = {
>>>>>> +	.driver		= {
>>>>>> +		.name	= "tps65912",
>>>>>> +		.of_match_table = tps65912_i2c_of_match_table,
>>>>>
>>>>> of_match_ptr()
>>>>>
>>>>
>>>> Why? tps65912_i2c_of_match_table is always compiled in.
>>>
>>> But it needn't be.
>>>
>>
>> This driver is DT only, would it make more sense to just add a dependency
>> on CONFIG_OF in the Kconfig?
>
> Yes, that is the alternitive.
>
>> I don't see many other drivers that are DT
>> only doing this, the driver should compile just fine without OF enabled,
>> it just wont have DT functionality, so is it really dependent on OF?
>
> Then it should be "depends on OF || COMPILE_TEST"
>

OK, I'll add this.

>> The of_match_ptr(x) macro looks to be useful when the x is conditionally
>> compiled in, but in my case the x (my of_device_id table) is always compiled.
>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-29 15:50                   ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 15:50 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mark Brown, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/29/2015 02:19 AM, Lee Jones wrote:
> On Mon, 28 Sep 2015, Andrew F. Davis wrote:
>
>> On 09/25/2015 04:24 PM, Lee Jones wrote:
>>> On Fri, 25 Sep 2015, Andrew F. Davis wrote:
>>>
>>>> On 09/25/2015 11:50 AM, Lee Jones wrote:
>>>>> On Thu, 24 Sep 2015, Andrew F. Davis wrote:
>>>>>
>>>>>> This patch adds support for TPS65912 mfd device. It provides
>>>>>> communication through the I2C and SPI interfaces. It contains
>>>>>> the following components:
>>>>>>
>>>>>>   - Regulators
>>>>>>   - GPIO controller
>>>>>>
>>>>>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>>>>>> ---
>>>>>>   drivers/mfd/Kconfig          |  24 +++
>>>>>>   drivers/mfd/Makefile         |   3 +
>>>>>>   drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>>>>>   drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>>>>>   drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>>>>>   include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>>>>>   6 files changed, 705 insertions(+)
>>>>>>   create mode 100644 drivers/mfd/tps65912-core.c
>>>>>>   create mode 100644 drivers/mfd/tps65912-i2c.c
>>>>>>   create mode 100644 drivers/mfd/tps65912-spi.c
>>>>>>   create mode 100644 include/linux/mfd/tps65912.h
>>>>>
>>>>> [...]
>>>>>
>>>>>> +#define TPS65912_IRQ(_name, _reg, _offset)			\
>>>>>> +	[TPS65912_IRQ_ ## _name] = {				\
>>>>>> +		.mask = TPS65912_ ## _reg ## _ ## _name,	\
>>>>>> +		.reg_offset = _offset,				\
>>>>>> +	}
>>>>>
>>>>> I told you about this already.
>>>>>
>>>>> If you want this set to be merged for v4.3 then you'll need commit
>>>>> b4fe8ba ("regmap: Add generic macro to define regmap_irq") from my
>>>>> tree.
>>>>
>>>> You asked me to submit this to Mark Brown, I didn't realize you also
>>>> wanted me to use the one in your tree. Using yours will make my lines
>>>> over 80 chars and so it kind of defeats the purpose but I'll do it
>>>> for v4.
>>>
>>> I asked two of you to upstream a generic incarnation of your
>>> implementation.  The other guy got there first.  Now I want everyone
>>> to use it instead of hand-rolling their own.
>>>
>>
>> Got it.
>>
>>>>> [...]
>>>>>
>>>>>> +static struct i2c_driver tps65912_i2c_driver = {
>>>>>> +	.driver		= {
>>>>>> +		.name	= "tps65912",
>>>>>> +		.of_match_table = tps65912_i2c_of_match_table,
>>>>>
>>>>> of_match_ptr()
>>>>>
>>>>
>>>> Why? tps65912_i2c_of_match_table is always compiled in.
>>>
>>> But it needn't be.
>>>
>>
>> This driver is DT only, would it make more sense to just add a dependency
>> on CONFIG_OF in the Kconfig?
>
> Yes, that is the alternitive.
>
>> I don't see many other drivers that are DT
>> only doing this, the driver should compile just fine without OF enabled,
>> it just wont have DT functionality, so is it really dependent on OF?
>
> Then it should be "depends on OF || COMPILE_TEST"
>

OK, I'll add this.

>> The of_match_ptr(x) macro looks to be useful when the x is conditionally
>> compiled in, but in my case the x (my of_device_id table) is always compiled.
>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-29 15:13         ` Mark Brown
@ 2015-09-29 18:08             ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 18:08 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/29/2015 10:13 AM, Mark Brown wrote:
> On Fri, Sep 25, 2015 at 03:10:04PM -0500, Andrew F. Davis wrote:
>> On 09/25/2015 01:05 PM, Mark Brown wrote:
>>> On Thu, Sep 24, 2015 at 09:52:53AM -0500, Andrew F. Davis wrote:
>
>>>> +	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
>>>> +	if (!match)
>>>> +		return -ENODEV;
>
>>>> +	template = match->data;
>>>> +	id = template->id;
>>>> +	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
>>>> +					       &regulators[id]);
>
>>> Don't open code this stuff, use the core DT matching in the
>>> regulator_desc instead.
>
>> I assume you are referring to your additions in a0c7b164ad11? If so I'm not
>
> Please don't refer to commits by ID only, include a human readable
> description of the commit for the benefit of any humans who might read
> your mail.
>

Forgot about those pesky humans :), OK, will do from now on.

>> sure that will save me anything as my probe function is called with a DT
>> match already, so no searching is needed.
>
> You've not understood what that change is replacing, the code I'm
> quoting above is exactly that code.  Check out some of the existing
> drivers using this API.
>

Looking at other drivers that use this API they all call regulator_register
in a loop in their probe, once for each possible regulator, in this case
letting the API do the DT node search makes sense. My probe on the other-hand
is only called when we already have a DT match, therefor searching is not
necessary and all I have to do is call of_get_regulator_init_data myself on
the already found DT node. No need to add node names to my regulator_desc
and make the API re-search for the node.

I have further cleaned up this code to show this.

If this is acceptable, I'll push the re-spin so you can review further.

>>> Please also use subject lines mathcing the style for the subsystem.
>
>> I'm not sure I know what you mean? What is wrong with my subject line, it looks
>> like the others I've looked at?
>
> You are using "regulators:", the regulator API uses "regulator:" - this
> should be really clear if you do something like a git shortlog.
>

Ah, slipped right past me, thanks for clarifying, fixed.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-09-29 18:08             ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 18:08 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/29/2015 10:13 AM, Mark Brown wrote:
> On Fri, Sep 25, 2015 at 03:10:04PM -0500, Andrew F. Davis wrote:
>> On 09/25/2015 01:05 PM, Mark Brown wrote:
>>> On Thu, Sep 24, 2015 at 09:52:53AM -0500, Andrew F. Davis wrote:
>
>>>> +	match = of_match_device(tps65912_regulator_of_match_table, &pdev->dev);
>>>> +	if (!match)
>>>> +		return -ENODEV;
>
>>>> +	template = match->data;
>>>> +	id = template->id;
>>>> +	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
>>>> +					       &regulators[id]);
>
>>> Don't open code this stuff, use the core DT matching in the
>>> regulator_desc instead.
>
>> I assume you are referring to your additions in a0c7b164ad11? If so I'm not
>
> Please don't refer to commits by ID only, include a human readable
> description of the commit for the benefit of any humans who might read
> your mail.
>

Forgot about those pesky humans :), OK, will do from now on.

>> sure that will save me anything as my probe function is called with a DT
>> match already, so no searching is needed.
>
> You've not understood what that change is replacing, the code I'm
> quoting above is exactly that code.  Check out some of the existing
> drivers using this API.
>

Looking at other drivers that use this API they all call regulator_register
in a loop in their probe, once for each possible regulator, in this case
letting the API do the DT node search makes sense. My probe on the other-hand
is only called when we already have a DT match, therefor searching is not
necessary and all I have to do is call of_get_regulator_init_data myself on
the already found DT node. No need to add node names to my regulator_desc
and make the API re-search for the node.

I have further cleaned up this code to show this.

If this is acceptable, I'll push the re-spin so you can review further.

>>> Please also use subject lines mathcing the style for the subsystem.
>
>> I'm not sure I know what you mean? What is wrong with my subject line, it looks
>> like the others I've looked at?
>
> You are using "regulators:", the regulator API uses "regulator:" - this
> should be really clear if you do something like a git shortlog.
>

Ah, slipped right past me, thanks for clarifying, fixed.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
  2015-09-28 16:01     ` Grygorii Strashko
@ 2015-09-29 18:16       ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 18:16 UTC (permalink / raw)
  To: Grygorii Strashko, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Lee Jones, Mark Brown, Linus Walleij,
	Alexandre Courbot, Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel

On 09/28/2015 11:01 AM, Grygorii Strashko wrote:
> On 09/24/2015 09:52 AM, Andrew F. Davis wrote:
>> This patch adds support for TPS65912 mfd device. It provides
>> communication through the I2C and SPI interfaces. It contains
>> the following components:
>>
>>    - Regulators
>>    - GPIO controller
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>    drivers/mfd/Kconfig          |  24 +++
>>    drivers/mfd/Makefile         |   3 +
>>    drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>    drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>    drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>    include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>    6 files changed, 705 insertions(+)
>>    create mode 100644 drivers/mfd/tps65912-core.c
>>    create mode 100644 drivers/mfd/tps65912-i2c.c
>>    create mode 100644 drivers/mfd/tps65912-spi.c
>>    create mode 100644 include/linux/mfd/tps65912.h
>>
>
> [...]
>
>> +
>> +/*
>> + * struct tps_info - packages regulator constraints
>> + * @id: Id of the regulator
>> + * @name: Voltage regulator name
>> + * @min_uV: Minimum micro volts
>> + * @max_uV: Minimum micro volts
>> + *
>> + * This data is used to check the regulator voltage limits while setting.
>> + */
>> +struct tps_info {
>> +	int id;
>> +	const char *name;
>> +	int min_uV;
>> +	int max_uV;
>> +};
>
> Could you move structure's definitions to the corresponding c-files
> if they are used only locally in this files, pls?
>

ACK

>> +
>> +/*
>> + * struct tps65912 - state holder for the tps65912 driver
>> + *
>> + * Device data may be used to access the TPS65912 chip
>> + */
>> +struct tps65912 {
>> +	struct device *dev;
>> +	unsigned int id;
>> +
>> +	/* IRQ Data */
>> +	int irq;
>> +	struct regmap_irq_chip_data *irq_data;
>> +
>> +	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
>> +	struct tps_info *info[TPS65912_NUM_REGULATOR];
>
> seems above two field are not used (and id?).
>

The idea was for a someday use, but because I never did that I'll
remove them for now.

Thanks,
Andrew

>> +	struct regmap *regmap;
>> +};
>> +
>> +static const struct regmap_range tps65912_yes_ranges[] = {
>> +	regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
>> +};
>> +
>> +static const struct regmap_access_table tps65912_volatile_table = {
>> +	.yes_ranges = tps65912_yes_ranges,
>> +	.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
>> +};
>> +
>> +static const struct regmap_config tps65912_regmap_co	nfig = {
>> +	.reg_bits = 8,
>> +	.val_bits = 8,
>> +	.cache_type = REGCACHE_RBTREE,
>> +	.volatile_table = &tps65912_volatile_table,
>> +};
>> +
>> +int tps65912_device_init(struct tps65912 *tps);
>> +int tps65912_device_exit(struct tps65912 *tps);
>> +
>> +#endif /*  __LINUX_MFD_TPS65912_H */
>>
>
>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC
@ 2015-09-29 18:16       ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 18:16 UTC (permalink / raw)
  To: Grygorii Strashko, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Lee Jones, Mark Brown, Linus Walleij,
	Alexandre Courbot, Samuel Ortiz, Liam Girdwood
  Cc: linux-gpio, devicetree, linux-kernel

On 09/28/2015 11:01 AM, Grygorii Strashko wrote:
> On 09/24/2015 09:52 AM, Andrew F. Davis wrote:
>> This patch adds support for TPS65912 mfd device. It provides
>> communication through the I2C and SPI interfaces. It contains
>> the following components:
>>
>>    - Regulators
>>    - GPIO controller
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>    drivers/mfd/Kconfig          |  24 +++
>>    drivers/mfd/Makefile         |   3 +
>>    drivers/mfd/tps65912-core.c  | 114 +++++++++++++
>>    drivers/mfd/tps65912-i2c.c   |  86 ++++++++++
>>    drivers/mfd/tps65912-spi.c   |  85 ++++++++++
>>    include/linux/mfd/tps65912.h | 393 +++++++++++++++++++++++++++++++++++++++++++
>>    6 files changed, 705 insertions(+)
>>    create mode 100644 drivers/mfd/tps65912-core.c
>>    create mode 100644 drivers/mfd/tps65912-i2c.c
>>    create mode 100644 drivers/mfd/tps65912-spi.c
>>    create mode 100644 include/linux/mfd/tps65912.h
>>
>
> [...]
>
>> +
>> +/*
>> + * struct tps_info - packages regulator constraints
>> + * @id: Id of the regulator
>> + * @name: Voltage regulator name
>> + * @min_uV: Minimum micro volts
>> + * @max_uV: Minimum micro volts
>> + *
>> + * This data is used to check the regulator voltage limits while setting.
>> + */
>> +struct tps_info {
>> +	int id;
>> +	const char *name;
>> +	int min_uV;
>> +	int max_uV;
>> +};
>
> Could you move structure's definitions to the corresponding c-files
> if they are used only locally in this files, pls?
>

ACK

>> +
>> +/*
>> + * struct tps65912 - state holder for the tps65912 driver
>> + *
>> + * Device data may be used to access the TPS65912 chip
>> + */
>> +struct tps65912 {
>> +	struct device *dev;
>> +	unsigned int id;
>> +
>> +	/* IRQ Data */
>> +	int irq;
>> +	struct regmap_irq_chip_data *irq_data;
>> +
>> +	struct regulator_desc desc[TPS65912_NUM_REGULATOR];
>> +	struct tps_info *info[TPS65912_NUM_REGULATOR];
>
> seems above two field are not used (and id?).
>

The idea was for a someday use, but because I never did that I'll
remove them for now.

Thanks,
Andrew

>> +	struct regmap *regmap;
>> +};
>> +
>> +static const struct regmap_range tps65912_yes_ranges[] = {
>> +	regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
>> +};
>> +
>> +static const struct regmap_access_table tps65912_volatile_table = {
>> +	.yes_ranges = tps65912_yes_ranges,
>> +	.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
>> +};
>> +
>> +static const struct regmap_config tps65912_regmap_co	nfig = {
>> +	.reg_bits = 8,
>> +	.val_bits = 8,
>> +	.cache_type = REGCACHE_RBTREE,
>> +	.volatile_table = &tps65912_volatile_table,
>> +};
>> +
>> +int tps65912_device_init(struct tps65912 *tps);
>> +int tps65912_device_exit(struct tps65912 *tps);
>> +
>> +#endif /*  __LINUX_MFD_TPS65912_H */
>>
>
>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-29 18:08             ` Andrew F. Davis
  (?)
@ 2015-09-29 18:38             ` Mark Brown
  2015-09-29 18:58                 ` Andrew F. Davis
  -1 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2015-09-29 18:38 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1580 bytes --]

On Tue, Sep 29, 2015 at 01:08:50PM -0500, Andrew F. Davis wrote:
> On 09/29/2015 10:13 AM, Mark Brown wrote:

> >>sure that will save me anything as my probe function is called with a DT
> >>match already, so no searching is needed.

> >You've not understood what that change is replacing, the code I'm
> >quoting above is exactly that code.  Check out some of the existing
> >drivers using this API.

> Looking at other drivers that use this API they all call regulator_register
> in a loop in their probe, once for each possible regulator, in this case
> letting the API do the DT node search makes sense. My probe on the other-hand
> is only called when we already have a DT match, therefor searching is not
> necessary and all I have to do is call of_get_regulator_init_data myself on
> the already found DT node. No need to add node names to my regulator_desc
> and make the API re-search for the node.

Oh, ick.  The binding has a compatible string in the individual
regulator bindings which is broken unless there really are lots of
variants being configured via DT (which is just not the case here).
It's not only more typing in the DT, it also means that we can't read
back the configuration of the device unless the user goes and creates a
DT which explicitly lists each regulator on the device which is
unhelpful.  We should be able to read back the configurations of all the
regulators by simply listing the device in DT.

The fact that this is different to the bindings for other regulator
drivers and requires more code ought to have been a big warning sign
here :(

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-29 18:38             ` Mark Brown
@ 2015-09-29 18:58                 ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 18:58 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/29/2015 01:38 PM, Mark Brown wrote:
> On Tue, Sep 29, 2015 at 01:08:50PM -0500, Andrew F. Davis wrote:
>> On 09/29/2015 10:13 AM, Mark Brown wrote:
>
>>>> sure that will save me anything as my probe function is called with a DT
>>>> match already, so no searching is needed.
>
>>> You've not understood what that change is replacing, the code I'm
>>> quoting above is exactly that code.  Check out some of the existing
>>> drivers using this API.
>
>> Looking at other drivers that use this API they all call regulator_register
>> in a loop in their probe, once for each possible regulator, in this case
>> letting the API do the DT node search makes sense. My probe on the other-hand
>> is only called when we already have a DT match, therefor searching is not
>> necessary and all I have to do is call of_get_regulator_init_data myself on
>> the already found DT node. No need to add node names to my regulator_desc
>> and make the API re-search for the node.
>
> Oh, ick.  The binding has a compatible string in the individual
> regulator bindings which is broken unless there really are lots of
> variants being configured via DT (which is just not the case here).
> It's not only more typing in the DT,

I don't see this, the alternative is matching to this "regulator-compatible",
why not just use the existing compatible.

> it also means that we can't read
> back the configuration of the device unless the user goes and creates a
> DT which explicitly lists each regulator on the device which is
> unhelpful.  We should be able to read back the configurations of all the
> regulators by simply listing the device in DT.
>

Could you expand this? I'm not sure I understand why we still cant do this
using this new way.

Bindings should have compatible strings when they describe hardware like this,
we can then do stuff like put the LDO and DCDC drivers in separate modules for
instance, letting DT only load what we need. There are other benefits like
not having to search our own DT binding for data, and we only get probed for
devices in the DT.

This also eliminates the need for MFD_CORE, we just call
of_platform_populate on ourself and DT helpers do the rest. Why hard code
mfd_cell's and do matching when DT does the same thing.

> The fact that this is different to the bindings for other regulator
> drivers and requires more code ought to have been a big warning sign
> here :(
>

The binding is the same as the new tps65218 driver, different isn't always
a warning sign. And what do you mean "requires more code"? This regulator
driver is smaller than almost any other. DT takes care of everything for
us relating to hardware instantiation like it should.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-09-29 18:58                 ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-29 18:58 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/29/2015 01:38 PM, Mark Brown wrote:
> On Tue, Sep 29, 2015 at 01:08:50PM -0500, Andrew F. Davis wrote:
>> On 09/29/2015 10:13 AM, Mark Brown wrote:
>
>>>> sure that will save me anything as my probe function is called with a DT
>>>> match already, so no searching is needed.
>
>>> You've not understood what that change is replacing, the code I'm
>>> quoting above is exactly that code.  Check out some of the existing
>>> drivers using this API.
>
>> Looking at other drivers that use this API they all call regulator_register
>> in a loop in their probe, once for each possible regulator, in this case
>> letting the API do the DT node search makes sense. My probe on the other-hand
>> is only called when we already have a DT match, therefor searching is not
>> necessary and all I have to do is call of_get_regulator_init_data myself on
>> the already found DT node. No need to add node names to my regulator_desc
>> and make the API re-search for the node.
>
> Oh, ick.  The binding has a compatible string in the individual
> regulator bindings which is broken unless there really are lots of
> variants being configured via DT (which is just not the case here).
> It's not only more typing in the DT,

I don't see this, the alternative is matching to this "regulator-compatible",
why not just use the existing compatible.

> it also means that we can't read
> back the configuration of the device unless the user goes and creates a
> DT which explicitly lists each regulator on the device which is
> unhelpful.  We should be able to read back the configurations of all the
> regulators by simply listing the device in DT.
>

Could you expand this? I'm not sure I understand why we still cant do this
using this new way.

Bindings should have compatible strings when they describe hardware like this,
we can then do stuff like put the LDO and DCDC drivers in separate modules for
instance, letting DT only load what we need. There are other benefits like
not having to search our own DT binding for data, and we only get probed for
devices in the DT.

This also eliminates the need for MFD_CORE, we just call
of_platform_populate on ourself and DT helpers do the rest. Why hard code
mfd_cell's and do matching when DT does the same thing.

> The fact that this is different to the bindings for other regulator
> drivers and requires more code ought to have been a big warning sign
> here :(
>

The binding is the same as the new tps65218 driver, different isn't always
a warning sign. And what do you mean "requires more code"? This regulator
driver is smaller than almost any other. DT takes care of everything for
us relating to hardware instantiation like it should.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-29 18:58                 ` Andrew F. Davis
  (?)
@ 2015-09-30 17:28                 ` Mark Brown
  2015-09-30 20:29                     ` Andrew F. Davis
  -1 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2015-09-30 17:28 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2695 bytes --]

On Tue, Sep 29, 2015 at 01:58:41PM -0500, Andrew F. Davis wrote:
> On 09/29/2015 01:38 PM, Mark Brown wrote:

> >Oh, ick.  The binding has a compatible string in the individual
> >regulator bindings which is broken unless there really are lots of
> >variants being configured via DT (which is just not the case here).
> >It's not only more typing in the DT,

> I don't see this, the alternative is matching to this "regulator-compatible",
> why not just use the existing compatible.

No, you don't need to use regulator-compatible - that's deprecated.
Just use the node names.

> >it also means that we can't read
> >back the configuration of the device unless the user goes and creates a
> >DT which explicitly lists each regulator on the device which is
> >unhelpful.  We should be able to read back the configurations of all the
> >regulators by simply listing the device in DT.

> Could you expand this? I'm not sure I understand why we still cant do this
> using this new way.

I'm not sure what there is to add...  if the regulator is only
instantiated when it features in the device tree then obviously it must
be included in the device to be instantiated.

> Bindings should have compatible strings when they describe hardware like this,
> we can then do stuff like put the LDO and DCDC drivers in separate modules for
> instance, letting DT only load what we need. There are other benefits like
> not having to search our own DT binding for data, and we only get probed for
> devices in the DT.

Only getting probed for device is in DT is exactly the problem here, and
nothing prevents us having separate modules for things without
enumerating everything in DT.

> This also eliminates the need for MFD_CORE, we just call
> of_platform_populate on ourself and DT helpers do the rest. Why hard code
> mfd_cell's and do matching when DT does the same thing.

Putting everything in DT means more work for people integrating the
device and means that we have to have a full and complete understanding
of the device at the time we write the DT, including decions about how
we split the functionality of the device between subsystems.

> >The fact that this is different to the bindings for other regulator
> >drivers and requires more code ought to have been a big warning sign
> >here :(

> The binding is the same as the new tps65218 driver, different isn't always
> a warning sign. And what do you mean "requires more code"? This regulator
> driver is smaller than almost any other. DT takes care of everything for
> us relating to hardware instantiation like it should.

That's not a new driver, it's from more than a year ago (before or about
the same time the helpers got added IIRC).

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-30 17:28                 ` Mark Brown
@ 2015-09-30 20:29                     ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-30 20:29 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/30/2015 12:28 PM, Mark Brown wrote:
> On Tue, Sep 29, 2015 at 01:58:41PM -0500, Andrew F. Davis wrote:
>> On 09/29/2015 01:38 PM, Mark Brown wrote:
>
>>> Oh, ick.  The binding has a compatible string in the individual
>>> regulator bindings which is broken unless there really are lots of
>>> variants being configured via DT (which is just not the case here).
>>> It's not only more typing in the DT,
>
>> I don't see this, the alternative is matching to this "regulator-compatible",
>> why not just use the existing compatible.
>
> No, you don't need to use regulator-compatible - that's deprecated.
> Just use the node names.
>

Are we sure matching on node names is a good idea? Most are just arbitrary
names meant to be human readable and reference-able, giving them function
may lead to confusion. This seems to be why we have "compatible", for specific
identification of node function. But I'm new so maybe I'm wrong?

>>> it also means that we can't read
>>> back the configuration of the device unless the user goes and creates a
>>> DT which explicitly lists each regulator on the device which is
>>> unhelpful.  We should be able to read back the configurations of all the
>>> regulators by simply listing the device in DT.
>
>> Could you expand this? I'm not sure I understand why we still cant do this
>> using this new way.
>
> I'm not sure what there is to add...  if the regulator is only
> instantiated when it features in the device tree then obviously it must
> be included in the device to be instantiated.
>

This is already the case then, missing regulator nodes in old drivers will not
get instantiated ether. And old drivers don't always store any more info about
available regulators than mine does.

>> Bindings should have compatible strings when they describe hardware like this,
>> we can then do stuff like put the LDO and DCDC drivers in separate modules for
>> instance, letting DT only load what we need. There are other benefits like
>> not having to search our own DT binding for data, and we only get probed for
>> devices in the DT.
>
> Only getting probed for device is in DT is exactly the problem here, and
> nothing prevents us having separate modules for things without
> enumerating everything in DT.
>

Sure, but then we have to do some fiddling with MFD_CORE to do that work,
why not remove the dependency and let DT do that for DT only drivers?

>> This also eliminates the need for MFD_CORE, we just call
>> of_platform_populate on ourself and DT helpers do the rest. Why hard code
>> mfd_cell's and do matching when DT does the same thing.
>
> Putting everything in DT means more work for people integrating the
> device and means that we have to have a full and complete understanding
> of the device at the time we write the DT, including decions about how
> we split the functionality of the device between subsystems.
>

We are not adding anything extra to the DT node, we just use the "compatible"
string to identify and match the node vs. "regulator-name", or the nodes name,
or whatever else has been used. The node is then just filled with the standard
optional properties just like every other driver's node.

>>> The fact that this is different to the bindings for other regulator
>>> drivers and requires more code ought to have been a big warning sign
>>> here :(
>
>> The binding is the same as the new tps65218 driver, different isn't always
>> a warning sign. And what do you mean "requires more code"? This regulator
>> driver is smaller than almost any other. DT takes care of everything for
>> us relating to hardware instantiation like it should.
>
> That's not a new driver, it's from more than a year ago (before or about
> the same time the helpers got added IIRC).
>

Newer than a lot, I chose to base my driver off of that not just because
it is a similar TI part, but because it was the cleanest, simplest looking
one IMHO. The helpers would require more code (you need to know how many
regulators you have and call the helpers in a loop).

I have another PMIC I'm about to push a driver for when this gets figured out
that does the same thing, and it's more important I think to do it this way for
this new part. Some of the new regulators are designed without a dedicated
SOC or board to power in mind, so they will have a whole bunch for different
regulator types on one chip and it will be up to the designer to pick which ones
to turn on and use. With this DT approach you can just list the ones you want,
and we may even be able to split different types into different modules, then
we can use the same regulator driver in different spins of the PMIC with more
or less of that type of regulator, we just add that same node under a different
parent PMIC driver.

I could use the helper with this style and save a couple lines of code if we
could make regulator_of_get_init_data to also match on "compatible", it
currently only matches on "regulator-compatible" or the node name. I could make
this addition and send the patch if you would like to see what I have in mind.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-09-30 20:29                     ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-30 20:29 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/30/2015 12:28 PM, Mark Brown wrote:
> On Tue, Sep 29, 2015 at 01:58:41PM -0500, Andrew F. Davis wrote:
>> On 09/29/2015 01:38 PM, Mark Brown wrote:
>
>>> Oh, ick.  The binding has a compatible string in the individual
>>> regulator bindings which is broken unless there really are lots of
>>> variants being configured via DT (which is just not the case here).
>>> It's not only more typing in the DT,
>
>> I don't see this, the alternative is matching to this "regulator-compatible",
>> why not just use the existing compatible.
>
> No, you don't need to use regulator-compatible - that's deprecated.
> Just use the node names.
>

Are we sure matching on node names is a good idea? Most are just arbitrary
names meant to be human readable and reference-able, giving them function
may lead to confusion. This seems to be why we have "compatible", for specific
identification of node function. But I'm new so maybe I'm wrong?

>>> it also means that we can't read
>>> back the configuration of the device unless the user goes and creates a
>>> DT which explicitly lists each regulator on the device which is
>>> unhelpful.  We should be able to read back the configurations of all the
>>> regulators by simply listing the device in DT.
>
>> Could you expand this? I'm not sure I understand why we still cant do this
>> using this new way.
>
> I'm not sure what there is to add...  if the regulator is only
> instantiated when it features in the device tree then obviously it must
> be included in the device to be instantiated.
>

This is already the case then, missing regulator nodes in old drivers will not
get instantiated ether. And old drivers don't always store any more info about
available regulators than mine does.

>> Bindings should have compatible strings when they describe hardware like this,
>> we can then do stuff like put the LDO and DCDC drivers in separate modules for
>> instance, letting DT only load what we need. There are other benefits like
>> not having to search our own DT binding for data, and we only get probed for
>> devices in the DT.
>
> Only getting probed for device is in DT is exactly the problem here, and
> nothing prevents us having separate modules for things without
> enumerating everything in DT.
>

Sure, but then we have to do some fiddling with MFD_CORE to do that work,
why not remove the dependency and let DT do that for DT only drivers?

>> This also eliminates the need for MFD_CORE, we just call
>> of_platform_populate on ourself and DT helpers do the rest. Why hard code
>> mfd_cell's and do matching when DT does the same thing.
>
> Putting everything in DT means more work for people integrating the
> device and means that we have to have a full and complete understanding
> of the device at the time we write the DT, including decions about how
> we split the functionality of the device between subsystems.
>

We are not adding anything extra to the DT node, we just use the "compatible"
string to identify and match the node vs. "regulator-name", or the nodes name,
or whatever else has been used. The node is then just filled with the standard
optional properties just like every other driver's node.

>>> The fact that this is different to the bindings for other regulator
>>> drivers and requires more code ought to have been a big warning sign
>>> here :(
>
>> The binding is the same as the new tps65218 driver, different isn't always
>> a warning sign. And what do you mean "requires more code"? This regulator
>> driver is smaller than almost any other. DT takes care of everything for
>> us relating to hardware instantiation like it should.
>
> That's not a new driver, it's from more than a year ago (before or about
> the same time the helpers got added IIRC).
>

Newer than a lot, I chose to base my driver off of that not just because
it is a similar TI part, but because it was the cleanest, simplest looking
one IMHO. The helpers would require more code (you need to know how many
regulators you have and call the helpers in a loop).

I have another PMIC I'm about to push a driver for when this gets figured out
that does the same thing, and it's more important I think to do it this way for
this new part. Some of the new regulators are designed without a dedicated
SOC or board to power in mind, so they will have a whole bunch for different
regulator types on one chip and it will be up to the designer to pick which ones
to turn on and use. With this DT approach you can just list the ones you want,
and we may even be able to split different types into different modules, then
we can use the same regulator driver in different spins of the PMIC with more
or less of that type of regulator, we just add that same node under a different
parent PMIC driver.

I could use the helper with this style and save a couple lines of code if we
could make regulator_of_get_init_data to also match on "compatible", it
currently only matches on "regulator-compatible" or the node name. I could make
this addition and send the patch if you would like to see what I have in mind.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-30 20:29                     ` Andrew F. Davis
  (?)
@ 2015-09-30 22:20                     ` Mark Brown
  2015-09-30 23:32                         ` Andrew F. Davis
  -1 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2015-09-30 22:20 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3970 bytes --]

On Wed, Sep 30, 2015 at 03:29:30PM -0500, Andrew F. Davis wrote:
> On 09/30/2015 12:28 PM, Mark Brown wrote:

> >No, you don't need to use regulator-compatible - that's deprecated.
> >Just use the node names.

> Are we sure matching on node names is a good idea? Most are just arbitrary
> names meant to be human readable and reference-able, giving them function
> may lead to confusion. This seems to be why we have "compatible", for specific
> identification of node function. But I'm new so maybe I'm wrong?

Yes, I'm sure.  The regulators are just properties on the device, they
are not devices themselves.

> >I'm not sure what there is to add...  if the regulator is only
> >instantiated when it features in the device tree then obviously it must
> >be included in the device to be instantiated.

> This is already the case then, missing regulator nodes in old drivers will not
> get instantiated ether. And old drivers don't always store any more info about
> available regulators than mine does.

No, well implemented older drivers will still unconditionally register
everything.

> >Only getting probed for device is in DT is exactly the problem here, and
> >nothing prevents us having separate modules for things without
> >enumerating everything in DT.

> Sure, but then we have to do some fiddling with MFD_CORE to do that work,
> why not remove the dependency and let DT do that for DT only drivers?

For the reasons I've outlined repeatedly.

> >Putting everything in DT means more work for people integrating the
> >device and means that we have to have a full and complete understanding
> >of the device at the time we write the DT, including decions about how
> >we split the functionality of the device between subsystems.

> We are not adding anything extra to the DT node, we just use the "compatible"
> string to identify and match the node vs. "regulator-name", or the nodes name,
> or whatever else has been used. The node is then just filled with the standard
> optional properties just like every other driver's node.

No, you are missing the point.  The point is that only regulators
explicitly listed in the DT will be instantiated.

> Newer than a lot, I chose to base my driver off of that not just because
> it is a similar TI part, but because it was the cleanest, simplest looking
> one IMHO. The helpers would require more code (you need to know how many
> regulators you have and call the helpers in a loop).

You're talking about a trivial loop that takes perhaps a couple of lines
to open and close the for loop and another line to declare an iterator
variable.

Look, please stop arguing about this.  There appears to be nothing
special about this device that makes it different to other devices.

> I have another PMIC I'm about to push a driver for when this gets figured out
> that does the same thing, and it's more important I think to do it this way for
> this new part. Some of the new regulators are designed without a dedicated
> SOC or board to power in mind, so they will have a whole bunch for different
> regulator types on one chip and it will be up to the designer to pick which ones
> to turn on and use. With this DT approach you can just list the ones you want,
> and we may even be able to split different types into different modules, then
> we can use the same regulator driver in different spins of the PMIC with more
> or less of that type of regulator, we just add that same node under a different
> parent PMIC driver.

This sounds exactly the same as the majority of PMIC drivers, there is
nothing remarkable here.

> I could use the helper with this style and save a couple lines of code if we
> could make regulator_of_get_init_data to also match on "compatible", it
> currently only matches on "regulator-compatible" or the node name. I could make
> this addition and send the patch if you would like to see what I have in mind.

No, this would be broken - devices are instantiated via the driver
model.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-30 22:20                     ` Mark Brown
@ 2015-09-30 23:32                         ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-30 23:32 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/30/2015 05:20 PM, Mark Brown wrote:
> On Wed, Sep 30, 2015 at 03:29:30PM -0500, Andrew F. Davis wrote:
>> On 09/30/2015 12:28 PM, Mark Brown wrote:
>
>>> No, you don't need to use regulator-compatible - that's deprecated.
>>> Just use the node names.
>
>> Are we sure matching on node names is a good idea? Most are just arbitrary
>> names meant to be human readable and reference-able, giving them function
>> may lead to confusion. This seems to be why we have "compatible", for specific
>> identification of node function. But I'm new so maybe I'm wrong?
>
> Yes, I'm sure.  The regulators are just properties on the device, they
> are not devices themselves.
>

OK

>>> I'm not sure what there is to add...  if the regulator is only
>>> instantiated when it features in the device tree then obviously it must
>>> be included in the device to be instantiated.
>
>> This is already the case then, missing regulator nodes in old drivers will not
>> get instantiated ether. And old drivers don't always store any more info about
>> available regulators than mine does.
>
> No, well implemented older drivers will still unconditionally register
> everything.
>

Is this desired? If they are not in the DT could this be used to signal
we don't want to register this regulator?

>>> Only getting probed for device is in DT is exactly the problem here, and
>>> nothing prevents us having separate modules for things without
>>> enumerating everything in DT.
>
>> Sure, but then we have to do some fiddling with MFD_CORE to do that work,
>> why not remove the dependency and let DT do that for DT only drivers?
>
> For the reasons I've outlined repeatedly.
>
>>> Putting everything in DT means more work for people integrating the
>>> device and means that we have to have a full and complete understanding
>>> of the device at the time we write the DT, including decions about how
>>> we split the functionality of the device between subsystems.
>
>> We are not adding anything extra to the DT node, we just use the "compatible"
>> string to identify and match the node vs. "regulator-name", or the nodes name,
>> or whatever else has been used. The node is then just filled with the standard
>> optional properties just like every other driver's node.
>
> No, you are missing the point.  The point is that only regulators
> explicitly listed in the DT will be instantiated.
>

Same questions as above. ^^^

>> Newer than a lot, I chose to base my driver off of that not just because
>> it is a similar TI part, but because it was the cleanest, simplest looking
>> one IMHO. The helpers would require more code (you need to know how many
>> regulators you have and call the helpers in a loop).
>
> You're talking about a trivial loop that takes perhaps a couple of lines
> to open and close the for loop and another line to declare an iterator
> variable.
>

Adding any extra code and complexity to use a helper that does something
that already works with less doesn't make much sense to me, but if that's
the API you want I'll use it.

> Look, please stop arguing about this.  There appears to be nothing
> special about this device that makes it different to other devices.
>

I'm sorry if I sounded overly argumentative about this, I'm just trying to make
points in favor of me not having to re-write my driver.

The new framework helpers do not help my driver as it does things differently.
You signed off on this different way of doing things just last year with the
TPS65218.

If you no longer want it done this way then I'll go and change my driver.

>> I have another PMIC I'm about to push a driver for when this gets figured out
>> that does the same thing, and it's more important I think to do it this way for
>> this new part. Some of the new regulators are designed without a dedicated
>> SOC or board to power in mind, so they will have a whole bunch for different
>> regulator types on one chip and it will be up to the designer to pick which ones
>> to turn on and use. With this DT approach you can just list the ones you want,
>> and we may even be able to split different types into different modules, then
>> we can use the same regulator driver in different spins of the PMIC with more
>> or less of that type of regulator, we just add that same node under a different
>> parent PMIC driver.
>
> This sounds exactly the same as the majority of PMIC drivers, there is
> nothing remarkable here.
>

Nothing meant to be remarkable, I was pointing out uses.

>> I could use the helper with this style and save a couple lines of code if we
>> could make regulator_of_get_init_data to also match on "compatible", it
>> currently only matches on "regulator-compatible" or the node name. I could make
>> this addition and send the patch if you would like to see what I have in mind.
>
> No, this would be broken - devices are instantiated via the driver
> model.
>

OK

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-09-30 23:32                         ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-09-30 23:32 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 09/30/2015 05:20 PM, Mark Brown wrote:
> On Wed, Sep 30, 2015 at 03:29:30PM -0500, Andrew F. Davis wrote:
>> On 09/30/2015 12:28 PM, Mark Brown wrote:
>
>>> No, you don't need to use regulator-compatible - that's deprecated.
>>> Just use the node names.
>
>> Are we sure matching on node names is a good idea? Most are just arbitrary
>> names meant to be human readable and reference-able, giving them function
>> may lead to confusion. This seems to be why we have "compatible", for specific
>> identification of node function. But I'm new so maybe I'm wrong?
>
> Yes, I'm sure.  The regulators are just properties on the device, they
> are not devices themselves.
>

OK

>>> I'm not sure what there is to add...  if the regulator is only
>>> instantiated when it features in the device tree then obviously it must
>>> be included in the device to be instantiated.
>
>> This is already the case then, missing regulator nodes in old drivers will not
>> get instantiated ether. And old drivers don't always store any more info about
>> available regulators than mine does.
>
> No, well implemented older drivers will still unconditionally register
> everything.
>

Is this desired? If they are not in the DT could this be used to signal
we don't want to register this regulator?

>>> Only getting probed for device is in DT is exactly the problem here, and
>>> nothing prevents us having separate modules for things without
>>> enumerating everything in DT.
>
>> Sure, but then we have to do some fiddling with MFD_CORE to do that work,
>> why not remove the dependency and let DT do that for DT only drivers?
>
> For the reasons I've outlined repeatedly.
>
>>> Putting everything in DT means more work for people integrating the
>>> device and means that we have to have a full and complete understanding
>>> of the device at the time we write the DT, including decions about how
>>> we split the functionality of the device between subsystems.
>
>> We are not adding anything extra to the DT node, we just use the "compatible"
>> string to identify and match the node vs. "regulator-name", or the nodes name,
>> or whatever else has been used. The node is then just filled with the standard
>> optional properties just like every other driver's node.
>
> No, you are missing the point.  The point is that only regulators
> explicitly listed in the DT will be instantiated.
>

Same questions as above. ^^^

>> Newer than a lot, I chose to base my driver off of that not just because
>> it is a similar TI part, but because it was the cleanest, simplest looking
>> one IMHO. The helpers would require more code (you need to know how many
>> regulators you have and call the helpers in a loop).
>
> You're talking about a trivial loop that takes perhaps a couple of lines
> to open and close the for loop and another line to declare an iterator
> variable.
>

Adding any extra code and complexity to use a helper that does something
that already works with less doesn't make much sense to me, but if that's
the API you want I'll use it.

> Look, please stop arguing about this.  There appears to be nothing
> special about this device that makes it different to other devices.
>

I'm sorry if I sounded overly argumentative about this, I'm just trying to make
points in favor of me not having to re-write my driver.

The new framework helpers do not help my driver as it does things differently.
You signed off on this different way of doing things just last year with the
TPS65218.

If you no longer want it done this way then I'll go and change my driver.

>> I have another PMIC I'm about to push a driver for when this gets figured out
>> that does the same thing, and it's more important I think to do it this way for
>> this new part. Some of the new regulators are designed without a dedicated
>> SOC or board to power in mind, so they will have a whole bunch for different
>> regulator types on one chip and it will be up to the designer to pick which ones
>> to turn on and use. With this DT approach you can just list the ones you want,
>> and we may even be able to split different types into different modules, then
>> we can use the same regulator driver in different spins of the PMIC with more
>> or less of that type of regulator, we just add that same node under a different
>> parent PMIC driver.
>
> This sounds exactly the same as the majority of PMIC drivers, there is
> nothing remarkable here.
>

Nothing meant to be remarkable, I was pointing out uses.

>> I could use the helper with this style and save a couple lines of code if we
>> could make regulator_of_get_init_data to also match on "compatible", it
>> currently only matches on "regulator-compatible" or the node name. I could make
>> this addition and send the patch if you would like to see what I have in mind.
>
> No, this would be broken - devices are instantiated via the driver
> model.
>

OK

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-30 23:32                         ` Andrew F. Davis
  (?)
@ 2015-10-01 10:53                         ` Mark Brown
  -1 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2015-10-01 10:53 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2009 bytes --]

On Wed, Sep 30, 2015 at 06:32:14PM -0500, Andrew F. Davis wrote:
> On 09/30/2015 05:20 PM, Mark Brown wrote:

> >>This is already the case then, missing regulator nodes in old drivers will not
> >>get instantiated ether. And old drivers don't always store any more info about
> >>available regulators than mine does.

> >No, well implemented older drivers will still unconditionally register
> >everything.

> Is this desired? If they are not in the DT could this be used to signal
> we don't want to register this regulator?

Yes, this is desired.  The point is that there is no situation in which
we do not want to register all the regulators physically present on the
device.

> >You're talking about a trivial loop that takes perhaps a couple of lines
> >to open and close the for loop and another line to declare an iterator
> >variable.

> Adding any extra code and complexity to use a helper that does something
> that already works with less doesn't make much sense to me, but if that's
> the API you want I'll use it.

It would take a lot less effort to implement the requested changes
rather than go on and on about this.  There is no meaningful complexity
here, we're talking about removing code and moving some data tables from
DT (where they are an ABI) to code (where they are not an ABI).

> >Look, please stop arguing about this.  There appears to be nothing
> >special about this device that makes it different to other devices.

> I'm sorry if I sounded overly argumentative about this, I'm just trying to make
> points in favor of me not having to re-write my driver.

It's hardly a rewrite.

> The new framework helpers do not help my driver as it does things differently.
> You signed off on this different way of doing things just last year with the
> TPS65218.

> If you no longer want it done this way then I'll go and change my driver.

It should already be apparent that this is not a desired configuration,
old drivers are never a good reason not to do the right thing on new
code.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-09-30 20:29                     ` Andrew F. Davis
@ 2015-10-01 15:33                       ` Grygorii Strashko
  -1 siblings, 0 replies; 56+ messages in thread
From: Grygorii Strashko @ 2015-10-01 15:33 UTC (permalink / raw)
  To: Andrew F. Davis, Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

Hi Andrew,
 
On 09/30/2015 03:29 PM, Andrew F. Davis wrote:
> On 09/30/2015 12:28 PM, Mark Brown wrote:
>> On Tue, Sep 29, 2015 at 01:58:41PM -0500, Andrew F. Davis wrote:
>>> On 09/29/2015 01:38 PM, Mark Brown wrote:
>>
>>>> Oh, ick.  The binding has a compatible string in the individual
>>>> regulator bindings which is broken unless there really are lots of
>>>> variants being configured via DT (which is just not the case here).
>>>> It's not only more typing in the DT,
>>
>>> I don't see this, the alternative is matching to this 
>>> "regulator-compatible",
>>> why not just use the existing compatible.
>>
>> No, you don't need to use regulator-compatible - that's deprecated.
>> Just use the node names.
>>
> 
> Are we sure matching on node names is a good idea? Most are just arbitrary
> names meant to be human readable and reference-able, giving them function
> may lead to confusion. This seems to be why we have "compatible", for 
> specific
> identification of node function. But I'm new so maybe I'm wrong?
> 
>>>> it also means that we can't read
>>>> back the configuration of the device unless the user goes and creates a
>>>> DT which explicitly lists each regulator on the device which is
>>>> unhelpful.  We should be able to read back the configurations of all 
>>>> the
>>>> regulators by simply listing the device in DT.
>>
>>> Could you expand this? I'm not sure I understand why we still cant do 
>>> this
>>> using this new way.
>>
>> I'm not sure what there is to add...  if the regulator is only
>> instantiated when it features in the device tree then obviously it must
>> be included in the device to be instantiated.
>>
> 
> This is already the case then, missing regulator nodes in old drivers 
> will not
> get instantiated ether. And old drivers don't always store any more info 
> about
> available regulators than mine does.
> 
>>> Bindings should have compatible strings when they describe hardware 
>>> like this,
>>> we can then do stuff like put the LDO and DCDC drivers in separate 
>>> modules for
>>> instance, letting DT only load what we need. There are other benefits 
>>> like
>>> not having to search our own DT binding for data, and we only get 
>>> probed for
>>> devices in the DT.
>>
>> Only getting probed for device is in DT is exactly the problem here, and
>> nothing prevents us having separate modules for things without
>> enumerating everything in DT.
>>
> 
> Sure, but then we have to do some fiddling with MFD_CORE to do that work,
> why not remove the dependency and let DT do that for DT only drivers?
> 
>>> This also eliminates the need for MFD_CORE, we just call
>>> of_platform_populate on ourself and DT helpers do the rest. Why hard 
>>> code
>>> mfd_cell's and do matching when DT does the same thing.
>>
>> Putting everything in DT means more work for people integrating the
>> device and means that we have to have a full and complete understanding
>> of the device at the time we write the DT, including decions about how
>> we split the functionality of the device between subsystems.
>>
> 
> We are not adding anything extra to the DT node, we just use the 
> "compatible"
> string to identify and match the node vs. "regulator-name", or the nodes 
> name,
> or whatever else has been used. The node is then just filled with the 
> standard
> optional properties just like every other driver's node.
> 
>>>> The fact that this is different to the bindings for other regulator
>>>> drivers and requires more code ought to have been a big warning sign
>>>> here :(
>>
>>> The binding is the same as the new tps65218 driver, different isn't 
>>> always
>>> a warning sign. And what do you mean "requires more code"? This 
>>> regulator
>>> driver is smaller than almost any other. DT takes care of everything for
>>> us relating to hardware instantiation like it should.
>>
>> That's not a new driver, it's from more than a year ago (before or about
>> the same time the helpers got added IIRC).
>>
> 
> Newer than a lot, I chose to base my driver off of that not just because
> it is a similar TI part, but because it was the cleanest, simplest looking
> one IMHO. The helpers would require more code (you need to know how many
> regulators you have and call the helpers in a loop).
> 
> I have another PMIC I'm about to push a driver for when this gets 
> figured out
> that does the same thing, and it's more important I think to do it this 
> way for
> this new part. Some of the new regulators are designed without a dedicated
> SOC or board to power in mind, so they will have a whole bunch for 
> different
> regulator types on one chip and it will be up to the designer to pick 
> which ones
> to turn on and use. With this DT approach you can just list the ones you 
> want,
> and we may even be able to split different types into different modules, 
> then
> we can use the same regulator driver in different spins of the PMIC with 
> more
> or less of that type of regulator, we just add that same node under a 
> different
> parent PMIC driver.
> 

That's all make sense only if you have all information required for driver probing in DT.
But you don't, because  a lot of information are still hard-coded in driver:
- regulator IDs,
- registers required to control regulator
- ranges information and etc.

So, you will not be be able to easily separate some regulator and reuse it with another PMIC.

Actually, both approaches have right to live and which one to select depends on 
functionality which has to be implemented by regulator driver. 
For example, with this (your) approach the separate platform device will be created 
for each regulator, so, if needed, corresponding driver's callback (.remove/shutdown and
dev_pm_ops)  can be implemented individually for each regulator. Do you need this?
As for me, such approach is reasonable if you have devices which represents one/two regulators max.

The disadvantage of this approach is that you need separate compatible string fore each regulator
- and this, actually, is usually banned by DT maintainers ;)

For devices, like this one (or twl, or plamas) which has dozens of regulators it simply make no sense :)
Just imaging that tomorrow tps65912-1 will be released and it will be fully compatible with  tps65912, but
with one exception - it will have dcdc5 and all followed registers offsets will be shifted.
What will you do? All this code, based on compatible strings, will not work any more.
And you will need to introduce another bunch of compatible strings.. 

By the way, this implementation is not optimal any way :)
- you are using compatible string to get tps65912_pmic_regs structure
- then tps65912_pmic_regs is used to get regulator ID
- and then, finally, regulator ID is used to get regulator_desc structure   

And, finally, pay attention pls, that regulator_of_get_init_data() is called from
from regulator_register().

So, in my opinion, the tps65217-regulator.c driver is really good example of how it could be done.



-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-10-01 15:33                       ` Grygorii Strashko
  0 siblings, 0 replies; 56+ messages in thread
From: Grygorii Strashko @ 2015-10-01 15:33 UTC (permalink / raw)
  To: Andrew F. Davis, Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

Hi Andrew,
 
On 09/30/2015 03:29 PM, Andrew F. Davis wrote:
> On 09/30/2015 12:28 PM, Mark Brown wrote:
>> On Tue, Sep 29, 2015 at 01:58:41PM -0500, Andrew F. Davis wrote:
>>> On 09/29/2015 01:38 PM, Mark Brown wrote:
>>
>>>> Oh, ick.  The binding has a compatible string in the individual
>>>> regulator bindings which is broken unless there really are lots of
>>>> variants being configured via DT (which is just not the case here).
>>>> It's not only more typing in the DT,
>>
>>> I don't see this, the alternative is matching to this 
>>> "regulator-compatible",
>>> why not just use the existing compatible.
>>
>> No, you don't need to use regulator-compatible - that's deprecated.
>> Just use the node names.
>>
> 
> Are we sure matching on node names is a good idea? Most are just arbitrary
> names meant to be human readable and reference-able, giving them function
> may lead to confusion. This seems to be why we have "compatible", for 
> specific
> identification of node function. But I'm new so maybe I'm wrong?
> 
>>>> it also means that we can't read
>>>> back the configuration of the device unless the user goes and creates a
>>>> DT which explicitly lists each regulator on the device which is
>>>> unhelpful.  We should be able to read back the configurations of all 
>>>> the
>>>> regulators by simply listing the device in DT.
>>
>>> Could you expand this? I'm not sure I understand why we still cant do 
>>> this
>>> using this new way.
>>
>> I'm not sure what there is to add...  if the regulator is only
>> instantiated when it features in the device tree then obviously it must
>> be included in the device to be instantiated.
>>
> 
> This is already the case then, missing regulator nodes in old drivers 
> will not
> get instantiated ether. And old drivers don't always store any more info 
> about
> available regulators than mine does.
> 
>>> Bindings should have compatible strings when they describe hardware 
>>> like this,
>>> we can then do stuff like put the LDO and DCDC drivers in separate 
>>> modules for
>>> instance, letting DT only load what we need. There are other benefits 
>>> like
>>> not having to search our own DT binding for data, and we only get 
>>> probed for
>>> devices in the DT.
>>
>> Only getting probed for device is in DT is exactly the problem here, and
>> nothing prevents us having separate modules for things without
>> enumerating everything in DT.
>>
> 
> Sure, but then we have to do some fiddling with MFD_CORE to do that work,
> why not remove the dependency and let DT do that for DT only drivers?
> 
>>> This also eliminates the need for MFD_CORE, we just call
>>> of_platform_populate on ourself and DT helpers do the rest. Why hard 
>>> code
>>> mfd_cell's and do matching when DT does the same thing.
>>
>> Putting everything in DT means more work for people integrating the
>> device and means that we have to have a full and complete understanding
>> of the device at the time we write the DT, including decions about how
>> we split the functionality of the device between subsystems.
>>
> 
> We are not adding anything extra to the DT node, we just use the 
> "compatible"
> string to identify and match the node vs. "regulator-name", or the nodes 
> name,
> or whatever else has been used. The node is then just filled with the 
> standard
> optional properties just like every other driver's node.
> 
>>>> The fact that this is different to the bindings for other regulator
>>>> drivers and requires more code ought to have been a big warning sign
>>>> here :(
>>
>>> The binding is the same as the new tps65218 driver, different isn't 
>>> always
>>> a warning sign. And what do you mean "requires more code"? This 
>>> regulator
>>> driver is smaller than almost any other. DT takes care of everything for
>>> us relating to hardware instantiation like it should.
>>
>> That's not a new driver, it's from more than a year ago (before or about
>> the same time the helpers got added IIRC).
>>
> 
> Newer than a lot, I chose to base my driver off of that not just because
> it is a similar TI part, but because it was the cleanest, simplest looking
> one IMHO. The helpers would require more code (you need to know how many
> regulators you have and call the helpers in a loop).
> 
> I have another PMIC I'm about to push a driver for when this gets 
> figured out
> that does the same thing, and it's more important I think to do it this 
> way for
> this new part. Some of the new regulators are designed without a dedicated
> SOC or board to power in mind, so they will have a whole bunch for 
> different
> regulator types on one chip and it will be up to the designer to pick 
> which ones
> to turn on and use. With this DT approach you can just list the ones you 
> want,
> and we may even be able to split different types into different modules, 
> then
> we can use the same regulator driver in different spins of the PMIC with 
> more
> or less of that type of regulator, we just add that same node under a 
> different
> parent PMIC driver.
> 

That's all make sense only if you have all information required for driver probing in DT.
But you don't, because  a lot of information are still hard-coded in driver:
- regulator IDs,
- registers required to control regulator
- ranges information and etc.

So, you will not be be able to easily separate some regulator and reuse it with another PMIC.

Actually, both approaches have right to live and which one to select depends on 
functionality which has to be implemented by regulator driver. 
For example, with this (your) approach the separate platform device will be created 
for each regulator, so, if needed, corresponding driver's callback (.remove/shutdown and
dev_pm_ops)  can be implemented individually for each regulator. Do you need this?
As for me, such approach is reasonable if you have devices which represents one/two regulators max.

The disadvantage of this approach is that you need separate compatible string fore each regulator
- and this, actually, is usually banned by DT maintainers ;)

For devices, like this one (or twl, or plamas) which has dozens of regulators it simply make no sense :)
Just imaging that tomorrow tps65912-1 will be released and it will be fully compatible with  tps65912, but
with one exception - it will have dcdc5 and all followed registers offsets will be shifted.
What will you do? All this code, based on compatible strings, will not work any more.
And you will need to introduce another bunch of compatible strings.. 

By the way, this implementation is not optimal any way :)
- you are using compatible string to get tps65912_pmic_regs structure
- then tps65912_pmic_regs is used to get regulator ID
- and then, finally, regulator ID is used to get regulator_desc structure   

And, finally, pay attention pls, that regulator_of_get_init_data() is called from
from regulator_register().

So, in my opinion, the tps65217-regulator.c driver is really good example of how it could be done.



-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-10-01 15:33                       ` Grygorii Strashko
@ 2015-10-01 16:08                         ` Andrew F. Davis
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-10-01 16:08 UTC (permalink / raw)
  To: Grygorii Strashko, Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 10/01/2015 10:33 AM, Grygorii Strashko wrote:
> Hi Andrew,
>
> On 09/30/2015 03:29 PM, Andrew F. Davis wrote:
>> On 09/30/2015 12:28 PM, Mark Brown wrote:
>>> On Tue, Sep 29, 2015 at 01:58:41PM -0500, Andrew F. Davis wrote:
>>>> On 09/29/2015 01:38 PM, Mark Brown wrote:
>>>
>>>>> Oh, ick.  The binding has a compatible string in the individual
>>>>> regulator bindings which is broken unless there really are lots of
>>>>> variants being configured via DT (which is just not the case here).
>>>>> It's not only more typing in the DT,
>>>
>>>> I don't see this, the alternative is matching to this
>>>> "regulator-compatible",
>>>> why not just use the existing compatible.
>>>
>>> No, you don't need to use regulator-compatible - that's deprecated.
>>> Just use the node names.
>>>
>>
>> Are we sure matching on node names is a good idea? Most are just arbitrary
>> names meant to be human readable and reference-able, giving them function
>> may lead to confusion. This seems to be why we have "compatible", for
>> specific
>> identification of node function. But I'm new so maybe I'm wrong?
>>
>>>>> it also means that we can't read
>>>>> back the configuration of the device unless the user goes and creates a
>>>>> DT which explicitly lists each regulator on the device which is
>>>>> unhelpful.  We should be able to read back the configurations of all
>>>>> the
>>>>> regulators by simply listing the device in DT.
>>>
>>>> Could you expand this? I'm not sure I understand why we still cant do
>>>> this
>>>> using this new way.
>>>
>>> I'm not sure what there is to add...  if the regulator is only
>>> instantiated when it features in the device tree then obviously it must
>>> be included in the device to be instantiated.
>>>
>>
>> This is already the case then, missing regulator nodes in old drivers
>> will not
>> get instantiated ether. And old drivers don't always store any more info
>> about
>> available regulators than mine does.
>>
>>>> Bindings should have compatible strings when they describe hardware
>>>> like this,
>>>> we can then do stuff like put the LDO and DCDC drivers in separate
>>>> modules for
>>>> instance, letting DT only load what we need. There are other benefits
>>>> like
>>>> not having to search our own DT binding for data, and we only get
>>>> probed for
>>>> devices in the DT.
>>>
>>> Only getting probed for device is in DT is exactly the problem here, and
>>> nothing prevents us having separate modules for things without
>>> enumerating everything in DT.
>>>
>>
>> Sure, but then we have to do some fiddling with MFD_CORE to do that work,
>> why not remove the dependency and let DT do that for DT only drivers?
>>
>>>> This also eliminates the need for MFD_CORE, we just call
>>>> of_platform_populate on ourself and DT helpers do the rest. Why hard
>>>> code
>>>> mfd_cell's and do matching when DT does the same thing.
>>>
>>> Putting everything in DT means more work for people integrating the
>>> device and means that we have to have a full and complete understanding
>>> of the device at the time we write the DT, including decions about how
>>> we split the functionality of the device between subsystems.
>>>
>>
>> We are not adding anything extra to the DT node, we just use the
>> "compatible"
>> string to identify and match the node vs. "regulator-name", or the nodes
>> name,
>> or whatever else has been used. The node is then just filled with the
>> standard
>> optional properties just like every other driver's node.
>>
>>>>> The fact that this is different to the bindings for other regulator
>>>>> drivers and requires more code ought to have been a big warning sign
>>>>> here :(
>>>
>>>> The binding is the same as the new tps65218 driver, different isn't
>>>> always
>>>> a warning sign. And what do you mean "requires more code"? This
>>>> regulator
>>>> driver is smaller than almost any other. DT takes care of everything for
>>>> us relating to hardware instantiation like it should.
>>>
>>> That's not a new driver, it's from more than a year ago (before or about
>>> the same time the helpers got added IIRC).
>>>
>>
>> Newer than a lot, I chose to base my driver off of that not just because
>> it is a similar TI part, but because it was the cleanest, simplest looking
>> one IMHO. The helpers would require more code (you need to know how many
>> regulators you have and call the helpers in a loop).
>>
>> I have another PMIC I'm about to push a driver for when this gets
>> figured out
>> that does the same thing, and it's more important I think to do it this
>> way for
>> this new part. Some of the new regulators are designed without a dedicated
>> SOC or board to power in mind, so they will have a whole bunch for
>> different
>> regulator types on one chip and it will be up to the designer to pick
>> which ones
>> to turn on and use. With this DT approach you can just list the ones you
>> want,
>> and we may even be able to split different types into different modules,
>> then
>> we can use the same regulator driver in different spins of the PMIC with
>> more
>> or less of that type of regulator, we just add that same node under a
>> different
>> parent PMIC driver.
>>
>
> That's all make sense only if you have all information required for driver probing in DT.
> But you don't, because  a lot of information are still hard-coded in driver:
> - regulator IDs,
> - registers required to control regulator
> - ranges information and etc.
>
> So, you will not be be able to easily separate some regulator and reuse it with another PMIC.
>

Unless we encode the needed registers/info into the DT, that info
could be considered a device description if you consider each regulator
to be a separate device burned onto the same silicon, much like we
do with the different IPs on SOCs. It would be nice to have 100% generic
regulator drivers, but the DT maintainers might not go for that :)

> Actually, both approaches have right to live and which one to select depends on
> functionality which has to be implemented by regulator driver.
> For example, with this (your) approach the separate platform device will be created
> for each regulator, so, if needed, corresponding driver's callback (.remove/shutdown and
> dev_pm_ops)  can be implemented individually for each regulator. Do you need this?
> As for me, such approach is reasonable if you have devices which represents one/two regulators max.
>
> The disadvantage of this approach is that you need separate compatible string fore each regulator
> - and this, actually, is usually banned by DT maintainers ;)
>
> For devices, like this one (or twl, or plamas) which has dozens of regulators it simply make no sense :)
> Just imaging that tomorrow tps65912-1 will be released and it will be fully compatible with  tps65912, but
> with one exception - it will have dcdc5 and all followed registers offsets will be shifted.
> What will you do? All this code, based on compatible strings, will not work any more.
> And you will need to introduce another bunch of compatible strings..
>

Agree, unless we go with my above idea! :)

> By the way, this implementation is not optimal any way :)
> - you are using compatible string to get tps65912_pmic_regs structure
> - then tps65912_pmic_regs is used to get regulator ID
> - and then, finally, regulator ID is used to get regulator_desc structure
>

Yeah, I saw that after I posted this, my new version just puts a pointer
to the right regulator_desc struct in the of_device_id.data, then we can
use it directly with no middle man steps, much cleaner.

> And, finally, pay attention pls, that regulator_of_get_init_data() is called from
> from regulator_register().
>

Right, but only if you supply .of_match in your regulator_desc, and even then it
only matches on node name, not "compatible" string, if it did I could use it to
eliminate my call to of_get_regulator_init_data, the whole probe function would
become about 10 lines of code :)

> So, in my opinion, the tps65217-regulator.c driver is really good example of how it could be done.
>
>

Thanks, I was looking for good examples, that and rt5033 seem to be the requested
style for new regulator drivers.

-- 
Andrew F. Davis

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
@ 2015-10-01 16:08                         ` Andrew F. Davis
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew F. Davis @ 2015-10-01 16:08 UTC (permalink / raw)
  To: Grygorii Strashko, Mark Brown
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Linus Walleij, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On 10/01/2015 10:33 AM, Grygorii Strashko wrote:
> Hi Andrew,
>
> On 09/30/2015 03:29 PM, Andrew F. Davis wrote:
>> On 09/30/2015 12:28 PM, Mark Brown wrote:
>>> On Tue, Sep 29, 2015 at 01:58:41PM -0500, Andrew F. Davis wrote:
>>>> On 09/29/2015 01:38 PM, Mark Brown wrote:
>>>
>>>>> Oh, ick.  The binding has a compatible string in the individual
>>>>> regulator bindings which is broken unless there really are lots of
>>>>> variants being configured via DT (which is just not the case here).
>>>>> It's not only more typing in the DT,
>>>
>>>> I don't see this, the alternative is matching to this
>>>> "regulator-compatible",
>>>> why not just use the existing compatible.
>>>
>>> No, you don't need to use regulator-compatible - that's deprecated.
>>> Just use the node names.
>>>
>>
>> Are we sure matching on node names is a good idea? Most are just arbitrary
>> names meant to be human readable and reference-able, giving them function
>> may lead to confusion. This seems to be why we have "compatible", for
>> specific
>> identification of node function. But I'm new so maybe I'm wrong?
>>
>>>>> it also means that we can't read
>>>>> back the configuration of the device unless the user goes and creates a
>>>>> DT which explicitly lists each regulator on the device which is
>>>>> unhelpful.  We should be able to read back the configurations of all
>>>>> the
>>>>> regulators by simply listing the device in DT.
>>>
>>>> Could you expand this? I'm not sure I understand why we still cant do
>>>> this
>>>> using this new way.
>>>
>>> I'm not sure what there is to add...  if the regulator is only
>>> instantiated when it features in the device tree then obviously it must
>>> be included in the device to be instantiated.
>>>
>>
>> This is already the case then, missing regulator nodes in old drivers
>> will not
>> get instantiated ether. And old drivers don't always store any more info
>> about
>> available regulators than mine does.
>>
>>>> Bindings should have compatible strings when they describe hardware
>>>> like this,
>>>> we can then do stuff like put the LDO and DCDC drivers in separate
>>>> modules for
>>>> instance, letting DT only load what we need. There are other benefits
>>>> like
>>>> not having to search our own DT binding for data, and we only get
>>>> probed for
>>>> devices in the DT.
>>>
>>> Only getting probed for device is in DT is exactly the problem here, and
>>> nothing prevents us having separate modules for things without
>>> enumerating everything in DT.
>>>
>>
>> Sure, but then we have to do some fiddling with MFD_CORE to do that work,
>> why not remove the dependency and let DT do that for DT only drivers?
>>
>>>> This also eliminates the need for MFD_CORE, we just call
>>>> of_platform_populate on ourself and DT helpers do the rest. Why hard
>>>> code
>>>> mfd_cell's and do matching when DT does the same thing.
>>>
>>> Putting everything in DT means more work for people integrating the
>>> device and means that we have to have a full and complete understanding
>>> of the device at the time we write the DT, including decions about how
>>> we split the functionality of the device between subsystems.
>>>
>>
>> We are not adding anything extra to the DT node, we just use the
>> "compatible"
>> string to identify and match the node vs. "regulator-name", or the nodes
>> name,
>> or whatever else has been used. The node is then just filled with the
>> standard
>> optional properties just like every other driver's node.
>>
>>>>> The fact that this is different to the bindings for other regulator
>>>>> drivers and requires more code ought to have been a big warning sign
>>>>> here :(
>>>
>>>> The binding is the same as the new tps65218 driver, different isn't
>>>> always
>>>> a warning sign. And what do you mean "requires more code"? This
>>>> regulator
>>>> driver is smaller than almost any other. DT takes care of everything for
>>>> us relating to hardware instantiation like it should.
>>>
>>> That's not a new driver, it's from more than a year ago (before or about
>>> the same time the helpers got added IIRC).
>>>
>>
>> Newer than a lot, I chose to base my driver off of that not just because
>> it is a similar TI part, but because it was the cleanest, simplest looking
>> one IMHO. The helpers would require more code (you need to know how many
>> regulators you have and call the helpers in a loop).
>>
>> I have another PMIC I'm about to push a driver for when this gets
>> figured out
>> that does the same thing, and it's more important I think to do it this
>> way for
>> this new part. Some of the new regulators are designed without a dedicated
>> SOC or board to power in mind, so they will have a whole bunch for
>> different
>> regulator types on one chip and it will be up to the designer to pick
>> which ones
>> to turn on and use. With this DT approach you can just list the ones you
>> want,
>> and we may even be able to split different types into different modules,
>> then
>> we can use the same regulator driver in different spins of the PMIC with
>> more
>> or less of that type of regulator, we just add that same node under a
>> different
>> parent PMIC driver.
>>
>
> That's all make sense only if you have all information required for driver probing in DT.
> But you don't, because  a lot of information are still hard-coded in driver:
> - regulator IDs,
> - registers required to control regulator
> - ranges information and etc.
>
> So, you will not be be able to easily separate some regulator and reuse it with another PMIC.
>

Unless we encode the needed registers/info into the DT, that info
could be considered a device description if you consider each regulator
to be a separate device burned onto the same silicon, much like we
do with the different IPs on SOCs. It would be nice to have 100% generic
regulator drivers, but the DT maintainers might not go for that :)

> Actually, both approaches have right to live and which one to select depends on
> functionality which has to be implemented by regulator driver.
> For example, with this (your) approach the separate platform device will be created
> for each regulator, so, if needed, corresponding driver's callback (.remove/shutdown and
> dev_pm_ops)  can be implemented individually for each regulator. Do you need this?
> As for me, such approach is reasonable if you have devices which represents one/two regulators max.
>
> The disadvantage of this approach is that you need separate compatible string fore each regulator
> - and this, actually, is usually banned by DT maintainers ;)
>
> For devices, like this one (or twl, or plamas) which has dozens of regulators it simply make no sense :)
> Just imaging that tomorrow tps65912-1 will be released and it will be fully compatible with  tps65912, but
> with one exception - it will have dcdc5 and all followed registers offsets will be shifted.
> What will you do? All this code, based on compatible strings, will not work any more.
> And you will need to introduce another bunch of compatible strings..
>

Agree, unless we go with my above idea! :)

> By the way, this implementation is not optimal any way :)
> - you are using compatible string to get tps65912_pmic_regs structure
> - then tps65912_pmic_regs is used to get regulator ID
> - and then, finally, regulator ID is used to get regulator_desc structure
>

Yeah, I saw that after I posted this, my new version just puts a pointer
to the right regulator_desc struct in the of_device_id.data, then we can
use it directly with no middle man steps, much cleaner.

> And, finally, pay attention pls, that regulator_of_get_init_data() is called from
> from regulator_register().
>

Right, but only if you supply .of_match in your regulator_desc, and even then it
only matches on node name, not "compatible" string, if it did I could use it to
eliminate my call to of_get_regulator_init_data, the whole probe function would
become about 10 lines of code :)

> So, in my opinion, the tps65217-regulator.c driver is really good example of how it could be done.
>
>

Thanks, I was looking for good examples, that and rt5033 seem to be the requested
style for new regulator drivers.

-- 
Andrew F. Davis

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 4/5] regulators: tps65912: Add regulator driver for the TPS65912 PMIC
  2015-10-01 15:33                       ` Grygorii Strashko
  (?)
  (?)
@ 2015-10-01 16:25                       ` Mark Brown
  -1 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2015-10-01 16:25 UTC (permalink / raw)
  To: Grygorii Strashko
  Cc: Andrew F. Davis, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Lee Jones, Linus Walleij,
	Alexandre Courbot, Samuel Ortiz, Liam Girdwood, linux-gpio,
	devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 220 bytes --]

On Thu, Oct 01, 2015 at 10:33:49AM -0500, Grygorii Strashko wrote:

> So, in my opinion, the tps65217-regulator.c driver is really good
> example of how it could be done.

Yes, this should be a good example to refer to.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 1/5] Documentation: tps65912: Add DT bindings for the TPS65912 PMIC
  2015-09-24 14:52   ` Andrew F. Davis
  (?)
@ 2015-10-02 11:12   ` Linus Walleij
  -1 siblings, 0 replies; 56+ messages in thread
From: Linus Walleij @ 2015-10-02 11:12 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On Thu, Sep 24, 2015 at 7:52 AM, Andrew F. Davis <afd@ti.com> wrote:

> The TPS65912 PMIC contains several regulators and a GPIO controller.
> Add bindings for the TPS65912 PMIC.
>
> Signed-off-by: Andrew F. Davis <afd@ti.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

For GPIO bindings.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH v3 2/5] mfd: tps65912: Remove old driver in preparation for new driver
  2015-09-24 14:52   ` Andrew F. Davis
  (?)
  (?)
@ 2015-10-02 12:16   ` Linus Walleij
  -1 siblings, 0 replies; 56+ messages in thread
From: Linus Walleij @ 2015-10-02 12:16 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Lee Jones, Mark Brown, Alexandre Courbot, Samuel Ortiz,
	Liam Girdwood, linux-gpio, devicetree, linux-kernel

On Thu, Sep 24, 2015 at 7:52 AM, Andrew F. Davis <afd@ti.com> wrote:

> The old tps65912 driver is being replaced, delete old driver.
>
> Signed-off-by: Andrew F. Davis <afd@ti.com>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

The merge collisions are unpredictable. Will this be merged
through the MFD tree?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 56+ messages in thread

end of thread, other threads:[~2015-10-02 12:16 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-24 14:52 [PATCH v3 0/5] mfd: tps65912: Driver rewrite with DT support Andrew F. Davis
2015-09-24 14:52 ` Andrew F. Davis
2015-09-24 14:52 ` [PATCH v3 1/5] Documentation: tps65912: Add DT bindings for the TPS65912 PMIC Andrew F. Davis
2015-09-24 14:52   ` Andrew F. Davis
2015-10-02 11:12   ` Linus Walleij
2015-09-24 14:52 ` [PATCH v3 2/5] mfd: tps65912: Remove old driver in preparation for new driver Andrew F. Davis
2015-09-24 14:52   ` Andrew F. Davis
     [not found]   ` <1443106374-4126-3-git-send-email-afd-l0cyMroinI0@public.gmane.org>
2015-09-25 16:52     ` Lee Jones
2015-09-25 16:52       ` Lee Jones
2015-10-02 12:16   ` Linus Walleij
2015-09-24 14:52 ` [PATCH v3 3/5] mfd: tps65912: Add driver for the TPS65912 PMIC Andrew F. Davis
2015-09-24 14:52   ` Andrew F. Davis
     [not found]   ` <1443106374-4126-4-git-send-email-afd-l0cyMroinI0@public.gmane.org>
2015-09-25 16:50     ` Lee Jones
2015-09-25 16:50       ` Lee Jones
2015-09-25 19:13       ` Andrew F. Davis
2015-09-25 19:13         ` Andrew F. Davis
     [not found]         ` <56059CDA.4020004-l0cyMroinI0@public.gmane.org>
2015-09-25 21:24           ` Lee Jones
2015-09-25 21:24             ` Lee Jones
2015-09-28 15:43             ` Andrew F. Davis
2015-09-28 15:43               ` Andrew F. Davis
2015-09-29  7:19               ` Lee Jones
2015-09-29 15:50                 ` Andrew F. Davis
2015-09-29 15:50                   ` Andrew F. Davis
2015-09-28 16:01   ` Grygorii Strashko
2015-09-28 16:01     ` Grygorii Strashko
2015-09-29 18:16     ` Andrew F. Davis
2015-09-29 18:16       ` Andrew F. Davis
2015-09-24 14:52 ` [PATCH v3 4/5] regulators: tps65912: Add regulator " Andrew F. Davis
2015-09-24 14:52   ` Andrew F. Davis
     [not found]   ` <1443106374-4126-5-git-send-email-afd-l0cyMroinI0@public.gmane.org>
2015-09-25 18:05     ` Mark Brown
2015-09-25 18:05       ` Mark Brown
2015-09-25 20:10       ` Andrew F. Davis
2015-09-25 20:10         ` Andrew F. Davis
2015-09-29 15:13         ` Mark Brown
2015-09-29 18:08           ` Andrew F. Davis
2015-09-29 18:08             ` Andrew F. Davis
2015-09-29 18:38             ` Mark Brown
2015-09-29 18:58               ` Andrew F. Davis
2015-09-29 18:58                 ` Andrew F. Davis
2015-09-30 17:28                 ` Mark Brown
2015-09-30 20:29                   ` Andrew F. Davis
2015-09-30 20:29                     ` Andrew F. Davis
2015-09-30 22:20                     ` Mark Brown
2015-09-30 23:32                       ` Andrew F. Davis
2015-09-30 23:32                         ` Andrew F. Davis
2015-10-01 10:53                         ` Mark Brown
2015-10-01 15:33                     ` Grygorii Strashko
2015-10-01 15:33                       ` Grygorii Strashko
2015-10-01 16:08                       ` Andrew F. Davis
2015-10-01 16:08                         ` Andrew F. Davis
2015-10-01 16:25                       ` Mark Brown
2015-09-24 14:52 ` [PATCH v3 5/5] gpio: tps65912: Add GPIO " Andrew F. Davis
2015-09-24 14:52   ` Andrew F. Davis
2015-09-28  2:54   ` Alexandre Courbot
     [not found]     ` <CAAVeFuKu8R5GCQo3NySCOVLUew4_1qpYydHPAz9tfNorj27-NA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-09-28 15:52       ` Andrew F. Davis
2015-09-28 15:52         ` Andrew F. Davis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.