gpio: generic: factor into gpio_chip struct

The separate struct bgpio_chip has been a pain to handle, both
by being confusingly similar in name to struct gpio_chip and
for being contained inside a struct so that struct gpio_chip
is contained in a struct contained in a struct, making several
steps of dereferencing necessary.

Make things simpler: include the fields directly into
<linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and
get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix
some of the member variables with bgpio_* and add proper
kerneldoc while we're at it.

Modify all users to handle the change and use a struct
gpio_chip directly. And while we're at it: replace all
container_of() dereferencing by gpiochip_get_data() and
registering the gpio_chip with gpiochip_add_data().

Cc: arm@kernel.org
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Brian Norris <computersforpeace@gmail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Cc: Olof Johansson <olof@lixom.net>
Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Cc: Rabin Vincent <rabin@rab.in>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-omap@vger.kernel.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: bcm-kernel-feedback-list@broadcom.com
Acked-by: Gregory Fong <gregory.0xf0@gmail.com>
Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index b833a5f..e2d05fd 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -8,6 +8,7 @@
 #include <linux/irqdomain.h>
 #include <linux/lockdep.h>
 #include <linux/pinctrl/pinctrl.h>
+#include <linux/kconfig.h>
 
 struct device;
 struct gpio_desc;
@@ -65,6 +66,23 @@
  *	registers.
  * @irq_not_threaded: flag must be set if @can_sleep is set but the
  *	IRQs don't need to be threaded
+ * @read_reg: reader function for generic GPIO
+ * @write_reg: writer function for generic GPIO
+ * @pin2mask: some generic GPIO controllers work with the big-endian bits
+ *	notation, e.g. in a 8-bits register, GPIO7 is the least significant
+ *	bit. This callback assigns the right bit mask.
+ * @reg_dat: data (in) register for generic GPIO
+ * @reg_set: output set register (out=high) for generic GPIO
+ * @reg_clk: output clear register (out=low) for generic GPIO
+ * @reg_dir: direction setting register for generic GPIO
+ * @bgpio_bits: number of register bits used for a generic GPIO i.e.
+ *	<register width> * 8
+ * @bgpio_lock: used to lock chip->bgpio_data. Also, this is needed to keep
+ *	shadowed and real data registers writes together.
+ * @bgpio_data:	shadowed data register for generic GPIO to clear/set bits
+ *	safely.
+ * @bgpio_dir: shadowed direction register for generic GPIO to clear/set
+ *	direction safely.
  * @irqchip: GPIO IRQ chip impl, provided by GPIO driver
  * @irqdomain: Interrupt translation domain; responsible for mapping
  *	between GPIO hwirq number and linux irq number
@@ -128,6 +146,20 @@
 	bool			can_sleep;
 	bool			irq_not_threaded;
 
+#if IS_ENABLED(CONFIG_GPIO_GENERIC)
+	unsigned long (*read_reg)(void __iomem *reg);
+	void (*write_reg)(void __iomem *reg, unsigned long data);
+	unsigned long (*pin2mask)(struct gpio_chip *gc, unsigned int pin);
+	void __iomem *reg_dat;
+	void __iomem *reg_set;
+	void __iomem *reg_clr;
+	void __iomem *reg_dir;
+	int bgpio_bits;
+	spinlock_t bgpio_lock;
+	unsigned long bgpio_data;
+	unsigned long bgpio_dir;
+#endif
+
 #ifdef CONFIG_GPIOLIB_IRQCHIP
 	/*
 	 * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib
@@ -188,6 +220,28 @@
 
 struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc);
 
+#if IS_ENABLED(CONFIG_GPIO_GENERIC)
+
+struct bgpio_pdata {
+	const char *label;
+	int base;
+	int ngpio;
+};
+
+int bgpio_init(struct gpio_chip *gc, struct device *dev,
+	       unsigned long sz, void __iomem *dat, void __iomem *set,
+	       void __iomem *clr, void __iomem *dirout, void __iomem *dirin,
+	       unsigned long flags);
+
+#define BGPIOF_BIG_ENDIAN		BIT(0)
+#define BGPIOF_UNREADABLE_REG_SET	BIT(1) /* reg_set is unreadable */
+#define BGPIOF_UNREADABLE_REG_DIR	BIT(2) /* reg_dir is unreadable */
+#define BGPIOF_BIG_ENDIAN_BYTE_ORDER	BIT(3)
+#define BGPIOF_READ_OUTPUT_REG_SET	BIT(4) /* reg_set stores output value */
+#define BGPIOF_NO_OUTPUT		BIT(5) /* only input */
+
+#endif
+
 #ifdef CONFIG_GPIOLIB_IRQCHIP
 
 void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,