All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
@ 2016-10-07 15:17 ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Pantelis Antoniou,
	linux-kernel, Wim Van Sebroeck, linux-mtd, linux-i2c,
	Frank Rowand, Alexandre Courbot, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Rob Herring, Debjit Ghosh, Georgi Vlaev, Rajat Jain,
	Guenter Roeck, Brian Norris, David Woodhouse, Peter Rosin

Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
are present in Juniper's PTX series of routers.

The MFD driver provices watchdog/i2c/gpio/mtd devices.

There are full device tree binding documents for the
master mfd driver and for all slave drivers.

This patchset is against mainline as of today: v4.8-9431-g3477d16
and is dependent on the "Juniper prerequisites" and
"Juniper infrastructure" patchsets sent earlier.

Georgi Vlaev (5):
  mfd: ptxpmb-cpld: Add documentation for PTXPMB CPLD
  watchdog: ptxpmb-wdt: Add ptxpmb-wdt device tree bindings
  i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
  gpio: ptxpmb-cpld: Document bindings of PTXPMB's CPLD GPIO
  mtd: ngpmb_nvram: Add bindings for Juniper's ngpmb NVRAM

Guenter Roeck (4):
  mfd: Juniper PTXPMB CPLD Multi-function core driver
  watchdog: Add support for PTXPMB CPLD watchdog
  i2c/muxes: Juniper's PTXPMB CPLD I2C multiplexer
  gpio: ptxpmb-cpld: Add support for PTXPMB CPLD's GPIO

JawaharBalaji Thirumalaisamy (1):
  mtd: devices: Add driver for memory mapped NVRAM on FPC

 .../bindings/gpio/jnx,gpio-ptxpmb-cpld.txt         |  30 ++
 .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       |  50 +++
 .../devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt    |  76 ++++
 .../devicetree/bindings/mtd/ngpmb-nvram.txt        |  22 ++
 .../bindings/watchdog/jnx-ptxpmb-wdt.txt           |  17 +
 drivers/gpio/Kconfig                               |  11 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-ptxpmb-cpld.c                    | 177 +++++++++
 drivers/i2c/muxes/Kconfig                          |  11 +
 drivers/i2c/muxes/Makefile                         |   1 +
 drivers/i2c/muxes/i2c-mux-ptxpmb.c                 | 299 +++++++++++++++
 drivers/mfd/Kconfig                                |  15 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/ptxpmb-cpld-core.c                     | 406 +++++++++++++++++++++
 drivers/mtd/devices/Kconfig                        |  11 +
 drivers/mtd/devices/Makefile                       |   1 +
 drivers/mtd/devices/jnx_pmb_nvram.c                | 191 ++++++++++
 drivers/watchdog/Kconfig                           |  12 +
 drivers/watchdog/Makefile                          |   1 +
 drivers/watchdog/ptxpmb_wdt.c                      | 283 ++++++++++++++
 include/linux/mfd/ptxpmb_cpld.h                    | 140 +++++++
 21 files changed, 1756 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
 create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
 create mode 100644 Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
 create mode 100644 drivers/gpio/gpio-ptxpmb-cpld.c
 create mode 100644 drivers/i2c/muxes/i2c-mux-ptxpmb.c
 create mode 100644 drivers/mfd/ptxpmb-cpld-core.c
 create mode 100644 drivers/mtd/devices/jnx_pmb_nvram.c
 create mode 100644 drivers/watchdog/ptxpmb_wdt.c
 create mode 100644 include/linux/mfd/ptxpmb_cpld.h

-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
@ 2016-10-07 15:17 ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
are present in Juniper's PTX series of routers.

The MFD driver provices watchdog/i2c/gpio/mtd devices.

There are full device tree binding documents for the
master mfd driver and for all slave drivers.

This patchset is against mainline as of today: v4.8-9431-g3477d16
and is dependent on the "Juniper prerequisites" and
"Juniper infrastructure" patchsets sent earlier.

Georgi Vlaev (5):
  mfd: ptxpmb-cpld: Add documentation for PTXPMB CPLD
  watchdog: ptxpmb-wdt: Add ptxpmb-wdt device tree bindings
  i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
  gpio: ptxpmb-cpld: Document bindings of PTXPMB's CPLD GPIO
  mtd: ngpmb_nvram: Add bindings for Juniper's ngpmb NVRAM

Guenter Roeck (4):
  mfd: Juniper PTXPMB CPLD Multi-function core driver
  watchdog: Add support for PTXPMB CPLD watchdog
  i2c/muxes: Juniper's PTXPMB CPLD I2C multiplexer
  gpio: ptxpmb-cpld: Add support for PTXPMB CPLD's GPIO

JawaharBalaji Thirumalaisamy (1):
  mtd: devices: Add driver for memory mapped NVRAM on FPC

 .../bindings/gpio/jnx,gpio-ptxpmb-cpld.txt         |  30 ++
 .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       |  50 +++
 .../devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt    |  76 ++++
 .../devicetree/bindings/mtd/ngpmb-nvram.txt        |  22 ++
 .../bindings/watchdog/jnx-ptxpmb-wdt.txt           |  17 +
 drivers/gpio/Kconfig                               |  11 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-ptxpmb-cpld.c                    | 177 +++++++++
 drivers/i2c/muxes/Kconfig                          |  11 +
 drivers/i2c/muxes/Makefile                         |   1 +
 drivers/i2c/muxes/i2c-mux-ptxpmb.c                 | 299 +++++++++++++++
 drivers/mfd/Kconfig                                |  15 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/ptxpmb-cpld-core.c                     | 406 +++++++++++++++++++++
 drivers/mtd/devices/Kconfig                        |  11 +
 drivers/mtd/devices/Makefile                       |   1 +
 drivers/mtd/devices/jnx_pmb_nvram.c                | 191 ++++++++++
 drivers/watchdog/Kconfig                           |  12 +
 drivers/watchdog/Makefile                          |   1 +
 drivers/watchdog/ptxpmb_wdt.c                      | 283 ++++++++++++++
 include/linux/mfd/ptxpmb_cpld.h                    | 140 +++++++
 21 files changed, 1756 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
 create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
 create mode 100644 Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
 create mode 100644 drivers/gpio/gpio-ptxpmb-cpld.c
 create mode 100644 drivers/i2c/muxes/i2c-mux-ptxpmb.c
 create mode 100644 drivers/mfd/ptxpmb-cpld-core.c
 create mode 100644 drivers/mtd/devices/jnx_pmb_nvram.c
 create mode 100644 drivers/watchdog/ptxpmb_wdt.c
 create mode 100644 include/linux/mfd/ptxpmb_cpld.h

-- 
1.9.1

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

* [PATCH 01/10] mfd: Juniper PTXPMB CPLD Multi-function core driver
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Pantelis Antoniou,
	linux-kernel, Wim Van Sebroeck, linux-mtd, linux-i2c,
	Frank Rowand, Alexandre Courbot, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Rob Herring, Debjit Ghosh, Georgi Vlaev, Rajat Jain,
	Guenter Roeck, Brian Norris, David Woodhouse, Peter Rosin

From: Guenter Roeck <groeck@juniper.net>

Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
are present in Juniper's PTX series of routers.

There are two variants, the original which is found on the
PTXPMB_P2020, PTXPMB_P2020_SPMB based on a Freescale P2020 SoC,
and PTXPMB_P5040 based on a Freescale P5040 SoC.

The new variant NGPMB is present on a new line of x86 based
boards (currently only the Gladiator FPC).

Both variants provide a hardware watchdog, i2c mux and a
gpio block, with the i2c mux block being different.

Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Signed-off-by: Guenter Roeck <groeck@juniper.net>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
Signed-off-by: Rajat Jain <rajatjain@juniper.net>
Signed-off-by: Tom Kavanagh <tkavanagh@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/mfd/Kconfig             |  15 ++
 drivers/mfd/Makefile            |   1 +
 drivers/mfd/ptxpmb-cpld-core.c  | 406 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/ptxpmb_cpld.h | 140 ++++++++++++++
 4 files changed, 562 insertions(+)
 create mode 100644 drivers/mfd/ptxpmb-cpld-core.c
 create mode 100644 include/linux/mfd/ptxpmb_cpld.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2caf7e9..438666a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1340,6 +1340,21 @@ config TWL4030_POWER
 	  and load scripts controlling which resources are switched off/on
 	  or reset when a sleep, wakeup or warm reset event occurs.
 
+config MFD_JUNIPER_CPLD
+	tristate "Juniper PTX PMB CPLD"
+	depends on (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	default y if (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	select MFD_CORE
+	select I2C_MUX_PTXPMB
+	select GPIO_PTXPMB_CPLD
+	select JNX_PTXPMB_WDT
+	help
+	  Select this to enable the PTX PMB CPLD multi-function kernel driver
+	  for the applicable Juniper platforms.
+
+	  This driver can be built as a module. If built as a module it will be
+	  called "ptxpmb-cpld"
+
 config MFD_TWL4030_AUDIO
 	bool "TI TWL4030 Audio"
 	depends on TWL4030_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 2bf6a1a..62decc9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -148,6 +148,7 @@ obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
 obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
 obj-$(CONFIG_AB8500_DEBUG)	+= ab8500-debugfs.o
 obj-$(CONFIG_AB8500_GPADC)	+= ab8500-gpadc.o
+obj-$(CONFIG_MFD_JUNIPER_CPLD)	+= ptxpmb-cpld-core.o
 obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
 # ab8500-core need to come after db8500-prcmu (which provides the channel)
 obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
diff --git a/drivers/mfd/ptxpmb-cpld-core.c b/drivers/mfd/ptxpmb-cpld-core.c
new file mode 100644
index 0000000..18e60a4
--- /dev/null
+++ b/drivers/mfd/ptxpmb-cpld-core.c
@@ -0,0 +1,406 @@
+/*
+ * Juniper PTX PMB CPLD multi-function core driver
+ *
+ * Copyright (C) 2012 Juniper Networks
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/dmi.h>
+#include <linux/mfd/core.h>
+#include <linux/of_device.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+#include <linux/jnx/jnx-subsys.h>
+#include <linux/jnx/board_ids.h>
+
+struct pmb_cpld_core {
+	struct device		*dev;
+	struct pmb_boot_cpld __iomem *cpld;
+	spinlock_t		lock;
+	int			irq;
+	wait_queue_head_t	wqh;
+};
+
+static const struct of_device_id pmb_cpld_of_ids[] = {
+	{ .compatible = "jnx,ptxpmb-cpld", .data = (void *)CPLD_TYPE_PTXPMB },
+	{ .compatible = "jnx,ngpmb-bcpld", .data = (void *)CPLD_TYPE_NGPMB },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pmb_cpld_of_ids);
+
+static struct dmi_system_id gld_2t_dmi_data[] = {
+	{
+		.ident = "Juniper Networks Gladiator 2T FPC",
+		.matches = {
+			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
+			    DMI_MATCH(DMI_PRODUCT_NAME, "0BF9"),
+			},
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(dmi, gld_2t_dmi_data);
+
+static struct dmi_system_id gld_3t_dmi_data[] = {
+	{
+		.ident = "Juniper Networks Gladiator 3T FPC",
+		.matches = {
+			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
+			    DMI_MATCH(DMI_PRODUCT_NAME, "0BFA"),
+			},
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(dmi, gld_3t_dmi_data);
+
+static int ptxpmb_cpld_get_master(void *data)
+{
+	struct pmb_cpld_core *cpld = data;
+	u8 s1;
+
+	s1 = ioread8(&cpld->cpld->i2c_host_sel) & CPLD_I2C_HOST_MSTR_MASK;
+
+	if ((s1 & CPLD_I2C_HOST0_MSTR) == CPLD_I2C_HOST0_MSTR)
+		return 0;
+
+	if ((s1 & CPLD_I2C_HOST1_MSTR) == CPLD_I2C_HOST1_MSTR)
+		return 1;
+
+	return -1;
+}
+
+static int ngpmb_cpld_get_master(void *data)
+{
+	struct pmb_cpld_core *cpld = data;
+
+	if (ioread8(&cpld->cpld->baseboard_status1) & NGPMB_MASTER_SELECT)
+		return 1;
+	else
+		return 0;
+}
+
+static irqreturn_t pmb_cpld_core_interrupt(int irq, void *dev_data)
+{
+	struct pmb_cpld_core *cpld = dev_data;
+
+	pr_info("pmb_cpld_core_interrupt %d\n", irq);
+
+	spin_lock(&cpld->wqh.lock);
+
+	/* clear interrupt, wake up any handlers */
+	wake_up_locked(&cpld->wqh);
+
+	spin_unlock(&cpld->wqh.lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct resource pmb_cpld_resources[] = {
+	{
+		.start	= 0,
+		.end	= sizeof(struct pmb_boot_cpld) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct mfd_cell pmb_cpld_cells[] = {
+	{
+		.name = "jnx-ptxpmb-wdt",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,ptxpmb-wdt",
+	},
+	{
+		.name = "i2c-mux-ptxpmb-cpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,i2c-mux-ptxpmb-cpld",
+	},
+	{
+		.name = "gpio-ptxpmb-cpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,gpio-ptxpmb-cpld",
+	},
+};
+
+static struct mfd_cell ngpmb_cpld_cells[] = {
+	{
+		.name = "jnx-ptxpmb-wdt",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,ptxpmb-wdt",
+	},
+	{
+		.name = "i2c-mux-ngpmb-bcpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,i2c-mux-ngpmb-bcpld",
+	},
+	{
+		.name = "gpio-ptxpmb-cpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,gpio-ptxpmb-cpld",
+	},
+};
+
+static void cpld_ngpmb_init(struct pmb_cpld_core *cpld,
+			    struct jnx_chassis_info *chinfo,
+			    struct jnx_card_info *cinfo)
+{
+	u8 s1, s2, val, chassis;
+
+	s1 = ioread8(&cpld->cpld->baseboard_status1);
+	s2 = ioread8(&cpld->cpld->baseboard_status2);
+	chassis = (ioread8(&cpld->cpld->board.ngpmb.chassis_type)
+		   & NGPMB_CHASSIS_TYPE_MASK) >> NGPMB_CHASSIS_TYPE_LSB;
+
+	dev_info(cpld->dev, "Revision 0x%02X chassis type %s (0x%02X)\n",
+		 ioread8(&cpld->cpld->cpld_rev),
+		 chassis == NGPMB_CHASSIS_TYPE_POLARIS ? "PTX-1000" :
+		 chassis == NGPMB_CHASSIS_TYPE_HENDRICKS ? "PTX-3000" :
+		 "Unknown", chassis);
+
+	/* Only the Gladiator 2t/3t FPC */
+	if (dmi_check_system(gld_2t_dmi_data) ||
+	    dmi_check_system(gld_3t_dmi_data)) {
+		/* Take SAM FPGA out of reset */
+		val = ioread8(&cpld->cpld->gpio_2);
+		iowrite8(val | NGPMB_GPIO2_TO_BASEBRD_LSB, &cpld->cpld->gpio_2);
+		mdelay(10);
+	} else {
+		/*
+		 * Get the PAM FPGA out of reset,
+		 * and wait for 100ms as per HW manual
+		 */
+		val = ioread8(&cpld->cpld->reset);
+		iowrite8(val & ~NGPMB_PCIE_OTHER_RESET, &cpld->cpld->reset);
+		mdelay(100);
+	}
+
+	/* No Card / Chassis info needed in stand alone mode */
+	if (!(s1 & NGPMB_PMB_STANDALONE) || !(s1 & NGPMB_BASEBRD_STANDALONE))
+		return;
+
+	cinfo->type = JNX_BOARD_TYPE_FPC;
+	cinfo->slot = (s1 & NGPMB_BASEBRD_SLOT_MASK) >> NGPMB_BASEBRD_SLOT_LSB;
+
+	if (((s2 & NGPMB_BASEBRD_TYPE_MASK) >> NGPMB_BASEBRD_TYPE_LSB) !=
+	    NGPMB_BASEBRD_TYPE_MX) {
+		if (dmi_check_system(gld_2t_dmi_data))
+			cinfo->assembly_id = JNX_ID_GLD_2T_FPC;
+		else if (dmi_check_system(gld_3t_dmi_data))
+			cinfo->assembly_id = JNX_ID_GLD_3T_FPC;
+		else
+			cinfo->assembly_id = JNX_ID_POLARIS_MLC;
+	}
+
+	/*
+	 * Multi chassis configuration. These bits are not
+	 * valid for Gladiator.
+	 */
+	if (!(dmi_check_system(gld_2t_dmi_data) ||
+	      dmi_check_system(gld_3t_dmi_data))) {
+		if (ioread8(&cpld->cpld->board.ngpmb.sys_config) &
+		    NGPMB_SYS_CONFIG_MULTI_CHASSIS) {
+			chinfo->multichassis = 1;
+			chinfo->chassis_no =
+			ioread8(&cpld->cpld->board.ngpmb.chassis_id);
+		}
+	}
+
+	switch (chassis) {
+	case NGPMB_CHASSIS_TYPE_POLARIS:
+		chinfo->platform = JNX_PRODUCT_POLARIS;
+		break;
+	case NGPMB_CHASSIS_TYPE_HENDRICKS:
+		chinfo->platform = JNX_PRODUCT_HENDRICKS;
+		break;
+	default:
+		chinfo->platform = 0;
+		break;
+	};
+	chinfo->get_master = ngpmb_cpld_get_master;
+}
+
+static void cpld_ptxpmb_init(struct pmb_cpld_core *cpld,
+			     struct jnx_chassis_info *chinfo,
+			     struct jnx_card_info *cinfo)
+{
+	u8 s1, s2;
+
+	s1 = ioread8(&cpld->cpld->baseboard_status1);
+	s2 = ioread8(&cpld->cpld->baseboard_status2);
+
+	dev_info(cpld->dev, "Revision 0x%02x carrier type 0x%x [%s]\n",
+		 ioread8(&cpld->cpld->cpld_rev), s2 & 0x1f,
+		 (s1 & 0X3F) == 0X1F ? "standalone"
+				     : (s2 & 0x10) ? "FPC" : "SPMB");
+
+	if ((s1 & 0x3f) != 0x1f) {	/* not standalone */
+		cinfo->slot = s1 & 0x0f;
+		if (s2 & 0x10) {	/* fpc */
+			cinfo->type = JNX_BOARD_TYPE_FPC;
+			switch (s2 & 0x0f) {
+			case 0x00:	/* Sangria */
+				cinfo->assembly_id = JNX_ID_SNG_VDV_BASE_P2;
+				chinfo->platform = JNX_PRODUCT_SANGRIA;
+				break;
+			case 0x01:	/* Tiny */
+				chinfo->platform = JNX_PRODUCT_TINY;
+				break;
+			case 0x02:	/* Hercules */
+				chinfo->platform = JNX_PRODUCT_HERCULES;
+				break;
+			case 0x03:      /* Hendricks */
+				cinfo->assembly_id = JNX_ID_HENDRICKS_FPC_P2;
+				chinfo->platform = JNX_PRODUCT_HENDRICKS;
+				break;
+			default:	/* unknown */
+				break;
+			}
+		} else {		/* spmb */
+			cinfo->type = JNX_BOARD_TYPE_SPMB;
+			switch (s2 & 0x0f) {
+			case 0x00:	/* Sangria */
+				cinfo->assembly_id = JNX_ID_SNG_PMB;
+				chinfo->platform = JNX_PRODUCT_SANGRIA;
+				break;
+			default:	/* unknown */
+				break;
+			}
+		}
+	}
+	chinfo->get_master = ptxpmb_cpld_get_master;
+}
+
+static int pmb_cpld_core_probe(struct platform_device *pdev)
+{
+	static struct pmb_cpld_core *cpld;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct ptxpmb_mux_data *pdata = dev->platform_data;
+	int i, error, mfd_size;
+	int cpld_type = CPLD_TYPE_PTXPMB;
+	const struct of_device_id *match;
+	struct mfd_cell *mfd_cells;
+
+	struct jnx_chassis_info chinfo = {
+		.chassis_no = 0,
+		.multichassis = 0,
+		.master_data = NULL,
+		.platform = -1,
+		.get_master = NULL,
+	};
+	struct jnx_card_info cinfo = {
+		.type = JNX_BOARD_TYPE_UNKNOWN,
+		.slot = -1,
+		.assembly_id = -1,
+	};
+
+	cpld = devm_kzalloc(dev, sizeof(*cpld), GFP_KERNEL);
+	if (!cpld)
+		return -ENOMEM;
+
+	cpld->dev = dev;
+	dev_set_drvdata(dev, cpld);
+
+	if (pdata) {
+		cpld_type = pdata->cpld_type;
+	} else {
+		match = of_match_device(pmb_cpld_of_ids, dev);
+		if (match)
+			cpld_type = (int)(unsigned long)match->data;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	cpld->cpld = devm_ioremap_resource(dev, res);
+	if (IS_ERR(cpld->cpld))
+		return PTR_ERR(cpld->cpld);
+
+	chinfo.master_data = cpld;
+
+	cpld->irq = platform_get_irq(pdev, 0);
+	if (cpld->irq >= 0) {
+		error = devm_request_threaded_irq(dev, cpld->irq, NULL,
+						  pmb_cpld_core_interrupt,
+						  IRQF_TRIGGER_RISING |
+						  IRQF_ONESHOT,
+						  dev_name(dev), cpld);
+		if (error < 0)
+			return error;
+	}
+
+	spin_lock_init(&cpld->lock);
+	init_waitqueue_head(&cpld->wqh);
+
+	mfd_cells = pmb_cpld_cells;
+	mfd_size = ARRAY_SIZE(pmb_cpld_cells);
+
+	switch (cpld_type) {
+	case CPLD_TYPE_PTXPMB:
+		cpld_ptxpmb_init(cpld, &chinfo, &cinfo);
+		break;
+	case CPLD_TYPE_NGPMB:
+		cpld_ngpmb_init(cpld, &chinfo, &cinfo);
+		mfd_cells = ngpmb_cpld_cells;
+		mfd_size = ARRAY_SIZE(ngpmb_cpld_cells);
+		break;
+	}
+
+	if (pdata) {
+		for (i = 0; i < mfd_size; i++) {
+			mfd_cells[i].platform_data = pdata;
+			mfd_cells[i].pdata_size = sizeof(*pdata);
+		}
+	}
+
+	error = mfd_add_devices(dev, pdev->id, mfd_cells,
+				mfd_size, res, 0, NULL);
+	if (error < 0)
+		return error;
+
+	jnx_register_chassis(&chinfo);
+	jnx_register_local_card(&cinfo);
+
+	return 0;
+}
+
+static int pmb_cpld_core_remove(struct platform_device *pdev)
+{
+	jnx_unregister_local_card();
+	jnx_unregister_chassis();
+	mfd_remove_devices(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver pmb_cpld_core_driver = {
+	.probe		= pmb_cpld_core_probe,
+	.remove		= pmb_cpld_core_remove,
+	.driver		= {
+		.name	= "ptxpmb-cpld",
+		.of_match_table = pmb_cpld_of_ids,
+		.owner	= THIS_MODULE,
+	}
+};
+
+module_platform_driver(pmb_cpld_core_driver);
+
+MODULE_DESCRIPTION("Juniper PTX PMB CPLD Core Driver");
+MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ptxpmb-cpld");
diff --git a/include/linux/mfd/ptxpmb_cpld.h b/include/linux/mfd/ptxpmb_cpld.h
new file mode 100644
index 0000000..e44afb4
--- /dev/null
+++ b/include/linux/mfd/ptxpmb_cpld.h
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------
+ *
+ * ptxpmb_cpld_core.h
+ *     Copyright (c) 2012 Juniper Networks
+ *
+ *---------------------------------------------------------------------------
+ */
+
+#ifndef PTXPMB_CPLD_CORE_H
+#define PTXPMB_CPLD_CORE_H
+
+struct pmb_boot_cpld {
+	u8 cpld_rev;		/* 0x00 */
+	u8 reset;
+#define CPLD_MAIN_RESET		(1 << 0)
+#define CPLD_PHYCB_RESET	(1 << 1)
+#define CPLD_PHYSW_RESET	(1 << 2)	/* P2020 only	*/
+#define NGPMB_PCIE_OTHER_RESET	(1 << 3)	/* PAM reset on MLC */
+	u8 reset_reason;
+#define NGPMB_REASON_MON_A_FAIL	(1 << 0)
+#define NGPMB_REASON_WDT1	(1 << 1)
+#define NGPMB_REASON_WDT2	(1 << 2)
+#define NGPMB_REASON_WDT3	(1 << 3)
+#define NGPMB_REASON_WDT4	(1 << 4)
+#define NGPMB_REASON_RE_HRST	(1 << 5)
+#define NGPMB_REASON_PWR_ON	(1 << 6)
+#define NGPMB_REASON_RE_SRST	(1 << 7)
+	u8 control;
+#define CPLD_CONTROL_BOOTED_LED	(1 << 0)
+#define CPLD_CONTROL_WATCHDOG	(1 << 6)
+#define CPLD_CONTROL_RTC	(1 << 7)
+#define NGPMB_FLASH_SELECT	(1 << 4)
+#define NGPMB_FLASH_SWIZZ_ENA	(1 << 5)
+	u8 sys_timer_cnt;
+	u8 watchdog_hbyte;
+	u8 watchdog_lbyte;
+	u8 unused1[1];
+	u8 baseboard_status1;	/* 0x08 */
+#define NGPMB_PMB_STANDALONE	(1 << 0)
+#define NGPMB_MASTER_SELECT	(1 << 1)
+#define NGPMB_BASEBRD_STANDALONE (1 << 2)
+#define NGPMB_BASEBRD_SLOT_LSB	3
+#define NGPMB_BASEBRD_SLOT_MASK	0xF8
+	u8 baseboard_status2;
+#define NGPMB_BASEBRD_TYPE_LSB	5
+#define NGPMB_BASEBRD_TYPE_MASK	0xE0
+#define NGPMB_BASEBRD_TYPE_MX	0
+	u8 chassis_number;
+	u8 sys_config;
+	u8 i2c_group_sel;	/* 0x0c */
+	u8 i2c_group_en;
+	u8 unused2[4];
+	u8 timer_irq_st;	/* 0x12 */
+	u8 timer_irq_en;
+	u8 unused3[12];
+	u8 prog_jtag_control;	/* 0x20 */
+	u8 gp_reset1;		/* 0x21 */
+#define CPLD_GP_RST1_PCISW	(1 << 0)
+#define CPLD_GP_RST1_SAM	(1 << 1)
+#define CPLD_GP_RST1_BRCM	(1 << 2)
+	u8 gp_reset2;		/* 0x22 */
+	u8 phy_control;
+	u8 gpio_1;
+	u8 gpio_2;
+#define NGPMB_GPIO2_TO_BASEBRD_LSB	(1 << 3)
+#define NGPMB_I2C_GRP_SEL_LSB	0
+#define NGPMB_I2C_GRP_SEL_MASK	0x03
+	u8 thermal_status;
+	u8 i2c_host_sel;
+#define CPLD_I2C_HOST0_MSTR     0x09
+#define CPLD_I2C_HOST1_MSTR     0x06
+#define CPLD_I2C_HOST_MSTR_MASK 0x0f
+	u8 scratch[3];
+	u8 misc_status;
+	u8 i2c_bus_control;	/* 0x2c */
+	union {
+		struct {
+			u8 mezz_present;
+			u8 unused1[4];
+			u8 i2c_group_sel_dbg;	/* 0x31 */
+			u8 i2c_group_en_dbg;	/* 0x32 */
+			u8 i2c_group_sel_force;	/* 0x33 */
+			u8 i2c_group_en_force;	/* 0x34 */
+			u8 unused2[0x4b];
+		} p2020;
+		struct {
+			u8 hdk_minor_version;	/* 0x2d */
+			u8 hdk_feature_ind;
+			u8 hdk_pmb_srds_mode;
+			u8 hdk_pwr_fail_status;
+			u8 hdk_pmb_pwr_status;
+			u8 hdk_pmb_mezz_status;
+			u8 cpld_self_reset;	/* 0x33 */
+			u8 unused[0x4c];
+			u8 hdk_bcpld_rcw[80];
+		} p5020;
+		struct {
+			u8 unused[3];
+			u8 chassis_id;		/* 0x30 */
+			u8 chassis_type;	/* 0x31 */
+#define NGPMB_CHASSIS_TYPE_LSB		0
+#define NGPMB_CHASSIS_TYPE_MASK		0x0F
+#define NGPMB_CHASSIS_TYPE_POLARIS	0x0B
+#define NGPMB_CHASSIS_TYPE_HENDRICKS	0x09
+			u8 sys_config;		/* 0x32 */
+#define NGPMB_SYS_CONFIG_MULTI_CHASSIS	0x01
+		} ngpmb;
+		struct {
+			u8 nv_win;		/* 0x2d */
+			u8 nv_addr1;
+			u8 nv_addr2;
+			u8 nv_wr_data;
+			u8 nv_rd_data;
+			u8 nv_cmd;
+			u8 nv_done_bit;
+		} nvram;
+	} board;
+};
+
+#ifdef CONFIG_P2020_PTXPMB
+#define CPLD_PHY_RESET	(CPLD_PHYCB_RESET | CPLD_PHYSW_RESET)
+#else
+#define CPLD_PHY_RESET	CPLD_PHYCB_RESET
+#endif
+
+#define i2c_group_sel_force board.p2020.i2c_group_sel_force
+#define i2c_group_en_force board.p2020.i2c_group_en_force
+
+struct ptxpmb_mux_data {
+	int cpld_type;
+#define CPLD_TYPE_PTXPMB    0	/* SPMB / Sangria FPC / Hendricks FPC */
+#define CPLD_TYPE_NGPMB     1	/* MLC / Stout / Gladiator... */
+	int num_enable;		/* Number of I2C enable pins		*/
+	int num_channels;	/* Number of I2C channels used in a mux chip */
+	int parent_bus_num;	/* parent i2c bus number		*/
+	int base_bus_num;	/* 1st bus number, 0 if undefined	*/
+	bool use_force;		/* Use i2c force registers if true	*/
+};
+
+#endif /* PTXPMB_CPLD_CORE_H */
-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH 01/10] mfd: Juniper PTXPMB CPLD Multi-function core driver
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Guenter Roeck <groeck@juniper.net>

Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
are present in Juniper's PTX series of routers.

There are two variants, the original which is found on the
PTXPMB_P2020, PTXPMB_P2020_SPMB based on a Freescale P2020 SoC,
and PTXPMB_P5040 based on a Freescale P5040 SoC.

The new variant NGPMB is present on a new line of x86 based
boards (currently only the Gladiator FPC).

Both variants provide a hardware watchdog, i2c mux and a
gpio block, with the i2c mux block being different.

Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Signed-off-by: Guenter Roeck <groeck@juniper.net>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
Signed-off-by: Rajat Jain <rajatjain@juniper.net>
Signed-off-by: Tom Kavanagh <tkavanagh@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/mfd/Kconfig             |  15 ++
 drivers/mfd/Makefile            |   1 +
 drivers/mfd/ptxpmb-cpld-core.c  | 406 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/ptxpmb_cpld.h | 140 ++++++++++++++
 4 files changed, 562 insertions(+)
 create mode 100644 drivers/mfd/ptxpmb-cpld-core.c
 create mode 100644 include/linux/mfd/ptxpmb_cpld.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2caf7e9..438666a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1340,6 +1340,21 @@ config TWL4030_POWER
 	  and load scripts controlling which resources are switched off/on
 	  or reset when a sleep, wakeup or warm reset event occurs.
 
+config MFD_JUNIPER_CPLD
+	tristate "Juniper PTX PMB CPLD"
+	depends on (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	default y if (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	select MFD_CORE
+	select I2C_MUX_PTXPMB
+	select GPIO_PTXPMB_CPLD
+	select JNX_PTXPMB_WDT
+	help
+	  Select this to enable the PTX PMB CPLD multi-function kernel driver
+	  for the applicable Juniper platforms.
+
+	  This driver can be built as a module. If built as a module it will be
+	  called "ptxpmb-cpld"
+
 config MFD_TWL4030_AUDIO
 	bool "TI TWL4030 Audio"
 	depends on TWL4030_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 2bf6a1a..62decc9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -148,6 +148,7 @@ obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
 obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
 obj-$(CONFIG_AB8500_DEBUG)	+= ab8500-debugfs.o
 obj-$(CONFIG_AB8500_GPADC)	+= ab8500-gpadc.o
+obj-$(CONFIG_MFD_JUNIPER_CPLD)	+= ptxpmb-cpld-core.o
 obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
 # ab8500-core need to come after db8500-prcmu (which provides the channel)
 obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
diff --git a/drivers/mfd/ptxpmb-cpld-core.c b/drivers/mfd/ptxpmb-cpld-core.c
new file mode 100644
index 0000000..18e60a4
--- /dev/null
+++ b/drivers/mfd/ptxpmb-cpld-core.c
@@ -0,0 +1,406 @@
+/*
+ * Juniper PTX PMB CPLD multi-function core driver
+ *
+ * Copyright (C) 2012 Juniper Networks
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/dmi.h>
+#include <linux/mfd/core.h>
+#include <linux/of_device.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+#include <linux/jnx/jnx-subsys.h>
+#include <linux/jnx/board_ids.h>
+
+struct pmb_cpld_core {
+	struct device		*dev;
+	struct pmb_boot_cpld __iomem *cpld;
+	spinlock_t		lock;
+	int			irq;
+	wait_queue_head_t	wqh;
+};
+
+static const struct of_device_id pmb_cpld_of_ids[] = {
+	{ .compatible = "jnx,ptxpmb-cpld", .data = (void *)CPLD_TYPE_PTXPMB },
+	{ .compatible = "jnx,ngpmb-bcpld", .data = (void *)CPLD_TYPE_NGPMB },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pmb_cpld_of_ids);
+
+static struct dmi_system_id gld_2t_dmi_data[] = {
+	{
+		.ident = "Juniper Networks Gladiator 2T FPC",
+		.matches = {
+			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
+			    DMI_MATCH(DMI_PRODUCT_NAME, "0BF9"),
+			},
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(dmi, gld_2t_dmi_data);
+
+static struct dmi_system_id gld_3t_dmi_data[] = {
+	{
+		.ident = "Juniper Networks Gladiator 3T FPC",
+		.matches = {
+			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
+			    DMI_MATCH(DMI_PRODUCT_NAME, "0BFA"),
+			},
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(dmi, gld_3t_dmi_data);
+
+static int ptxpmb_cpld_get_master(void *data)
+{
+	struct pmb_cpld_core *cpld = data;
+	u8 s1;
+
+	s1 = ioread8(&cpld->cpld->i2c_host_sel) & CPLD_I2C_HOST_MSTR_MASK;
+
+	if ((s1 & CPLD_I2C_HOST0_MSTR) == CPLD_I2C_HOST0_MSTR)
+		return 0;
+
+	if ((s1 & CPLD_I2C_HOST1_MSTR) == CPLD_I2C_HOST1_MSTR)
+		return 1;
+
+	return -1;
+}
+
+static int ngpmb_cpld_get_master(void *data)
+{
+	struct pmb_cpld_core *cpld = data;
+
+	if (ioread8(&cpld->cpld->baseboard_status1) & NGPMB_MASTER_SELECT)
+		return 1;
+	else
+		return 0;
+}
+
+static irqreturn_t pmb_cpld_core_interrupt(int irq, void *dev_data)
+{
+	struct pmb_cpld_core *cpld = dev_data;
+
+	pr_info("pmb_cpld_core_interrupt %d\n", irq);
+
+	spin_lock(&cpld->wqh.lock);
+
+	/* clear interrupt, wake up any handlers */
+	wake_up_locked(&cpld->wqh);
+
+	spin_unlock(&cpld->wqh.lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct resource pmb_cpld_resources[] = {
+	{
+		.start	= 0,
+		.end	= sizeof(struct pmb_boot_cpld) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct mfd_cell pmb_cpld_cells[] = {
+	{
+		.name = "jnx-ptxpmb-wdt",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,ptxpmb-wdt",
+	},
+	{
+		.name = "i2c-mux-ptxpmb-cpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,i2c-mux-ptxpmb-cpld",
+	},
+	{
+		.name = "gpio-ptxpmb-cpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,gpio-ptxpmb-cpld",
+	},
+};
+
+static struct mfd_cell ngpmb_cpld_cells[] = {
+	{
+		.name = "jnx-ptxpmb-wdt",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,ptxpmb-wdt",
+	},
+	{
+		.name = "i2c-mux-ngpmb-bcpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,i2c-mux-ngpmb-bcpld",
+	},
+	{
+		.name = "gpio-ptxpmb-cpld",
+		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
+		.resources = pmb_cpld_resources,
+		.of_compatible = "jnx,gpio-ptxpmb-cpld",
+	},
+};
+
+static void cpld_ngpmb_init(struct pmb_cpld_core *cpld,
+			    struct jnx_chassis_info *chinfo,
+			    struct jnx_card_info *cinfo)
+{
+	u8 s1, s2, val, chassis;
+
+	s1 = ioread8(&cpld->cpld->baseboard_status1);
+	s2 = ioread8(&cpld->cpld->baseboard_status2);
+	chassis = (ioread8(&cpld->cpld->board.ngpmb.chassis_type)
+		   & NGPMB_CHASSIS_TYPE_MASK) >> NGPMB_CHASSIS_TYPE_LSB;
+
+	dev_info(cpld->dev, "Revision 0x%02X chassis type %s (0x%02X)\n",
+		 ioread8(&cpld->cpld->cpld_rev),
+		 chassis == NGPMB_CHASSIS_TYPE_POLARIS ? "PTX-1000" :
+		 chassis == NGPMB_CHASSIS_TYPE_HENDRICKS ? "PTX-3000" :
+		 "Unknown", chassis);
+
+	/* Only the Gladiator 2t/3t FPC */
+	if (dmi_check_system(gld_2t_dmi_data) ||
+	    dmi_check_system(gld_3t_dmi_data)) {
+		/* Take SAM FPGA out of reset */
+		val = ioread8(&cpld->cpld->gpio_2);
+		iowrite8(val | NGPMB_GPIO2_TO_BASEBRD_LSB, &cpld->cpld->gpio_2);
+		mdelay(10);
+	} else {
+		/*
+		 * Get the PAM FPGA out of reset,
+		 * and wait for 100ms as per HW manual
+		 */
+		val = ioread8(&cpld->cpld->reset);
+		iowrite8(val & ~NGPMB_PCIE_OTHER_RESET, &cpld->cpld->reset);
+		mdelay(100);
+	}
+
+	/* No Card / Chassis info needed in stand alone mode */
+	if (!(s1 & NGPMB_PMB_STANDALONE) || !(s1 & NGPMB_BASEBRD_STANDALONE))
+		return;
+
+	cinfo->type = JNX_BOARD_TYPE_FPC;
+	cinfo->slot = (s1 & NGPMB_BASEBRD_SLOT_MASK) >> NGPMB_BASEBRD_SLOT_LSB;
+
+	if (((s2 & NGPMB_BASEBRD_TYPE_MASK) >> NGPMB_BASEBRD_TYPE_LSB) !=
+	    NGPMB_BASEBRD_TYPE_MX) {
+		if (dmi_check_system(gld_2t_dmi_data))
+			cinfo->assembly_id = JNX_ID_GLD_2T_FPC;
+		else if (dmi_check_system(gld_3t_dmi_data))
+			cinfo->assembly_id = JNX_ID_GLD_3T_FPC;
+		else
+			cinfo->assembly_id = JNX_ID_POLARIS_MLC;
+	}
+
+	/*
+	 * Multi chassis configuration. These bits are not
+	 * valid for Gladiator.
+	 */
+	if (!(dmi_check_system(gld_2t_dmi_data) ||
+	      dmi_check_system(gld_3t_dmi_data))) {
+		if (ioread8(&cpld->cpld->board.ngpmb.sys_config) &
+		    NGPMB_SYS_CONFIG_MULTI_CHASSIS) {
+			chinfo->multichassis = 1;
+			chinfo->chassis_no =
+			ioread8(&cpld->cpld->board.ngpmb.chassis_id);
+		}
+	}
+
+	switch (chassis) {
+	case NGPMB_CHASSIS_TYPE_POLARIS:
+		chinfo->platform = JNX_PRODUCT_POLARIS;
+		break;
+	case NGPMB_CHASSIS_TYPE_HENDRICKS:
+		chinfo->platform = JNX_PRODUCT_HENDRICKS;
+		break;
+	default:
+		chinfo->platform = 0;
+		break;
+	};
+	chinfo->get_master = ngpmb_cpld_get_master;
+}
+
+static void cpld_ptxpmb_init(struct pmb_cpld_core *cpld,
+			     struct jnx_chassis_info *chinfo,
+			     struct jnx_card_info *cinfo)
+{
+	u8 s1, s2;
+
+	s1 = ioread8(&cpld->cpld->baseboard_status1);
+	s2 = ioread8(&cpld->cpld->baseboard_status2);
+
+	dev_info(cpld->dev, "Revision 0x%02x carrier type 0x%x [%s]\n",
+		 ioread8(&cpld->cpld->cpld_rev), s2 & 0x1f,
+		 (s1 & 0X3F) == 0X1F ? "standalone"
+				     : (s2 & 0x10) ? "FPC" : "SPMB");
+
+	if ((s1 & 0x3f) != 0x1f) {	/* not standalone */
+		cinfo->slot = s1 & 0x0f;
+		if (s2 & 0x10) {	/* fpc */
+			cinfo->type = JNX_BOARD_TYPE_FPC;
+			switch (s2 & 0x0f) {
+			case 0x00:	/* Sangria */
+				cinfo->assembly_id = JNX_ID_SNG_VDV_BASE_P2;
+				chinfo->platform = JNX_PRODUCT_SANGRIA;
+				break;
+			case 0x01:	/* Tiny */
+				chinfo->platform = JNX_PRODUCT_TINY;
+				break;
+			case 0x02:	/* Hercules */
+				chinfo->platform = JNX_PRODUCT_HERCULES;
+				break;
+			case 0x03:      /* Hendricks */
+				cinfo->assembly_id = JNX_ID_HENDRICKS_FPC_P2;
+				chinfo->platform = JNX_PRODUCT_HENDRICKS;
+				break;
+			default:	/* unknown */
+				break;
+			}
+		} else {		/* spmb */
+			cinfo->type = JNX_BOARD_TYPE_SPMB;
+			switch (s2 & 0x0f) {
+			case 0x00:	/* Sangria */
+				cinfo->assembly_id = JNX_ID_SNG_PMB;
+				chinfo->platform = JNX_PRODUCT_SANGRIA;
+				break;
+			default:	/* unknown */
+				break;
+			}
+		}
+	}
+	chinfo->get_master = ptxpmb_cpld_get_master;
+}
+
+static int pmb_cpld_core_probe(struct platform_device *pdev)
+{
+	static struct pmb_cpld_core *cpld;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct ptxpmb_mux_data *pdata = dev->platform_data;
+	int i, error, mfd_size;
+	int cpld_type = CPLD_TYPE_PTXPMB;
+	const struct of_device_id *match;
+	struct mfd_cell *mfd_cells;
+
+	struct jnx_chassis_info chinfo = {
+		.chassis_no = 0,
+		.multichassis = 0,
+		.master_data = NULL,
+		.platform = -1,
+		.get_master = NULL,
+	};
+	struct jnx_card_info cinfo = {
+		.type = JNX_BOARD_TYPE_UNKNOWN,
+		.slot = -1,
+		.assembly_id = -1,
+	};
+
+	cpld = devm_kzalloc(dev, sizeof(*cpld), GFP_KERNEL);
+	if (!cpld)
+		return -ENOMEM;
+
+	cpld->dev = dev;
+	dev_set_drvdata(dev, cpld);
+
+	if (pdata) {
+		cpld_type = pdata->cpld_type;
+	} else {
+		match = of_match_device(pmb_cpld_of_ids, dev);
+		if (match)
+			cpld_type = (int)(unsigned long)match->data;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	cpld->cpld = devm_ioremap_resource(dev, res);
+	if (IS_ERR(cpld->cpld))
+		return PTR_ERR(cpld->cpld);
+
+	chinfo.master_data = cpld;
+
+	cpld->irq = platform_get_irq(pdev, 0);
+	if (cpld->irq >= 0) {
+		error = devm_request_threaded_irq(dev, cpld->irq, NULL,
+						  pmb_cpld_core_interrupt,
+						  IRQF_TRIGGER_RISING |
+						  IRQF_ONESHOT,
+						  dev_name(dev), cpld);
+		if (error < 0)
+			return error;
+	}
+
+	spin_lock_init(&cpld->lock);
+	init_waitqueue_head(&cpld->wqh);
+
+	mfd_cells = pmb_cpld_cells;
+	mfd_size = ARRAY_SIZE(pmb_cpld_cells);
+
+	switch (cpld_type) {
+	case CPLD_TYPE_PTXPMB:
+		cpld_ptxpmb_init(cpld, &chinfo, &cinfo);
+		break;
+	case CPLD_TYPE_NGPMB:
+		cpld_ngpmb_init(cpld, &chinfo, &cinfo);
+		mfd_cells = ngpmb_cpld_cells;
+		mfd_size = ARRAY_SIZE(ngpmb_cpld_cells);
+		break;
+	}
+
+	if (pdata) {
+		for (i = 0; i < mfd_size; i++) {
+			mfd_cells[i].platform_data = pdata;
+			mfd_cells[i].pdata_size = sizeof(*pdata);
+		}
+	}
+
+	error = mfd_add_devices(dev, pdev->id, mfd_cells,
+				mfd_size, res, 0, NULL);
+	if (error < 0)
+		return error;
+
+	jnx_register_chassis(&chinfo);
+	jnx_register_local_card(&cinfo);
+
+	return 0;
+}
+
+static int pmb_cpld_core_remove(struct platform_device *pdev)
+{
+	jnx_unregister_local_card();
+	jnx_unregister_chassis();
+	mfd_remove_devices(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver pmb_cpld_core_driver = {
+	.probe		= pmb_cpld_core_probe,
+	.remove		= pmb_cpld_core_remove,
+	.driver		= {
+		.name	= "ptxpmb-cpld",
+		.of_match_table = pmb_cpld_of_ids,
+		.owner	= THIS_MODULE,
+	}
+};
+
+module_platform_driver(pmb_cpld_core_driver);
+
+MODULE_DESCRIPTION("Juniper PTX PMB CPLD Core Driver");
+MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ptxpmb-cpld");
diff --git a/include/linux/mfd/ptxpmb_cpld.h b/include/linux/mfd/ptxpmb_cpld.h
new file mode 100644
index 0000000..e44afb4
--- /dev/null
+++ b/include/linux/mfd/ptxpmb_cpld.h
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------
+ *
+ * ptxpmb_cpld_core.h
+ *     Copyright (c) 2012 Juniper Networks
+ *
+ *---------------------------------------------------------------------------
+ */
+
+#ifndef PTXPMB_CPLD_CORE_H
+#define PTXPMB_CPLD_CORE_H
+
+struct pmb_boot_cpld {
+	u8 cpld_rev;		/* 0x00 */
+	u8 reset;
+#define CPLD_MAIN_RESET		(1 << 0)
+#define CPLD_PHYCB_RESET	(1 << 1)
+#define CPLD_PHYSW_RESET	(1 << 2)	/* P2020 only	*/
+#define NGPMB_PCIE_OTHER_RESET	(1 << 3)	/* PAM reset on MLC */
+	u8 reset_reason;
+#define NGPMB_REASON_MON_A_FAIL	(1 << 0)
+#define NGPMB_REASON_WDT1	(1 << 1)
+#define NGPMB_REASON_WDT2	(1 << 2)
+#define NGPMB_REASON_WDT3	(1 << 3)
+#define NGPMB_REASON_WDT4	(1 << 4)
+#define NGPMB_REASON_RE_HRST	(1 << 5)
+#define NGPMB_REASON_PWR_ON	(1 << 6)
+#define NGPMB_REASON_RE_SRST	(1 << 7)
+	u8 control;
+#define CPLD_CONTROL_BOOTED_LED	(1 << 0)
+#define CPLD_CONTROL_WATCHDOG	(1 << 6)
+#define CPLD_CONTROL_RTC	(1 << 7)
+#define NGPMB_FLASH_SELECT	(1 << 4)
+#define NGPMB_FLASH_SWIZZ_ENA	(1 << 5)
+	u8 sys_timer_cnt;
+	u8 watchdog_hbyte;
+	u8 watchdog_lbyte;
+	u8 unused1[1];
+	u8 baseboard_status1;	/* 0x08 */
+#define NGPMB_PMB_STANDALONE	(1 << 0)
+#define NGPMB_MASTER_SELECT	(1 << 1)
+#define NGPMB_BASEBRD_STANDALONE (1 << 2)
+#define NGPMB_BASEBRD_SLOT_LSB	3
+#define NGPMB_BASEBRD_SLOT_MASK	0xF8
+	u8 baseboard_status2;
+#define NGPMB_BASEBRD_TYPE_LSB	5
+#define NGPMB_BASEBRD_TYPE_MASK	0xE0
+#define NGPMB_BASEBRD_TYPE_MX	0
+	u8 chassis_number;
+	u8 sys_config;
+	u8 i2c_group_sel;	/* 0x0c */
+	u8 i2c_group_en;
+	u8 unused2[4];
+	u8 timer_irq_st;	/* 0x12 */
+	u8 timer_irq_en;
+	u8 unused3[12];
+	u8 prog_jtag_control;	/* 0x20 */
+	u8 gp_reset1;		/* 0x21 */
+#define CPLD_GP_RST1_PCISW	(1 << 0)
+#define CPLD_GP_RST1_SAM	(1 << 1)
+#define CPLD_GP_RST1_BRCM	(1 << 2)
+	u8 gp_reset2;		/* 0x22 */
+	u8 phy_control;
+	u8 gpio_1;
+	u8 gpio_2;
+#define NGPMB_GPIO2_TO_BASEBRD_LSB	(1 << 3)
+#define NGPMB_I2C_GRP_SEL_LSB	0
+#define NGPMB_I2C_GRP_SEL_MASK	0x03
+	u8 thermal_status;
+	u8 i2c_host_sel;
+#define CPLD_I2C_HOST0_MSTR     0x09
+#define CPLD_I2C_HOST1_MSTR     0x06
+#define CPLD_I2C_HOST_MSTR_MASK 0x0f
+	u8 scratch[3];
+	u8 misc_status;
+	u8 i2c_bus_control;	/* 0x2c */
+	union {
+		struct {
+			u8 mezz_present;
+			u8 unused1[4];
+			u8 i2c_group_sel_dbg;	/* 0x31 */
+			u8 i2c_group_en_dbg;	/* 0x32 */
+			u8 i2c_group_sel_force;	/* 0x33 */
+			u8 i2c_group_en_force;	/* 0x34 */
+			u8 unused2[0x4b];
+		} p2020;
+		struct {
+			u8 hdk_minor_version;	/* 0x2d */
+			u8 hdk_feature_ind;
+			u8 hdk_pmb_srds_mode;
+			u8 hdk_pwr_fail_status;
+			u8 hdk_pmb_pwr_status;
+			u8 hdk_pmb_mezz_status;
+			u8 cpld_self_reset;	/* 0x33 */
+			u8 unused[0x4c];
+			u8 hdk_bcpld_rcw[80];
+		} p5020;
+		struct {
+			u8 unused[3];
+			u8 chassis_id;		/* 0x30 */
+			u8 chassis_type;	/* 0x31 */
+#define NGPMB_CHASSIS_TYPE_LSB		0
+#define NGPMB_CHASSIS_TYPE_MASK		0x0F
+#define NGPMB_CHASSIS_TYPE_POLARIS	0x0B
+#define NGPMB_CHASSIS_TYPE_HENDRICKS	0x09
+			u8 sys_config;		/* 0x32 */
+#define NGPMB_SYS_CONFIG_MULTI_CHASSIS	0x01
+		} ngpmb;
+		struct {
+			u8 nv_win;		/* 0x2d */
+			u8 nv_addr1;
+			u8 nv_addr2;
+			u8 nv_wr_data;
+			u8 nv_rd_data;
+			u8 nv_cmd;
+			u8 nv_done_bit;
+		} nvram;
+	} board;
+};
+
+#ifdef CONFIG_P2020_PTXPMB
+#define CPLD_PHY_RESET	(CPLD_PHYCB_RESET | CPLD_PHYSW_RESET)
+#else
+#define CPLD_PHY_RESET	CPLD_PHYCB_RESET
+#endif
+
+#define i2c_group_sel_force board.p2020.i2c_group_sel_force
+#define i2c_group_en_force board.p2020.i2c_group_en_force
+
+struct ptxpmb_mux_data {
+	int cpld_type;
+#define CPLD_TYPE_PTXPMB    0	/* SPMB / Sangria FPC / Hendricks FPC */
+#define CPLD_TYPE_NGPMB     1	/* MLC / Stout / Gladiator... */
+	int num_enable;		/* Number of I2C enable pins		*/
+	int num_channels;	/* Number of I2C channels used in a mux chip */
+	int parent_bus_num;	/* parent i2c bus number		*/
+	int base_bus_num;	/* 1st bus number, 0 if undefined	*/
+	bool use_force;		/* Use i2c force registers if true	*/
+};
+
+#endif /* PTXPMB_CPLD_CORE_H */
-- 
1.9.1

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

* [PATCH 02/10] mfd: ptxpmb-cpld: Add documentation for PTXPMB CPLD
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Pantelis Antoniou,
	linux-kernel, Wim Van Sebroeck, linux-mtd, linux-i2c,
	Frank Rowand, Alexandre Courbot, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Rob Herring, Debjit Ghosh, Georgi Vlaev, Rajat Jain,
	Guenter Roeck, Brian Norris, David Woodhouse, Peter Rosin

From: Georgi Vlaev <gvlaev@juniper.net>

Add DT bindings document for the PTXPMB CPLD MFD device.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt    | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt

diff --git a/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
new file mode 100644
index 0000000..cc3cbb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
@@ -0,0 +1,76 @@
+* Device tree bindings for Juniper's PTXPMB CPLD FPGA MFD driver
+
+The device supports a number I2C muxes, hardware watchdog and a gpio block.
+Those devices bindings are described in the jnx-i2c-mux-ptxpmb-cpld,
+jnx-ptxpmb-wdt and jnx-gpio-ptxpmb-cpld documents.
+
+Required properties:
+
+- compatible:		"jnx,ptxpmb-cpld", "jnx,ngpmb-bcpld". They differ
+			in the i2c-mux blocks.
+
+- reg:			contains offset/length value for device state control
+			registers space.
+
+Optional properties:
+
+- interrupts:		The interrupt line(s) the /IRQ signal(s) for the device is
+			connected to.
+
+- interrupt-parent:	The parent interrupt controller.
+
+Example:
+
+cpld@0,0 {
+	compatible = "jnx,ptxpmb-cpld";
+	reg = <0x0 0 0x10000>;
+
+	cpld-i2c-mux {
+		compatible = "jnx,i2c-mux-ptxpmb-cpld";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c-parent = <&i2c_master_0>;
+
+		num-enable = <1>;
+
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PMB devices are accessed through FPC */
+
+			temp-sensor@1a { /* FPC */
+				compatible = "maxim,max6697";
+				reg = <0x1a>;
+				smbus-timeout-disable;
+				resistance-cancellation;
+				alert-mask = <0xff>;
+				over-temperature-mask = <0xff>;
+			};
+		};
+
+		pic0i2c: i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PIC 0 */
+		};
+
+		pic1i2c: i2c@2 {
+			reg = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PIC 1 */
+		};
+	};
+
+	gpio_cpld: cpld_gpio {
+		compatible = "jnx,gpio-ptxpmb-cpld";
+		#gpio-cells = <2>;
+		gpio-controller;
+	};
+};
-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH 02/10] mfd: ptxpmb-cpld: Add documentation for PTXPMB CPLD
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Georgi Vlaev <gvlaev@juniper.net>

Add DT bindings document for the PTXPMB CPLD MFD device.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt    | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt

diff --git a/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
new file mode 100644
index 0000000..cc3cbb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
@@ -0,0 +1,76 @@
+* Device tree bindings for Juniper's PTXPMB CPLD FPGA MFD driver
+
+The device supports a number I2C muxes, hardware watchdog and a gpio block.
+Those devices bindings are described in the jnx-i2c-mux-ptxpmb-cpld,
+jnx-ptxpmb-wdt and jnx-gpio-ptxpmb-cpld documents.
+
+Required properties:
+
+- compatible:		"jnx,ptxpmb-cpld", "jnx,ngpmb-bcpld". They differ
+			in the i2c-mux blocks.
+
+- reg:			contains offset/length value for device state control
+			registers space.
+
+Optional properties:
+
+- interrupts:		The interrupt line(s) the /IRQ signal(s) for the device is
+			connected to.
+
+- interrupt-parent:	The parent interrupt controller.
+
+Example:
+
+cpld@0,0 {
+	compatible = "jnx,ptxpmb-cpld";
+	reg = <0x0 0 0x10000>;
+
+	cpld-i2c-mux {
+		compatible = "jnx,i2c-mux-ptxpmb-cpld";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c-parent = <&i2c_master_0>;
+
+		num-enable = <1>;
+
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PMB devices are accessed through FPC */
+
+			temp-sensor@1a { /* FPC */
+				compatible = "maxim,max6697";
+				reg = <0x1a>;
+				smbus-timeout-disable;
+				resistance-cancellation;
+				alert-mask = <0xff>;
+				over-temperature-mask = <0xff>;
+			};
+		};
+
+		pic0i2c: i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PIC 0 */
+		};
+
+		pic1i2c: i2c@2 {
+			reg = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PIC 1 */
+		};
+	};
+
+	gpio_cpld: cpld_gpio {
+		compatible = "jnx,gpio-ptxpmb-cpld";
+		#gpio-cells = <2>;
+		gpio-controller;
+	};
+};
-- 
1.9.1

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

* [PATCH 03/10] watchdog: Add support for PTXPMB CPLD watchdog
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Pantelis Antoniou,
	linux-kernel, Wim Van Sebroeck, linux-mtd, linux-i2c,
	Frank Rowand, Alexandre Courbot, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Rob Herring, Debjit Ghosh, Georgi Vlaev, Rajat Jain,
	Guenter Roeck, Brian Norris, David Woodhouse, Peter Rosin

From: Guenter Roeck <groeck@juniper.net>

Add support for Junipers PTXPMB CPLD's watchdog device.

Signed-off-by: Guenter Roeck <groeck@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/watchdog/Kconfig      |  12 ++
 drivers/watchdog/Makefile     |   1 +
 drivers/watchdog/ptxpmb_wdt.c | 283 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/watchdog/ptxpmb_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 50dbaa8..2554f47 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -131,6 +131,18 @@ config GPIO_WATCHDOG_ARCH_INITCALL
 	  arch_initcall.
 	  If in doubt, say N.
 
+config JNX_PTXPMB_WDT
+	tristate "Juniper PTX PMB CPLD watchdog"
+	depends on MFD_JUNIPER_CPLD
+	default y if MFD_JUNIPER_CPLD
+	select WATCHDOG_CORE
+	help
+	  Watchdog timer embedded into the boot CPLD on PTX PMB on
+	  relevant Juniper platforms.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called jnx-ptxpmb-wdt.
+
 config MENF21BMC_WATCHDOG
 	tristate "MEN 14F021P00 BMC Watchdog"
 	depends on MFD_MENF21BMC
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index cba0043..942b795 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
 endif
 obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
 obj-$(CONFIG_IT87_WDT) += it87_wdt.o
+obj-$(CONFIG_JNX_PTXPMB_WDT) += ptxpmb_wdt.o
 obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
 obj-$(CONFIG_KEMPLD_WDT) += kempld_wdt.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
diff --git a/drivers/watchdog/ptxpmb_wdt.c b/drivers/watchdog/ptxpmb_wdt.c
new file mode 100644
index 0000000..f04ac50
--- /dev/null
+++ b/drivers/watchdog/ptxpmb_wdt.c
@@ -0,0 +1,283 @@
+/*
+ * Watchdog driver for PTX PMB CPLD based watchdog
+ *
+ * Copyright (C) 2012 Juniper Networks
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+#include <linux/spinlock.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+
+#define DRV_NAME "jnx-ptxpmb-wdt"
+
+/*
+ * Since we can't really expect userspace to be responsive enough before a
+ * watchdog overflow happens, we maintain two separate timers .. One in
+ * the kernel for clearing out the watchdog every second, and another for
+ * monitoring userspace writes to the WDT device.
+ *
+ * As such, we currently use a configurable heartbeat interval which defaults
+ * to 30s. In this case, the userspace daemon is only responsible for periodic
+ * writes to the device before the next heartbeat is scheduled. If the daemon
+ * misses its deadline, the kernel timer will allow the WDT to overflow.
+ */
+
+#define WD_MIN_TIMEOUT		1
+#define WD_MAX_TIMEOUT		65535
+#define WD_DEFAULT_TIMEOUT	30	/* 30 sec default heartbeat */
+
+struct ptxpmb_wdt {
+	struct pmb_boot_cpld __iomem *cpld;
+	struct device		*dev;
+	spinlock_t		lock;
+	struct timer_list	timer;
+	unsigned long		next_heartbeat;
+};
+
+static void ptxpmb_wdt_enable(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+
+	wdt->next_heartbeat = jiffies + wdog->timeout * HZ;
+	mod_timer(&wdt->timer, jiffies + HZ);
+
+	iowrite8(0, &wdt->cpld->watchdog_hbyte);
+	iowrite8(0, &wdt->cpld->watchdog_lbyte);
+	iowrite8(ioread8(&wdt->cpld->control) | 0x40, &wdt->cpld->control);
+}
+
+static void ptxpmb_wdt_disable(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+
+	del_timer(&wdt->timer);
+
+	iowrite8(ioread8(&wdt->cpld->control) & ~0x40, &wdt->cpld->control);
+}
+
+static int ptxpmb_wdt_keepalive(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	wdt->next_heartbeat = jiffies + (wdog->timeout * HZ);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static int ptxpmb_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	wdog->timeout = t;
+	ptxpmb_wdt_enable(wdog);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static void ptxpmb_wdt_ping(unsigned long data)
+{
+	struct ptxpmb_wdt *wdt = (struct ptxpmb_wdt *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	if (time_before(jiffies, wdt->next_heartbeat)) {
+		mod_timer(&wdt->timer, jiffies + HZ);
+		iowrite8(0, &wdt->cpld->watchdog_hbyte);
+		iowrite8(0, &wdt->cpld->watchdog_lbyte);
+	} else {
+		dev_warn(wdt->dev, "Heartbeat lost! Will not ping the watchdog\n");
+	}
+	spin_unlock_irqrestore(&wdt->lock, flags);
+}
+
+static int ptxpmb_wdt_start(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	ptxpmb_wdt_enable(wdog);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static int ptxpmb_wdt_stop(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	ptxpmb_wdt_disable(wdog);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static const struct watchdog_info ptxpmb_wdt_info = {
+	.options		= WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+	.identity		= "PTX PMB WDT",
+};
+
+static const struct watchdog_ops ptxpmb_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = ptxpmb_wdt_start,
+	.stop = ptxpmb_wdt_stop,
+	.ping = ptxpmb_wdt_keepalive,
+	.set_timeout = ptxpmb_wdt_set_timeout,
+};
+
+static struct watchdog_device *ptxpmb_wdog;
+
+static int ptxpmb_wdt_notify_sys(struct notifier_block *this,
+				 unsigned long code, void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		ptxpmb_wdt_stop(ptxpmb_wdog);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ptxpmb_wdt_notifier = {
+	.notifier_call		= ptxpmb_wdt_notify_sys,
+};
+
+static int ptxpmb_wdt_probe(struct platform_device *pdev)
+{
+	struct ptxpmb_wdt *wdt;
+	bool nowayout = WATCHDOG_NOWAYOUT;
+	struct watchdog_device *wdog;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	int rc;
+
+	wdog = devm_kzalloc(dev, sizeof(*wdog), GFP_KERNEL);
+	if (unlikely(!wdog))
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (unlikely(!res))
+		return -EINVAL;
+
+#if 0
+	if (!devm_request_mem_region(dev, res->start,
+				     resource_size(res), DRV_NAME))
+		return -EBUSY;
+#endif
+
+	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
+	if (unlikely(!wdt))
+		return -ENOMEM;
+
+	wdt->dev = dev;
+
+	wdt->cpld = devm_ioremap(dev, res->start, resource_size(res));
+	if (unlikely(!wdt->cpld))
+		return -ENXIO;
+
+	spin_lock_init(&wdt->lock);
+
+	wdog->info = &ptxpmb_wdt_info;
+	wdog->ops = &ptxpmb_wdt_ops;
+	wdog->min_timeout = WD_MIN_TIMEOUT;
+	wdog->max_timeout = WD_MAX_TIMEOUT;
+	wdog->timeout = WD_DEFAULT_TIMEOUT;
+	wdog->parent = dev;
+
+	watchdog_set_drvdata(wdog, wdt);
+	watchdog_set_nowayout(wdog, nowayout);
+	platform_set_drvdata(pdev, wdog);
+
+	ptxpmb_wdt_disable(wdog);
+	ptxpmb_wdog = wdog;
+
+	rc = register_reboot_notifier(&ptxpmb_wdt_notifier);
+	if (unlikely(rc)) {
+		dev_err(dev, "Can't register reboot notifier (err=%d)\n", rc);
+		return rc;
+	}
+
+	rc = watchdog_register_device(wdog);
+	if (rc)
+		goto out_unreg;
+
+	init_timer(&wdt->timer);
+	wdt->timer.function	= ptxpmb_wdt_ping;
+	wdt->timer.data		= (unsigned long)wdt;
+	wdt->timer.expires	= jiffies + HZ;
+
+	dev_info(dev, "initialized\n");
+
+	return 0;
+
+out_unreg:
+	unregister_reboot_notifier(&ptxpmb_wdt_notifier);
+	return rc;
+}
+
+static int ptxpmb_wdt_remove(struct platform_device *pdev)
+{
+	struct watchdog_device *wdog = platform_get_drvdata(pdev);
+
+	unregister_reboot_notifier(&ptxpmb_wdt_notifier);
+	watchdog_unregister_device(wdog);
+
+	return 0;
+}
+
+static const struct of_device_id ptxpmb_wdt_of_ids[] = {
+	{ .compatible = "jnx,ptxpmb-wdt", NULL },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ptxpmb_wdt_of_ids);
+
+static struct platform_driver ptxpmb_wdt_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = ptxpmb_wdt_of_ids,
+	},
+
+	.probe	= ptxpmb_wdt_probe,
+	.remove	= ptxpmb_wdt_remove,
+};
+
+static int __init ptxpmb_wdt_init(void)
+{
+	return platform_driver_register(&ptxpmb_wdt_driver);
+}
+
+static void __exit ptxpmb_wdt_exit(void)
+{
+	platform_driver_unregister(&ptxpmb_wdt_driver);
+}
+module_init(ptxpmb_wdt_init);
+module_exit(ptxpmb_wdt_exit);
+
+MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
+MODULE_DESCRIPTION("Juniper PTX PMB CPLD watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH 03/10] watchdog: Add support for PTXPMB CPLD watchdog
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Guenter Roeck <groeck@juniper.net>

Add support for Junipers PTXPMB CPLD's watchdog device.

Signed-off-by: Guenter Roeck <groeck@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/watchdog/Kconfig      |  12 ++
 drivers/watchdog/Makefile     |   1 +
 drivers/watchdog/ptxpmb_wdt.c | 283 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/watchdog/ptxpmb_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 50dbaa8..2554f47 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -131,6 +131,18 @@ config GPIO_WATCHDOG_ARCH_INITCALL
 	  arch_initcall.
 	  If in doubt, say N.
 
+config JNX_PTXPMB_WDT
+	tristate "Juniper PTX PMB CPLD watchdog"
+	depends on MFD_JUNIPER_CPLD
+	default y if MFD_JUNIPER_CPLD
+	select WATCHDOG_CORE
+	help
+	  Watchdog timer embedded into the boot CPLD on PTX PMB on
+	  relevant Juniper platforms.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called jnx-ptxpmb-wdt.
+
 config MENF21BMC_WATCHDOG
 	tristate "MEN 14F021P00 BMC Watchdog"
 	depends on MFD_MENF21BMC
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index cba0043..942b795 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
 endif
 obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
 obj-$(CONFIG_IT87_WDT) += it87_wdt.o
+obj-$(CONFIG_JNX_PTXPMB_WDT) += ptxpmb_wdt.o
 obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
 obj-$(CONFIG_KEMPLD_WDT) += kempld_wdt.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
diff --git a/drivers/watchdog/ptxpmb_wdt.c b/drivers/watchdog/ptxpmb_wdt.c
new file mode 100644
index 0000000..f04ac50
--- /dev/null
+++ b/drivers/watchdog/ptxpmb_wdt.c
@@ -0,0 +1,283 @@
+/*
+ * Watchdog driver for PTX PMB CPLD based watchdog
+ *
+ * Copyright (C) 2012 Juniper Networks
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+#include <linux/spinlock.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+
+#define DRV_NAME "jnx-ptxpmb-wdt"
+
+/*
+ * Since we can't really expect userspace to be responsive enough before a
+ * watchdog overflow happens, we maintain two separate timers .. One in
+ * the kernel for clearing out the watchdog every second, and another for
+ * monitoring userspace writes to the WDT device.
+ *
+ * As such, we currently use a configurable heartbeat interval which defaults
+ * to 30s. In this case, the userspace daemon is only responsible for periodic
+ * writes to the device before the next heartbeat is scheduled. If the daemon
+ * misses its deadline, the kernel timer will allow the WDT to overflow.
+ */
+
+#define WD_MIN_TIMEOUT		1
+#define WD_MAX_TIMEOUT		65535
+#define WD_DEFAULT_TIMEOUT	30	/* 30 sec default heartbeat */
+
+struct ptxpmb_wdt {
+	struct pmb_boot_cpld __iomem *cpld;
+	struct device		*dev;
+	spinlock_t		lock;
+	struct timer_list	timer;
+	unsigned long		next_heartbeat;
+};
+
+static void ptxpmb_wdt_enable(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+
+	wdt->next_heartbeat = jiffies + wdog->timeout * HZ;
+	mod_timer(&wdt->timer, jiffies + HZ);
+
+	iowrite8(0, &wdt->cpld->watchdog_hbyte);
+	iowrite8(0, &wdt->cpld->watchdog_lbyte);
+	iowrite8(ioread8(&wdt->cpld->control) | 0x40, &wdt->cpld->control);
+}
+
+static void ptxpmb_wdt_disable(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+
+	del_timer(&wdt->timer);
+
+	iowrite8(ioread8(&wdt->cpld->control) & ~0x40, &wdt->cpld->control);
+}
+
+static int ptxpmb_wdt_keepalive(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	wdt->next_heartbeat = jiffies + (wdog->timeout * HZ);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static int ptxpmb_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	wdog->timeout = t;
+	ptxpmb_wdt_enable(wdog);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static void ptxpmb_wdt_ping(unsigned long data)
+{
+	struct ptxpmb_wdt *wdt = (struct ptxpmb_wdt *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	if (time_before(jiffies, wdt->next_heartbeat)) {
+		mod_timer(&wdt->timer, jiffies + HZ);
+		iowrite8(0, &wdt->cpld->watchdog_hbyte);
+		iowrite8(0, &wdt->cpld->watchdog_lbyte);
+	} else {
+		dev_warn(wdt->dev, "Heartbeat lost! Will not ping the watchdog\n");
+	}
+	spin_unlock_irqrestore(&wdt->lock, flags);
+}
+
+static int ptxpmb_wdt_start(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	ptxpmb_wdt_enable(wdog);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static int ptxpmb_wdt_stop(struct watchdog_device *wdog)
+{
+	struct ptxpmb_wdt *wdt = watchdog_get_drvdata(wdog);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdt->lock, flags);
+	ptxpmb_wdt_disable(wdog);
+	spin_unlock_irqrestore(&wdt->lock, flags);
+
+	return 0;
+}
+
+static const struct watchdog_info ptxpmb_wdt_info = {
+	.options		= WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+	.identity		= "PTX PMB WDT",
+};
+
+static const struct watchdog_ops ptxpmb_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = ptxpmb_wdt_start,
+	.stop = ptxpmb_wdt_stop,
+	.ping = ptxpmb_wdt_keepalive,
+	.set_timeout = ptxpmb_wdt_set_timeout,
+};
+
+static struct watchdog_device *ptxpmb_wdog;
+
+static int ptxpmb_wdt_notify_sys(struct notifier_block *this,
+				 unsigned long code, void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		ptxpmb_wdt_stop(ptxpmb_wdog);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ptxpmb_wdt_notifier = {
+	.notifier_call		= ptxpmb_wdt_notify_sys,
+};
+
+static int ptxpmb_wdt_probe(struct platform_device *pdev)
+{
+	struct ptxpmb_wdt *wdt;
+	bool nowayout = WATCHDOG_NOWAYOUT;
+	struct watchdog_device *wdog;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	int rc;
+
+	wdog = devm_kzalloc(dev, sizeof(*wdog), GFP_KERNEL);
+	if (unlikely(!wdog))
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (unlikely(!res))
+		return -EINVAL;
+
+#if 0
+	if (!devm_request_mem_region(dev, res->start,
+				     resource_size(res), DRV_NAME))
+		return -EBUSY;
+#endif
+
+	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
+	if (unlikely(!wdt))
+		return -ENOMEM;
+
+	wdt->dev = dev;
+
+	wdt->cpld = devm_ioremap(dev, res->start, resource_size(res));
+	if (unlikely(!wdt->cpld))
+		return -ENXIO;
+
+	spin_lock_init(&wdt->lock);
+
+	wdog->info = &ptxpmb_wdt_info;
+	wdog->ops = &ptxpmb_wdt_ops;
+	wdog->min_timeout = WD_MIN_TIMEOUT;
+	wdog->max_timeout = WD_MAX_TIMEOUT;
+	wdog->timeout = WD_DEFAULT_TIMEOUT;
+	wdog->parent = dev;
+
+	watchdog_set_drvdata(wdog, wdt);
+	watchdog_set_nowayout(wdog, nowayout);
+	platform_set_drvdata(pdev, wdog);
+
+	ptxpmb_wdt_disable(wdog);
+	ptxpmb_wdog = wdog;
+
+	rc = register_reboot_notifier(&ptxpmb_wdt_notifier);
+	if (unlikely(rc)) {
+		dev_err(dev, "Can't register reboot notifier (err=%d)\n", rc);
+		return rc;
+	}
+
+	rc = watchdog_register_device(wdog);
+	if (rc)
+		goto out_unreg;
+
+	init_timer(&wdt->timer);
+	wdt->timer.function	= ptxpmb_wdt_ping;
+	wdt->timer.data		= (unsigned long)wdt;
+	wdt->timer.expires	= jiffies + HZ;
+
+	dev_info(dev, "initialized\n");
+
+	return 0;
+
+out_unreg:
+	unregister_reboot_notifier(&ptxpmb_wdt_notifier);
+	return rc;
+}
+
+static int ptxpmb_wdt_remove(struct platform_device *pdev)
+{
+	struct watchdog_device *wdog = platform_get_drvdata(pdev);
+
+	unregister_reboot_notifier(&ptxpmb_wdt_notifier);
+	watchdog_unregister_device(wdog);
+
+	return 0;
+}
+
+static const struct of_device_id ptxpmb_wdt_of_ids[] = {
+	{ .compatible = "jnx,ptxpmb-wdt", NULL },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ptxpmb_wdt_of_ids);
+
+static struct platform_driver ptxpmb_wdt_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = ptxpmb_wdt_of_ids,
+	},
+
+	.probe	= ptxpmb_wdt_probe,
+	.remove	= ptxpmb_wdt_remove,
+};
+
+static int __init ptxpmb_wdt_init(void)
+{
+	return platform_driver_register(&ptxpmb_wdt_driver);
+}
+
+static void __exit ptxpmb_wdt_exit(void)
+{
+	platform_driver_unregister(&ptxpmb_wdt_driver);
+}
+module_init(ptxpmb_wdt_init);
+module_exit(ptxpmb_wdt_exit);
+
+MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
+MODULE_DESCRIPTION("Juniper PTX PMB CPLD watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
-- 
1.9.1

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

* [PATCH 04/10] watchdog: ptxpmb-wdt: Add ptxpmb-wdt device tree bindings
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c

From: Georgi Vlaev <gvlaev@juniper.net>

Add binding document for the watchdog driver of PTXPMB CPLD.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt     | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
new file mode 100644
index 0000000..34b64f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
@@ -0,0 +1,17 @@
+Juniper's PTXPMB FPGA watchdog driver
+
+Required properties:
+
+- compatible:	Should be "jnx,ptxpmb-wdt"
+
+Optional properties:
+
+- reg : Specifies base physical address and size of the registers. It is
+  optional since the MFD parent driver supplies it, but can be overridden.
+
+Example:
+
+wdt {
+	compatible = "jnx,ptxpmb-wdt";
+	/* no properties defined */
+};
-- 
1.9.1

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

* [PATCH 04/10] watchdog: ptxpmb-wdt: Add ptxpmb-wdt device tree bindings
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Georgi Vlaev <gvlaev@juniper.net>

Add binding document for the watchdog driver of PTXPMB CPLD.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt     | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
new file mode 100644
index 0000000..34b64f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
@@ -0,0 +1,17 @@
+Juniper's PTXPMB FPGA watchdog driver
+
+Required properties:
+
+- compatible:	Should be "jnx,ptxpmb-wdt"
+
+Optional properties:
+
+- reg : Specifies base physical address and size of the registers. It is
+  optional since the MFD parent driver supplies it, but can be overridden.
+
+Example:
+
+wdt {
+	compatible = "jnx,ptxpmb-wdt";
+	/* no properties defined */
+};
-- 
1.9.1

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

* [PATCH 05/10] i2c/muxes: Juniper's PTXPMB CPLD I2C multiplexer
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17     ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA, linux-i2c

From: Guenter Roeck <groeck-3r7Miqu9kMnR7s880joybQ@public.gmane.org>

Introduce Juniper's PTX PMB CPLD I2C multiplexer driver.

Signed-off-by: Debjit Ghosh <dghosh-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
Signed-off-by: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
Signed-off-by: Guenter Roeck <groeck-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
Signed-off-by: Rajat Jain <rajatjain-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
---
 drivers/i2c/muxes/Kconfig          |  11 ++
 drivers/i2c/muxes/Makefile         |   1 +
 drivers/i2c/muxes/i2c-mux-ptxpmb.c | 299 +++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+)
 create mode 100644 drivers/i2c/muxes/i2c-mux-ptxpmb.c

diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index e280c8e..f45a9cb 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -61,6 +61,17 @@ config I2C_MUX_PINCTRL
 	  This driver can also be built as a module. If so, the module will be
 	  called pinctrl-i2cmux.
 
+config I2C_MUX_PTXPMB
+	tristate "Juniper PTX PMB CPLD I2C multiplexer"
+	depends on MFD_JUNIPER_CPLD
+	default y if MFD_JUNIPER_CPLD
+	help
+	  Select this to enable the Juniper PTX PMB CPLD I2C multiplexer driver
+	  on the relevant Juniper platforms.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-mux-ptxpmb-cpld.
+
 config I2C_MUX_REG
 	tristate "Register-based I2C multiplexer"
 	help
diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile
index 7c267c2..78d8cba 100644
--- a/drivers/i2c/muxes/Makefile
+++ b/drivers/i2c/muxes/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_I2C_MUX_GPIO)	+= i2c-mux-gpio.o
 obj-$(CONFIG_I2C_MUX_PCA9541)	+= i2c-mux-pca9541.o
 obj-$(CONFIG_I2C_MUX_PCA954x)	+= i2c-mux-pca954x.o
 obj-$(CONFIG_I2C_MUX_PINCTRL)	+= i2c-mux-pinctrl.o
+obj-$(CONFIG_I2C_MUX_PTXPMB)	+= i2c-mux-ptxpmb.o
 obj-$(CONFIG_I2C_MUX_REG)	+= i2c-mux-reg.o
 
 ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
diff --git a/drivers/i2c/muxes/i2c-mux-ptxpmb.c b/drivers/i2c/muxes/i2c-mux-ptxpmb.c
new file mode 100644
index 0000000..e8c7aee
--- /dev/null
+++ b/drivers/i2c/muxes/i2c-mux-ptxpmb.c
@@ -0,0 +1,299 @@
+/*
+ * PTX PMB CPLD I2C multiplexer
+ *
+ * Copyright (c) 2012, Juniper Networks.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+#include <linux/io.h>
+#include <linux/of_device.h>
+
+struct i2c_mux_ptxpmb {
+	struct device *dev;
+	struct ptxpmb_mux_data *pdata;
+	struct pmb_boot_cpld __iomem *cpld;
+	struct i2c_adapter *parent;
+	int bus_count;
+	struct i2c_mux_core *muxc;
+};
+
+static const struct of_device_id i2c_mux_ptxpmb_of_match[] = {
+	{ .compatible = "jnx,i2c-mux-ptxpmb-cpld",
+	  .data = (void *)CPLD_TYPE_PTXPMB },
+	{ .compatible = "jnx,i2c-mux-ngpmb-bcpld",
+	  .data = (void *)CPLD_TYPE_NGPMB },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, i2c_mux_ptxpmb_of_match);
+
+#define I2C_GRP_FORCE_EN	0x80
+
+static int i2c_mux_ptxpmb_select(struct i2c_mux_core *muxc, u32 chan)
+{
+	struct i2c_mux_ptxpmb *mux = i2c_mux_priv(muxc);
+	struct ptxpmb_mux_data *pdata = mux->pdata;
+	u8 group, enable, val;
+
+	switch (pdata->cpld_type) {
+	case CPLD_TYPE_PTXPMB:
+		group = chan % pdata->num_channels;
+		enable = 1 << (chan / pdata->num_channels);
+		/*
+		 * Writing into the enable register does not have an effect on
+		 * FPC with P2020. It is necessary for FPC with P5020/P5040.
+		 * The uKernel for SPMB uses undocumented CPLD registers to set
+		 * group enable values (i2c_group_sel_force and
+		 * i2c_group_en_force at offset 0x33 and 0x34). Bit 7 in
+		 * i2c_group_sel_force must be set for this to work.
+		 * i2c_group_en_force is active-low. This applies to SPMB with
+		 * P2020; behavior with P5020/P5040 is unknown at this time.
+		 */
+		if (pdata->use_force) {
+			iowrite8(group | I2C_GRP_FORCE_EN,
+				 &mux->cpld->i2c_group_sel_force);
+			iowrite8(~enable, &mux->cpld->i2c_group_en_force);
+		} else {
+			iowrite8(group, &mux->cpld->i2c_group_sel);
+			ioread8(&mux->cpld->i2c_group_sel);
+			iowrite8(enable, &mux->cpld->i2c_group_en);
+			ioread8(&mux->cpld->i2c_group_en);
+		}
+		break;
+	case CPLD_TYPE_NGPMB:
+		val = ioread8(&mux->cpld->gpio_2);
+		val &= ~NGPMB_I2C_GRP_SEL_MASK;
+		val |= (chan << NGPMB_I2C_GRP_SEL_LSB) & NGPMB_I2C_GRP_SEL_MASK;
+		iowrite8(val, &mux->cpld->gpio_2);
+		break;
+	}
+	udelay(50);
+
+	return 0;
+}
+
+static int i2c_mux_ptxpmb_deselect(struct i2c_mux_core *muxc, u32 chan)
+{
+	struct i2c_mux_ptxpmb *mux = i2c_mux_priv(muxc);
+	u8 val;
+
+	switch (mux->pdata->cpld_type) {
+	case CPLD_TYPE_PTXPMB:
+		/*
+		 * Restore defaults. Note that setting i2c_group_en does not
+		 * have an effect on FPC with P2020, but is necessary for FPC
+		 * with P5020/P5040.
+		 */
+		if (mux->pdata->use_force) {
+			iowrite8(0 | I2C_GRP_FORCE_EN,
+				 &mux->cpld->i2c_group_sel_force);
+			iowrite8(0xff, &mux->cpld->i2c_group_en_force);
+		} else {
+			iowrite8(0, &mux->cpld->i2c_group_sel);
+			ioread8(&mux->cpld->i2c_group_sel);
+			iowrite8(0, &mux->cpld->i2c_group_en);
+			ioread8(&mux->cpld->i2c_group_en);
+		}
+		break;
+	case CPLD_TYPE_NGPMB:
+		/* Use the (unconnected) channel 3 to deselct */
+		val = ioread8(&mux->cpld->gpio_2);
+		val &= ~NGPMB_I2C_GRP_SEL_MASK;
+		val |= (3 << NGPMB_I2C_GRP_SEL_LSB) & NGPMB_I2C_GRP_SEL_MASK;
+		iowrite8(val, &mux->cpld->gpio_2);
+		break;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static int i2c_mux_ptxpmb_parse_dt(struct i2c_mux_ptxpmb *mux,
+				   struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	int ret;
+	struct device_node *adapter_np;
+	struct i2c_adapter *adapter;
+	const struct of_device_id *match;
+
+	if (!np)
+		return 0;
+
+	mux->pdata = devm_kzalloc(dev, sizeof(*mux->pdata), GFP_KERNEL);
+	if (!mux->pdata)
+		return -ENOMEM;
+
+	match = of_match_device(i2c_mux_ptxpmb_of_match, dev);
+	if (match)
+		mux->pdata->cpld_type = (int)(unsigned long)match->data;
+
+	ret = of_property_read_u32(np, "num-enable", &mux->pdata->num_enable);
+	if (ret) {
+		dev_err(dev, "num-enable missing\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(np, "num-channels",
+				   &mux->pdata->num_channels);
+	if (ret)
+		mux->pdata->num_channels = 8;
+
+	ret = of_property_read_u32(np, "base-bus-num",
+				   &mux->pdata->base_bus_num);
+	if (ret)
+		mux->pdata->base_bus_num = 0;
+
+	if (of_find_property(np, "use-force", NULL))
+		mux->pdata->use_force = true;
+
+	adapter_np = of_parse_phandle(np, "i2c-parent", 0);
+	if (!adapter_np) {
+		dev_err(dev, "Cannot parse i2c-parent\n");
+		return -ENODEV;
+	}
+	adapter = of_find_i2c_adapter_by_node(adapter_np);
+	if (!adapter) {
+		dev_err(dev, "Cannot find parent bus\n");
+		return -ENODEV;
+	}
+	mux->pdata->parent_bus_num = i2c_adapter_id(adapter);
+	put_device(&adapter->dev);
+
+	return 0;
+}
+#else
+static inline int i2c_mux_ptxpmb_parse_dt(struct i2c_mux_ptxpmb *mux,
+					  struct device *dev)
+{
+	return 0;
+}
+#endif
+
+static int i2c_mux_ptxpmb_probe(struct platform_device *pdev)
+{
+	struct i2c_mux_ptxpmb *mux;
+	struct i2c_mux_core *muxc;
+	int i, ret;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+
+	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, mux);
+
+	mux->dev = dev;
+
+	mux->pdata = dev->platform_data;
+	if (!mux->pdata) {
+		ret = i2c_mux_ptxpmb_parse_dt(mux, dev);
+		if (ret < 0)
+			return ret;
+	}
+	if (!mux->pdata) {
+		dev_err(dev, "No platform / devicetree data\n");
+		return -ENODEV;
+	}
+
+	if (mux->pdata->num_enable <= 0 || mux->pdata->num_enable > 8 ||
+	    mux->pdata->num_channels <= 0 || mux->pdata->num_channels > 8) {
+		dev_err(dev, "Invalid platform data\n");
+		return -EINVAL;
+	}
+
+	mux->bus_count = mux->pdata->num_enable * mux->pdata->num_channels;
+
+	mux->parent = i2c_get_adapter(mux->pdata->parent_bus_num);
+	if (!mux->parent) {
+		dev_err(dev, "Parent adapter (%d) not found\n",
+			mux->pdata->parent_bus_num);
+		return -ENODEV;
+	}
+
+	muxc = i2c_mux_alloc(mux->parent, dev, mux->bus_count, 0, 0,
+			     i2c_mux_ptxpmb_select, i2c_mux_ptxpmb_deselect);
+	if (!muxc) {
+		ret =  -ENOMEM;
+		goto err;
+	}
+	muxc->priv = mux;
+	mux->muxc = muxc;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "No memory resource\n");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	mux->cpld = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!mux->cpld) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < mux->bus_count; i++) {
+		u32 bus = mux->pdata->base_bus_num ?
+			mux->pdata->base_bus_num + i : 0;
+
+		ret = i2c_mux_add_adapter(muxc, bus, i, 0);
+		if (ret) {
+			dev_err(dev, "Failed to add adapter %d\n", i);
+			goto err_del_adapter;
+		}
+	}
+
+	return 0;
+
+err_del_adapter:
+	i2c_mux_del_adapters(mux->muxc);
+err:
+	i2c_put_adapter(mux->parent);
+	return ret;
+}
+
+static int i2c_mux_ptxpmb_remove(struct platform_device *pdev)
+{
+	struct i2c_mux_ptxpmb *mux = platform_get_drvdata(pdev);
+
+	i2c_mux_del_adapters(mux->muxc);
+	i2c_put_adapter(mux->parent);
+
+	return 0;
+}
+
+static struct platform_driver i2c_mux_ptxpmb_driver = {
+	.driver	= {
+		.name	= "i2c-mux-ptxpmb-cpld",
+		.owner	= THIS_MODULE,
+		.of_match_table = i2c_mux_ptxpmb_of_match,
+	},
+	.probe	= i2c_mux_ptxpmb_probe,
+	.remove	= i2c_mux_ptxpmb_remove,
+};
+
+module_platform_driver(i2c_mux_ptxpmb_driver);
+
+MODULE_DESCRIPTION("ptxpmb CPLD I2C multiplexer driver");
+MODULE_AUTHOR("Guenter Roeck <groeck-3r7Miqu9kMnR7s880joybQ@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:i2c-mux-ptxpmb-cpld");
-- 
1.9.1

--
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 related	[flat|nested] 47+ messages in thread

* [PATCH 05/10] i2c/muxes: Juniper's PTXPMB CPLD I2C multiplexer
@ 2016-10-07 15:17     ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Guenter Roeck <groeck@juniper.net>

Introduce Juniper's PTX PMB CPLD I2C multiplexer driver.

Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Signed-off-by: Guenter Roeck <groeck@juniper.net>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
Signed-off-by: Rajat Jain <rajatjain@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/i2c/muxes/Kconfig          |  11 ++
 drivers/i2c/muxes/Makefile         |   1 +
 drivers/i2c/muxes/i2c-mux-ptxpmb.c | 299 +++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+)
 create mode 100644 drivers/i2c/muxes/i2c-mux-ptxpmb.c

diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index e280c8e..f45a9cb 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -61,6 +61,17 @@ config I2C_MUX_PINCTRL
 	  This driver can also be built as a module. If so, the module will be
 	  called pinctrl-i2cmux.
 
+config I2C_MUX_PTXPMB
+	tristate "Juniper PTX PMB CPLD I2C multiplexer"
+	depends on MFD_JUNIPER_CPLD
+	default y if MFD_JUNIPER_CPLD
+	help
+	  Select this to enable the Juniper PTX PMB CPLD I2C multiplexer driver
+	  on the relevant Juniper platforms.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-mux-ptxpmb-cpld.
+
 config I2C_MUX_REG
 	tristate "Register-based I2C multiplexer"
 	help
diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile
index 7c267c2..78d8cba 100644
--- a/drivers/i2c/muxes/Makefile
+++ b/drivers/i2c/muxes/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_I2C_MUX_GPIO)	+= i2c-mux-gpio.o
 obj-$(CONFIG_I2C_MUX_PCA9541)	+= i2c-mux-pca9541.o
 obj-$(CONFIG_I2C_MUX_PCA954x)	+= i2c-mux-pca954x.o
 obj-$(CONFIG_I2C_MUX_PINCTRL)	+= i2c-mux-pinctrl.o
+obj-$(CONFIG_I2C_MUX_PTXPMB)	+= i2c-mux-ptxpmb.o
 obj-$(CONFIG_I2C_MUX_REG)	+= i2c-mux-reg.o
 
 ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
diff --git a/drivers/i2c/muxes/i2c-mux-ptxpmb.c b/drivers/i2c/muxes/i2c-mux-ptxpmb.c
new file mode 100644
index 0000000..e8c7aee
--- /dev/null
+++ b/drivers/i2c/muxes/i2c-mux-ptxpmb.c
@@ -0,0 +1,299 @@
+/*
+ * PTX PMB CPLD I2C multiplexer
+ *
+ * Copyright (c) 2012, Juniper Networks.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+#include <linux/io.h>
+#include <linux/of_device.h>
+
+struct i2c_mux_ptxpmb {
+	struct device *dev;
+	struct ptxpmb_mux_data *pdata;
+	struct pmb_boot_cpld __iomem *cpld;
+	struct i2c_adapter *parent;
+	int bus_count;
+	struct i2c_mux_core *muxc;
+};
+
+static const struct of_device_id i2c_mux_ptxpmb_of_match[] = {
+	{ .compatible = "jnx,i2c-mux-ptxpmb-cpld",
+	  .data = (void *)CPLD_TYPE_PTXPMB },
+	{ .compatible = "jnx,i2c-mux-ngpmb-bcpld",
+	  .data = (void *)CPLD_TYPE_NGPMB },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, i2c_mux_ptxpmb_of_match);
+
+#define I2C_GRP_FORCE_EN	0x80
+
+static int i2c_mux_ptxpmb_select(struct i2c_mux_core *muxc, u32 chan)
+{
+	struct i2c_mux_ptxpmb *mux = i2c_mux_priv(muxc);
+	struct ptxpmb_mux_data *pdata = mux->pdata;
+	u8 group, enable, val;
+
+	switch (pdata->cpld_type) {
+	case CPLD_TYPE_PTXPMB:
+		group = chan % pdata->num_channels;
+		enable = 1 << (chan / pdata->num_channels);
+		/*
+		 * Writing into the enable register does not have an effect on
+		 * FPC with P2020. It is necessary for FPC with P5020/P5040.
+		 * The uKernel for SPMB uses undocumented CPLD registers to set
+		 * group enable values (i2c_group_sel_force and
+		 * i2c_group_en_force at offset 0x33 and 0x34). Bit 7 in
+		 * i2c_group_sel_force must be set for this to work.
+		 * i2c_group_en_force is active-low. This applies to SPMB with
+		 * P2020; behavior with P5020/P5040 is unknown at this time.
+		 */
+		if (pdata->use_force) {
+			iowrite8(group | I2C_GRP_FORCE_EN,
+				 &mux->cpld->i2c_group_sel_force);
+			iowrite8(~enable, &mux->cpld->i2c_group_en_force);
+		} else {
+			iowrite8(group, &mux->cpld->i2c_group_sel);
+			ioread8(&mux->cpld->i2c_group_sel);
+			iowrite8(enable, &mux->cpld->i2c_group_en);
+			ioread8(&mux->cpld->i2c_group_en);
+		}
+		break;
+	case CPLD_TYPE_NGPMB:
+		val = ioread8(&mux->cpld->gpio_2);
+		val &= ~NGPMB_I2C_GRP_SEL_MASK;
+		val |= (chan << NGPMB_I2C_GRP_SEL_LSB) & NGPMB_I2C_GRP_SEL_MASK;
+		iowrite8(val, &mux->cpld->gpio_2);
+		break;
+	}
+	udelay(50);
+
+	return 0;
+}
+
+static int i2c_mux_ptxpmb_deselect(struct i2c_mux_core *muxc, u32 chan)
+{
+	struct i2c_mux_ptxpmb *mux = i2c_mux_priv(muxc);
+	u8 val;
+
+	switch (mux->pdata->cpld_type) {
+	case CPLD_TYPE_PTXPMB:
+		/*
+		 * Restore defaults. Note that setting i2c_group_en does not
+		 * have an effect on FPC with P2020, but is necessary for FPC
+		 * with P5020/P5040.
+		 */
+		if (mux->pdata->use_force) {
+			iowrite8(0 | I2C_GRP_FORCE_EN,
+				 &mux->cpld->i2c_group_sel_force);
+			iowrite8(0xff, &mux->cpld->i2c_group_en_force);
+		} else {
+			iowrite8(0, &mux->cpld->i2c_group_sel);
+			ioread8(&mux->cpld->i2c_group_sel);
+			iowrite8(0, &mux->cpld->i2c_group_en);
+			ioread8(&mux->cpld->i2c_group_en);
+		}
+		break;
+	case CPLD_TYPE_NGPMB:
+		/* Use the (unconnected) channel 3 to deselct */
+		val = ioread8(&mux->cpld->gpio_2);
+		val &= ~NGPMB_I2C_GRP_SEL_MASK;
+		val |= (3 << NGPMB_I2C_GRP_SEL_LSB) & NGPMB_I2C_GRP_SEL_MASK;
+		iowrite8(val, &mux->cpld->gpio_2);
+		break;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static int i2c_mux_ptxpmb_parse_dt(struct i2c_mux_ptxpmb *mux,
+				   struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	int ret;
+	struct device_node *adapter_np;
+	struct i2c_adapter *adapter;
+	const struct of_device_id *match;
+
+	if (!np)
+		return 0;
+
+	mux->pdata = devm_kzalloc(dev, sizeof(*mux->pdata), GFP_KERNEL);
+	if (!mux->pdata)
+		return -ENOMEM;
+
+	match = of_match_device(i2c_mux_ptxpmb_of_match, dev);
+	if (match)
+		mux->pdata->cpld_type = (int)(unsigned long)match->data;
+
+	ret = of_property_read_u32(np, "num-enable", &mux->pdata->num_enable);
+	if (ret) {
+		dev_err(dev, "num-enable missing\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(np, "num-channels",
+				   &mux->pdata->num_channels);
+	if (ret)
+		mux->pdata->num_channels = 8;
+
+	ret = of_property_read_u32(np, "base-bus-num",
+				   &mux->pdata->base_bus_num);
+	if (ret)
+		mux->pdata->base_bus_num = 0;
+
+	if (of_find_property(np, "use-force", NULL))
+		mux->pdata->use_force = true;
+
+	adapter_np = of_parse_phandle(np, "i2c-parent", 0);
+	if (!adapter_np) {
+		dev_err(dev, "Cannot parse i2c-parent\n");
+		return -ENODEV;
+	}
+	adapter = of_find_i2c_adapter_by_node(adapter_np);
+	if (!adapter) {
+		dev_err(dev, "Cannot find parent bus\n");
+		return -ENODEV;
+	}
+	mux->pdata->parent_bus_num = i2c_adapter_id(adapter);
+	put_device(&adapter->dev);
+
+	return 0;
+}
+#else
+static inline int i2c_mux_ptxpmb_parse_dt(struct i2c_mux_ptxpmb *mux,
+					  struct device *dev)
+{
+	return 0;
+}
+#endif
+
+static int i2c_mux_ptxpmb_probe(struct platform_device *pdev)
+{
+	struct i2c_mux_ptxpmb *mux;
+	struct i2c_mux_core *muxc;
+	int i, ret;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+
+	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, mux);
+
+	mux->dev = dev;
+
+	mux->pdata = dev->platform_data;
+	if (!mux->pdata) {
+		ret = i2c_mux_ptxpmb_parse_dt(mux, dev);
+		if (ret < 0)
+			return ret;
+	}
+	if (!mux->pdata) {
+		dev_err(dev, "No platform / devicetree data\n");
+		return -ENODEV;
+	}
+
+	if (mux->pdata->num_enable <= 0 || mux->pdata->num_enable > 8 ||
+	    mux->pdata->num_channels <= 0 || mux->pdata->num_channels > 8) {
+		dev_err(dev, "Invalid platform data\n");
+		return -EINVAL;
+	}
+
+	mux->bus_count = mux->pdata->num_enable * mux->pdata->num_channels;
+
+	mux->parent = i2c_get_adapter(mux->pdata->parent_bus_num);
+	if (!mux->parent) {
+		dev_err(dev, "Parent adapter (%d) not found\n",
+			mux->pdata->parent_bus_num);
+		return -ENODEV;
+	}
+
+	muxc = i2c_mux_alloc(mux->parent, dev, mux->bus_count, 0, 0,
+			     i2c_mux_ptxpmb_select, i2c_mux_ptxpmb_deselect);
+	if (!muxc) {
+		ret =  -ENOMEM;
+		goto err;
+	}
+	muxc->priv = mux;
+	mux->muxc = muxc;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "No memory resource\n");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	mux->cpld = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!mux->cpld) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < mux->bus_count; i++) {
+		u32 bus = mux->pdata->base_bus_num ?
+			mux->pdata->base_bus_num + i : 0;
+
+		ret = i2c_mux_add_adapter(muxc, bus, i, 0);
+		if (ret) {
+			dev_err(dev, "Failed to add adapter %d\n", i);
+			goto err_del_adapter;
+		}
+	}
+
+	return 0;
+
+err_del_adapter:
+	i2c_mux_del_adapters(mux->muxc);
+err:
+	i2c_put_adapter(mux->parent);
+	return ret;
+}
+
+static int i2c_mux_ptxpmb_remove(struct platform_device *pdev)
+{
+	struct i2c_mux_ptxpmb *mux = platform_get_drvdata(pdev);
+
+	i2c_mux_del_adapters(mux->muxc);
+	i2c_put_adapter(mux->parent);
+
+	return 0;
+}
+
+static struct platform_driver i2c_mux_ptxpmb_driver = {
+	.driver	= {
+		.name	= "i2c-mux-ptxpmb-cpld",
+		.owner	= THIS_MODULE,
+		.of_match_table = i2c_mux_ptxpmb_of_match,
+	},
+	.probe	= i2c_mux_ptxpmb_probe,
+	.remove	= i2c_mux_ptxpmb_remove,
+};
+
+module_platform_driver(i2c_mux_ptxpmb_driver);
+
+MODULE_DESCRIPTION("ptxpmb CPLD I2C multiplexer driver");
+MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:i2c-mux-ptxpmb-cpld");
-- 
1.9.1

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

* [PATCH 06/10] i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17     ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA, linux-i2c

From: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>

Add binding document for the i2c driver of PTXPMB CPLD.

Signed-off-by: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
---
 .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt

diff --git a/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
new file mode 100644
index 0000000..3b201f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
@@ -0,0 +1,50 @@
+* Juniper PTXPMB CPLD I2C Mux
+
+I2C mux on the PTXPMB CPLD on Juniper series of routers.
+
+Required properties:
+
+  - compatible: Must contain one of the following.
+    "jnx,i2c-mux-ptxpmb-cpld", "jnx,i2c-mux-ngpmb-bcpld"
+  - num-enable: Number of muxes to enable.
+
+  The following required properties are defined externally:
+
+  - Standard I2C mux properties. See i2c-mux.txt in this directory.
+  - I2C child bus nodes. See i2c-mux.txt in this directory.
+
+Optional Properties:
+
+  - num-channels: Number of channels. If not present the default is 8.
+  - base-bus-num: Base bus number. If not present it is 0.
+  - use-force: Use the force method of the controller.
+
+
+Example:
+
+cpld-i2c-mux {
+	compatible = "jnx,i2c-mux-ptxpmb-cpld";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	i2c-parent = <&i2c1>;
+
+	num-enable = <1>;
+
+	i2c@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* PMB devices are accessed through FPC */
+
+		temp-sensor@1a { /* FPC */
+			compatible = "maxim,max6697";
+			reg = <0x1a>;
+			smbus-timeout-disable;
+			resistance-cancellation;
+			alert-mask = <0xff>;
+			over-temperature-mask = <0xff>;
+		};
+	};
+};
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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 related	[flat|nested] 47+ messages in thread

* [PATCH 06/10] i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
@ 2016-10-07 15:17     ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Georgi Vlaev <gvlaev@juniper.net>

Add binding document for the i2c driver of PTXPMB CPLD.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt

diff --git a/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
new file mode 100644
index 0000000..3b201f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
@@ -0,0 +1,50 @@
+* Juniper PTXPMB CPLD I2C Mux
+
+I2C mux on the PTXPMB CPLD on Juniper series of routers.
+
+Required properties:
+
+  - compatible: Must contain one of the following.
+    "jnx,i2c-mux-ptxpmb-cpld", "jnx,i2c-mux-ngpmb-bcpld"
+  - num-enable: Number of muxes to enable.
+
+  The following required properties are defined externally:
+
+  - Standard I2C mux properties. See i2c-mux.txt in this directory.
+  - I2C child bus nodes. See i2c-mux.txt in this directory.
+
+Optional Properties:
+
+  - num-channels: Number of channels. If not present the default is 8.
+  - base-bus-num: Base bus number. If not present it is 0.
+  - use-force: Use the force method of the controller.
+
+
+Example:
+
+cpld-i2c-mux {
+	compatible = "jnx,i2c-mux-ptxpmb-cpld";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	i2c-parent = <&i2c1>;
+
+	num-enable = <1>;
+
+	i2c@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* PMB devices are accessed through FPC */
+
+		temp-sensor@1a { /* FPC */
+			compatible = "maxim,max6697";
+			reg = <0x1a>;
+			smbus-timeout-disable;
+			resistance-cancellation;
+			alert-mask = <0xff>;
+			over-temperature-mask = <0xff>;
+		};
+	};
+};
-- 
1.9.1

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

* [PATCH 07/10] gpio: ptxpmb-cpld: Add support for PTXPMB CPLD's GPIO
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Pantelis Antoniou,
	linux-kernel, Wim Van Sebroeck, linux-mtd, linux-i2c,
	Frank Rowand, Alexandre Courbot, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Rob Herring, Debjit Ghosh, Georgi Vlaev, Rajat Jain,
	Guenter Roeck, Brian Norris, David Woodhouse, Peter Rosin

From: Guenter Roeck <groeck@juniper.net>

Support the GPIO block which is located in PTXPMB CPLDs
on relevant Juniper platforms.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Signed-off-by: Guenter Roeck <groeck@juniper.net>
Signed-off-by: Rajat Jain <rajatjain@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/gpio/Kconfig            |  11 +++
 drivers/gpio/Makefile           |   1 +
 drivers/gpio/gpio-ptxpmb-cpld.c | 177 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 189 insertions(+)
 create mode 100644 drivers/gpio/gpio-ptxpmb-cpld.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 26ee00f..9c91de6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -360,6 +360,17 @@ config GPIO_PL061
 	help
 	  Say yes here to support the PrimeCell PL061 GPIO device
 
+config GPIO_PTXPMB_CPLD
+	tristate "PTXPMB CPLD GPIO"
+	depends on MFD_JUNIPER_CPLD
+	default y if MFD_JUNIPER_CPLD
+	help
+	  This driver supports the GPIO interfaces on the PTXPMB CPLD which is
+	  present on the relevant Juniper platforms.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called gpio-ptxpmb-cpld.
+
 config GPIO_PXA
 	bool "PXA GPIO support"
 	depends on ARCH_PXA || ARCH_MMP
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ab28a2d..d397ea5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_GPIO_PCF857X)	+= gpio-pcf857x.o
 obj-$(CONFIG_GPIO_PCH)		+= gpio-pch.o
 obj-$(CONFIG_GPIO_PISOSR)	+= gpio-pisosr.o
 obj-$(CONFIG_GPIO_PL061)	+= gpio-pl061.o
+obj-$(CONFIG_GPIO_PTXPMB_CPLD)	+= gpio-ptxpmb-cpld.o
 obj-$(CONFIG_GPIO_PXA)		+= gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583)	+= gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X)	+= gpio-rdc321x.o
diff --git a/drivers/gpio/gpio-ptxpmb-cpld.c b/drivers/gpio/gpio-ptxpmb-cpld.c
new file mode 100644
index 0000000..e6fab7c
--- /dev/null
+++ b/drivers/gpio/gpio-ptxpmb-cpld.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2012 Juniper networks
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/gpio.h>
+#include <linux/errno.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <linux/mfd/ptxpmb_cpld.h>
+
+/**
+ * struct ptxpmb_cpld_gpio - GPIO private data structure.
+ * @base:			PCI base address of Memory mapped I/O register.
+ * @dev:			Pointer to device structure.
+ * @gpio:			Data for GPIO infrastructure.
+ */
+struct ptxpmb_cpld_gpio {
+	void __iomem *base;
+	struct device *dev;
+	struct gpio_chip gpio;
+	struct mutex lock;
+};
+
+static u8 *ptxpmb_cpld_gpio_get_addr(struct pmb_boot_cpld *cpld,
+				     unsigned int nr)
+{
+	if (nr < 8)			/* 0..7: reset			*/
+		return &cpld->reset;
+	else if (nr < 16)		/* 8..15: control		*/
+		return &cpld->control;
+	else if (nr < 24)		/* 16..23: gpio1		*/
+		return &cpld->gpio_1;
+	else if (nr < 32)		/* 24..31: gpio2		*/
+		return &cpld->gpio_2;
+	else if (nr < 40)		/* 32..39: gp_reset1		*/
+		return &cpld->gp_reset1;
+	return &cpld->thermal_status;	/* 40..41: thermal status	*/
+}
+
+static void ptxpmb_cpld_gpio_set(struct gpio_chip *gpio, unsigned int nr,
+				 int val)
+{
+	u32 reg;
+	u8 bit = 1 << (nr & 7);
+	struct ptxpmb_cpld_gpio *chip =
+	  container_of(gpio, struct ptxpmb_cpld_gpio, gpio);
+	u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
+
+	mutex_lock(&chip->lock);
+	reg = ioread8(addr);
+	if (val)
+		reg |= bit;
+	else
+		reg &= ~bit;
+
+	iowrite8(reg, addr);
+	mutex_unlock(&chip->lock);
+}
+
+static int ptxpmb_cpld_gpio_get(struct gpio_chip *gpio, unsigned int nr)
+{
+	struct ptxpmb_cpld_gpio *chip = container_of(gpio,
+						     struct ptxpmb_cpld_gpio,
+						     gpio);
+	u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
+	u8 bit = 1 << (nr & 7);
+
+	return !!(ioread8(addr) & bit);
+}
+
+static int ptxpmb_cpld_gpio_direction_output(struct gpio_chip *gpio,
+					     unsigned int nr, int val)
+{
+	return 0;
+}
+
+static int ptxpmb_cpld_gpio_direction_input(struct gpio_chip *gpio,
+					    unsigned int nr)
+{
+	return 0;
+}
+
+static void ptxpmb_cpld_gpio_setup(struct ptxpmb_cpld_gpio *chip)
+{
+	struct gpio_chip *gpio = &chip->gpio;
+
+	gpio->label = dev_name(chip->dev);
+	gpio->owner = THIS_MODULE;
+	gpio->direction_input = ptxpmb_cpld_gpio_direction_input;
+	gpio->get = ptxpmb_cpld_gpio_get;
+	gpio->direction_output = ptxpmb_cpld_gpio_direction_output;
+	gpio->set = ptxpmb_cpld_gpio_set;
+	gpio->dbg_show = NULL;
+	gpio->base = -1;
+	gpio->ngpio = 48;
+	gpio->can_sleep = 0;
+#ifdef CONFIG_OF_GPIO
+	gpio->of_node = chip->dev->of_node;
+#endif
+}
+
+static int ptxpmb_cpld_gpio_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct ptxpmb_cpld_gpio *chip;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->dev = dev;
+	platform_set_drvdata(pdev, chip);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!chip->base)
+		return -ENOMEM;
+
+	mutex_init(&chip->lock);
+	ptxpmb_cpld_gpio_setup(chip);
+	ret = gpiochip_add(&chip->gpio);
+	if (ret) {
+		dev_err(dev, "CPLD gpio: Failed to register GPIO\n");
+		return ret;
+	}
+	return 0;
+}
+
+static int ptxpmb_cpld_gpio_remove(struct platform_device *pdev)
+{
+	struct ptxpmb_cpld_gpio *chip = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&chip->gpio);
+
+	return 0;
+}
+
+static const struct of_device_id ptxpmb_cpld_gpio_ids[] = {
+	{ .compatible = "jnx,gpio-ptxpmb-cpld", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ptxpmb_cpld_gpio_ids);
+
+static struct platform_driver ptxpmb_cpld_gpio_driver = {
+	.driver = {
+		.name = "gpio-ptxpmb-cpld",
+		.owner  = THIS_MODULE,
+		.of_match_table = ptxpmb_cpld_gpio_ids,
+	},
+	.probe = ptxpmb_cpld_gpio_probe,
+	.remove = ptxpmb_cpld_gpio_remove,
+};
+
+module_platform_driver(ptxpmb_cpld_gpio_driver);
+
+MODULE_DESCRIPTION("CPLD FPGA GPIO Driver");
+MODULE_LICENSE("GPL");
-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH 07/10] gpio: ptxpmb-cpld: Add support for PTXPMB CPLD's GPIO
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Guenter Roeck <groeck@juniper.net>

Support the GPIO block which is located in PTXPMB CPLDs
on relevant Juniper platforms.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Signed-off-by: Guenter Roeck <groeck@juniper.net>
Signed-off-by: Rajat Jain <rajatjain@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/gpio/Kconfig            |  11 +++
 drivers/gpio/Makefile           |   1 +
 drivers/gpio/gpio-ptxpmb-cpld.c | 177 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 189 insertions(+)
 create mode 100644 drivers/gpio/gpio-ptxpmb-cpld.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 26ee00f..9c91de6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -360,6 +360,17 @@ config GPIO_PL061
 	help
 	  Say yes here to support the PrimeCell PL061 GPIO device
 
+config GPIO_PTXPMB_CPLD
+	tristate "PTXPMB CPLD GPIO"
+	depends on MFD_JUNIPER_CPLD
+	default y if MFD_JUNIPER_CPLD
+	help
+	  This driver supports the GPIO interfaces on the PTXPMB CPLD which is
+	  present on the relevant Juniper platforms.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called gpio-ptxpmb-cpld.
+
 config GPIO_PXA
 	bool "PXA GPIO support"
 	depends on ARCH_PXA || ARCH_MMP
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ab28a2d..d397ea5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_GPIO_PCF857X)	+= gpio-pcf857x.o
 obj-$(CONFIG_GPIO_PCH)		+= gpio-pch.o
 obj-$(CONFIG_GPIO_PISOSR)	+= gpio-pisosr.o
 obj-$(CONFIG_GPIO_PL061)	+= gpio-pl061.o
+obj-$(CONFIG_GPIO_PTXPMB_CPLD)	+= gpio-ptxpmb-cpld.o
 obj-$(CONFIG_GPIO_PXA)		+= gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583)	+= gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X)	+= gpio-rdc321x.o
diff --git a/drivers/gpio/gpio-ptxpmb-cpld.c b/drivers/gpio/gpio-ptxpmb-cpld.c
new file mode 100644
index 0000000..e6fab7c
--- /dev/null
+++ b/drivers/gpio/gpio-ptxpmb-cpld.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2012 Juniper networks
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/gpio.h>
+#include <linux/errno.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <linux/mfd/ptxpmb_cpld.h>
+
+/**
+ * struct ptxpmb_cpld_gpio - GPIO private data structure.
+ * @base:			PCI base address of Memory mapped I/O register.
+ * @dev:			Pointer to device structure.
+ * @gpio:			Data for GPIO infrastructure.
+ */
+struct ptxpmb_cpld_gpio {
+	void __iomem *base;
+	struct device *dev;
+	struct gpio_chip gpio;
+	struct mutex lock;
+};
+
+static u8 *ptxpmb_cpld_gpio_get_addr(struct pmb_boot_cpld *cpld,
+				     unsigned int nr)
+{
+	if (nr < 8)			/* 0..7: reset			*/
+		return &cpld->reset;
+	else if (nr < 16)		/* 8..15: control		*/
+		return &cpld->control;
+	else if (nr < 24)		/* 16..23: gpio1		*/
+		return &cpld->gpio_1;
+	else if (nr < 32)		/* 24..31: gpio2		*/
+		return &cpld->gpio_2;
+	else if (nr < 40)		/* 32..39: gp_reset1		*/
+		return &cpld->gp_reset1;
+	return &cpld->thermal_status;	/* 40..41: thermal status	*/
+}
+
+static void ptxpmb_cpld_gpio_set(struct gpio_chip *gpio, unsigned int nr,
+				 int val)
+{
+	u32 reg;
+	u8 bit = 1 << (nr & 7);
+	struct ptxpmb_cpld_gpio *chip =
+	  container_of(gpio, struct ptxpmb_cpld_gpio, gpio);
+	u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
+
+	mutex_lock(&chip->lock);
+	reg = ioread8(addr);
+	if (val)
+		reg |= bit;
+	else
+		reg &= ~bit;
+
+	iowrite8(reg, addr);
+	mutex_unlock(&chip->lock);
+}
+
+static int ptxpmb_cpld_gpio_get(struct gpio_chip *gpio, unsigned int nr)
+{
+	struct ptxpmb_cpld_gpio *chip = container_of(gpio,
+						     struct ptxpmb_cpld_gpio,
+						     gpio);
+	u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
+	u8 bit = 1 << (nr & 7);
+
+	return !!(ioread8(addr) & bit);
+}
+
+static int ptxpmb_cpld_gpio_direction_output(struct gpio_chip *gpio,
+					     unsigned int nr, int val)
+{
+	return 0;
+}
+
+static int ptxpmb_cpld_gpio_direction_input(struct gpio_chip *gpio,
+					    unsigned int nr)
+{
+	return 0;
+}
+
+static void ptxpmb_cpld_gpio_setup(struct ptxpmb_cpld_gpio *chip)
+{
+	struct gpio_chip *gpio = &chip->gpio;
+
+	gpio->label = dev_name(chip->dev);
+	gpio->owner = THIS_MODULE;
+	gpio->direction_input = ptxpmb_cpld_gpio_direction_input;
+	gpio->get = ptxpmb_cpld_gpio_get;
+	gpio->direction_output = ptxpmb_cpld_gpio_direction_output;
+	gpio->set = ptxpmb_cpld_gpio_set;
+	gpio->dbg_show = NULL;
+	gpio->base = -1;
+	gpio->ngpio = 48;
+	gpio->can_sleep = 0;
+#ifdef CONFIG_OF_GPIO
+	gpio->of_node = chip->dev->of_node;
+#endif
+}
+
+static int ptxpmb_cpld_gpio_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct ptxpmb_cpld_gpio *chip;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->dev = dev;
+	platform_set_drvdata(pdev, chip);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!chip->base)
+		return -ENOMEM;
+
+	mutex_init(&chip->lock);
+	ptxpmb_cpld_gpio_setup(chip);
+	ret = gpiochip_add(&chip->gpio);
+	if (ret) {
+		dev_err(dev, "CPLD gpio: Failed to register GPIO\n");
+		return ret;
+	}
+	return 0;
+}
+
+static int ptxpmb_cpld_gpio_remove(struct platform_device *pdev)
+{
+	struct ptxpmb_cpld_gpio *chip = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&chip->gpio);
+
+	return 0;
+}
+
+static const struct of_device_id ptxpmb_cpld_gpio_ids[] = {
+	{ .compatible = "jnx,gpio-ptxpmb-cpld", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ptxpmb_cpld_gpio_ids);
+
+static struct platform_driver ptxpmb_cpld_gpio_driver = {
+	.driver = {
+		.name = "gpio-ptxpmb-cpld",
+		.owner  = THIS_MODULE,
+		.of_match_table = ptxpmb_cpld_gpio_ids,
+	},
+	.probe = ptxpmb_cpld_gpio_probe,
+	.remove = ptxpmb_cpld_gpio_remove,
+};
+
+module_platform_driver(ptxpmb_cpld_gpio_driver);
+
+MODULE_DESCRIPTION("CPLD FPGA GPIO Driver");
+MODULE_LICENSE("GPL");
-- 
1.9.1

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

* [PATCH 08/10] gpio: ptxpmb-cpld: Document bindings of PTXPMB's CPLD GPIO
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Pantelis Antoniou,
	linux-kernel, Wim Van Sebroeck, linux-mtd, linux-i2c,
	Frank Rowand, Alexandre Courbot, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Rob Herring, Debjit Ghosh, Georgi Vlaev, Rajat Jain,
	Guenter Roeck, Brian Norris, David Woodhouse, Peter Rosin

From: Georgi Vlaev <gvlaev@juniper.net>

Add device tree bindings document for the GPIO driver of
Juniper's PTXPMB/NGPMB CPLD.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../bindings/gpio/jnx,gpio-ptxpmb-cpld.txt         | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt

diff --git a/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
new file mode 100644
index 0000000..1122021
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
@@ -0,0 +1,30 @@
+Juniper PTXPMB CPLD GPIO block
+
+Required properties:
+
+- compatible:
+    Must be "jnx,gpio-ptxpmb-cpld"
+
+- #gpio-cells:
+    Should be <2>.  The first cell is the pin number (within the controller's
+    pin space), and the second is used for the following flags:
+	bit[0]: direction (0 = out, 1 = in)
+	bit[1]: init high
+	bit[2]: active low
+
+- gpio-controller:
+    Specifies that the node is a GPIO controller.
+
+Optional properties:
+
+- reg:
+    Address and length of the register set for the device. Usually supplied by
+    the parent MFD driver
+
+Example:
+
+gpio_cpld: cpld_gpio {
+	compatible = "jnx,gpio-ptxpmb-cpld";
+	#gpio-cells = <2>;
+	gpio-controller;
+};
-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH 08/10] gpio: ptxpmb-cpld: Document bindings of PTXPMB's CPLD GPIO
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Georgi Vlaev <gvlaev@juniper.net>

Add device tree bindings document for the GPIO driver of
Juniper's PTXPMB/NGPMB CPLD.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../bindings/gpio/jnx,gpio-ptxpmb-cpld.txt         | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt

diff --git a/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
new file mode 100644
index 0000000..1122021
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
@@ -0,0 +1,30 @@
+Juniper PTXPMB CPLD GPIO block
+
+Required properties:
+
+- compatible:
+    Must be "jnx,gpio-ptxpmb-cpld"
+
+- #gpio-cells:
+    Should be <2>.  The first cell is the pin number (within the controller's
+    pin space), and the second is used for the following flags:
+	bit[0]: direction (0 = out, 1 = in)
+	bit[1]: init high
+	bit[2]: active low
+
+- gpio-controller:
+    Specifies that the node is a GPIO controller.
+
+Optional properties:
+
+- reg:
+    Address and length of the register set for the device. Usually supplied by
+    the parent MFD driver
+
+Example:
+
+gpio_cpld: cpld_gpio {
+	compatible = "jnx,gpio-ptxpmb-cpld";
+	#gpio-cells = <2>;
+	gpio-controller;
+};
-- 
1.9.1

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

* [PATCH 09/10] mtd: devices: Add driver for memory mapped NVRAM on FPC
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Pantelis Antoniou,
	linux-kernel, Wim Van Sebroeck, linux-mtd, linux-i2c,
	Frank Rowand, Alexandre Courbot, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Rob Herring, Debjit Ghosh, Georgi Vlaev, Rajat Jain,
	Guenter Roeck, Brian Norris, David Woodhouse, Peter Rosin

From: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>

Add MTD driver for NVRAM on Juniper Gladiator FPC PMB. This driver uses
indirect memory-mapped access facilitated by bootcpld. Requires
cpld_ver >= 0XC6 and DT support.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/mtd/devices/Kconfig         |  11 +++
 drivers/mtd/devices/Makefile        |   1 +
 drivers/mtd/devices/jnx_pmb_nvram.c | 191 ++++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 drivers/mtd/devices/jnx_pmb_nvram.c

diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 58329d2..d4255fb 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -144,6 +144,17 @@ config MTD_LART
 	  not need any mapping/chip driver for LART. This one does it all
 	  for you, so go disable all of those if you enabled some of them (:
 
+config JNX_PMB_NVRAM
+	tristate "Juniper FPC PMB NVRAM Driver"
+	depends on (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	default y if (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	help
+	  This driver adds support for NVRAM on Gladiator 3T FPC which is connected
+	  to the BOOTCPLD (cpld_version >= C6).
+
+	  This driver can also be built as a module. When it is so the name of
+	  the module is ngpmb-nvram.
+
 config MTD_MTDRAM
 	tristate "Test driver using RAM"
 	help
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 7912d3a..b407c5fc 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
 obj-$(CONFIG_MTD_ST_SPI_FSM)    += st_spi_fsm.o
 obj-$(CONFIG_MTD_POWERNV_FLASH)	+= powernv_flash.o
 
+obj-$(CONFIG_JNX_PMB_NVRAM)     += jnx_pmb_nvram.o
 
 CFLAGS_docg3.o			+= -I$(src)
diff --git a/drivers/mtd/devices/jnx_pmb_nvram.c b/drivers/mtd/devices/jnx_pmb_nvram.c
new file mode 100644
index 0000000..8a1e812
--- /dev/null
+++ b/drivers/mtd/devices/jnx_pmb_nvram.c
@@ -0,0 +1,191 @@
+/*
+ * Juniper Networks PTX1K RCB I2CS Boot FPGA MTD driver
+ * FPGA upgrades of the Spartan3AN/XC3S700 based I2CS.
+ *
+ * Copyright (C) 2015 Juniper Networks. All rights reserved.
+ * Author:	JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+
+struct nvram_mtd {
+	void __iomem *base;
+	struct device *dev;
+	struct mtd_info mtd;
+	struct mutex lock;
+};
+
+
+static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	memset((char *)nvram->base + instr->addr, 0xff, instr->len);
+	instr->state = MTD_ERASE_DONE;
+	mtd_erase_callback(instr);
+	return 0;
+}
+
+static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
+		     size_t *retlen, void **virt, resource_size_t *phys)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	virt = nvram->base + from;
+	*retlen = len;
+	return 0;
+}
+
+static int ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+{
+	return 0;
+}
+
+static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
+		    size_t *retlen, u_char *buf)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	memcpy(buf, nvram->base + from, len);
+	*retlen = len;
+	return 0;
+}
+
+static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
+		     size_t *retlen, const u_char *buf)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	memcpy((char *)nvram->base + to, buf, len);
+	*retlen = len;
+	return 0;
+}
+
+int nvram_init_mtd_parse(struct platform_device *pdev, struct mtd_info *mtd)
+{
+	struct mtd_part_parser_data ppdata = {};
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	mtd->name = dev_name(dev);
+	mtd->type = MTD_RAM;
+	mtd->flags = MTD_CAP_RAM;
+	mtd->size = 0xFF00;
+	mtd->writesize = 1;
+	mtd->writebufsize = 64; /* Mimic CFI NOR flashes */
+	mtd->erasesize = 0x1000;
+	mtd->owner = THIS_MODULE;
+	mtd->_erase = ram_erase;
+	mtd->_point = ram_point;
+	mtd->_unpoint = ram_unpoint;
+	mtd->_read = ram_read;
+	mtd->_write = ram_write;
+	mtd->_panic_write = ram_write;
+
+	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+	if (ret) {
+		dev_err(dev, "mtd_device_parse_register returned %d\n", ret);
+		return ret;
+	}
+	return ret;
+}
+
+static int nvram_probe(struct platform_device *pdev)
+{
+	struct pmb_boot_cpld __iomem *cpld;
+	struct nvram_mtd *nvram;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int ret;
+
+	nvram = devm_kzalloc(dev, sizeof(*nvram), GFP_KERNEL);
+	if (!nvram)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "Failed to get nvram mmio resource\n");
+		return -ENOENT;
+	}
+	nvram->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!nvram->base) {
+		dev_err(dev, "Cannot map nvram\n");
+		return -EADDRNOTAVAIL;
+	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		/* Always assume that we need cpld control */
+		dev_err(dev, "Failed to get cpld mmio resource\n");
+		return -ENOENT;
+	}
+	cpld = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!cpld) {
+		dev_err(dev, "Cannot map cpld\n");
+		return -EADDRNOTAVAIL;
+	}
+	nvram->dev = dev;
+	platform_set_drvdata(pdev, nvram);
+	ret = nvram_init_mtd_parse(pdev, &nvram->mtd);
+	if (ret)
+		return ret;
+
+	if (READ_ONCE(cpld->cpld_rev) < 0xC6)
+		dev_info(dev, "NVRAM requires atleast cpld_rev 0XC6\n");
+
+	/* Initialize the window register in the cpld*/
+	WRITE_ONCE(cpld->board.nvram.nv_win, 0x0);
+	dev_info(dev, "Initialized window:0x%x\n",
+			READ_ONCE(cpld->board.nvram.nv_win));
+	return ret;
+}
+
+static int nvram_remove(struct platform_device *pdev)
+{
+	struct nvram_mtd *nvram;
+
+	nvram = platform_get_drvdata(pdev);
+	mtd_device_unregister(&nvram->mtd);
+	return 0;
+}
+
+static const struct of_device_id ngpmb_mtd_ids[] = {
+	{ .compatible = "jnx,ngpmb-nvram", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ngpmb_mtd_ids);
+
+static struct platform_driver nvram_driver = {
+	.probe  = nvram_probe,
+	.remove = nvram_remove,
+	.driver = {
+		.name = "ngpmb-nvram",
+		.owner = THIS_MODULE,
+		.of_match_table = ngpmb_mtd_ids,
+	},
+};
+
+module_platform_driver(nvram_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>");
+MODULE_DESCRIPTION("EVO PTXPMB CPLD NVRAM Driver");
+MODULE_ALIAS("platform:ngpmb-nvram");
-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH 09/10] mtd: devices: Add driver for memory mapped NVRAM on FPC
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>

Add MTD driver for NVRAM on Juniper Gladiator FPC PMB. This driver uses
indirect memory-mapped access facilitated by bootcpld. Requires
cpld_ver >= 0XC6 and DT support.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/mtd/devices/Kconfig         |  11 +++
 drivers/mtd/devices/Makefile        |   1 +
 drivers/mtd/devices/jnx_pmb_nvram.c | 191 ++++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 drivers/mtd/devices/jnx_pmb_nvram.c

diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 58329d2..d4255fb 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -144,6 +144,17 @@ config MTD_LART
 	  not need any mapping/chip driver for LART. This one does it all
 	  for you, so go disable all of those if you enabled some of them (:
 
+config JNX_PMB_NVRAM
+	tristate "Juniper FPC PMB NVRAM Driver"
+	depends on (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	default y if (PTXPMB_COMMON || JNX_PTX_NGPMB)
+	help
+	  This driver adds support for NVRAM on Gladiator 3T FPC which is connected
+	  to the BOOTCPLD (cpld_version >= C6).
+
+	  This driver can also be built as a module. When it is so the name of
+	  the module is ngpmb-nvram.
+
 config MTD_MTDRAM
 	tristate "Test driver using RAM"
 	help
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 7912d3a..b407c5fc 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
 obj-$(CONFIG_MTD_ST_SPI_FSM)    += st_spi_fsm.o
 obj-$(CONFIG_MTD_POWERNV_FLASH)	+= powernv_flash.o
 
+obj-$(CONFIG_JNX_PMB_NVRAM)     += jnx_pmb_nvram.o
 
 CFLAGS_docg3.o			+= -I$(src)
diff --git a/drivers/mtd/devices/jnx_pmb_nvram.c b/drivers/mtd/devices/jnx_pmb_nvram.c
new file mode 100644
index 0000000..8a1e812
--- /dev/null
+++ b/drivers/mtd/devices/jnx_pmb_nvram.c
@@ -0,0 +1,191 @@
+/*
+ * Juniper Networks PTX1K RCB I2CS Boot FPGA MTD driver
+ * FPGA upgrades of the Spartan3AN/XC3S700 based I2CS.
+ *
+ * Copyright (C) 2015 Juniper Networks. All rights reserved.
+ * Author:	JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mfd/ptxpmb_cpld.h>
+
+struct nvram_mtd {
+	void __iomem *base;
+	struct device *dev;
+	struct mtd_info mtd;
+	struct mutex lock;
+};
+
+
+static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	memset((char *)nvram->base + instr->addr, 0xff, instr->len);
+	instr->state = MTD_ERASE_DONE;
+	mtd_erase_callback(instr);
+	return 0;
+}
+
+static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
+		     size_t *retlen, void **virt, resource_size_t *phys)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	virt = nvram->base + from;
+	*retlen = len;
+	return 0;
+}
+
+static int ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+{
+	return 0;
+}
+
+static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
+		    size_t *retlen, u_char *buf)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	memcpy(buf, nvram->base + from, len);
+	*retlen = len;
+	return 0;
+}
+
+static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
+		     size_t *retlen, const u_char *buf)
+{
+	struct nvram_mtd *nvram = container_of(mtd, struct nvram_mtd, mtd);
+
+	memcpy((char *)nvram->base + to, buf, len);
+	*retlen = len;
+	return 0;
+}
+
+int nvram_init_mtd_parse(struct platform_device *pdev, struct mtd_info *mtd)
+{
+	struct mtd_part_parser_data ppdata = {};
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	mtd->name = dev_name(dev);
+	mtd->type = MTD_RAM;
+	mtd->flags = MTD_CAP_RAM;
+	mtd->size = 0xFF00;
+	mtd->writesize = 1;
+	mtd->writebufsize = 64; /* Mimic CFI NOR flashes */
+	mtd->erasesize = 0x1000;
+	mtd->owner = THIS_MODULE;
+	mtd->_erase = ram_erase;
+	mtd->_point = ram_point;
+	mtd->_unpoint = ram_unpoint;
+	mtd->_read = ram_read;
+	mtd->_write = ram_write;
+	mtd->_panic_write = ram_write;
+
+	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+	if (ret) {
+		dev_err(dev, "mtd_device_parse_register returned %d\n", ret);
+		return ret;
+	}
+	return ret;
+}
+
+static int nvram_probe(struct platform_device *pdev)
+{
+	struct pmb_boot_cpld __iomem *cpld;
+	struct nvram_mtd *nvram;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int ret;
+
+	nvram = devm_kzalloc(dev, sizeof(*nvram), GFP_KERNEL);
+	if (!nvram)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "Failed to get nvram mmio resource\n");
+		return -ENOENT;
+	}
+	nvram->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!nvram->base) {
+		dev_err(dev, "Cannot map nvram\n");
+		return -EADDRNOTAVAIL;
+	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		/* Always assume that we need cpld control */
+		dev_err(dev, "Failed to get cpld mmio resource\n");
+		return -ENOENT;
+	}
+	cpld = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!cpld) {
+		dev_err(dev, "Cannot map cpld\n");
+		return -EADDRNOTAVAIL;
+	}
+	nvram->dev = dev;
+	platform_set_drvdata(pdev, nvram);
+	ret = nvram_init_mtd_parse(pdev, &nvram->mtd);
+	if (ret)
+		return ret;
+
+	if (READ_ONCE(cpld->cpld_rev) < 0xC6)
+		dev_info(dev, "NVRAM requires atleast cpld_rev 0XC6\n");
+
+	/* Initialize the window register in the cpld*/
+	WRITE_ONCE(cpld->board.nvram.nv_win, 0x0);
+	dev_info(dev, "Initialized window:0x%x\n",
+			READ_ONCE(cpld->board.nvram.nv_win));
+	return ret;
+}
+
+static int nvram_remove(struct platform_device *pdev)
+{
+	struct nvram_mtd *nvram;
+
+	nvram = platform_get_drvdata(pdev);
+	mtd_device_unregister(&nvram->mtd);
+	return 0;
+}
+
+static const struct of_device_id ngpmb_mtd_ids[] = {
+	{ .compatible = "jnx,ngpmb-nvram", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ngpmb_mtd_ids);
+
+static struct platform_driver nvram_driver = {
+	.probe  = nvram_probe,
+	.remove = nvram_remove,
+	.driver = {
+		.name = "ngpmb-nvram",
+		.owner = THIS_MODULE,
+		.of_match_table = ngpmb_mtd_ids,
+	},
+};
+
+module_platform_driver(nvram_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>");
+MODULE_DESCRIPTION("EVO PTXPMB CPLD NVRAM Driver");
+MODULE_ALIAS("platform:ngpmb-nvram");
-- 
1.9.1

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

* [PATCH 10/10] mtd: ngpmb_nvram: Add bindings for Juniper's ngpmb NVRAM
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 15:17   ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c

From: Georgi Vlaev <gvlaev@juniper.net>

Add device tree binging document for the ngpmb NVRAM device.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../devicetree/bindings/mtd/ngpmb-nvram.txt        | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt

diff --git a/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
new file mode 100644
index 0000000..297ad0e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
@@ -0,0 +1,22 @@
+Non Volatile RAM device on a Juniper NG PMB FPGA
+
+These devices are found in the PTX series of Juniper routers.
+
+Required properties:
+- compatible : must be "jnx,ngpmb-nvram"
+
+Optional properties:
+- reg : memory address for the RAM, note that this is not
+required since usually the device is a subdevice of the SAM MFD
+driver which fills in the register fields.
+
+For the rest of the properties, see mtd-physmap.txt.
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Example:
+
+ngpmb_nvram {
+	compatible = "jnx,ngpmb-nvram";
+};
-- 
1.9.1

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

* [PATCH 10/10] mtd: ngpmb_nvram: Add bindings for Juniper's ngpmb NVRAM
@ 2016-10-07 15:17   ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-07 15:17 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, Pantelis Antoniou, devicetree, linux-kernel,
	linux-gpio, linux-i2c, linux-mtd, linux-watchdog

From: Georgi Vlaev <gvlaev@juniper.net>

Add device tree binging document for the ngpmb NVRAM device.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 .../devicetree/bindings/mtd/ngpmb-nvram.txt        | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt

diff --git a/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
new file mode 100644
index 0000000..297ad0e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
@@ -0,0 +1,22 @@
+Non Volatile RAM device on a Juniper NG PMB FPGA
+
+These devices are found in the PTX series of Juniper routers.
+
+Required properties:
+- compatible : must be "jnx,ngpmb-nvram"
+
+Optional properties:
+- reg : memory address for the RAM, note that this is not
+required since usually the device is a subdevice of the SAM MFD
+driver which fills in the register fields.
+
+For the rest of the properties, see mtd-physmap.txt.
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Example:
+
+ngpmb_nvram {
+	compatible = "jnx,ngpmb-nvram";
+};
-- 
1.9.1

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

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-07 23:39     ` Frank Rowand
  -1 siblings, 0 replies; 47+ messages in thread
From: Frank Rowand @ 2016-10-07 23:39 UTC (permalink / raw)
  To: Pantelis Antoniou, Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Wolfram Sang, David Woodhouse, Brian Norris, Wim Van Sebroeck,
	Guenter Roeck, Peter Rosin, Debjit Ghosh, Georgi Vlaev,
	Guenter Roeck, JawaharBalaji Thirumalaisamy, Rajat Jain,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA

On 10/07/16 08:17, Pantelis Antoniou wrote:
> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
> are present in Juniper's PTX series of routers.
> 
> The MFD driver provices watchdog/i2c/gpio/mtd devices.
> 
> There are full device tree binding documents for the
> master mfd driver and for all slave drivers.
> 
> This patchset is against mainline as of today: v4.8-9431-g3477d16
> and is dependent on the "Juniper prerequisites" and
> "Juniper infrastructure" patchsets sent earlier.

Pointers to the patchsets please.

< snip >

-Frank

--
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] 47+ messages in thread

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
@ 2016-10-07 23:39     ` Frank Rowand
  0 siblings, 0 replies; 47+ messages in thread
From: Frank Rowand @ 2016-10-07 23:39 UTC (permalink / raw)
  To: Pantelis Antoniou, Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Wolfram Sang, David Woodhouse, Brian Norris, Wim Van Sebroeck,
	Guenter Roeck, Peter Rosin, Debjit Ghosh, Georgi Vlaev,
	Guenter Roeck, JawaharBalaji Thirumalaisamy, Rajat Jain,
	devicetree, linux-kernel, linux-gpio, linux-i2c, linux-mtd,
	linux-watchdog

On 10/07/16 08:17, Pantelis Antoniou wrote:
> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
> are present in Juniper's PTX series of routers.
> 
> The MFD driver provices watchdog/i2c/gpio/mtd devices.
> 
> There are full device tree binding documents for the
> master mfd driver and for all slave drivers.
> 
> This patchset is against mainline as of today: v4.8-9431-g3477d16
> and is dependent on the "Juniper prerequisites" and
> "Juniper infrastructure" patchsets sent earlier.

Pointers to the patchsets please.

< snip >

-Frank

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

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
  2016-10-07 23:39     ` Frank Rowand
@ 2016-10-08  2:17         ` Frank Rowand
  -1 siblings, 0 replies; 47+ messages in thread
From: Frank Rowand @ 2016-10-08  2:17 UTC (permalink / raw)
  To: Pantelis Antoniou, Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Wolfram Sang, David Woodhouse, Brian Norris, Wim Van Sebroeck,
	Guenter Roeck, Peter Rosin, Debjit Ghosh, Georgi Vlaev,
	Guenter Roeck, JawaharBalaji Thirumalaisamy, Rajat Jain,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA

On 10/07/16 16:39, Frank Rowand wrote:
> On 10/07/16 08:17, Pantelis Antoniou wrote:
>> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
>> are present in Juniper's PTX series of routers.
>>
>> The MFD driver provices watchdog/i2c/gpio/mtd devices.
>>
>> There are full device tree binding documents for the
>> master mfd driver and for all slave drivers.
>>
>> This patchset is against mainline as of today: v4.8-9431-g3477d16
>> and is dependent on the "Juniper prerequisites" and
>> "Juniper infrastructure" patchsets sent earlier.
> 
> Pointers to the patchsets please.
> 

Nevermind.  Found them.

-Frank

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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] 47+ messages in thread

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
@ 2016-10-08  2:17         ` Frank Rowand
  0 siblings, 0 replies; 47+ messages in thread
From: Frank Rowand @ 2016-10-08  2:17 UTC (permalink / raw)
  To: Pantelis Antoniou, Lee Jones
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Wolfram Sang, David Woodhouse, Brian Norris, Wim Van Sebroeck,
	Guenter Roeck, Peter Rosin, Debjit Ghosh, Georgi Vlaev,
	Guenter Roeck, JawaharBalaji Thirumalaisamy, Rajat Jain,
	devicetree, linux-kernel, linux-gpio, linux-i2c, linux-mtd,
	linux-watchdog

On 10/07/16 16:39, Frank Rowand wrote:
> On 10/07/16 08:17, Pantelis Antoniou wrote:
>> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
>> are present in Juniper's PTX series of routers.
>>
>> The MFD driver provices watchdog/i2c/gpio/mtd devices.
>>
>> There are full device tree binding documents for the
>> master mfd driver and for all slave drivers.
>>
>> This patchset is against mainline as of today: v4.8-9431-g3477d16
>> and is dependent on the "Juniper prerequisites" and
>> "Juniper infrastructure" patchsets sent earlier.
> 
> Pointers to the patchsets please.
> 

Nevermind.  Found them.

-Frank

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

* Re: [PATCH 02/10] mfd: ptxpmb-cpld: Add documentation for PTXPMB CPLD
  2016-10-07 15:17   ` Pantelis Antoniou
@ 2016-10-10 17:38     ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 17:38 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Mark Rutland, Wolfram Sang, Linus Walleij, Guenter Roeck,
	Wim Van Sebroeck, linux-mtd, linux-i2c, Frank Rowand,
	Alexandre Courbot, Lee Jones, JawaharBalaji Thirumalaisamy,
	Guenter Roeck, devicetree, linux-watchdog, linux-gpio,
	Debjit Ghosh, Georgi Vlaev, Rajat Jain, linux-kernel,
	Brian Norris, David Woodhouse, Peter Rosin

On Fri, Oct 07, 2016 at 06:17:23PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add DT bindings document for the PTXPMB CPLD MFD device.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  .../devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt    | 76 ++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
> new file mode 100644
> index 0000000..cc3cbb9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
> @@ -0,0 +1,76 @@
> +* Device tree bindings for Juniper's PTXPMB CPLD FPGA MFD driver
> +
> +The device supports a number I2C muxes, hardware watchdog and a gpio block.
> +Those devices bindings are described in the jnx-i2c-mux-ptxpmb-cpld,
> +jnx-ptxpmb-wdt and jnx-gpio-ptxpmb-cpld documents.
> +
> +Required properties:
> +
> +- compatible:		"jnx,ptxpmb-cpld", "jnx,ngpmb-bcpld". They differ

bcpld? looks like a typo?

> +			in the i2c-mux blocks.
> +
> +- reg:			contains offset/length value for device state control
> +			registers space.
> +
> +Optional properties:
> +
> +- interrupts:		The interrupt line(s) the /IRQ signal(s) for the device is
> +			connected to.
> +
> +- interrupt-parent:	The parent interrupt controller.
> +
> +Example:
> +
> +cpld@0,0 {

What bus is this on? If just simple-bus, then just '...@0'

> +	compatible = "jnx,ptxpmb-cpld";
> +	reg = <0x0 0 0x10000>;

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH 02/10] mfd: ptxpmb-cpld: Add documentation for PTXPMB CPLD
@ 2016-10-10 17:38     ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 17:38 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, Oct 07, 2016 at 06:17:23PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add DT bindings document for the PTXPMB CPLD MFD device.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  .../devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt    | 76 ++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
> new file mode 100644
> index 0000000..cc3cbb9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-cpld.txt
> @@ -0,0 +1,76 @@
> +* Device tree bindings for Juniper's PTXPMB CPLD FPGA MFD driver
> +
> +The device supports a number I2C muxes, hardware watchdog and a gpio block.
> +Those devices bindings are described in the jnx-i2c-mux-ptxpmb-cpld,
> +jnx-ptxpmb-wdt and jnx-gpio-ptxpmb-cpld documents.
> +
> +Required properties:
> +
> +- compatible:		"jnx,ptxpmb-cpld", "jnx,ngpmb-bcpld". They differ

bcpld? looks like a typo?

> +			in the i2c-mux blocks.
> +
> +- reg:			contains offset/length value for device state control
> +			registers space.
> +
> +Optional properties:
> +
> +- interrupts:		The interrupt line(s) the /IRQ signal(s) for the device is
> +			connected to.
> +
> +- interrupt-parent:	The parent interrupt controller.
> +
> +Example:
> +
> +cpld@0,0 {

What bus is this on? If just simple-bus, then just '...@0'

> +	compatible = "jnx,ptxpmb-cpld";
> +	reg = <0x0 0 0x10000>;

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

* Re: [PATCH 04/10] watchdog: ptxpmb-wdt: Add ptxpmb-wdt device tree bindings
  2016-10-07 15:17   ` Pantelis Antoniou
@ 2016-10-10 17:41       ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 17:41 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, Oct 07, 2016 at 06:17:25PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> 
> Add binding document for the watchdog driver of PTXPMB CPLD.
> 
> Signed-off-by: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
>  .../devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt     | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
> new file mode 100644
> index 0000000..34b64f6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
> @@ -0,0 +1,17 @@
> +Juniper's PTXPMB FPGA watchdog driver
> +
> +Required properties:
> +
> +- compatible:	Should be "jnx,ptxpmb-wdt"
> +
> +Optional properties:
> +
> +- reg : Specifies base physical address and size of the registers. It is
> +  optional since the MFD parent driver supplies it, but can be overridden.

What the driver does is irrelevant. It should be required or there's no 
point to have the node. If the parent knows the address, then it knows 
the type of device too and DT is not needed.

> +
> +Example:
> +
> +wdt {

s/wdt/watchdog/

> +	compatible = "jnx,ptxpmb-wdt";
> +	/* no properties defined */
> +};
> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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] 47+ messages in thread

* Re: [PATCH 04/10] watchdog: ptxpmb-wdt: Add ptxpmb-wdt device tree bindings
@ 2016-10-10 17:41       ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 17:41 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, Oct 07, 2016 at 06:17:25PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add binding document for the watchdog driver of PTXPMB CPLD.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  .../devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt     | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
> new file mode 100644
> index 0000000..34b64f6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/watchdog/jnx-ptxpmb-wdt.txt
> @@ -0,0 +1,17 @@
> +Juniper's PTXPMB FPGA watchdog driver
> +
> +Required properties:
> +
> +- compatible:	Should be "jnx,ptxpmb-wdt"
> +
> +Optional properties:
> +
> +- reg : Specifies base physical address and size of the registers. It is
> +  optional since the MFD parent driver supplies it, but can be overridden.

What the driver does is irrelevant. It should be required or there's no 
point to have the node. If the parent knows the address, then it knows 
the type of device too and DT is not needed.

> +
> +Example:
> +
> +wdt {

s/wdt/watchdog/

> +	compatible = "jnx,ptxpmb-wdt";
> +	/* no properties defined */
> +};
> -- 
> 1.9.1
> 

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

* Re: [PATCH 06/10] i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
  2016-10-07 15:17     ` Pantelis Antoniou
@ 2016-10-10 17:45         ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 17:45 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, Oct 07, 2016 at 06:17:27PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> 
> Add binding document for the i2c driver of PTXPMB CPLD.
> 
> Signed-off-by: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
>  .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       | 50 ++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
> new file mode 100644
> index 0000000..3b201f7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
> @@ -0,0 +1,50 @@
> +* Juniper PTXPMB CPLD I2C Mux
> +
> +I2C mux on the PTXPMB CPLD on Juniper series of routers.
> +
> +Required properties:
> +
> +  - compatible: Must contain one of the following.
> +    "jnx,i2c-mux-ptxpmb-cpld", "jnx,i2c-mux-ngpmb-bcpld"
> +  - num-enable: Number of muxes to enable.

No. Use status property.

> +
> +  The following required properties are defined externally:
> +
> +  - Standard I2C mux properties. See i2c-mux.txt in this directory.
> +  - I2C child bus nodes. See i2c-mux.txt in this directory.
> +
> +Optional Properties:
> +
> +  - num-channels: Number of channels. If not present the default is 8.

What's a channel?

> +  - base-bus-num: Base bus number. If not present it is 0.

No. Linuxism and why do you care?

> +  - use-force: Use the force method of the controller.
> +
> +
> +Example:
> +
> +cpld-i2c-mux {

mux {

> +	compatible = "jnx,i2c-mux-ptxpmb-cpld";
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	i2c-parent = <&i2c1>;
> +
> +	num-enable = <1>;
> +
> +	i2c@0 {
> +		reg = <0>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		/* PMB devices are accessed through FPC */
> +
> +		temp-sensor@1a { /* FPC */
> +			compatible = "maxim,max6697";
> +			reg = <0x1a>;
> +			smbus-timeout-disable;
> +			resistance-cancellation;
> +			alert-mask = <0xff>;
> +			over-temperature-mask = <0xff>;
> +		};
> +	};
> +};
> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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] 47+ messages in thread

* Re: [PATCH 06/10] i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
@ 2016-10-10 17:45         ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 17:45 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, Oct 07, 2016 at 06:17:27PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add binding document for the i2c driver of PTXPMB CPLD.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       | 50 ++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
> new file mode 100644
> index 0000000..3b201f7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
> @@ -0,0 +1,50 @@
> +* Juniper PTXPMB CPLD I2C Mux
> +
> +I2C mux on the PTXPMB CPLD on Juniper series of routers.
> +
> +Required properties:
> +
> +  - compatible: Must contain one of the following.
> +    "jnx,i2c-mux-ptxpmb-cpld", "jnx,i2c-mux-ngpmb-bcpld"
> +  - num-enable: Number of muxes to enable.

No. Use status property.

> +
> +  The following required properties are defined externally:
> +
> +  - Standard I2C mux properties. See i2c-mux.txt in this directory.
> +  - I2C child bus nodes. See i2c-mux.txt in this directory.
> +
> +Optional Properties:
> +
> +  - num-channels: Number of channels. If not present the default is 8.

What's a channel?

> +  - base-bus-num: Base bus number. If not present it is 0.

No. Linuxism and why do you care?

> +  - use-force: Use the force method of the controller.
> +
> +
> +Example:
> +
> +cpld-i2c-mux {

mux {

> +	compatible = "jnx,i2c-mux-ptxpmb-cpld";
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	i2c-parent = <&i2c1>;
> +
> +	num-enable = <1>;
> +
> +	i2c@0 {
> +		reg = <0>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		/* PMB devices are accessed through FPC */
> +
> +		temp-sensor@1a { /* FPC */
> +			compatible = "maxim,max6697";
> +			reg = <0x1a>;
> +			smbus-timeout-disable;
> +			resistance-cancellation;
> +			alert-mask = <0xff>;
> +			over-temperature-mask = <0xff>;
> +		};
> +	};
> +};
> -- 
> 1.9.1
> 

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

* Re: [PATCH 08/10] gpio: ptxpmb-cpld: Document bindings of PTXPMB's CPLD GPIO
  2016-10-07 15:17   ` Pantelis Antoniou
@ 2016-10-10 18:08     ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 18:08 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd

On Fri, Oct 07, 2016 at 06:17:29PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add device tree bindings document for the GPIO driver of
> Juniper's PTXPMB/NGPMB CPLD.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  .../bindings/gpio/jnx,gpio-ptxpmb-cpld.txt         | 30 ++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
> new file mode 100644
> index 0000000..1122021
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
> @@ -0,0 +1,30 @@
> +Juniper PTXPMB CPLD GPIO block
> +
> +Required properties:
> +
> +- compatible:
> +    Must be "jnx,gpio-ptxpmb-cpld"
> +
> +- #gpio-cells:
> +    Should be <2>.  The first cell is the pin number (within the controller's
> +    pin space), and the second is used for the following flags:
> +	bit[0]: direction (0 = out, 1 = in)
> +	bit[1]: init high
> +	bit[2]: active low

Use and/or add standard flags.

> +
> +- gpio-controller:
> +    Specifies that the node is a GPIO controller.
> +
> +Optional properties:
> +
> +- reg:
> +    Address and length of the register set for the device. Usually supplied by
> +    the parent MFD driver

Make this mandatory.

> +
> +Example:
> +
> +gpio_cpld: cpld_gpio {
> +	compatible = "jnx,gpio-ptxpmb-cpld";
> +	#gpio-cells = <2>;
> +	gpio-controller;
> +};
> -- 
> 1.9.1
> 

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

* Re: [PATCH 08/10] gpio: ptxpmb-cpld: Document bindings of PTXPMB's CPLD GPIO
@ 2016-10-10 18:08     ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 18:08 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, Oct 07, 2016 at 06:17:29PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add device tree bindings document for the GPIO driver of
> Juniper's PTXPMB/NGPMB CPLD.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  .../bindings/gpio/jnx,gpio-ptxpmb-cpld.txt         | 30 ++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
> new file mode 100644
> index 0000000..1122021
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-cpld.txt
> @@ -0,0 +1,30 @@
> +Juniper PTXPMB CPLD GPIO block
> +
> +Required properties:
> +
> +- compatible:
> +    Must be "jnx,gpio-ptxpmb-cpld"
> +
> +- #gpio-cells:
> +    Should be <2>.  The first cell is the pin number (within the controller's
> +    pin space), and the second is used for the following flags:
> +	bit[0]: direction (0 = out, 1 = in)
> +	bit[1]: init high
> +	bit[2]: active low

Use and/or add standard flags.

> +
> +- gpio-controller:
> +    Specifies that the node is a GPIO controller.
> +
> +Optional properties:
> +
> +- reg:
> +    Address and length of the register set for the device. Usually supplied by
> +    the parent MFD driver

Make this mandatory.

> +
> +Example:
> +
> +gpio_cpld: cpld_gpio {
> +	compatible = "jnx,gpio-ptxpmb-cpld";
> +	#gpio-cells = <2>;
> +	gpio-controller;
> +};
> -- 
> 1.9.1
> 

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

* Re: [PATCH 10/10] mtd: ngpmb_nvram: Add bindings for Juniper's ngpmb NVRAM
  2016-10-07 15:17   ` Pantelis Antoniou
@ 2016-10-10 18:18       ` Rob Herring
  -1 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 18:18 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, Oct 07, 2016 at 06:17:31PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> 
> Add device tree binging document for the ngpmb NVRAM device.
> 
> Signed-off-by: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
>  .../devicetree/bindings/mtd/ngpmb-nvram.txt        | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
> 
> diff --git a/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
> new file mode 100644
> index 0000000..297ad0e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt

mtd is really flash. sram/ or nvmem/ are probably better choices.

> @@ -0,0 +1,22 @@
> +Non Volatile RAM device on a Juniper NG PMB FPGA
> +
> +These devices are found in the PTX series of Juniper routers.
> +
> +Required properties:
> +- compatible : must be "jnx,ngpmb-nvram"

Compatible with mmio-sram?

> +
> +Optional properties:
> +- reg : memory address for the RAM, note that this is not
> +required since usually the device is a subdevice of the SAM MFD
> +driver which fills in the register fields.
> +
> +For the rest of the properties, see mtd-physmap.txt.
> +
> +The device tree may optionally contain sub-nodes describing partitions of the
> +address space. See partition.txt for more detail.

sram or nvmem style partitioning is probably more appropriate.

> +
> +Example:
> +
> +ngpmb_nvram {
> +	compatible = "jnx,ngpmb-nvram";
> +};
> -- 
> 1.9.1
> 
--
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] 47+ messages in thread

* Re: [PATCH 10/10] mtd: ngpmb_nvram: Add bindings for Juniper's ngpmb NVRAM
@ 2016-10-10 18:18       ` Rob Herring
  0 siblings, 0 replies; 47+ messages in thread
From: Rob Herring @ 2016-10-10 18:18 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, Oct 07, 2016 at 06:17:31PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add device tree binging document for the ngpmb NVRAM device.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  .../devicetree/bindings/mtd/ngpmb-nvram.txt        | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
> 
> diff --git a/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt
> new file mode 100644
> index 0000000..297ad0e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/ngpmb-nvram.txt

mtd is really flash. sram/ or nvmem/ are probably better choices.

> @@ -0,0 +1,22 @@
> +Non Volatile RAM device on a Juniper NG PMB FPGA
> +
> +These devices are found in the PTX series of Juniper routers.
> +
> +Required properties:
> +- compatible : must be "jnx,ngpmb-nvram"

Compatible with mmio-sram?

> +
> +Optional properties:
> +- reg : memory address for the RAM, note that this is not
> +required since usually the device is a subdevice of the SAM MFD
> +driver which fills in the register fields.
> +
> +For the rest of the properties, see mtd-physmap.txt.
> +
> +The device tree may optionally contain sub-nodes describing partitions of the
> +address space. See partition.txt for more detail.

sram or nvmem style partitioning is probably more appropriate.

> +
> +Example:
> +
> +ngpmb_nvram {
> +	compatible = "jnx,ngpmb-nvram";
> +};
> -- 
> 1.9.1
> 

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

* Re: [PATCH 06/10] i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
  2016-10-10 17:45         ` Rob Herring
@ 2016-10-11  7:36           ` Peter Rosin
  -1 siblings, 0 replies; 47+ messages in thread
From: Peter Rosin @ 2016-10-11  7:36 UTC (permalink / raw)
  To: Rob Herring, Pantelis Antoniou
  Cc: Mark Rutland, Alexandre Courbot, Georgi Vlaev, linux-watchdog,
	Wolfram Sang, devicetree, Frank Rowand, Linus Walleij,
	Guenter Roeck, linux-kernel, JawaharBalaji Thirumalaisamy,
	linux-gpio, Wim Van Sebroeck, linux-mtd, Debjit Ghosh,
	Rajat Jain, Brian Norris, Lee Jones, David Woodhouse,
	Guenter Roeck, linux-i2c

On 2016-10-10 19:45, Rob Herring wrote:
> On Fri, Oct 07, 2016 at 06:17:27PM +0300, Pantelis Antoniou wrote:
>> From: Georgi Vlaev <gvlaev@juniper.net>
>>
>> Add binding document for the i2c driver of PTXPMB CPLD.
>>
>> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
>> [Ported from Juniper kernel]
>> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
>> ---
>>  .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       | 50 ++++++++++++++++++++++
>>  1 file changed, 50 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
>>
>> diff --git a/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
>> new file mode 100644
>> index 0000000..3b201f7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
>> @@ -0,0 +1,50 @@
>> +* Juniper PTXPMB CPLD I2C Mux
>> +
>> +I2C mux on the PTXPMB CPLD on Juniper series of routers.
>> +
>> +Required properties:
>> +
>> +  - compatible: Must contain one of the following.
>> +    "jnx,i2c-mux-ptxpmb-cpld", "jnx,i2c-mux-ngpmb-bcpld"
>> +  - num-enable: Number of muxes to enable.
> 
> No. Use status property.

Reading the code, I understand this mux to be like a combination of
i2c switches (like pca9548) where the slave i2c busses can be
enabled individually using an "enable" bitmask in one register, and
"regular" i2c muxes (like pca9547) where you can only select one
slave i2c bus at a time using an enumeration.

num-enable would be the number of switches and num-channels would be
the number of muxes per switch channel. Or the other way around? This
is a real problem. The bindings are too tightly coupled to the way
Linux currently handles i2c switches (i.e. not very well, you can only
select one slave bus on an i2c switch, thus reducing the more
flexible switch hardware to a regular mux). The bindings should not
describe what the driver does, they should describe the hardware.

Basically, you need to describe the i2c topology of the hardware in
the bindings, because I'm just guessing all this, and I shouldn't
have to.

Cheers,
Peter

>> +
>> +  The following required properties are defined externally:
>> +
>> +  - Standard I2C mux properties. See i2c-mux.txt in this directory.
>> +  - I2C child bus nodes. See i2c-mux.txt in this directory.
>> +
>> +Optional Properties:
>> +
>> +  - num-channels: Number of channels. If not present the default is 8.
> 
> What's a channel?
> 
>> +  - base-bus-num: Base bus number. If not present it is 0.
> 
> No. Linuxism and why do you care?
> 
>> +  - use-force: Use the force method of the controller.
>> +
>> +
>> +Example:
>> +
>> +cpld-i2c-mux {
> 
> mux {
> 
>> +	compatible = "jnx,i2c-mux-ptxpmb-cpld";
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +
>> +	i2c-parent = <&i2c1>;
>> +
>> +	num-enable = <1>;
>> +
>> +	i2c@0 {
>> +		reg = <0>;
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		/* PMB devices are accessed through FPC */
>> +
>> +		temp-sensor@1a { /* FPC */
>> +			compatible = "maxim,max6697";
>> +			reg = <0x1a>;
>> +			smbus-timeout-disable;
>> +			resistance-cancellation;
>> +			alert-mask = <0xff>;
>> +			over-temperature-mask = <0xff>;
>> +		};
>> +	};
>> +};
>> -- 
>> 1.9.1
>>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH 06/10] i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings
@ 2016-10-11  7:36           ` Peter Rosin
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Rosin @ 2016-10-11  7:36 UTC (permalink / raw)
  To: Rob Herring, Pantelis Antoniou
  Cc: Lee Jones, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Debjit Ghosh, Georgi Vlaev,
	Guenter Roeck, JawaharBalaji Thirumalaisamy, Rajat Jain,
	devicetree, linux-kernel, linux-gpio, linux-i2c, linux-mtd,
	linux-watchdog

On 2016-10-10 19:45, Rob Herring wrote:
> On Fri, Oct 07, 2016 at 06:17:27PM +0300, Pantelis Antoniou wrote:
>> From: Georgi Vlaev <gvlaev@juniper.net>
>>
>> Add binding document for the i2c driver of PTXPMB CPLD.
>>
>> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
>> [Ported from Juniper kernel]
>> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
>> ---
>>  .../bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt       | 50 ++++++++++++++++++++++
>>  1 file changed, 50 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
>>
>> diff --git a/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
>> new file mode 100644
>> index 0000000..3b201f7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/i2c/jnx,i2c-mux-ptxpmb-cpld.txt
>> @@ -0,0 +1,50 @@
>> +* Juniper PTXPMB CPLD I2C Mux
>> +
>> +I2C mux on the PTXPMB CPLD on Juniper series of routers.
>> +
>> +Required properties:
>> +
>> +  - compatible: Must contain one of the following.
>> +    "jnx,i2c-mux-ptxpmb-cpld", "jnx,i2c-mux-ngpmb-bcpld"
>> +  - num-enable: Number of muxes to enable.
> 
> No. Use status property.

Reading the code, I understand this mux to be like a combination of
i2c switches (like pca9548) where the slave i2c busses can be
enabled individually using an "enable" bitmask in one register, and
"regular" i2c muxes (like pca9547) where you can only select one
slave i2c bus at a time using an enumeration.

num-enable would be the number of switches and num-channels would be
the number of muxes per switch channel. Or the other way around? This
is a real problem. The bindings are too tightly coupled to the way
Linux currently handles i2c switches (i.e. not very well, you can only
select one slave bus on an i2c switch, thus reducing the more
flexible switch hardware to a regular mux). The bindings should not
describe what the driver does, they should describe the hardware.

Basically, you need to describe the i2c topology of the hardware in
the bindings, because I'm just guessing all this, and I shouldn't
have to.

Cheers,
Peter

>> +
>> +  The following required properties are defined externally:
>> +
>> +  - Standard I2C mux properties. See i2c-mux.txt in this directory.
>> +  - I2C child bus nodes. See i2c-mux.txt in this directory.
>> +
>> +Optional Properties:
>> +
>> +  - num-channels: Number of channels. If not present the default is 8.
> 
> What's a channel?
> 
>> +  - base-bus-num: Base bus number. If not present it is 0.
> 
> No. Linuxism and why do you care?
> 
>> +  - use-force: Use the force method of the controller.
>> +
>> +
>> +Example:
>> +
>> +cpld-i2c-mux {
> 
> mux {
> 
>> +	compatible = "jnx,i2c-mux-ptxpmb-cpld";
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +
>> +	i2c-parent = <&i2c1>;
>> +
>> +	num-enable = <1>;
>> +
>> +	i2c@0 {
>> +		reg = <0>;
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		/* PMB devices are accessed through FPC */
>> +
>> +		temp-sensor@1a { /* FPC */
>> +			compatible = "maxim,max6697";
>> +			reg = <0x1a>;
>> +			smbus-timeout-disable;
>> +			resistance-cancellation;
>> +			alert-mask = <0xff>;
>> +			over-temperature-mask = <0xff>;
>> +		};
>> +	};
>> +};
>> -- 
>> 1.9.1
>>

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

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
  2016-10-07 15:17 ` Pantelis Antoniou
@ 2016-10-20 13:42   ` Linus Walleij
  -1 siblings, 0 replies; 47+ messages in thread
From: Linus Walleij @ 2016-10-20 13:42 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Rob Herring, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio@vger.kernel.org

On Fri, Oct 7, 2016 at 5:17 PM, Pantelis Antoniou
<pantelis.antoniou@konsulko.com> wrote:

> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
> are present in Juniper's PTX series of routers.
>
> The MFD driver provices watchdog/i2c/gpio/mtd devices.

Since it's quite a bunch of patches to quite a bunch of controllers
I think it's best if you get the MFD parts ready and merged through
Lee first for v4.10, then we can add the subdrivers on top, maybe
in v4.11, or on top of an immutable branch from Lee once he is
happy with the core if the MFD core is finished quickly.

I will review all the GPIO stuff though so you can revise these
patches too :)

Yours,
Linus Walleij

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

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
@ 2016-10-20 13:42   ` Linus Walleij
  0 siblings, 0 replies; 47+ messages in thread
From: Linus Walleij @ 2016-10-20 13:42 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Rob Herring, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, Oct 7, 2016 at 5:17 PM, Pantelis Antoniou
<pantelis.antoniou@konsulko.com> wrote:

> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
> are present in Juniper's PTX series of routers.
>
> The MFD driver provices watchdog/i2c/gpio/mtd devices.

Since it's quite a bunch of patches to quite a bunch of controllers
I think it's best if you get the MFD parts ready and merged through
Lee first for v4.10, then we can add the subdrivers on top, maybe
in v4.11, or on top of an immutable branch from Lee once he is
happy with the core if the MFD core is finished quickly.

I will review all the GPIO stuff though so you can revise these
patches too :)

Yours,
Linus Walleij

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

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
  2016-10-20 13:42   ` Linus Walleij
@ 2016-10-20 13:43     ` Pantelis Antoniou
  -1 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-20 13:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Lee Jones, Rob Herring, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio@vger.kernel.org

Hi Linus,

> On Oct 20, 2016, at 16:42 , Linus Walleij <linus.walleij@linaro.org> wrote:
> 
> On Fri, Oct 7, 2016 at 5:17 PM, Pantelis Antoniou
> <pantelis.antoniou@konsulko.com> wrote:
> 
>> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
>> are present in Juniper's PTX series of routers.
>> 
>> The MFD driver provices watchdog/i2c/gpio/mtd devices.
> 
> Since it's quite a bunch of patches to quite a bunch of controllers
> I think it's best if you get the MFD parts ready and merged through
> Lee first for v4.10, then we can add the subdrivers on top, maybe
> in v4.11, or on top of an immutable branch from Lee once he is
> happy with the core if the MFD core is finished quickly.
> 

Will do.

> I will review all the GPIO stuff though so you can revise these
> patches too :)
> 

Goodie :)

> Yours,
> Linus Walleij

Regards

— Pantelis

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

* Re: [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver
@ 2016-10-20 13:43     ` Pantelis Antoniou
  0 siblings, 0 replies; 47+ messages in thread
From: Pantelis Antoniou @ 2016-10-20 13:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Lee Jones, Rob Herring, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

Hi Linus,

> On Oct 20, 2016, at 16:42 , Linus Walleij <linus.walleij@linaro.org> wrote:
> 
> On Fri, Oct 7, 2016 at 5:17 PM, Pantelis Antoniou
> <pantelis.antoniou@konsulko.com> wrote:
> 
>> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
>> are present in Juniper's PTX series of routers.
>> 
>> The MFD driver provices watchdog/i2c/gpio/mtd devices.
> 
> Since it's quite a bunch of patches to quite a bunch of controllers
> I think it's best if you get the MFD parts ready and merged through
> Lee first for v4.10, then we can add the subdrivers on top, maybe
> in v4.11, or on top of an immutable branch from Lee once he is
> happy with the core if the MFD core is finished quickly.
> 

Will do.

> I will review all the GPIO stuff though so you can revise these
> patches too :)
> 

Goodie :)

> Yours,
> Linus Walleij

Regards

— Pantelis

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

* Re: [PATCH 07/10] gpio: ptxpmb-cpld: Add support for PTXPMB CPLD's GPIO
  2016-10-07 15:17   ` Pantelis Antoniou
@ 2016-10-20 22:24       ` Linus Walleij
  -1 siblings, 0 replies; 47+ messages in thread
From: Linus Walleij @ 2016-10-20 22:24 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Rob Herring, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

On Fri, Oct 7, 2016 at 5:17 PM, Pantelis Antoniou
<pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org> wrote:

> From: Guenter Roeck <groeck-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
>
> Support the GPIO block which is located in PTXPMB CPLDs
> on relevant Juniper platforms.
>
> Signed-off-by: Georgi Vlaev <gvlaev-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> Signed-off-by: Guenter Roeck <groeck-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> Signed-off-by: Rajat Jain <rajatjain-3r7Miqu9kMnR7s880joybQ@public.gmane.org>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

Nice with preserved credits.

> +config GPIO_PTXPMB_CPLD
> +       tristate "PTXPMB CPLD GPIO"
> +       depends on MFD_JUNIPER_CPLD
> +       default y if MFD_JUNIPER_CPLD

Can't you do something like

default MFD_JUNIPER_CPLD

so it will become a module if the MFD driver is a module
and compiled-in if the MFD driver is compiled in?

Please check if that works.

> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/pci.h>
> +#include <linux/gpio.h>

Just:
#include <linux/gpio/driver.h>

Should work.

> +#include <linux/errno.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_gpio.h>

Strange that a PCI driver need so much OF stuff.
Really? But OK, do you really use all these includes?

> +#include <linux/io.h>
> +#include <linux/module.h>
> +
> +#include <linux/mfd/ptxpmb_cpld.h>

Is this include deserving a separate whitespace in
front of it?

> +static u8 *ptxpmb_cpld_gpio_get_addr(struct pmb_boot_cpld *cpld,
> +                                    unsigned int nr)
> +{
> +       if (nr < 8)                     /* 0..7: reset                  */
> +               return &cpld->reset;
> +       else if (nr < 16)               /* 8..15: control               */
> +               return &cpld->control;
> +       else if (nr < 24)               /* 16..23: gpio1                */
> +               return &cpld->gpio_1;
> +       else if (nr < 32)               /* 24..31: gpio2                */
> +               return &cpld->gpio_2;
> +       else if (nr < 40)               /* 32..39: gp_reset1            */
> +               return &cpld->gp_reset1;
> +       return &cpld->thermal_status;   /* 40..41: thermal status       */
> +}

Reset, control, gp_reset and *especially* thermal status
does not seem to be GPIO at all. Rather these seem to be
special purpose lines rather than general purpose.

Can you explain why the GPIO driver should even poke at them?

It seems other subdrivers should use these registers...

> +static void ptxpmb_cpld_gpio_set(struct gpio_chip *gpio, unsigned int nr,
> +                                int val)
> +{
> +       u32 reg;
> +       u8 bit = 1 << (nr & 7);

Use this:

#include <linux/bitops.h>

Then inline BIT() instead of making a local variable like this.
See below...

> +       struct ptxpmb_cpld_gpio *chip =
> +         container_of(gpio, struct ptxpmb_cpld_gpio, gpio);

Use:
struct ptxpmb_cpld_gpio *cpldg = gpiochip_get_data(gpio);

Please don't name it "chip" it is confusing with the gpio chip
proper.

> +       u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
> +
> +       mutex_lock(&chip->lock);
> +       reg = ioread8(addr);
> +       if (val)
> +               reg |= bit;
> +       else
> +               reg &= ~bit;

So instead:
if (val)
    reg |= BIT(nr);
else
    reg &= ~BIT(nr);

> +static int ptxpmb_cpld_gpio_get(struct gpio_chip *gpio, unsigned int nr)
> +{
> +       struct ptxpmb_cpld_gpio *chip = container_of(gpio,
> +                                                    struct ptxpmb_cpld_gpio,
> +                                                    gpio);

Same comment as before.

> +       u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
> +       u8 bit = 1 << (nr & 7);
> +
> +       return !!(ioread8(addr) & bit);

Same comment on using BIT()

> +static int ptxpmb_cpld_gpio_direction_output(struct gpio_chip *gpio,
> +                                            unsigned int nr, int val)
> +{
> +       return 0;
> +}
> +
> +static int ptxpmb_cpld_gpio_direction_input(struct gpio_chip *gpio,
> +                                           unsigned int nr)
> +{
> +       return 0;
> +}

Oh yeah? Can you explain how this works electronically?

If these lines are open drain you should also implement
.set_single_ended().

> +static void ptxpmb_cpld_gpio_setup(struct ptxpmb_cpld_gpio *chip)

Again rename from chip.

> +static int ptxpmb_cpld_gpio_probe(struct platform_device *pdev)
> +{
> +       int ret;
> +       struct ptxpmb_cpld_gpio *chip;

Rename from chip.

> +       struct resource *res;
> +       struct device *dev = &pdev->dev;
> +
> +       chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
> +       if (chip == NULL)
> +               return -ENOMEM;
> +
> +       chip->dev = dev;
> +       platform_set_drvdata(pdev, chip);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res)
> +               return -ENODEV;
> +
> +       chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
> +       if (!chip->base)
> +               return -ENOMEM;
> +
> +       mutex_init(&chip->lock);
> +       ptxpmb_cpld_gpio_setup(chip);
> +       ret = gpiochip_add(&chip->gpio);

Use devm_gpiochip_add_data() so you can use gpiochip_get_data() in the
callbacks and get rid of container_of().

> +       if (ret) {
> +               dev_err(dev, "CPLD gpio: Failed to register GPIO\n");
> +               return ret;
> +       }
> +       return 0;
> +}
> +
> +static int ptxpmb_cpld_gpio_remove(struct platform_device *pdev)
> +{
> +       struct ptxpmb_cpld_gpio *chip = platform_get_drvdata(pdev);
> +
> +       gpiochip_remove(&chip->gpio);
> +
> +       return 0;
> +}

If you use devm_gpiochip_add_data() I don't think this function is
even needed.

Yours,
Linus Walleij
--
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] 47+ messages in thread

* Re: [PATCH 07/10] gpio: ptxpmb-cpld: Add support for PTXPMB CPLD's GPIO
@ 2016-10-20 22:24       ` Linus Walleij
  0 siblings, 0 replies; 47+ messages in thread
From: Linus Walleij @ 2016-10-20 22:24 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Lee Jones, Rob Herring, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, Oct 7, 2016 at 5:17 PM, Pantelis Antoniou
<pantelis.antoniou@konsulko.com> wrote:

> From: Guenter Roeck <groeck@juniper.net>
>
> Support the GPIO block which is located in PTXPMB CPLDs
> on relevant Juniper platforms.
>
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> Signed-off-by: Guenter Roeck <groeck@juniper.net>
> Signed-off-by: Rajat Jain <rajatjain@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>

Nice with preserved credits.

> +config GPIO_PTXPMB_CPLD
> +       tristate "PTXPMB CPLD GPIO"
> +       depends on MFD_JUNIPER_CPLD
> +       default y if MFD_JUNIPER_CPLD

Can't you do something like

default MFD_JUNIPER_CPLD

so it will become a module if the MFD driver is a module
and compiled-in if the MFD driver is compiled in?

Please check if that works.

> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/pci.h>
> +#include <linux/gpio.h>

Just:
#include <linux/gpio/driver.h>

Should work.

> +#include <linux/errno.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_gpio.h>

Strange that a PCI driver need so much OF stuff.
Really? But OK, do you really use all these includes?

> +#include <linux/io.h>
> +#include <linux/module.h>
> +
> +#include <linux/mfd/ptxpmb_cpld.h>

Is this include deserving a separate whitespace in
front of it?

> +static u8 *ptxpmb_cpld_gpio_get_addr(struct pmb_boot_cpld *cpld,
> +                                    unsigned int nr)
> +{
> +       if (nr < 8)                     /* 0..7: reset                  */
> +               return &cpld->reset;
> +       else if (nr < 16)               /* 8..15: control               */
> +               return &cpld->control;
> +       else if (nr < 24)               /* 16..23: gpio1                */
> +               return &cpld->gpio_1;
> +       else if (nr < 32)               /* 24..31: gpio2                */
> +               return &cpld->gpio_2;
> +       else if (nr < 40)               /* 32..39: gp_reset1            */
> +               return &cpld->gp_reset1;
> +       return &cpld->thermal_status;   /* 40..41: thermal status       */
> +}

Reset, control, gp_reset and *especially* thermal status
does not seem to be GPIO at all. Rather these seem to be
special purpose lines rather than general purpose.

Can you explain why the GPIO driver should even poke at them?

It seems other subdrivers should use these registers...

> +static void ptxpmb_cpld_gpio_set(struct gpio_chip *gpio, unsigned int nr,
> +                                int val)
> +{
> +       u32 reg;
> +       u8 bit = 1 << (nr & 7);

Use this:

#include <linux/bitops.h>

Then inline BIT() instead of making a local variable like this.
See below...

> +       struct ptxpmb_cpld_gpio *chip =
> +         container_of(gpio, struct ptxpmb_cpld_gpio, gpio);

Use:
struct ptxpmb_cpld_gpio *cpldg = gpiochip_get_data(gpio);

Please don't name it "chip" it is confusing with the gpio chip
proper.

> +       u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
> +
> +       mutex_lock(&chip->lock);
> +       reg = ioread8(addr);
> +       if (val)
> +               reg |= bit;
> +       else
> +               reg &= ~bit;

So instead:
if (val)
    reg |= BIT(nr);
else
    reg &= ~BIT(nr);

> +static int ptxpmb_cpld_gpio_get(struct gpio_chip *gpio, unsigned int nr)
> +{
> +       struct ptxpmb_cpld_gpio *chip = container_of(gpio,
> +                                                    struct ptxpmb_cpld_gpio,
> +                                                    gpio);

Same comment as before.

> +       u8 *addr = ptxpmb_cpld_gpio_get_addr(chip->base, nr);
> +       u8 bit = 1 << (nr & 7);
> +
> +       return !!(ioread8(addr) & bit);

Same comment on using BIT()

> +static int ptxpmb_cpld_gpio_direction_output(struct gpio_chip *gpio,
> +                                            unsigned int nr, int val)
> +{
> +       return 0;
> +}
> +
> +static int ptxpmb_cpld_gpio_direction_input(struct gpio_chip *gpio,
> +                                           unsigned int nr)
> +{
> +       return 0;
> +}

Oh yeah? Can you explain how this works electronically?

If these lines are open drain you should also implement
.set_single_ended().

> +static void ptxpmb_cpld_gpio_setup(struct ptxpmb_cpld_gpio *chip)

Again rename from chip.

> +static int ptxpmb_cpld_gpio_probe(struct platform_device *pdev)
> +{
> +       int ret;
> +       struct ptxpmb_cpld_gpio *chip;

Rename from chip.

> +       struct resource *res;
> +       struct device *dev = &pdev->dev;
> +
> +       chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
> +       if (chip == NULL)
> +               return -ENOMEM;
> +
> +       chip->dev = dev;
> +       platform_set_drvdata(pdev, chip);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res)
> +               return -ENODEV;
> +
> +       chip->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
> +       if (!chip->base)
> +               return -ENOMEM;
> +
> +       mutex_init(&chip->lock);
> +       ptxpmb_cpld_gpio_setup(chip);
> +       ret = gpiochip_add(&chip->gpio);

Use devm_gpiochip_add_data() so you can use gpiochip_get_data() in the
callbacks and get rid of container_of().

> +       if (ret) {
> +               dev_err(dev, "CPLD gpio: Failed to register GPIO\n");
> +               return ret;
> +       }
> +       return 0;
> +}
> +
> +static int ptxpmb_cpld_gpio_remove(struct platform_device *pdev)
> +{
> +       struct ptxpmb_cpld_gpio *chip = platform_get_drvdata(pdev);
> +
> +       gpiochip_remove(&chip->gpio);
> +
> +       return 0;
> +}

If you use devm_gpiochip_add_data() I don't think this function is
even needed.

Yours,
Linus Walleij

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

* Re: [PATCH 01/10] mfd: Juniper PTXPMB CPLD Multi-function core driver
  2016-10-07 15:17   ` Pantelis Antoniou
  (?)
@ 2016-10-26 13:50     ` Lee Jones
  -1 siblings, 0 replies; 47+ messages in thread
From: Lee Jones @ 2016-10-26 13:50 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd

On Fri, 07 Oct 2016, Pantelis Antoniou wrote:

> From: Guenter Roeck <groeck@juniper.net>
> 
> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
> are present in Juniper's PTX series of routers.
> 
> There are two variants, the original which is found on the
> PTXPMB_P2020, PTXPMB_P2020_SPMB based on a Freescale P2020 SoC,
> and PTXPMB_P5040 based on a Freescale P5040 SoC.
> 
> The new variant NGPMB is present on a new line of x86 based
> boards (currently only the Gladiator FPC).
> 
> Both variants provide a hardware watchdog, i2c mux and a
> gpio block, with the i2c mux block being different.
> 
> Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> Signed-off-by: Guenter Roeck <groeck@juniper.net>
> Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
> Signed-off-by: Rajat Jain <rajatjain@juniper.net>
> Signed-off-by: Tom Kavanagh <tkavanagh@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  drivers/mfd/Kconfig             |  15 ++
>  drivers/mfd/Makefile            |   1 +
>  drivers/mfd/ptxpmb-cpld-core.c  | 406 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/ptxpmb_cpld.h | 140 ++++++++++++++
>  4 files changed, 562 insertions(+)
>  create mode 100644 drivers/mfd/ptxpmb-cpld-core.c
>  create mode 100644 include/linux/mfd/ptxpmb_cpld.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 2caf7e9..438666a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1340,6 +1340,21 @@ config TWL4030_POWER
>  	  and load scripts controlling which resources are switched off/on
>  	  or reset when a sleep, wakeup or warm reset event occurs.
>  
> +config MFD_JUNIPER_CPLD
> +	tristate "Juniper PTX PMB CPLD"
> +	depends on (PTXPMB_COMMON || JNX_PTX_NGPMB)
> +	default y if (PTXPMB_COMMON || JNX_PTX_NGPMB)

Nit: I'd like to see the default line above 'depends|select'.

> +	select MFD_CORE
> +	select I2C_MUX_PTXPMB
> +	select GPIO_PTXPMB_CPLD
> +	select JNX_PTXPMB_WDT

I don't think these should be selected blindly from here.

> +	help
> +	  Select this to enable the PTX PMB CPLD multi-function kernel driver

What is PTX PMB?

> +	  for the applicable Juniper platforms.

What applicable platforms?  Might wish to consider removing this part.

It would also be nice to mention what functionality this provides and
little more info besides "this enables".

> +	  This driver can be built as a module. If built as a module it will be
> +	  called "ptxpmb-cpld"
> +
>  config MFD_TWL4030_AUDIO
>  	bool "TI TWL4030 Audio"
>  	depends on TWL4030_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 2bf6a1a..62decc9 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -148,6 +148,7 @@ obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
>  obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
>  obj-$(CONFIG_AB8500_DEBUG)	+= ab8500-debugfs.o
>  obj-$(CONFIG_AB8500_GPADC)	+= ab8500-gpadc.o
> +obj-$(CONFIG_MFD_JUNIPER_CPLD)	+= ptxpmb-cpld-core.o

Is there only ever going to be one Juniper CPLD?

>  obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
>  # ab8500-core need to come after db8500-prcmu (which provides the channel)
>  obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
> diff --git a/drivers/mfd/ptxpmb-cpld-core.c b/drivers/mfd/ptxpmb-cpld-core.c
> new file mode 100644
> index 0000000..18e60a4
> --- /dev/null
> +++ b/drivers/mfd/ptxpmb-cpld-core.c
> @@ -0,0 +1,406 @@
> +/*
> + * Juniper PTX PMB CPLD multi-function core driver

Please expand on what a PTX PMB is.

> + * Copyright (C) 2012 Juniper Networks

This needs updating.

Why is this required now and not in the past 4 years?

> + * 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 program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *

Superfluous line.

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/sched.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/dmi.h>
> +#include <linux/mfd/core.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/ptxpmb_cpld.h>
> +#include <linux/jnx/jnx-subsys.h>
> +#include <linux/jnx/board_ids.h>

Alphabetical.

> +struct pmb_cpld_core {
> +	struct device		*dev;
> +	struct pmb_boot_cpld __iomem *cpld;

This isn't how we usually handle IO registers.

> +	spinlock_t		lock;
> +	int			irq;
> +	wait_queue_head_t	wqh;

This is not a very good variable name.

> +};
> +
> +static const struct of_device_id pmb_cpld_of_ids[] = {
> +	{ .compatible = "jnx,ptxpmb-cpld", .data = (void *)CPLD_TYPE_PTXPMB },
> +	{ .compatible = "jnx,ngpmb-bcpld", .data = (void *)CPLD_TYPE_NGPMB },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, pmb_cpld_of_ids);

Place this just before it's about to be used.  Since you're matching
on this, I would expect it be be located just above .probe().

> +static struct dmi_system_id gld_2t_dmi_data[] = {
> +	{
> +		.ident = "Juniper Networks Gladiator 2T FPC",
> +		.matches = {
> +			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
> +			    DMI_MATCH(DMI_PRODUCT_NAME, "0BF9"),
> +			},
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(dmi, gld_2t_dmi_data);
> +
> +static struct dmi_system_id gld_3t_dmi_data[] = {
> +	{
> +		.ident = "Juniper Networks Gladiator 3T FPC",
> +		.matches = {
> +			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
> +			    DMI_MATCH(DMI_PRODUCT_NAME, "0BFA"),
> +			},
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(dmi, gld_3t_dmi_data);
> +
> +static int ptxpmb_cpld_get_master(void *data)
> +{
> +	struct pmb_cpld_core *cpld = data;
> +	u8 s1;

s1 is not a good variable name.

> +	s1 = ioread8(&cpld->cpld->i2c_host_sel) & CPLD_I2C_HOST_MSTR_MASK;

Why aren't you using readb()?

> +	if ((s1 & CPLD_I2C_HOST0_MSTR) == CPLD_I2C_HOST0_MSTR)
> +		return 0;

Define this.

> +	if ((s1 & CPLD_I2C_HOST1_MSTR) == CPLD_I2C_HOST1_MSTR)
> +		return 1;

And this.

> +	return -1;

Why aren't you using Linux error numbers.

> +}
> +
> +static int ngpmb_cpld_get_master(void *data)
> +{
> +	struct pmb_cpld_core *cpld = data;
> +
> +	if (ioread8(&cpld->cpld->baseboard_status1) & NGPMB_MASTER_SELECT)
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static irqreturn_t pmb_cpld_core_interrupt(int irq, void *dev_data)
> +{
> +	struct pmb_cpld_core *cpld = dev_data;
> +
> +	pr_info("pmb_cpld_core_interrupt %d\n", irq);

This should be dgb at most, but doesn't really have any place in
Mainline code.  Please remove it.

> +	spin_lock(&cpld->wqh.lock);
> +
> +	/* clear interrupt, wake up any handlers */
> +	wake_up_locked(&cpld->wqh);
> +
> +	spin_unlock(&cpld->wqh.lock);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct resource pmb_cpld_resources[] = {
> +	{
> +		.start	= 0,
> +		.end	= sizeof(struct pmb_boot_cpld) - 1,

Define these properly.

> +		.flags	= IORESOURCE_MEM,
> +	},
> +};

Use the DEFINE_RES_*() helpers.

> +static struct mfd_cell pmb_cpld_cells[] = {
> +	{
> +		.name = "jnx-ptxpmb-wdt",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,ptxpmb-wdt",
> +	},
> +	{
> +		.name = "i2c-mux-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,i2c-mux-ptxpmb-cpld",
> +	},
> +	{
> +		.name = "gpio-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,gpio-ptxpmb-cpld",
> +	},
> +};
> +
> +static struct mfd_cell ngpmb_cpld_cells[] = {
> +	{
> +		.name = "jnx-ptxpmb-wdt",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,ptxpmb-wdt",
> +	},
> +	{
> +		.name = "i2c-mux-ngpmb-bcpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,i2c-mux-ngpmb-bcpld",
> +	},
> +	{
> +		.name = "gpio-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,gpio-ptxpmb-cpld",
> +	},
> +};
> +
> +static void cpld_ngpmb_init(struct pmb_cpld_core *cpld,
> +			    struct jnx_chassis_info *chinfo,
> +			    struct jnx_card_info *cinfo)
> +{
> +	u8 s1, s2, val, chassis;

s1 and s1 are not good variable names.

status1 and status2 would be better.

> +	s1 = ioread8(&cpld->cpld->baseboard_status1);
> +	s2 = ioread8(&cpld->cpld->baseboard_status2);
> +	chassis = (ioread8(&cpld->cpld->board.ngpmb.chassis_type)
> +		   & NGPMB_CHASSIS_TYPE_MASK) >> NGPMB_CHASSIS_TYPE_LSB;
> +
> +	dev_info(cpld->dev, "Revision 0x%02X chassis type %s (0x%02X)\n",
> +		 ioread8(&cpld->cpld->cpld_rev),
> +		 chassis == NGPMB_CHASSIS_TYPE_POLARIS ? "PTX-1000" :
> +		 chassis == NGPMB_CHASSIS_TYPE_HENDRICKS ? "PTX-3000" :
> +		 "Unknown", chassis);
> +
> +	/* Only the Gladiator 2t/3t FPC */
> +	if (dmi_check_system(gld_2t_dmi_data) ||
> +	    dmi_check_system(gld_3t_dmi_data)) {
> +		/* Take SAM FPGA out of reset */
> +		val = ioread8(&cpld->cpld->gpio_2);
> +		iowrite8(val | NGPMB_GPIO2_TO_BASEBRD_LSB, &cpld->cpld->gpio_2);
> +		mdelay(10);
> +	} else {
> +		/*
> +		 * Get the PAM FPGA out of reset,
> +		 * and wait for 100ms as per HW manual
> +		 */
> +		val = ioread8(&cpld->cpld->reset);
> +		iowrite8(val & ~NGPMB_PCIE_OTHER_RESET, &cpld->cpld->reset);
> +		mdelay(100);
> +	}
> +
> +	/* No Card / Chassis info needed in stand alone mode */
> +	if (!(s1 & NGPMB_PMB_STANDALONE) || !(s1 & NGPMB_BASEBRD_STANDALONE))
> +		return;
> +
> +	cinfo->type = JNX_BOARD_TYPE_FPC;
> +	cinfo->slot = (s1 & NGPMB_BASEBRD_SLOT_MASK) >> NGPMB_BASEBRD_SLOT_LSB;
> +
> +	if (((s2 & NGPMB_BASEBRD_TYPE_MASK) >> NGPMB_BASEBRD_TYPE_LSB) !=
> +	    NGPMB_BASEBRD_TYPE_MX) {
> +		if (dmi_check_system(gld_2t_dmi_data))
> +			cinfo->assembly_id = JNX_ID_GLD_2T_FPC;
> +		else if (dmi_check_system(gld_3t_dmi_data))
> +			cinfo->assembly_id = JNX_ID_GLD_3T_FPC;
> +		else
> +			cinfo->assembly_id = JNX_ID_POLARIS_MLC;
> +	}
> +
> +	/*
> +	 * Multi chassis configuration. These bits are not
> +	 * valid for Gladiator.
> +	 */
> +	if (!(dmi_check_system(gld_2t_dmi_data) ||
> +	      dmi_check_system(gld_3t_dmi_data))) {
> +		if (ioread8(&cpld->cpld->board.ngpmb.sys_config) &
> +		    NGPMB_SYS_CONFIG_MULTI_CHASSIS) {
> +			chinfo->multichassis = 1;

"true"?

> +			chinfo->chassis_no =

"no" is ambiguous.

chassis_id?

> +			ioread8(&cpld->cpld->board.ngpmb.chassis_id);
> +		}
> +	}
> +
> +	switch (chassis) {
> +	case NGPMB_CHASSIS_TYPE_POLARIS:
> +		chinfo->platform = JNX_PRODUCT_POLARIS;
> +		break;
> +	case NGPMB_CHASSIS_TYPE_HENDRICKS:
> +		chinfo->platform = JNX_PRODUCT_HENDRICKS;
> +		break;
> +	default:
> +		chinfo->platform = 0;

Define this.

> +		break;
> +	};
> +	chinfo->get_master = ngpmb_cpld_get_master;

Where is get_master() called from?

I think you're probably better off exporting the call, rather than
using call-backs.

> +}
> +
> +static void cpld_ptxpmb_init(struct pmb_cpld_core *cpld,
> +			     struct jnx_chassis_info *chinfo,
> +			     struct jnx_card_info *cinfo)
> +{
> +	u8 s1, s2;
> +
> +	s1 = ioread8(&cpld->cpld->baseboard_status1);
> +	s2 = ioread8(&cpld->cpld->baseboard_status2);
> +
> +	dev_info(cpld->dev, "Revision 0x%02x carrier type 0x%x [%s]\n",
> +		 ioread8(&cpld->cpld->cpld_rev), s2 & 0x1f,
> +		 (s1 & 0X3F) == 0X1F ? "standalone"
> +				     : (s2 & 0x10) ? "FPC" : "SPMB");
> +
> +	if ((s1 & 0x3f) != 0x1f) {	/* not standalone */

Define these, and all the other magic numbers in this driver.

I won't say "define this" again in this review.

> +		cinfo->slot = s1 & 0x0f;
> +		if (s2 & 0x10) {	/* fpc */

Pointless comment.  What is an FPC?

> +			cinfo->type = JNX_BOARD_TYPE_FPC;
> +			switch (s2 & 0x0f) {
> +			case 0x00:	/* Sangria */
> +				cinfo->assembly_id = JNX_ID_SNG_VDV_BASE_P2;
> +				chinfo->platform = JNX_PRODUCT_SANGRIA;
> +				break;
> +			case 0x01:	/* Tiny */
> +				chinfo->platform = JNX_PRODUCT_TINY;
> +				break;
> +			case 0x02:	/* Hercules */
> +				chinfo->platform = JNX_PRODUCT_HERCULES;
> +				break;
> +			case 0x03:      /* Hendricks */
> +				cinfo->assembly_id = JNX_ID_HENDRICKS_FPC_P2;
> +				chinfo->platform = JNX_PRODUCT_HENDRICKS;
> +				break;
> +			default:	/* unknown */
> +				break;
> +			}
> +		} else {		/* spmb */
> +			cinfo->type = JNX_BOARD_TYPE_SPMB;
> +			switch (s2 & 0x0f) {
> +			case 0x00:	/* Sangria */
> +				cinfo->assembly_id = JNX_ID_SNG_PMB;
> +				chinfo->platform = JNX_PRODUCT_SANGRIA;
> +				break;
> +			default:	/* unknown */
> +				break;
> +			}
> +		}
> +	}
> +	chinfo->get_master = ptxpmb_cpld_get_master;
> +}
> +
> +static int pmb_cpld_core_probe(struct platform_device *pdev)
> +{
> +	static struct pmb_cpld_core *cpld;
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct ptxpmb_mux_data *pdata = dev->platform_data;
> +	int i, error, mfd_size;
> +	int cpld_type = CPLD_TYPE_PTXPMB;
> +	const struct of_device_id *match;
> +	struct mfd_cell *mfd_cells;
> +
> +	struct jnx_chassis_info chinfo = {
> +		.chassis_no = 0,
> +		.multichassis = 0,
> +		.master_data = NULL,
> +		.platform = -1,
> +		.get_master = NULL,
> +	};
> +	struct jnx_card_info cinfo = {
> +		.type = JNX_BOARD_TYPE_UNKNOWN,
> +		.slot = -1,
> +		.assembly_id = -1,
> +	};
> +
> +	cpld = devm_kzalloc(dev, sizeof(*cpld), GFP_KERNEL);
> +	if (!cpld)
> +		return -ENOMEM;
> +
> +	cpld->dev = dev;
> +	dev_set_drvdata(dev, cpld);
> +
> +	if (pdata) {
> +		cpld_type = pdata->cpld_type;
> +	} else {
> +		match = of_match_device(pmb_cpld_of_ids, dev);
> +		if (match)
> +			cpld_type = (int)(unsigned long)match->data;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	cpld->cpld = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(cpld->cpld))
> +		return PTR_ERR(cpld->cpld);

cpld->cpld is confusing.  Please rename.

> +	chinfo.master_data = cpld;
> +
> +	cpld->irq = platform_get_irq(pdev, 0);
> +	if (cpld->irq >= 0) {
> +		error = devm_request_threaded_irq(dev, cpld->irq, NULL,
> +						  pmb_cpld_core_interrupt,
> +						  IRQF_TRIGGER_RISING |
> +						  IRQF_ONESHOT,
> +						  dev_name(dev), cpld);
> +		if (error < 0)
> +			return error;
> +	}
> +
> +	spin_lock_init(&cpld->lock);
> +	init_waitqueue_head(&cpld->wqh);
> +
> +	mfd_cells = pmb_cpld_cells;
> +	mfd_size = ARRAY_SIZE(pmb_cpld_cells);
> +
> +	switch (cpld_type) {
> +	case CPLD_TYPE_PTXPMB:
> +		cpld_ptxpmb_init(cpld, &chinfo, &cinfo);
> +		break;
> +	case CPLD_TYPE_NGPMB:
> +		cpld_ngpmb_init(cpld, &chinfo, &cinfo);
> +		mfd_cells = ngpmb_cpld_cells;
> +		mfd_size = ARRAY_SIZE(ngpmb_cpld_cells);
> +		break;

Are other types supported?

> +	}
> +
> +	if (pdata) {
> +		for (i = 0; i < mfd_size; i++) {
> +			mfd_cells[i].platform_data = pdata;
> +			mfd_cells[i].pdata_size = sizeof(*pdata);
> +		}
> +	}
> +
> +	error = mfd_add_devices(dev, pdev->id, mfd_cells,

The use of pdev->id here is unusual.

Are you sure this is what you want?

> +				mfd_size, res, 0, NULL);
> +	if (error < 0)
> +		return error;
> +
> +	jnx_register_chassis(&chinfo);
> +	jnx_register_local_card(&cinfo);
> +
> +	return 0;
> +}
> +
> +static int pmb_cpld_core_remove(struct platform_device *pdev)
> +{
> +	jnx_unregister_local_card();
> +	jnx_unregister_chassis();
> +	mfd_remove_devices(&pdev->dev);

'\n' here.

> +	return 0;
> +}
> +
> +static struct platform_driver pmb_cpld_core_driver = {
> +	.probe		= pmb_cpld_core_probe,
> +	.remove		= pmb_cpld_core_remove,
> +	.driver		= {
> +		.name	= "ptxpmb-cpld",
> +		.of_match_table = pmb_cpld_of_ids,
> +		.owner	= THIS_MODULE,

Remove this line.

> +	}
> +};
> +

Remove this line.

> +module_platform_driver(pmb_cpld_core_driver);
> +
> +MODULE_DESCRIPTION("Juniper PTX PMB CPLD Core Driver");
> +MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:ptxpmb-cpld");
> diff --git a/include/linux/mfd/ptxpmb_cpld.h b/include/linux/mfd/ptxpmb_cpld.h
> new file mode 100644
> index 0000000..e44afb4
> --- /dev/null
> +++ b/include/linux/mfd/ptxpmb_cpld.h
> @@ -0,0 +1,140 @@
> +/*---------------------------------------------------------------------------
> + *
> + * ptxpmb_cpld_core.h
> + *     Copyright (c) 2012 Juniper Networks
> + *
> + *---------------------------------------------------------------------------
> + */

This it not how we write header comments.

> +#ifndef PTXPMB_CPLD_CORE_H
> +#define PTXPMB_CPLD_CORE_H

__MFD_*

> +struct pmb_boot_cpld {
> +	u8 cpld_rev;		/* 0x00 */
> +	u8 reset;
> +#define CPLD_MAIN_RESET		(1 << 0)

Use BIT() for all these "1 <<"s

> +#define CPLD_PHYCB_RESET	(1 << 1)
> +#define CPLD_PHYSW_RESET	(1 << 2)	/* P2020 only	*/
> +#define NGPMB_PCIE_OTHER_RESET	(1 << 3)	/* PAM reset on MLC */
> +	u8 reset_reason;
> +#define NGPMB_REASON_MON_A_FAIL	(1 << 0)
> +#define NGPMB_REASON_WDT1	(1 << 1)
> +#define NGPMB_REASON_WDT2	(1 << 2)
> +#define NGPMB_REASON_WDT3	(1 << 3)
> +#define NGPMB_REASON_WDT4	(1 << 4)
> +#define NGPMB_REASON_RE_HRST	(1 << 5)
> +#define NGPMB_REASON_PWR_ON	(1 << 6)
> +#define NGPMB_REASON_RE_SRST	(1 << 7)
> +	u8 control;
> +#define CPLD_CONTROL_BOOTED_LED	(1 << 0)
> +#define CPLD_CONTROL_WATCHDOG	(1 << 6)
> +#define CPLD_CONTROL_RTC	(1 << 7)
> +#define NGPMB_FLASH_SELECT	(1 << 4)
> +#define NGPMB_FLASH_SWIZZ_ENA	(1 << 5)
> +	u8 sys_timer_cnt;
> +	u8 watchdog_hbyte;
> +	u8 watchdog_lbyte;
> +	u8 unused1[1];
> +	u8 baseboard_status1;	/* 0x08 */
> +#define NGPMB_PMB_STANDALONE	(1 << 0)
> +#define NGPMB_MASTER_SELECT	(1 << 1)
> +#define NGPMB_BASEBRD_STANDALONE (1 << 2)
> +#define NGPMB_BASEBRD_SLOT_LSB	3
> +#define NGPMB_BASEBRD_SLOT_MASK	0xF8
> +	u8 baseboard_status2;
> +#define NGPMB_BASEBRD_TYPE_LSB	5
> +#define NGPMB_BASEBRD_TYPE_MASK	0xE0
> +#define NGPMB_BASEBRD_TYPE_MX	0
> +	u8 chassis_number;
> +	u8 sys_config;
> +	u8 i2c_group_sel;	/* 0x0c */
> +	u8 i2c_group_en;
> +	u8 unused2[4];
> +	u8 timer_irq_st;	/* 0x12 */
> +	u8 timer_irq_en;
> +	u8 unused3[12];
> +	u8 prog_jtag_control;	/* 0x20 */
> +	u8 gp_reset1;		/* 0x21 */
> +#define CPLD_GP_RST1_PCISW	(1 << 0)
> +#define CPLD_GP_RST1_SAM	(1 << 1)
> +#define CPLD_GP_RST1_BRCM	(1 << 2)
> +	u8 gp_reset2;		/* 0x22 */
> +	u8 phy_control;
> +	u8 gpio_1;
> +	u8 gpio_2;
> +#define NGPMB_GPIO2_TO_BASEBRD_LSB	(1 << 3)
> +#define NGPMB_I2C_GRP_SEL_LSB	0
> +#define NGPMB_I2C_GRP_SEL_MASK	0x03
> +	u8 thermal_status;
> +	u8 i2c_host_sel;
> +#define CPLD_I2C_HOST0_MSTR     0x09
> +#define CPLD_I2C_HOST1_MSTR     0x06
> +#define CPLD_I2C_HOST_MSTR_MASK 0x0f
> +	u8 scratch[3];
> +	u8 misc_status;
> +	u8 i2c_bus_control;	/* 0x2c */
> +	union {
> +		struct {
> +			u8 mezz_present;
> +			u8 unused1[4];
> +			u8 i2c_group_sel_dbg;	/* 0x31 */
> +			u8 i2c_group_en_dbg;	/* 0x32 */
> +			u8 i2c_group_sel_force;	/* 0x33 */
> +			u8 i2c_group_en_force;	/* 0x34 */
> +			u8 unused2[0x4b];
> +		} p2020;
> +		struct {
> +			u8 hdk_minor_version;	/* 0x2d */
> +			u8 hdk_feature_ind;
> +			u8 hdk_pmb_srds_mode;
> +			u8 hdk_pwr_fail_status;
> +			u8 hdk_pmb_pwr_status;
> +			u8 hdk_pmb_mezz_status;
> +			u8 cpld_self_reset;	/* 0x33 */
> +			u8 unused[0x4c];
> +			u8 hdk_bcpld_rcw[80];
> +		} p5020;
> +		struct {
> +			u8 unused[3];
> +			u8 chassis_id;		/* 0x30 */
> +			u8 chassis_type;	/* 0x31 */
> +#define NGPMB_CHASSIS_TYPE_LSB		0
> +#define NGPMB_CHASSIS_TYPE_MASK		0x0F
> +#define NGPMB_CHASSIS_TYPE_POLARIS	0x0B
> +#define NGPMB_CHASSIS_TYPE_HENDRICKS	0x09
> +			u8 sys_config;		/* 0x32 */
> +#define NGPMB_SYS_CONFIG_MULTI_CHASSIS	0x01
> +		} ngpmb;
> +		struct {
> +			u8 nv_win;		/* 0x2d */
> +			u8 nv_addr1;
> +			u8 nv_addr2;
> +			u8 nv_wr_data;
> +			u8 nv_rd_data;
> +			u8 nv_cmd;
> +			u8 nv_done_bit;
> +		} nvram;
> +	} board;
> +};

Please use the standard conventions for detailing registers and bits.

> +#ifdef CONFIG_P2020_PTXPMB
> +#define CPLD_PHY_RESET	(CPLD_PHYCB_RESET | CPLD_PHYSW_RESET)
> +#else
> +#define CPLD_PHY_RESET	CPLD_PHYCB_RESET
> +#endif
> +
> +#define i2c_group_sel_force board.p2020.i2c_group_sel_force
> +#define i2c_group_en_force board.p2020.i2c_group_en_force

I've never seen this before.  Please don't do it.

> +struct ptxpmb_mux_data {
> +	int cpld_type;
> +#define CPLD_TYPE_PTXPMB    0	/* SPMB / Sangria FPC / Hendricks FPC */
> +#define CPLD_TYPE_NGPMB     1	/* MLC / Stout / Gladiator... */
> +	int num_enable;		/* Number of I2C enable pins		*/
> +	int num_channels;	/* Number of I2C channels used in a mux chip */
> +	int parent_bus_num;	/* parent i2c bus number		*/
> +	int base_bus_num;	/* 1st bus number, 0 if undefined	*/
> +	bool use_force;		/* Use i2c force registers if true	*/
> +};

Rename to *_mux_pdata for clarity.

Use kdoc throughout.

> +#endif /* PTXPMB_CPLD_CORE_H */

-- 
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] 47+ messages in thread

* Re: [PATCH 01/10] mfd: Juniper PTXPMB CPLD Multi-function core driver
@ 2016-10-26 13:50     ` Lee Jones
  0 siblings, 0 replies; 47+ messages in thread
From: Lee Jones @ 2016-10-26 13:50 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, 07 Oct 2016, Pantelis Antoniou wrote:

> From: Guenter Roeck <groeck@juniper.net>
> 
> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
> are present in Juniper's PTX series of routers.
> 
> There are two variants, the original which is found on the
> PTXPMB_P2020, PTXPMB_P2020_SPMB based on a Freescale P2020 SoC,
> and PTXPMB_P5040 based on a Freescale P5040 SoC.
> 
> The new variant NGPMB is present on a new line of x86 based
> boards (currently only the Gladiator FPC).
> 
> Both variants provide a hardware watchdog, i2c mux and a
> gpio block, with the i2c mux block being different.
> 
> Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> Signed-off-by: Guenter Roeck <groeck@juniper.net>
> Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
> Signed-off-by: Rajat Jain <rajatjain@juniper.net>
> Signed-off-by: Tom Kavanagh <tkavanagh@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  drivers/mfd/Kconfig             |  15 ++
>  drivers/mfd/Makefile            |   1 +
>  drivers/mfd/ptxpmb-cpld-core.c  | 406 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/ptxpmb_cpld.h | 140 ++++++++++++++
>  4 files changed, 562 insertions(+)
>  create mode 100644 drivers/mfd/ptxpmb-cpld-core.c
>  create mode 100644 include/linux/mfd/ptxpmb_cpld.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 2caf7e9..438666a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1340,6 +1340,21 @@ config TWL4030_POWER
>  	  and load scripts controlling which resources are switched off/on
>  	  or reset when a sleep, wakeup or warm reset event occurs.
>  
> +config MFD_JUNIPER_CPLD
> +	tristate "Juniper PTX PMB CPLD"
> +	depends on (PTXPMB_COMMON || JNX_PTX_NGPMB)
> +	default y if (PTXPMB_COMMON || JNX_PTX_NGPMB)

Nit: I'd like to see the default line above 'depends|select'.

> +	select MFD_CORE
> +	select I2C_MUX_PTXPMB
> +	select GPIO_PTXPMB_CPLD
> +	select JNX_PTXPMB_WDT

I don't think these should be selected blindly from here.

> +	help
> +	  Select this to enable the PTX PMB CPLD multi-function kernel driver

What is PTX PMB?

> +	  for the applicable Juniper platforms.

What applicable platforms?  Might wish to consider removing this part.

It would also be nice to mention what functionality this provides and
little more info besides "this enables".

> +	  This driver can be built as a module. If built as a module it will be
> +	  called "ptxpmb-cpld"
> +
>  config MFD_TWL4030_AUDIO
>  	bool "TI TWL4030 Audio"
>  	depends on TWL4030_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 2bf6a1a..62decc9 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -148,6 +148,7 @@ obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
>  obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
>  obj-$(CONFIG_AB8500_DEBUG)	+= ab8500-debugfs.o
>  obj-$(CONFIG_AB8500_GPADC)	+= ab8500-gpadc.o
> +obj-$(CONFIG_MFD_JUNIPER_CPLD)	+= ptxpmb-cpld-core.o

Is there only ever going to be one Juniper CPLD?

>  obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
>  # ab8500-core need to come after db8500-prcmu (which provides the channel)
>  obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
> diff --git a/drivers/mfd/ptxpmb-cpld-core.c b/drivers/mfd/ptxpmb-cpld-core.c
> new file mode 100644
> index 0000000..18e60a4
> --- /dev/null
> +++ b/drivers/mfd/ptxpmb-cpld-core.c
> @@ -0,0 +1,406 @@
> +/*
> + * Juniper PTX PMB CPLD multi-function core driver

Please expand on what a PTX PMB is.

> + * Copyright (C) 2012 Juniper Networks

This needs updating.

Why is this required now and not in the past 4 years?

> + * 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 program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *

Superfluous line.

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/sched.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/dmi.h>
> +#include <linux/mfd/core.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/ptxpmb_cpld.h>
> +#include <linux/jnx/jnx-subsys.h>
> +#include <linux/jnx/board_ids.h>

Alphabetical.

> +struct pmb_cpld_core {
> +	struct device		*dev;
> +	struct pmb_boot_cpld __iomem *cpld;

This isn't how we usually handle IO registers.

> +	spinlock_t		lock;
> +	int			irq;
> +	wait_queue_head_t	wqh;

This is not a very good variable name.

> +};
> +
> +static const struct of_device_id pmb_cpld_of_ids[] = {
> +	{ .compatible = "jnx,ptxpmb-cpld", .data = (void *)CPLD_TYPE_PTXPMB },
> +	{ .compatible = "jnx,ngpmb-bcpld", .data = (void *)CPLD_TYPE_NGPMB },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, pmb_cpld_of_ids);

Place this just before it's about to be used.  Since you're matching
on this, I would expect it be be located just above .probe().

> +static struct dmi_system_id gld_2t_dmi_data[] = {
> +	{
> +		.ident = "Juniper Networks Gladiator 2T FPC",
> +		.matches = {
> +			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
> +			    DMI_MATCH(DMI_PRODUCT_NAME, "0BF9"),
> +			},
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(dmi, gld_2t_dmi_data);
> +
> +static struct dmi_system_id gld_3t_dmi_data[] = {
> +	{
> +		.ident = "Juniper Networks Gladiator 3T FPC",
> +		.matches = {
> +			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
> +			    DMI_MATCH(DMI_PRODUCT_NAME, "0BFA"),
> +			},
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(dmi, gld_3t_dmi_data);
> +
> +static int ptxpmb_cpld_get_master(void *data)
> +{
> +	struct pmb_cpld_core *cpld = data;
> +	u8 s1;

s1 is not a good variable name.

> +	s1 = ioread8(&cpld->cpld->i2c_host_sel) & CPLD_I2C_HOST_MSTR_MASK;

Why aren't you using readb()?

> +	if ((s1 & CPLD_I2C_HOST0_MSTR) == CPLD_I2C_HOST0_MSTR)
> +		return 0;

Define this.

> +	if ((s1 & CPLD_I2C_HOST1_MSTR) == CPLD_I2C_HOST1_MSTR)
> +		return 1;

And this.

> +	return -1;

Why aren't you using Linux error numbers.

> +}
> +
> +static int ngpmb_cpld_get_master(void *data)
> +{
> +	struct pmb_cpld_core *cpld = data;
> +
> +	if (ioread8(&cpld->cpld->baseboard_status1) & NGPMB_MASTER_SELECT)
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static irqreturn_t pmb_cpld_core_interrupt(int irq, void *dev_data)
> +{
> +	struct pmb_cpld_core *cpld = dev_data;
> +
> +	pr_info("pmb_cpld_core_interrupt %d\n", irq);

This should be dgb at most, but doesn't really have any place in
Mainline code.  Please remove it.

> +	spin_lock(&cpld->wqh.lock);
> +
> +	/* clear interrupt, wake up any handlers */
> +	wake_up_locked(&cpld->wqh);
> +
> +	spin_unlock(&cpld->wqh.lock);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct resource pmb_cpld_resources[] = {
> +	{
> +		.start	= 0,
> +		.end	= sizeof(struct pmb_boot_cpld) - 1,

Define these properly.

> +		.flags	= IORESOURCE_MEM,
> +	},
> +};

Use the DEFINE_RES_*() helpers.

> +static struct mfd_cell pmb_cpld_cells[] = {
> +	{
> +		.name = "jnx-ptxpmb-wdt",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,ptxpmb-wdt",
> +	},
> +	{
> +		.name = "i2c-mux-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,i2c-mux-ptxpmb-cpld",
> +	},
> +	{
> +		.name = "gpio-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,gpio-ptxpmb-cpld",
> +	},
> +};
> +
> +static struct mfd_cell ngpmb_cpld_cells[] = {
> +	{
> +		.name = "jnx-ptxpmb-wdt",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,ptxpmb-wdt",
> +	},
> +	{
> +		.name = "i2c-mux-ngpmb-bcpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,i2c-mux-ngpmb-bcpld",
> +	},
> +	{
> +		.name = "gpio-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,gpio-ptxpmb-cpld",
> +	},
> +};
> +
> +static void cpld_ngpmb_init(struct pmb_cpld_core *cpld,
> +			    struct jnx_chassis_info *chinfo,
> +			    struct jnx_card_info *cinfo)
> +{
> +	u8 s1, s2, val, chassis;

s1 and s1 are not good variable names.

status1 and status2 would be better.

> +	s1 = ioread8(&cpld->cpld->baseboard_status1);
> +	s2 = ioread8(&cpld->cpld->baseboard_status2);
> +	chassis = (ioread8(&cpld->cpld->board.ngpmb.chassis_type)
> +		   & NGPMB_CHASSIS_TYPE_MASK) >> NGPMB_CHASSIS_TYPE_LSB;
> +
> +	dev_info(cpld->dev, "Revision 0x%02X chassis type %s (0x%02X)\n",
> +		 ioread8(&cpld->cpld->cpld_rev),
> +		 chassis == NGPMB_CHASSIS_TYPE_POLARIS ? "PTX-1000" :
> +		 chassis == NGPMB_CHASSIS_TYPE_HENDRICKS ? "PTX-3000" :
> +		 "Unknown", chassis);
> +
> +	/* Only the Gladiator 2t/3t FPC */
> +	if (dmi_check_system(gld_2t_dmi_data) ||
> +	    dmi_check_system(gld_3t_dmi_data)) {
> +		/* Take SAM FPGA out of reset */
> +		val = ioread8(&cpld->cpld->gpio_2);
> +		iowrite8(val | NGPMB_GPIO2_TO_BASEBRD_LSB, &cpld->cpld->gpio_2);
> +		mdelay(10);
> +	} else {
> +		/*
> +		 * Get the PAM FPGA out of reset,
> +		 * and wait for 100ms as per HW manual
> +		 */
> +		val = ioread8(&cpld->cpld->reset);
> +		iowrite8(val & ~NGPMB_PCIE_OTHER_RESET, &cpld->cpld->reset);
> +		mdelay(100);
> +	}
> +
> +	/* No Card / Chassis info needed in stand alone mode */
> +	if (!(s1 & NGPMB_PMB_STANDALONE) || !(s1 & NGPMB_BASEBRD_STANDALONE))
> +		return;
> +
> +	cinfo->type = JNX_BOARD_TYPE_FPC;
> +	cinfo->slot = (s1 & NGPMB_BASEBRD_SLOT_MASK) >> NGPMB_BASEBRD_SLOT_LSB;
> +
> +	if (((s2 & NGPMB_BASEBRD_TYPE_MASK) >> NGPMB_BASEBRD_TYPE_LSB) !=
> +	    NGPMB_BASEBRD_TYPE_MX) {
> +		if (dmi_check_system(gld_2t_dmi_data))
> +			cinfo->assembly_id = JNX_ID_GLD_2T_FPC;
> +		else if (dmi_check_system(gld_3t_dmi_data))
> +			cinfo->assembly_id = JNX_ID_GLD_3T_FPC;
> +		else
> +			cinfo->assembly_id = JNX_ID_POLARIS_MLC;
> +	}
> +
> +	/*
> +	 * Multi chassis configuration. These bits are not
> +	 * valid for Gladiator.
> +	 */
> +	if (!(dmi_check_system(gld_2t_dmi_data) ||
> +	      dmi_check_system(gld_3t_dmi_data))) {
> +		if (ioread8(&cpld->cpld->board.ngpmb.sys_config) &
> +		    NGPMB_SYS_CONFIG_MULTI_CHASSIS) {
> +			chinfo->multichassis = 1;

"true"?

> +			chinfo->chassis_no =

"no" is ambiguous.

chassis_id?

> +			ioread8(&cpld->cpld->board.ngpmb.chassis_id);
> +		}
> +	}
> +
> +	switch (chassis) {
> +	case NGPMB_CHASSIS_TYPE_POLARIS:
> +		chinfo->platform = JNX_PRODUCT_POLARIS;
> +		break;
> +	case NGPMB_CHASSIS_TYPE_HENDRICKS:
> +		chinfo->platform = JNX_PRODUCT_HENDRICKS;
> +		break;
> +	default:
> +		chinfo->platform = 0;

Define this.

> +		break;
> +	};
> +	chinfo->get_master = ngpmb_cpld_get_master;

Where is get_master() called from?

I think you're probably better off exporting the call, rather than
using call-backs.

> +}
> +
> +static void cpld_ptxpmb_init(struct pmb_cpld_core *cpld,
> +			     struct jnx_chassis_info *chinfo,
> +			     struct jnx_card_info *cinfo)
> +{
> +	u8 s1, s2;
> +
> +	s1 = ioread8(&cpld->cpld->baseboard_status1);
> +	s2 = ioread8(&cpld->cpld->baseboard_status2);
> +
> +	dev_info(cpld->dev, "Revision 0x%02x carrier type 0x%x [%s]\n",
> +		 ioread8(&cpld->cpld->cpld_rev), s2 & 0x1f,
> +		 (s1 & 0X3F) == 0X1F ? "standalone"
> +				     : (s2 & 0x10) ? "FPC" : "SPMB");
> +
> +	if ((s1 & 0x3f) != 0x1f) {	/* not standalone */

Define these, and all the other magic numbers in this driver.

I won't say "define this" again in this review.

> +		cinfo->slot = s1 & 0x0f;
> +		if (s2 & 0x10) {	/* fpc */

Pointless comment.  What is an FPC?

> +			cinfo->type = JNX_BOARD_TYPE_FPC;
> +			switch (s2 & 0x0f) {
> +			case 0x00:	/* Sangria */
> +				cinfo->assembly_id = JNX_ID_SNG_VDV_BASE_P2;
> +				chinfo->platform = JNX_PRODUCT_SANGRIA;
> +				break;
> +			case 0x01:	/* Tiny */
> +				chinfo->platform = JNX_PRODUCT_TINY;
> +				break;
> +			case 0x02:	/* Hercules */
> +				chinfo->platform = JNX_PRODUCT_HERCULES;
> +				break;
> +			case 0x03:      /* Hendricks */
> +				cinfo->assembly_id = JNX_ID_HENDRICKS_FPC_P2;
> +				chinfo->platform = JNX_PRODUCT_HENDRICKS;
> +				break;
> +			default:	/* unknown */
> +				break;
> +			}
> +		} else {		/* spmb */
> +			cinfo->type = JNX_BOARD_TYPE_SPMB;
> +			switch (s2 & 0x0f) {
> +			case 0x00:	/* Sangria */
> +				cinfo->assembly_id = JNX_ID_SNG_PMB;
> +				chinfo->platform = JNX_PRODUCT_SANGRIA;
> +				break;
> +			default:	/* unknown */
> +				break;
> +			}
> +		}
> +	}
> +	chinfo->get_master = ptxpmb_cpld_get_master;
> +}
> +
> +static int pmb_cpld_core_probe(struct platform_device *pdev)
> +{
> +	static struct pmb_cpld_core *cpld;
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct ptxpmb_mux_data *pdata = dev->platform_data;
> +	int i, error, mfd_size;
> +	int cpld_type = CPLD_TYPE_PTXPMB;
> +	const struct of_device_id *match;
> +	struct mfd_cell *mfd_cells;
> +
> +	struct jnx_chassis_info chinfo = {
> +		.chassis_no = 0,
> +		.multichassis = 0,
> +		.master_data = NULL,
> +		.platform = -1,
> +		.get_master = NULL,
> +	};
> +	struct jnx_card_info cinfo = {
> +		.type = JNX_BOARD_TYPE_UNKNOWN,
> +		.slot = -1,
> +		.assembly_id = -1,
> +	};
> +
> +	cpld = devm_kzalloc(dev, sizeof(*cpld), GFP_KERNEL);
> +	if (!cpld)
> +		return -ENOMEM;
> +
> +	cpld->dev = dev;
> +	dev_set_drvdata(dev, cpld);
> +
> +	if (pdata) {
> +		cpld_type = pdata->cpld_type;
> +	} else {
> +		match = of_match_device(pmb_cpld_of_ids, dev);
> +		if (match)
> +			cpld_type = (int)(unsigned long)match->data;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	cpld->cpld = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(cpld->cpld))
> +		return PTR_ERR(cpld->cpld);

cpld->cpld is confusing.  Please rename.

> +	chinfo.master_data = cpld;
> +
> +	cpld->irq = platform_get_irq(pdev, 0);
> +	if (cpld->irq >= 0) {
> +		error = devm_request_threaded_irq(dev, cpld->irq, NULL,
> +						  pmb_cpld_core_interrupt,
> +						  IRQF_TRIGGER_RISING |
> +						  IRQF_ONESHOT,
> +						  dev_name(dev), cpld);
> +		if (error < 0)
> +			return error;
> +	}
> +
> +	spin_lock_init(&cpld->lock);
> +	init_waitqueue_head(&cpld->wqh);
> +
> +	mfd_cells = pmb_cpld_cells;
> +	mfd_size = ARRAY_SIZE(pmb_cpld_cells);
> +
> +	switch (cpld_type) {
> +	case CPLD_TYPE_PTXPMB:
> +		cpld_ptxpmb_init(cpld, &chinfo, &cinfo);
> +		break;
> +	case CPLD_TYPE_NGPMB:
> +		cpld_ngpmb_init(cpld, &chinfo, &cinfo);
> +		mfd_cells = ngpmb_cpld_cells;
> +		mfd_size = ARRAY_SIZE(ngpmb_cpld_cells);
> +		break;

Are other types supported?

> +	}
> +
> +	if (pdata) {
> +		for (i = 0; i < mfd_size; i++) {
> +			mfd_cells[i].platform_data = pdata;
> +			mfd_cells[i].pdata_size = sizeof(*pdata);
> +		}
> +	}
> +
> +	error = mfd_add_devices(dev, pdev->id, mfd_cells,

The use of pdev->id here is unusual.

Are you sure this is what you want?

> +				mfd_size, res, 0, NULL);
> +	if (error < 0)
> +		return error;
> +
> +	jnx_register_chassis(&chinfo);
> +	jnx_register_local_card(&cinfo);
> +
> +	return 0;
> +}
> +
> +static int pmb_cpld_core_remove(struct platform_device *pdev)
> +{
> +	jnx_unregister_local_card();
> +	jnx_unregister_chassis();
> +	mfd_remove_devices(&pdev->dev);

'\n' here.

> +	return 0;
> +}
> +
> +static struct platform_driver pmb_cpld_core_driver = {
> +	.probe		= pmb_cpld_core_probe,
> +	.remove		= pmb_cpld_core_remove,
> +	.driver		= {
> +		.name	= "ptxpmb-cpld",
> +		.of_match_table = pmb_cpld_of_ids,
> +		.owner	= THIS_MODULE,

Remove this line.

> +	}
> +};
> +

Remove this line.

> +module_platform_driver(pmb_cpld_core_driver);
> +
> +MODULE_DESCRIPTION("Juniper PTX PMB CPLD Core Driver");
> +MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:ptxpmb-cpld");
> diff --git a/include/linux/mfd/ptxpmb_cpld.h b/include/linux/mfd/ptxpmb_cpld.h
> new file mode 100644
> index 0000000..e44afb4
> --- /dev/null
> +++ b/include/linux/mfd/ptxpmb_cpld.h
> @@ -0,0 +1,140 @@
> +/*---------------------------------------------------------------------------
> + *
> + * ptxpmb_cpld_core.h
> + *     Copyright (c) 2012 Juniper Networks
> + *
> + *---------------------------------------------------------------------------
> + */

This it not how we write header comments.

> +#ifndef PTXPMB_CPLD_CORE_H
> +#define PTXPMB_CPLD_CORE_H

__MFD_*

> +struct pmb_boot_cpld {
> +	u8 cpld_rev;		/* 0x00 */
> +	u8 reset;
> +#define CPLD_MAIN_RESET		(1 << 0)

Use BIT() for all these "1 <<"s

> +#define CPLD_PHYCB_RESET	(1 << 1)
> +#define CPLD_PHYSW_RESET	(1 << 2)	/* P2020 only	*/
> +#define NGPMB_PCIE_OTHER_RESET	(1 << 3)	/* PAM reset on MLC */
> +	u8 reset_reason;
> +#define NGPMB_REASON_MON_A_FAIL	(1 << 0)
> +#define NGPMB_REASON_WDT1	(1 << 1)
> +#define NGPMB_REASON_WDT2	(1 << 2)
> +#define NGPMB_REASON_WDT3	(1 << 3)
> +#define NGPMB_REASON_WDT4	(1 << 4)
> +#define NGPMB_REASON_RE_HRST	(1 << 5)
> +#define NGPMB_REASON_PWR_ON	(1 << 6)
> +#define NGPMB_REASON_RE_SRST	(1 << 7)
> +	u8 control;
> +#define CPLD_CONTROL_BOOTED_LED	(1 << 0)
> +#define CPLD_CONTROL_WATCHDOG	(1 << 6)
> +#define CPLD_CONTROL_RTC	(1 << 7)
> +#define NGPMB_FLASH_SELECT	(1 << 4)
> +#define NGPMB_FLASH_SWIZZ_ENA	(1 << 5)
> +	u8 sys_timer_cnt;
> +	u8 watchdog_hbyte;
> +	u8 watchdog_lbyte;
> +	u8 unused1[1];
> +	u8 baseboard_status1;	/* 0x08 */
> +#define NGPMB_PMB_STANDALONE	(1 << 0)
> +#define NGPMB_MASTER_SELECT	(1 << 1)
> +#define NGPMB_BASEBRD_STANDALONE (1 << 2)
> +#define NGPMB_BASEBRD_SLOT_LSB	3
> +#define NGPMB_BASEBRD_SLOT_MASK	0xF8
> +	u8 baseboard_status2;
> +#define NGPMB_BASEBRD_TYPE_LSB	5
> +#define NGPMB_BASEBRD_TYPE_MASK	0xE0
> +#define NGPMB_BASEBRD_TYPE_MX	0
> +	u8 chassis_number;
> +	u8 sys_config;
> +	u8 i2c_group_sel;	/* 0x0c */
> +	u8 i2c_group_en;
> +	u8 unused2[4];
> +	u8 timer_irq_st;	/* 0x12 */
> +	u8 timer_irq_en;
> +	u8 unused3[12];
> +	u8 prog_jtag_control;	/* 0x20 */
> +	u8 gp_reset1;		/* 0x21 */
> +#define CPLD_GP_RST1_PCISW	(1 << 0)
> +#define CPLD_GP_RST1_SAM	(1 << 1)
> +#define CPLD_GP_RST1_BRCM	(1 << 2)
> +	u8 gp_reset2;		/* 0x22 */
> +	u8 phy_control;
> +	u8 gpio_1;
> +	u8 gpio_2;
> +#define NGPMB_GPIO2_TO_BASEBRD_LSB	(1 << 3)
> +#define NGPMB_I2C_GRP_SEL_LSB	0
> +#define NGPMB_I2C_GRP_SEL_MASK	0x03
> +	u8 thermal_status;
> +	u8 i2c_host_sel;
> +#define CPLD_I2C_HOST0_MSTR     0x09
> +#define CPLD_I2C_HOST1_MSTR     0x06
> +#define CPLD_I2C_HOST_MSTR_MASK 0x0f
> +	u8 scratch[3];
> +	u8 misc_status;
> +	u8 i2c_bus_control;	/* 0x2c */
> +	union {
> +		struct {
> +			u8 mezz_present;
> +			u8 unused1[4];
> +			u8 i2c_group_sel_dbg;	/* 0x31 */
> +			u8 i2c_group_en_dbg;	/* 0x32 */
> +			u8 i2c_group_sel_force;	/* 0x33 */
> +			u8 i2c_group_en_force;	/* 0x34 */
> +			u8 unused2[0x4b];
> +		} p2020;
> +		struct {
> +			u8 hdk_minor_version;	/* 0x2d */
> +			u8 hdk_feature_ind;
> +			u8 hdk_pmb_srds_mode;
> +			u8 hdk_pwr_fail_status;
> +			u8 hdk_pmb_pwr_status;
> +			u8 hdk_pmb_mezz_status;
> +			u8 cpld_self_reset;	/* 0x33 */
> +			u8 unused[0x4c];
> +			u8 hdk_bcpld_rcw[80];
> +		} p5020;
> +		struct {
> +			u8 unused[3];
> +			u8 chassis_id;		/* 0x30 */
> +			u8 chassis_type;	/* 0x31 */
> +#define NGPMB_CHASSIS_TYPE_LSB		0
> +#define NGPMB_CHASSIS_TYPE_MASK		0x0F
> +#define NGPMB_CHASSIS_TYPE_POLARIS	0x0B
> +#define NGPMB_CHASSIS_TYPE_HENDRICKS	0x09
> +			u8 sys_config;		/* 0x32 */
> +#define NGPMB_SYS_CONFIG_MULTI_CHASSIS	0x01
> +		} ngpmb;
> +		struct {
> +			u8 nv_win;		/* 0x2d */
> +			u8 nv_addr1;
> +			u8 nv_addr2;
> +			u8 nv_wr_data;
> +			u8 nv_rd_data;
> +			u8 nv_cmd;
> +			u8 nv_done_bit;
> +		} nvram;
> +	} board;
> +};

Please use the standard conventions for detailing registers and bits.

> +#ifdef CONFIG_P2020_PTXPMB
> +#define CPLD_PHY_RESET	(CPLD_PHYCB_RESET | CPLD_PHYSW_RESET)
> +#else
> +#define CPLD_PHY_RESET	CPLD_PHYCB_RESET
> +#endif
> +
> +#define i2c_group_sel_force board.p2020.i2c_group_sel_force
> +#define i2c_group_en_force board.p2020.i2c_group_en_force

I've never seen this before.  Please don't do it.

> +struct ptxpmb_mux_data {
> +	int cpld_type;
> +#define CPLD_TYPE_PTXPMB    0	/* SPMB / Sangria FPC / Hendricks FPC */
> +#define CPLD_TYPE_NGPMB     1	/* MLC / Stout / Gladiator... */
> +	int num_enable;		/* Number of I2C enable pins		*/
> +	int num_channels;	/* Number of I2C channels used in a mux chip */
> +	int parent_bus_num;	/* parent i2c bus number		*/
> +	int base_bus_num;	/* 1st bus number, 0 if undefined	*/
> +	bool use_force;		/* Use i2c force registers if true	*/
> +};

Rename to *_mux_pdata for clarity.

Use kdoc throughout.

> +#endif /* PTXPMB_CPLD_CORE_H */

-- 
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] 47+ messages in thread

* Re: [PATCH 01/10] mfd: Juniper PTXPMB CPLD Multi-function core driver
@ 2016-10-26 13:50     ` Lee Jones
  0 siblings, 0 replies; 47+ messages in thread
From: Lee Jones @ 2016-10-26 13:50 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Rob Herring, Linus Walleij, Alexandre Courbot, Mark Rutland,
	Frank Rowand, Wolfram Sang, David Woodhouse, Brian Norris,
	Wim Van Sebroeck, Guenter Roeck, Peter Rosin, Debjit Ghosh,
	Georgi Vlaev, Guenter Roeck, JawaharBalaji Thirumalaisamy,
	Rajat Jain, devicetree, linux-kernel, linux-gpio, linux-i2c,
	linux-mtd, linux-watchdog

On Fri, 07 Oct 2016, Pantelis Antoniou wrote:

> From: Guenter Roeck <groeck@juniper.net>
> 
> Add Juniper's PTXPMB FPGA CPLD driver. Those FPGAs
> are present in Juniper's PTX series of routers.
> 
> There are two variants, the original which is found on the
> PTXPMB_P2020, PTXPMB_P2020_SPMB based on a Freescale P2020 SoC,
> and PTXPMB_P5040 based on a Freescale P5040 SoC.
> 
> The new variant NGPMB is present on a new line of x86 based
> boards (currently only the Gladiator FPC).
> 
> Both variants provide a hardware watchdog, i2c mux and a
> gpio block, with the i2c mux block being different.
> 
> Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> Signed-off-by: Guenter Roeck <groeck@juniper.net>
> Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
> Signed-off-by: Rajat Jain <rajatjain@juniper.net>
> Signed-off-by: Tom Kavanagh <tkavanagh@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  drivers/mfd/Kconfig             |  15 ++
>  drivers/mfd/Makefile            |   1 +
>  drivers/mfd/ptxpmb-cpld-core.c  | 406 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/ptxpmb_cpld.h | 140 ++++++++++++++
>  4 files changed, 562 insertions(+)
>  create mode 100644 drivers/mfd/ptxpmb-cpld-core.c
>  create mode 100644 include/linux/mfd/ptxpmb_cpld.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 2caf7e9..438666a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1340,6 +1340,21 @@ config TWL4030_POWER
>  	  and load scripts controlling which resources are switched off/on
>  	  or reset when a sleep, wakeup or warm reset event occurs.
>  
> +config MFD_JUNIPER_CPLD
> +	tristate "Juniper PTX PMB CPLD"
> +	depends on (PTXPMB_COMMON || JNX_PTX_NGPMB)
> +	default y if (PTXPMB_COMMON || JNX_PTX_NGPMB)

Nit: I'd like to see the default line above 'depends|select'.

> +	select MFD_CORE
> +	select I2C_MUX_PTXPMB
> +	select GPIO_PTXPMB_CPLD
> +	select JNX_PTXPMB_WDT

I don't think these should be selected blindly from here.

> +	help
> +	  Select this to enable the PTX PMB CPLD multi-function kernel driver

What is PTX PMB?

> +	  for the applicable Juniper platforms.

What applicable platforms?  Might wish to consider removing this part.

It would also be nice to mention what functionality this provides and
little more info besides "this enables".

> +	  This driver can be built as a module. If built as a module it will be
> +	  called "ptxpmb-cpld"
> +
>  config MFD_TWL4030_AUDIO
>  	bool "TI TWL4030 Audio"
>  	depends on TWL4030_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 2bf6a1a..62decc9 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -148,6 +148,7 @@ obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
>  obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
>  obj-$(CONFIG_AB8500_DEBUG)	+= ab8500-debugfs.o
>  obj-$(CONFIG_AB8500_GPADC)	+= ab8500-gpadc.o
> +obj-$(CONFIG_MFD_JUNIPER_CPLD)	+= ptxpmb-cpld-core.o

Is there only ever going to be one Juniper CPLD?

>  obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
>  # ab8500-core need to come after db8500-prcmu (which provides the channel)
>  obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
> diff --git a/drivers/mfd/ptxpmb-cpld-core.c b/drivers/mfd/ptxpmb-cpld-core.c
> new file mode 100644
> index 0000000..18e60a4
> --- /dev/null
> +++ b/drivers/mfd/ptxpmb-cpld-core.c
> @@ -0,0 +1,406 @@
> +/*
> + * Juniper PTX PMB CPLD multi-function core driver

Please expand on what a PTX PMB is.

> + * Copyright (C) 2012 Juniper Networks

This needs updating.

Why is this required now and not in the past 4 years?

> + * 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 program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *

Superfluous line.

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/sched.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/dmi.h>
> +#include <linux/mfd/core.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/ptxpmb_cpld.h>
> +#include <linux/jnx/jnx-subsys.h>
> +#include <linux/jnx/board_ids.h>

Alphabetical.

> +struct pmb_cpld_core {
> +	struct device		*dev;
> +	struct pmb_boot_cpld __iomem *cpld;

This isn't how we usually handle IO registers.

> +	spinlock_t		lock;
> +	int			irq;
> +	wait_queue_head_t	wqh;

This is not a very good variable name.

> +};
> +
> +static const struct of_device_id pmb_cpld_of_ids[] = {
> +	{ .compatible = "jnx,ptxpmb-cpld", .data = (void *)CPLD_TYPE_PTXPMB },
> +	{ .compatible = "jnx,ngpmb-bcpld", .data = (void *)CPLD_TYPE_NGPMB },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, pmb_cpld_of_ids);

Place this just before it's about to be used.  Since you're matching
on this, I would expect it be be located just above .probe().

> +static struct dmi_system_id gld_2t_dmi_data[] = {
> +	{
> +		.ident = "Juniper Networks Gladiator 2T FPC",
> +		.matches = {
> +			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
> +			    DMI_MATCH(DMI_PRODUCT_NAME, "0BF9"),
> +			},
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(dmi, gld_2t_dmi_data);
> +
> +static struct dmi_system_id gld_3t_dmi_data[] = {
> +	{
> +		.ident = "Juniper Networks Gladiator 3T FPC",
> +		.matches = {
> +			    DMI_MATCH(DMI_SYS_VENDOR, "Juniper Networks Inc."),
> +			    DMI_MATCH(DMI_PRODUCT_NAME, "0BFA"),
> +			},
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(dmi, gld_3t_dmi_data);
> +
> +static int ptxpmb_cpld_get_master(void *data)
> +{
> +	struct pmb_cpld_core *cpld = data;
> +	u8 s1;

s1 is not a good variable name.

> +	s1 = ioread8(&cpld->cpld->i2c_host_sel) & CPLD_I2C_HOST_MSTR_MASK;

Why aren't you using readb()?

> +	if ((s1 & CPLD_I2C_HOST0_MSTR) == CPLD_I2C_HOST0_MSTR)
> +		return 0;

Define this.

> +	if ((s1 & CPLD_I2C_HOST1_MSTR) == CPLD_I2C_HOST1_MSTR)
> +		return 1;

And this.

> +	return -1;

Why aren't you using Linux error numbers.

> +}
> +
> +static int ngpmb_cpld_get_master(void *data)
> +{
> +	struct pmb_cpld_core *cpld = data;
> +
> +	if (ioread8(&cpld->cpld->baseboard_status1) & NGPMB_MASTER_SELECT)
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static irqreturn_t pmb_cpld_core_interrupt(int irq, void *dev_data)
> +{
> +	struct pmb_cpld_core *cpld = dev_data;
> +
> +	pr_info("pmb_cpld_core_interrupt %d\n", irq);

This should be dgb at most, but doesn't really have any place in
Mainline code.  Please remove it.

> +	spin_lock(&cpld->wqh.lock);
> +
> +	/* clear interrupt, wake up any handlers */
> +	wake_up_locked(&cpld->wqh);
> +
> +	spin_unlock(&cpld->wqh.lock);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct resource pmb_cpld_resources[] = {
> +	{
> +		.start	= 0,
> +		.end	= sizeof(struct pmb_boot_cpld) - 1,

Define these properly.

> +		.flags	= IORESOURCE_MEM,
> +	},
> +};

Use the DEFINE_RES_*() helpers.

> +static struct mfd_cell pmb_cpld_cells[] = {
> +	{
> +		.name = "jnx-ptxpmb-wdt",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,ptxpmb-wdt",
> +	},
> +	{
> +		.name = "i2c-mux-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,i2c-mux-ptxpmb-cpld",
> +	},
> +	{
> +		.name = "gpio-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,gpio-ptxpmb-cpld",
> +	},
> +};
> +
> +static struct mfd_cell ngpmb_cpld_cells[] = {
> +	{
> +		.name = "jnx-ptxpmb-wdt",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,ptxpmb-wdt",
> +	},
> +	{
> +		.name = "i2c-mux-ngpmb-bcpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,i2c-mux-ngpmb-bcpld",
> +	},
> +	{
> +		.name = "gpio-ptxpmb-cpld",
> +		.num_resources = ARRAY_SIZE(pmb_cpld_resources),
> +		.resources = pmb_cpld_resources,
> +		.of_compatible = "jnx,gpio-ptxpmb-cpld",
> +	},
> +};
> +
> +static void cpld_ngpmb_init(struct pmb_cpld_core *cpld,
> +			    struct jnx_chassis_info *chinfo,
> +			    struct jnx_card_info *cinfo)
> +{
> +	u8 s1, s2, val, chassis;

s1 and s1 are not good variable names.

status1 and status2 would be better.

> +	s1 = ioread8(&cpld->cpld->baseboard_status1);
> +	s2 = ioread8(&cpld->cpld->baseboard_status2);
> +	chassis = (ioread8(&cpld->cpld->board.ngpmb.chassis_type)
> +		   & NGPMB_CHASSIS_TYPE_MASK) >> NGPMB_CHASSIS_TYPE_LSB;
> +
> +	dev_info(cpld->dev, "Revision 0x%02X chassis type %s (0x%02X)\n",
> +		 ioread8(&cpld->cpld->cpld_rev),
> +		 chassis == NGPMB_CHASSIS_TYPE_POLARIS ? "PTX-1000" :
> +		 chassis == NGPMB_CHASSIS_TYPE_HENDRICKS ? "PTX-3000" :
> +		 "Unknown", chassis);
> +
> +	/* Only the Gladiator 2t/3t FPC */
> +	if (dmi_check_system(gld_2t_dmi_data) ||
> +	    dmi_check_system(gld_3t_dmi_data)) {
> +		/* Take SAM FPGA out of reset */
> +		val = ioread8(&cpld->cpld->gpio_2);
> +		iowrite8(val | NGPMB_GPIO2_TO_BASEBRD_LSB, &cpld->cpld->gpio_2);
> +		mdelay(10);
> +	} else {
> +		/*
> +		 * Get the PAM FPGA out of reset,
> +		 * and wait for 100ms as per HW manual
> +		 */
> +		val = ioread8(&cpld->cpld->reset);
> +		iowrite8(val & ~NGPMB_PCIE_OTHER_RESET, &cpld->cpld->reset);
> +		mdelay(100);
> +	}
> +
> +	/* No Card / Chassis info needed in stand alone mode */
> +	if (!(s1 & NGPMB_PMB_STANDALONE) || !(s1 & NGPMB_BASEBRD_STANDALONE))
> +		return;
> +
> +	cinfo->type = JNX_BOARD_TYPE_FPC;
> +	cinfo->slot = (s1 & NGPMB_BASEBRD_SLOT_MASK) >> NGPMB_BASEBRD_SLOT_LSB;
> +
> +	if (((s2 & NGPMB_BASEBRD_TYPE_MASK) >> NGPMB_BASEBRD_TYPE_LSB) !=
> +	    NGPMB_BASEBRD_TYPE_MX) {
> +		if (dmi_check_system(gld_2t_dmi_data))
> +			cinfo->assembly_id = JNX_ID_GLD_2T_FPC;
> +		else if (dmi_check_system(gld_3t_dmi_data))
> +			cinfo->assembly_id = JNX_ID_GLD_3T_FPC;
> +		else
> +			cinfo->assembly_id = JNX_ID_POLARIS_MLC;
> +	}
> +
> +	/*
> +	 * Multi chassis configuration. These bits are not
> +	 * valid for Gladiator.
> +	 */
> +	if (!(dmi_check_system(gld_2t_dmi_data) ||
> +	      dmi_check_system(gld_3t_dmi_data))) {
> +		if (ioread8(&cpld->cpld->board.ngpmb.sys_config) &
> +		    NGPMB_SYS_CONFIG_MULTI_CHASSIS) {
> +			chinfo->multichassis = 1;

"true"?

> +			chinfo->chassis_no =

"no" is ambiguous.

chassis_id?

> +			ioread8(&cpld->cpld->board.ngpmb.chassis_id);
> +		}
> +	}
> +
> +	switch (chassis) {
> +	case NGPMB_CHASSIS_TYPE_POLARIS:
> +		chinfo->platform = JNX_PRODUCT_POLARIS;
> +		break;
> +	case NGPMB_CHASSIS_TYPE_HENDRICKS:
> +		chinfo->platform = JNX_PRODUCT_HENDRICKS;
> +		break;
> +	default:
> +		chinfo->platform = 0;

Define this.

> +		break;
> +	};
> +	chinfo->get_master = ngpmb_cpld_get_master;

Where is get_master() called from?

I think you're probably better off exporting the call, rather than
using call-backs.

> +}
> +
> +static void cpld_ptxpmb_init(struct pmb_cpld_core *cpld,
> +			     struct jnx_chassis_info *chinfo,
> +			     struct jnx_card_info *cinfo)
> +{
> +	u8 s1, s2;
> +
> +	s1 = ioread8(&cpld->cpld->baseboard_status1);
> +	s2 = ioread8(&cpld->cpld->baseboard_status2);
> +
> +	dev_info(cpld->dev, "Revision 0x%02x carrier type 0x%x [%s]\n",
> +		 ioread8(&cpld->cpld->cpld_rev), s2 & 0x1f,
> +		 (s1 & 0X3F) == 0X1F ? "standalone"
> +				     : (s2 & 0x10) ? "FPC" : "SPMB");
> +
> +	if ((s1 & 0x3f) != 0x1f) {	/* not standalone */

Define these, and all the other magic numbers in this driver.

I won't say "define this" again in this review.

> +		cinfo->slot = s1 & 0x0f;
> +		if (s2 & 0x10) {	/* fpc */

Pointless comment.  What is an FPC?

> +			cinfo->type = JNX_BOARD_TYPE_FPC;
> +			switch (s2 & 0x0f) {
> +			case 0x00:	/* Sangria */
> +				cinfo->assembly_id = JNX_ID_SNG_VDV_BASE_P2;
> +				chinfo->platform = JNX_PRODUCT_SANGRIA;
> +				break;
> +			case 0x01:	/* Tiny */
> +				chinfo->platform = JNX_PRODUCT_TINY;
> +				break;
> +			case 0x02:	/* Hercules */
> +				chinfo->platform = JNX_PRODUCT_HERCULES;
> +				break;
> +			case 0x03:      /* Hendricks */
> +				cinfo->assembly_id = JNX_ID_HENDRICKS_FPC_P2;
> +				chinfo->platform = JNX_PRODUCT_HENDRICKS;
> +				break;
> +			default:	/* unknown */
> +				break;
> +			}
> +		} else {		/* spmb */
> +			cinfo->type = JNX_BOARD_TYPE_SPMB;
> +			switch (s2 & 0x0f) {
> +			case 0x00:	/* Sangria */
> +				cinfo->assembly_id = JNX_ID_SNG_PMB;
> +				chinfo->platform = JNX_PRODUCT_SANGRIA;
> +				break;
> +			default:	/* unknown */
> +				break;
> +			}
> +		}
> +	}
> +	chinfo->get_master = ptxpmb_cpld_get_master;
> +}
> +
> +static int pmb_cpld_core_probe(struct platform_device *pdev)
> +{
> +	static struct pmb_cpld_core *cpld;
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct ptxpmb_mux_data *pdata = dev->platform_data;
> +	int i, error, mfd_size;
> +	int cpld_type = CPLD_TYPE_PTXPMB;
> +	const struct of_device_id *match;
> +	struct mfd_cell *mfd_cells;
> +
> +	struct jnx_chassis_info chinfo = {
> +		.chassis_no = 0,
> +		.multichassis = 0,
> +		.master_data = NULL,
> +		.platform = -1,
> +		.get_master = NULL,
> +	};
> +	struct jnx_card_info cinfo = {
> +		.type = JNX_BOARD_TYPE_UNKNOWN,
> +		.slot = -1,
> +		.assembly_id = -1,
> +	};
> +
> +	cpld = devm_kzalloc(dev, sizeof(*cpld), GFP_KERNEL);
> +	if (!cpld)
> +		return -ENOMEM;
> +
> +	cpld->dev = dev;
> +	dev_set_drvdata(dev, cpld);
> +
> +	if (pdata) {
> +		cpld_type = pdata->cpld_type;
> +	} else {
> +		match = of_match_device(pmb_cpld_of_ids, dev);
> +		if (match)
> +			cpld_type = (int)(unsigned long)match->data;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	cpld->cpld = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(cpld->cpld))
> +		return PTR_ERR(cpld->cpld);

cpld->cpld is confusing.  Please rename.

> +	chinfo.master_data = cpld;
> +
> +	cpld->irq = platform_get_irq(pdev, 0);
> +	if (cpld->irq >= 0) {
> +		error = devm_request_threaded_irq(dev, cpld->irq, NULL,
> +						  pmb_cpld_core_interrupt,
> +						  IRQF_TRIGGER_RISING |
> +						  IRQF_ONESHOT,
> +						  dev_name(dev), cpld);
> +		if (error < 0)
> +			return error;
> +	}
> +
> +	spin_lock_init(&cpld->lock);
> +	init_waitqueue_head(&cpld->wqh);
> +
> +	mfd_cells = pmb_cpld_cells;
> +	mfd_size = ARRAY_SIZE(pmb_cpld_cells);
> +
> +	switch (cpld_type) {
> +	case CPLD_TYPE_PTXPMB:
> +		cpld_ptxpmb_init(cpld, &chinfo, &cinfo);
> +		break;
> +	case CPLD_TYPE_NGPMB:
> +		cpld_ngpmb_init(cpld, &chinfo, &cinfo);
> +		mfd_cells = ngpmb_cpld_cells;
> +		mfd_size = ARRAY_SIZE(ngpmb_cpld_cells);
> +		break;

Are other types supported?

> +	}
> +
> +	if (pdata) {
> +		for (i = 0; i < mfd_size; i++) {
> +			mfd_cells[i].platform_data = pdata;
> +			mfd_cells[i].pdata_size = sizeof(*pdata);
> +		}
> +	}
> +
> +	error = mfd_add_devices(dev, pdev->id, mfd_cells,

The use of pdev->id here is unusual.

Are you sure this is what you want?

> +				mfd_size, res, 0, NULL);
> +	if (error < 0)
> +		return error;
> +
> +	jnx_register_chassis(&chinfo);
> +	jnx_register_local_card(&cinfo);
> +
> +	return 0;
> +}
> +
> +static int pmb_cpld_core_remove(struct platform_device *pdev)
> +{
> +	jnx_unregister_local_card();
> +	jnx_unregister_chassis();
> +	mfd_remove_devices(&pdev->dev);

'\n' here.

> +	return 0;
> +}
> +
> +static struct platform_driver pmb_cpld_core_driver = {
> +	.probe		= pmb_cpld_core_probe,
> +	.remove		= pmb_cpld_core_remove,
> +	.driver		= {
> +		.name	= "ptxpmb-cpld",
> +		.of_match_table = pmb_cpld_of_ids,
> +		.owner	= THIS_MODULE,

Remove this line.

> +	}
> +};
> +

Remove this line.

> +module_platform_driver(pmb_cpld_core_driver);
> +
> +MODULE_DESCRIPTION("Juniper PTX PMB CPLD Core Driver");
> +MODULE_AUTHOR("Guenter Roeck <groeck@juniper.net>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:ptxpmb-cpld");
> diff --git a/include/linux/mfd/ptxpmb_cpld.h b/include/linux/mfd/ptxpmb_cpld.h
> new file mode 100644
> index 0000000..e44afb4
> --- /dev/null
> +++ b/include/linux/mfd/ptxpmb_cpld.h
> @@ -0,0 +1,140 @@
> +/*---------------------------------------------------------------------------
> + *
> + * ptxpmb_cpld_core.h
> + *     Copyright (c) 2012 Juniper Networks
> + *
> + *---------------------------------------------------------------------------
> + */

This it not how we write header comments.

> +#ifndef PTXPMB_CPLD_CORE_H
> +#define PTXPMB_CPLD_CORE_H

__MFD_*

> +struct pmb_boot_cpld {
> +	u8 cpld_rev;		/* 0x00 */
> +	u8 reset;
> +#define CPLD_MAIN_RESET		(1 << 0)

Use BIT() for all these "1 <<"s

> +#define CPLD_PHYCB_RESET	(1 << 1)
> +#define CPLD_PHYSW_RESET	(1 << 2)	/* P2020 only	*/
> +#define NGPMB_PCIE_OTHER_RESET	(1 << 3)	/* PAM reset on MLC */
> +	u8 reset_reason;
> +#define NGPMB_REASON_MON_A_FAIL	(1 << 0)
> +#define NGPMB_REASON_WDT1	(1 << 1)
> +#define NGPMB_REASON_WDT2	(1 << 2)
> +#define NGPMB_REASON_WDT3	(1 << 3)
> +#define NGPMB_REASON_WDT4	(1 << 4)
> +#define NGPMB_REASON_RE_HRST	(1 << 5)
> +#define NGPMB_REASON_PWR_ON	(1 << 6)
> +#define NGPMB_REASON_RE_SRST	(1 << 7)
> +	u8 control;
> +#define CPLD_CONTROL_BOOTED_LED	(1 << 0)
> +#define CPLD_CONTROL_WATCHDOG	(1 << 6)
> +#define CPLD_CONTROL_RTC	(1 << 7)
> +#define NGPMB_FLASH_SELECT	(1 << 4)
> +#define NGPMB_FLASH_SWIZZ_ENA	(1 << 5)
> +	u8 sys_timer_cnt;
> +	u8 watchdog_hbyte;
> +	u8 watchdog_lbyte;
> +	u8 unused1[1];
> +	u8 baseboard_status1;	/* 0x08 */
> +#define NGPMB_PMB_STANDALONE	(1 << 0)
> +#define NGPMB_MASTER_SELECT	(1 << 1)
> +#define NGPMB_BASEBRD_STANDALONE (1 << 2)
> +#define NGPMB_BASEBRD_SLOT_LSB	3
> +#define NGPMB_BASEBRD_SLOT_MASK	0xF8
> +	u8 baseboard_status2;
> +#define NGPMB_BASEBRD_TYPE_LSB	5
> +#define NGPMB_BASEBRD_TYPE_MASK	0xE0
> +#define NGPMB_BASEBRD_TYPE_MX	0
> +	u8 chassis_number;
> +	u8 sys_config;
> +	u8 i2c_group_sel;	/* 0x0c */
> +	u8 i2c_group_en;
> +	u8 unused2[4];
> +	u8 timer_irq_st;	/* 0x12 */
> +	u8 timer_irq_en;
> +	u8 unused3[12];
> +	u8 prog_jtag_control;	/* 0x20 */
> +	u8 gp_reset1;		/* 0x21 */
> +#define CPLD_GP_RST1_PCISW	(1 << 0)
> +#define CPLD_GP_RST1_SAM	(1 << 1)
> +#define CPLD_GP_RST1_BRCM	(1 << 2)
> +	u8 gp_reset2;		/* 0x22 */
> +	u8 phy_control;
> +	u8 gpio_1;
> +	u8 gpio_2;
> +#define NGPMB_GPIO2_TO_BASEBRD_LSB	(1 << 3)
> +#define NGPMB_I2C_GRP_SEL_LSB	0
> +#define NGPMB_I2C_GRP_SEL_MASK	0x03
> +	u8 thermal_status;
> +	u8 i2c_host_sel;
> +#define CPLD_I2C_HOST0_MSTR     0x09
> +#define CPLD_I2C_HOST1_MSTR     0x06
> +#define CPLD_I2C_HOST_MSTR_MASK 0x0f
> +	u8 scratch[3];
> +	u8 misc_status;
> +	u8 i2c_bus_control;	/* 0x2c */
> +	union {
> +		struct {
> +			u8 mezz_present;
> +			u8 unused1[4];
> +			u8 i2c_group_sel_dbg;	/* 0x31 */
> +			u8 i2c_group_en_dbg;	/* 0x32 */
> +			u8 i2c_group_sel_force;	/* 0x33 */
> +			u8 i2c_group_en_force;	/* 0x34 */
> +			u8 unused2[0x4b];
> +		} p2020;
> +		struct {
> +			u8 hdk_minor_version;	/* 0x2d */
> +			u8 hdk_feature_ind;
> +			u8 hdk_pmb_srds_mode;
> +			u8 hdk_pwr_fail_status;
> +			u8 hdk_pmb_pwr_status;
> +			u8 hdk_pmb_mezz_status;
> +			u8 cpld_self_reset;	/* 0x33 */
> +			u8 unused[0x4c];
> +			u8 hdk_bcpld_rcw[80];
> +		} p5020;
> +		struct {
> +			u8 unused[3];
> +			u8 chassis_id;		/* 0x30 */
> +			u8 chassis_type;	/* 0x31 */
> +#define NGPMB_CHASSIS_TYPE_LSB		0
> +#define NGPMB_CHASSIS_TYPE_MASK		0x0F
> +#define NGPMB_CHASSIS_TYPE_POLARIS	0x0B
> +#define NGPMB_CHASSIS_TYPE_HENDRICKS	0x09
> +			u8 sys_config;		/* 0x32 */
> +#define NGPMB_SYS_CONFIG_MULTI_CHASSIS	0x01
> +		} ngpmb;
> +		struct {
> +			u8 nv_win;		/* 0x2d */
> +			u8 nv_addr1;
> +			u8 nv_addr2;
> +			u8 nv_wr_data;
> +			u8 nv_rd_data;
> +			u8 nv_cmd;
> +			u8 nv_done_bit;
> +		} nvram;
> +	} board;
> +};

Please use the standard conventions for detailing registers and bits.

> +#ifdef CONFIG_P2020_PTXPMB
> +#define CPLD_PHY_RESET	(CPLD_PHYCB_RESET | CPLD_PHYSW_RESET)
> +#else
> +#define CPLD_PHY_RESET	CPLD_PHYCB_RESET
> +#endif
> +
> +#define i2c_group_sel_force board.p2020.i2c_group_sel_force
> +#define i2c_group_en_force board.p2020.i2c_group_en_force

I've never seen this before.  Please don't do it.

> +struct ptxpmb_mux_data {
> +	int cpld_type;
> +#define CPLD_TYPE_PTXPMB    0	/* SPMB / Sangria FPC / Hendricks FPC */
> +#define CPLD_TYPE_NGPMB     1	/* MLC / Stout / Gladiator... */
> +	int num_enable;		/* Number of I2C enable pins		*/
> +	int num_channels;	/* Number of I2C channels used in a mux chip */
> +	int parent_bus_num;	/* parent i2c bus number		*/
> +	int base_bus_num;	/* 1st bus number, 0 if undefined	*/
> +	bool use_force;		/* Use i2c force registers if true	*/
> +};

Rename to *_mux_pdata for clarity.

Use kdoc throughout.

> +#endif /* PTXPMB_CPLD_CORE_H */

-- 
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 linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2016-10-26 13:50 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-07 15:17 [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver Pantelis Antoniou
2016-10-07 15:17 ` Pantelis Antoniou
2016-10-07 15:17 ` [PATCH 01/10] mfd: Juniper PTXPMB CPLD Multi-function core driver Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
2016-10-26 13:50   ` Lee Jones
2016-10-26 13:50     ` Lee Jones
2016-10-26 13:50     ` Lee Jones
2016-10-07 15:17 ` [PATCH 02/10] mfd: ptxpmb-cpld: Add documentation for PTXPMB CPLD Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
2016-10-10 17:38   ` Rob Herring
2016-10-10 17:38     ` Rob Herring
2016-10-07 15:17 ` [PATCH 03/10] watchdog: Add support for PTXPMB CPLD watchdog Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
2016-10-07 15:17 ` [PATCH 04/10] watchdog: ptxpmb-wdt: Add ptxpmb-wdt device tree bindings Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
     [not found]   ` <1475853451-22121-5-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2016-10-10 17:41     ` Rob Herring
2016-10-10 17:41       ` Rob Herring
2016-10-07 15:17 ` [PATCH 07/10] gpio: ptxpmb-cpld: Add support for PTXPMB CPLD's GPIO Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
     [not found]   ` <1475853451-22121-8-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2016-10-20 22:24     ` Linus Walleij
2016-10-20 22:24       ` Linus Walleij
2016-10-07 15:17 ` [PATCH 08/10] gpio: ptxpmb-cpld: Document bindings of PTXPMB's CPLD GPIO Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
2016-10-10 18:08   ` Rob Herring
2016-10-10 18:08     ` Rob Herring
2016-10-07 15:17 ` [PATCH 09/10] mtd: devices: Add driver for memory mapped NVRAM on FPC Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
2016-10-07 15:17 ` [PATCH 10/10] mtd: ngpmb_nvram: Add bindings for Juniper's ngpmb NVRAM Pantelis Antoniou
2016-10-07 15:17   ` Pantelis Antoniou
     [not found]   ` <1475853451-22121-11-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2016-10-10 18:18     ` Rob Herring
2016-10-10 18:18       ` Rob Herring
     [not found] ` <1475853451-22121-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2016-10-07 15:17   ` [PATCH 05/10] i2c/muxes: Juniper's PTXPMB CPLD I2C multiplexer Pantelis Antoniou
2016-10-07 15:17     ` Pantelis Antoniou
2016-10-07 15:17   ` [PATCH 06/10] i2c: i2c-mux-ptxpmb-cpld: Add device tree bindings Pantelis Antoniou
2016-10-07 15:17     ` Pantelis Antoniou
     [not found]     ` <1475853451-22121-7-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2016-10-10 17:45       ` Rob Herring
2016-10-10 17:45         ` Rob Herring
2016-10-11  7:36         ` Peter Rosin
2016-10-11  7:36           ` Peter Rosin
2016-10-07 23:39   ` [PATCH 00/10] Introduce Juniper PTXPMB CPLD driver Frank Rowand
2016-10-07 23:39     ` Frank Rowand
     [not found]     ` <57F8324C.2040804-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-08  2:17       ` Frank Rowand
2016-10-08  2:17         ` Frank Rowand
2016-10-20 13:42 ` Linus Walleij
2016-10-20 13:42   ` Linus Walleij
2016-10-20 13:43   ` Pantelis Antoniou
2016-10-20 13:43     ` Pantelis Antoniou

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.