All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8
@ 2021-01-05 13:44 Tomer Maimon
  2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 01/11] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
                   ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:44 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

In this patch set we will like to align with relevant modifications
in Nuvoton OpenBMC Linux kernel 5.4.

Linux upstream current status:
	1. npcm7xx clock driver - adding read only 
		flag to divider clocks, Will be sent to Linux community.
	2. Adding NPCM ADC calibration - Will be sent to Linux vanilla,
		but I am not sure it will be approved.
	3. Add DT restart priority and reset type support - sent to Linux 
		community la but havent approved yet.
	4. persist configuration to the pin control driver - asked by a costumer,
		didnt sent to Linux community.
	5. Add HGPIO pin support to NPCM7xx pinctrl driver - will be sent
		to Linux community
	6. JTAG master driver - will be sent to Linux community once we will 
		have BMC folder.

Changes since version 1:
- Address comments from Jonathan Neuschäfer: removing trailing whitespace
	in NPCM watchdog documentation.
- Adding Stanley Chu to NPCM JTAG master driver

Tomer Maimon (11):
  clk: npcm7xx: add read only flag to divider clocks
  iio: adc: add calibration support to npcm ADC
  dts: npcm750: add fuse regmap support node
  watchdog: npcm: Add DT restart priority and reset type support
  dt-binding: watchdog: Add DT restart priority and reset type
  pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
  pinctrl: pinconf: add pin persist configuration
  pinctrl: npcm7xx: Add pin persist configuration support
  spi: npcm-pspi: Add full duplex support
  dt-binding: bmc: add NPCM7XX JTAG master documentation
  misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver

 .../bindings/bmc/npcm7xx-jtag-master.txt      |  38 +
 .../bindings/watchdog/nuvoton,npcm-wdt.txt    |  32 +
 arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi |   6 +
 drivers/clk/clk-npcm7xx.c                     |  70 +-
 drivers/iio/adc/npcm_adc.c                    | 191 ++++
 drivers/misc/Kconfig                          |   6 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/npcm7xx-jtag-master.c            | 840 ++++++++++++++++++
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c     | 130 ++-
 drivers/pinctrl/pinconf-generic.c             |   3 +
 drivers/spi/spi-npcm-pspi.c                   |  75 +-
 drivers/watchdog/npcm_wdt.c                   | 121 ++-
 12 files changed, 1418 insertions(+), 95 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
 create mode 100644 drivers/misc/npcm7xx-jtag-master.c

-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 01/11] clk: npcm7xx: add read only flag to divider clocks
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
@ 2021-01-05 13:44 ` Tomer Maimon
  2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 02/11] iio: adc: add calibration support to npcm ADC Tomer Maimon
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:44 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add read only flag to all divider clocks except
SPI3 clock.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/clk/clk-npcm7xx.c | 70 +++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c
index 27a86b7a34db..bf721ec2bbc6 100644
--- a/drivers/clk/clk-npcm7xx.c
+++ b/drivers/clk/clk-npcm7xx.c
@@ -370,67 +370,73 @@ static const struct npcm7xx_clk_div_fixed_data npcm7xx_divs_fx[] __initconst = {
 
 /* configurable dividers: */
 static const struct npcm7xx_clk_div_data npcm7xx_divs[] __initconst = {
-	{NPCM7XX_CLKDIV1, 28, 3, NPCM7XX_CLK_S_ADC,
-	NPCM7XX_CLK_S_TIMER, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_ADC},
+	{NPCM7XX_CLKDIV1, 28, 3, NPCM7XX_CLK_S_ADC, NPCM7XX_CLK_S_TIMER,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_ADC},
 	/*30-28 ADCCKDIV*/
-	{NPCM7XX_CLKDIV1, 26, 2, NPCM7XX_CLK_S_AHB,
-	NPCM7XX_CLK_S_AXI, 0, CLK_IS_CRITICAL, NPCM7XX_CLK_AHB},
+	{NPCM7XX_CLKDIV1, 26, 2, NPCM7XX_CLK_S_AHB, NPCM7XX_CLK_S_AXI,
+		CLK_DIVIDER_READ_ONLY, CLK_IS_CRITICAL, NPCM7XX_CLK_AHB},
 	/*27-26 CLK4DIV*/
 	{NPCM7XX_CLKDIV1, 21, 5, NPCM7XX_CLK_S_TIMER,
-	NPCM7XX_CLK_S_TIM_MUX, 0, 0, NPCM7XX_CLK_TIMER},
+	NPCM7XX_CLK_S_TIM_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_TIMER},
 	/*25-21 TIMCKDIV*/
 	{NPCM7XX_CLKDIV1, 16, 5, NPCM7XX_CLK_S_UART,
-	NPCM7XX_CLK_S_UART_MUX, 0, 0, NPCM7XX_CLK_UART},
+	NPCM7XX_CLK_S_UART_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_UART},
 	/*20-16 UARTDIV*/
 	{NPCM7XX_CLKDIV1, 11, 5, NPCM7XX_CLK_S_MMC,
-	NPCM7XX_CLK_S_SD_MUX, 0, 0, NPCM7XX_CLK_MMC},
+	NPCM7XX_CLK_S_SD_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_MMC},
 	/*15-11 MMCCKDIV*/
 	{NPCM7XX_CLKDIV1, 6, 5, NPCM7XX_CLK_S_SPI3,
 	NPCM7XX_CLK_S_AHB, 0, 0, NPCM7XX_CLK_SPI3},
 	/*10-6 AHB3CKDIV*/
 	{NPCM7XX_CLKDIV1, 2, 4, NPCM7XX_CLK_S_PCI,
-	NPCM7XX_CLK_S_GFX_MUX, 0, 0, NPCM7XX_CLK_PCI},
+	NPCM7XX_CLK_S_GFX_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_PCI},
 	/*5-2 PCICKDIV*/
-	{NPCM7XX_CLKDIV1, 0, 1, NPCM7XX_CLK_S_AXI,
-	NPCM7XX_CLK_S_CPU_MUX, CLK_DIVIDER_POWER_OF_TWO, CLK_IS_CRITICAL,
-	NPCM7XX_CLK_AXI},/*0 CLK2DIV*/
+	{NPCM7XX_CLKDIV1, 0, 1, NPCM7XX_CLK_S_AXI, NPCM7XX_CLK_S_CPU_MUX,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO,
+		CLK_IS_CRITICAL, NPCM7XX_CLK_AXI},/*0 CLK2DIV*/
 
-	{NPCM7XX_CLKDIV2, 30, 2, NPCM7XX_CLK_S_APB4,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB4},
+	{NPCM7XX_CLKDIV2, 30, 2, NPCM7XX_CLK_S_APB4, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY| CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB4},
 	/*31-30 APB4CKDIV*/
-	{NPCM7XX_CLKDIV2, 28, 2, NPCM7XX_CLK_S_APB3,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB3},
+	{NPCM7XX_CLKDIV2, 28, 2, NPCM7XX_CLK_S_APB3, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY| CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB3},
 	/*29-28 APB3CKDIV*/
-	{NPCM7XX_CLKDIV2, 26, 2, NPCM7XX_CLK_S_APB2,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB2},
+	{NPCM7XX_CLKDIV2, 26, 2, NPCM7XX_CLK_S_APB2, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB2},
 	/*27-26 APB2CKDIV*/
-	{NPCM7XX_CLKDIV2, 24, 2, NPCM7XX_CLK_S_APB1,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB1},
+	{NPCM7XX_CLKDIV2, 24, 2, NPCM7XX_CLK_S_APB1, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB1},
 	/*25-24 APB1CKDIV*/
-	{NPCM7XX_CLKDIV2, 22, 2, NPCM7XX_CLK_S_APB5,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB5},
+	{NPCM7XX_CLKDIV2, 22, 2, NPCM7XX_CLK_S_APB5, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB5},
 	/*23-22 APB5CKDIV*/
-	{NPCM7XX_CLKDIV2, 16, 5, NPCM7XX_CLK_S_CLKOUT,
-	NPCM7XX_CLK_S_CLKOUT_MUX, 0, 0, NPCM7XX_CLK_CLKOUT},
+	{NPCM7XX_CLKDIV2, 16, 5, NPCM7XX_CLK_S_CLKOUT, NPCM7XX_CLK_S_CLKOUT_MUX,
+		 CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_CLKOUT},
 	/*20-16 CLKOUTDIV*/
-	{NPCM7XX_CLKDIV2, 13, 3, NPCM7XX_CLK_S_GFX,
-	NPCM7XX_CLK_S_GFX_MUX, 0, 0, NPCM7XX_CLK_GFX},
+	{NPCM7XX_CLKDIV2, 13, 3, NPCM7XX_CLK_S_GFX, NPCM7XX_CLK_S_GFX_MUX,
+		CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_GFX},
 	/*15-13 GFXCKDIV*/
-	{NPCM7XX_CLKDIV2, 8, 5, NPCM7XX_CLK_S_USB_BRIDGE,
-	NPCM7XX_CLK_S_SU_MUX, 0, 0, NPCM7XX_CLK_SU},
+	{NPCM7XX_CLKDIV2, 8, 5, NPCM7XX_CLK_S_USB_BRIDGE, NPCM7XX_CLK_S_SU_MUX,
+		CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SU},
 	/*12-8 SUCKDIV*/
-	{NPCM7XX_CLKDIV2, 4, 4, NPCM7XX_CLK_S_USB_HOST,
-	NPCM7XX_CLK_S_SU_MUX, 0, 0, NPCM7XX_CLK_SU48},
+	{NPCM7XX_CLKDIV2, 4, 4, NPCM7XX_CLK_S_USB_HOST, NPCM7XX_CLK_S_SU_MUX,
+		CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SU48},
 	/*7-4 SU48CKDIV*/
 	{NPCM7XX_CLKDIV2, 0, 4, NPCM7XX_CLK_S_SDHC,
-	NPCM7XX_CLK_S_SD_MUX, 0, 0, NPCM7XX_CLK_SDHC}
+	NPCM7XX_CLK_S_SD_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SDHC}
 	,/*3-0 SD1CKDIV*/
 
 	{NPCM7XX_CLKDIV3, 6, 5, NPCM7XX_CLK_S_SPI0,
-	NPCM7XX_CLK_S_AHB, 0, 0, NPCM7XX_CLK_SPI0},
+	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SPI0},
 	/*10-6 SPI0CKDV*/
 	{NPCM7XX_CLKDIV3, 1, 5, NPCM7XX_CLK_S_SPIX,
-	NPCM7XX_CLK_S_AHB, 0, 0, NPCM7XX_CLK_SPIX},
+	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SPIX},
 	/*5-1 SPIXCKDV*/
 
 };
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 02/11] iio: adc: add calibration support to npcm ADC
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
  2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 01/11] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
@ 2021-01-05 13:44 ` Tomer Maimon
  2021-01-11  0:52   ` Joel Stanley
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 03/11] dts: npcm750: add fuse regmap support node Tomer Maimon
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:44 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add calibration to improve accuracy measurement when using
internal referance voltage.

the calibration values taken from the FUSE module.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/iio/adc/npcm_adc.c | 191 +++++++++++++++++++++++++++++++++++++
 1 file changed, 191 insertions(+)

diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c
index 83bad2d5575d..02628b7eaca1 100644
--- a/drivers/iio/adc/npcm_adc.c
+++ b/drivers/iio/adc/npcm_adc.c
@@ -17,6 +17,8 @@
 #include <linux/reset.h>
 
 struct npcm_adc {
+	u32 R05;
+	u32 R15;
 	bool int_status;
 	u32 adc_sample_hz;
 	struct device *dev;
@@ -51,6 +53,40 @@ struct npcm_adc {
 #define NPCM_RESOLUTION_BITS		10
 #define NPCM_INT_VREF_MV		2000
 
+/* FUSE registers */
+#define NPCM7XX_FST		0x00
+#define NPCM7XX_FADDR		0x04
+#define NPCM7XX_FDATA		0x08
+#define NPCM7XX_FCFG		0x0C
+#define NPCM7XX_FCTL		0x14
+
+/* FST Register Bits */
+#define NPCM7XX_FST_RDY		BIT(0)
+#define NPCM7XX_FST_RDST	BIT(1)
+
+/* FADDR Register Bits */
+#define NPCM7XX_FADDR_BYTEADDR		BIT(0)
+#define NPCM7XX_FADDR_BYTEADDR_MASK	GENMASK(9, 0)
+
+/* FADDR Register Bits */
+#define NPCM7XX_FDATA_DATA		BIT(0)
+#define NPCM7XX_FDATA_CLEAN_VALUE	BIT(1)
+#define NPCM7XX_FDATA_DATA_MASK		GENMASK(7, 0)
+
+/* FCTL Register Bits */
+#define NPCM7XX_FCTL_RDST		BIT(1)
+
+/* ADC Calibration Definition */
+#define NPCM_INT_1500MV		768
+#define NPCM_INT_1000MV		512
+#define NPCM_ADC_MIN_VAL	0
+#define NPCM_ADC_MAX_VAL	1023
+
+#define FUSE_CALIB_ADDR		24
+#define FUSE_CALIB_SIZE		8
+#define DATA_CALIB_SIZE		4
+#define FUSE_READ_TIMEOUT	0xDEADBEEF
+
 #define NPCM_ADC_CHAN(ch) {					\
 	.type = IIO_VOLTAGE,					\
 	.indexed = 1,						\
@@ -71,6 +107,133 @@ static const struct iio_chan_spec npcm_adc_iio_channels[] = {
 	NPCM_ADC_CHAN(7),
 };
 
+static int npcm750_fuse_wait_for_ready(struct regmap *fuse_regmap, u32 timeout)
+{
+	u32 time = timeout;
+	u32 fstreg;
+
+	while (--time > 1) {
+		regmap_read(fuse_regmap, NPCM7XX_FST, &fstreg);
+		if (fstreg & NPCM7XX_FST_RDY) {
+			regmap_write_bits(fuse_regmap, NPCM7XX_FST,
+					  NPCM7XX_FST_RDST, NPCM7XX_FST_RDST);
+			return 0;
+		}
+	}
+
+	/* try to clear the status in case it was set */
+	regmap_write_bits(fuse_regmap, NPCM7XX_FST, NPCM7XX_FST_RDST,
+			  NPCM7XX_FST_RDST);
+
+	return -EINVAL;
+}
+
+static void npcm750_fuse_read(struct regmap *fuse_regmap, u32 addr, u8 *data)
+{
+	u32 val;
+
+	npcm750_fuse_wait_for_ready(fuse_regmap, FUSE_READ_TIMEOUT);
+
+	regmap_write_bits(fuse_regmap, NPCM7XX_FADDR,
+			  NPCM7XX_FADDR_BYTEADDR_MASK, addr);
+	regmap_read(fuse_regmap, NPCM7XX_FADDR, &val);
+	regmap_write(fuse_regmap, NPCM7XX_FCTL, NPCM7XX_FCTL_RDST);
+
+	npcm750_fuse_wait_for_ready(fuse_regmap, FUSE_READ_TIMEOUT);
+	regmap_read(fuse_regmap, NPCM7XX_FDATA, &val);
+	*data = (u8)val;
+
+	regmap_write_bits(fuse_regmap, NPCM7XX_FDATA, NPCM7XX_FDATA_DATA_MASK,
+			  NPCM7XX_FDATA_CLEAN_VALUE);
+}
+
+static int npcm750_ECC_to_nibble(u8 ECC, u8 nibble)
+{
+	u8 nibble_b0 = (nibble >> 0) & BIT(0);
+	u8 nibble_b1 = (nibble >> 1) & BIT(0);
+	u8 nibble_b2 = (nibble >> 2) & BIT(0);
+	u8 nibble_b3 = (nibble >> 3) & BIT(0);
+	u8 tmp_ECC = nibble;
+
+	tmp_ECC |= (nibble_b0 ^ nibble_b1) << 4 | (nibble_b2 ^ nibble_b3) << 5 |
+		(nibble_b0 ^ nibble_b2) << 6  | (nibble_b1 ^ nibble_b3) << 7;
+
+	if (tmp_ECC != ECC)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int npcm750_ECC_to_byte(u16 ECC, u8 *Byte)
+{
+	u8 nibble_L, nibble_H;
+	u8 ECC_L, ECC_H;
+
+	ECC_H = ECC >> 8;
+	nibble_H = ECC_H & 0x0F;
+	ECC_L = ECC >> 0;
+	nibble_L = ECC_L & 0x0F;
+
+	if (npcm750_ECC_to_nibble(ECC_H, nibble_H) != 0 ||
+	    npcm750_ECC_to_nibble(ECC_L, nibble_L) != 0)
+		return -EINVAL;
+
+	*Byte = nibble_H << 4 | nibble_L << 0;
+
+	return 0;
+}
+
+static int npcm750_read_nibble_parity(u8 *block_ECC, u8 *ADC_calib)
+{
+	int i;
+	u16 ECC;
+
+	for (i = 0; i < DATA_CALIB_SIZE; i++) {
+		memcpy(&ECC, block_ECC + (i * 2), 2);
+		if (npcm750_ECC_to_byte(ECC, &ADC_calib[i]) != 0)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int npcm750_fuse_calibration_read(struct platform_device *pdev,
+					struct npcm_adc *info)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct regmap *fuse_regmap;
+	ssize_t bytes_read = 0;
+	u8 read_buf[8];
+	u32 ADC_calib;
+	u32 addr = FUSE_CALIB_ADDR;
+
+	if (of_device_is_compatible(np, "nuvoton,npcm750-adc")) {
+		fuse_regmap = syscon_regmap_lookup_by_compatible
+			("nuvoton,npcm750-fuse");
+		if (IS_ERR(fuse_regmap)) {
+			dev_warn(&pdev->dev, "Failed to find nuvoton,npcm750-fuse\n");
+			return PTR_ERR(fuse_regmap);
+		}
+
+		while (bytes_read < FUSE_CALIB_SIZE) {
+			npcm750_fuse_read(fuse_regmap, addr,
+					  &read_buf[bytes_read]);
+			bytes_read++;
+			addr++;
+		}
+
+		if (npcm750_read_nibble_parity(read_buf, (u8 *)&ADC_calib)) {
+			dev_warn(info->dev, "FUSE Clibration read failed\n");
+			return -EINVAL;
+		}
+
+		info->R05 = ADC_calib & 0xFFFF;
+		info->R15 = ADC_calib >> 16;
+	}
+
+	return 0;
+}
+
 static irqreturn_t npcm_adc_isr(int irq, void *data)
 {
 	u32 regtemp;
@@ -125,6 +288,29 @@ static int npcm_adc_read(struct npcm_adc *info, int *val, u8 channel)
 	return 0;
 }
 
+static void npcm_adc_calibration(int *val, struct npcm_adc *info)
+{
+	int mul_val;
+	int offset_val;
+
+	mul_val = NPCM_INT_1000MV * (*val - info->R15);
+	if (mul_val < 0) {
+		mul_val = mul_val * -1;
+		offset_val = DIV_ROUND_CLOSEST(mul_val,
+					       (info->R15 - info->R05));
+		*val = NPCM_INT_1500MV - offset_val;
+	} else {
+		offset_val = DIV_ROUND_CLOSEST(mul_val,
+					       (info->R15 - info->R05));
+		*val = NPCM_INT_1500MV + offset_val;
+	}
+
+	if (*val < NPCM_ADC_MIN_VAL)
+		*val = NPCM_ADC_MIN_VAL;
+	if (*val > NPCM_ADC_MAX_VAL)
+		*val = NPCM_ADC_MAX_VAL;
+}
+
 static int npcm_adc_read_raw(struct iio_dev *indio_dev,
 			     struct iio_chan_spec const *chan, int *val,
 			     int *val2, long mask)
@@ -142,6 +328,10 @@ static int npcm_adc_read_raw(struct iio_dev *indio_dev,
 			dev_err(info->dev, "NPCM ADC read failed\n");
 			return ret;
 		}
+
+		if ((info->R05 || info->R15) && IS_ERR(info->vref))
+			npcm_adc_calibration(val, info);
+
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 		if (!IS_ERR(info->vref)) {
@@ -248,6 +438,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
 			  info->regs + NPCM_ADCCON);
 	}
 
+	npcm750_fuse_calibration_read(pdev, info);
 	init_waitqueue_head(&info->wq);
 
 	reg_con = ioread32(info->regs + NPCM_ADCCON);
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 03/11] dts: npcm750: add fuse regmap support node
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
  2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 01/11] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
  2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 02/11] iio: adc: add calibration support to npcm ADC Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support Tomer Maimon
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
index 7eee4145127f..455a96b23b85 100644
--- a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
+++ b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
@@ -82,6 +82,12 @@
 			"simple-mfd";
 			reg = <0x801000 0x6C>;
 		};
+		
+		fuse:fuse@18a000 {
+			compatible = "nuvoton,npcm750-fuse", "syscon",
+				"simple-mfd";
+			reg = <0x18a000 0x1000>;
+		};
 
 		scu: scu@3fe000 {
 			compatible = "arm,cortex-a9-scu";
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (2 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 03/11] dts: npcm750: add fuse regmap support node Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-11  0:55   ` Joel Stanley
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 05/11] dt-binding: watchdog: Add DT restart priority and reset type Tomer Maimon
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add Device tree restart priority and
three reset types support.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/watchdog/npcm_wdt.c | 121 +++++++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
index 765577f11c8d..bbf27da34834 100644
--- a/drivers/watchdog/npcm_wdt.c
+++ b/drivers/watchdog/npcm_wdt.c
@@ -11,7 +11,24 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/watchdog.h>
-
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+/* NPCM7xx GCR module */
+#define NPCM7XX_RESSR_OFFSET		0x6C
+#define NPCM7XX_INTCR2_OFFSET		0x60
+
+#define NPCM7XX_PORST			BIT(31)
+#define NPCM7XX_CORST			BIT(30)
+#define NPCM7XX_WD0RST			BIT(29)
+#define NPCM7XX_WD1RST			BIT(24)
+#define NPCM7XX_WD2RST			BIT(23)
+#define NPCM7XX_SWR1RST			BIT(28)
+#define NPCM7XX_SWR2RST			BIT(27)
+#define NPCM7XX_SWR3RST			BIT(26)
+#define NPCM7XX_SWR4RST			BIT(25)
+
+ /* WD register */
 #define NPCM_WTCR	0x1C
 
 #define NPCM_WTCLK	(BIT(10) | BIT(11))	/* Clock divider */
@@ -43,6 +60,10 @@
 struct npcm_wdt {
 	struct watchdog_device  wdd;
 	void __iomem		*reg;
+	u32 			card_reset;
+	u32 			ext1_reset;
+	u32 			ext2_reset;
+
 };
 
 static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd)
@@ -176,14 +197,70 @@ static const struct watchdog_ops npcm_wdt_ops = {
 	.restart = npcm_wdt_restart,
 };
 
+static void npcm_get_reset_status(struct npcm_wdt *wdt, struct device *dev)
+{
+	struct regmap *gcr_regmap;
+	u32 rstval;
+
+	if (of_device_is_compatible(dev->of_node, "nuvoton,npcm750-wdt")) {
+		gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
+		if (IS_ERR(gcr_regmap)) {
+			dev_warn(dev, "Failed to find nuvoton,npcm750-gcr WD reset status not supported\n");
+		}
+
+		regmap_read(gcr_regmap, NPCM7XX_RESSR_OFFSET, &rstval);
+		if (!rstval) {
+			regmap_read(gcr_regmap, NPCM7XX_INTCR2_OFFSET, &rstval);
+			rstval = ~rstval;
+		}
+
+		if(rstval & wdt->card_reset)
+			wdt->wdd.bootstatus |= WDIOF_CARDRESET;
+		if(rstval & wdt->ext1_reset)
+			wdt->wdd.bootstatus |= WDIOF_EXTERN1;
+		if(rstval & wdt->ext2_reset)
+			wdt->wdd.bootstatus |= WDIOF_EXTERN2;
+	}
+
+}
+
+static u32 npcm_wdt_reset_type(const char *reset_type)
+{
+	if (!strcmp(reset_type, "porst"))
+		return NPCM7XX_PORST;
+	else if (!strcmp(reset_type, "corst"))
+		return NPCM7XX_CORST;
+	else if (!strcmp(reset_type, "wd0"))
+		return NPCM7XX_WD0RST;
+	else if (!strcmp(reset_type, "wd1"))
+		return NPCM7XX_WD1RST;
+	else if (!strcmp(reset_type, "wd2"))
+		return NPCM7XX_WD2RST;
+	else if (!strcmp(reset_type, "sw1"))
+		return NPCM7XX_SWR1RST;
+	else if (!strcmp(reset_type, "sw2"))
+		return NPCM7XX_SWR2RST;
+	else if (!strcmp(reset_type, "sw3"))
+		return NPCM7XX_SWR3RST;
+	else if (!strcmp(reset_type, "sw4"))
+		return NPCM7XX_SWR4RST;
+
+	return 0;
+}
+
 static int npcm_wdt_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	const char *card_reset_type;
+	const char *ext1_reset_type;
+	const char *ext2_reset_type;
 	struct npcm_wdt *wdt;
+	struct resource *res;
+	u32 priority;
 	int irq;
 	int ret;
 
-	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
 	if (!wdt)
 		return -ENOMEM;
 
@@ -195,6 +272,45 @@ static int npcm_wdt_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return irq;
 
+	if (of_property_read_u32(pdev->dev.of_node, "nuvoton,restart-priority", 
+				 &priority))
+		watchdog_set_restart_priority(&wdt->wdd, 128);
+	else
+		watchdog_set_restart_priority(&wdt->wdd, priority);
+
+	ret = of_property_read_string(pdev->dev.of_node,
+				      "nuvoton,card-reset-type",
+				      &card_reset_type);
+	if (ret)
+		wdt->card_reset = NPCM7XX_PORST;
+	else {
+		wdt->card_reset = npcm_wdt_reset_type(card_reset_type);
+		if (!wdt->card_reset)
+			wdt->card_reset = NPCM7XX_PORST;
+	}
+
+	ret = of_property_read_string(pdev->dev.of_node,
+				      "nuvoton,ext1-reset-type",
+				      &ext1_reset_type);
+	if (ret)
+		wdt->ext1_reset = NPCM7XX_WD0RST;
+	else {
+		wdt->ext1_reset = npcm_wdt_reset_type(ext1_reset_type);
+		if (!wdt->ext1_reset)
+			wdt->ext1_reset = NPCM7XX_WD0RST;
+	}
+
+	ret = of_property_read_string(pdev->dev.of_node,
+				      "nuvoton,ext2-reset-type",
+				      &ext2_reset_type);
+	if (ret)
+		wdt->ext2_reset = NPCM7XX_SWR1RST;
+	else {
+		wdt->ext2_reset = npcm_wdt_reset_type(ext2_reset_type);
+		if (!wdt->ext2_reset)
+			wdt->ext2_reset = NPCM7XX_SWR1RST;
+	}
+
 	wdt->wdd.info = &npcm_wdt_info;
 	wdt->wdd.ops = &npcm_wdt_ops;
 	wdt->wdd.min_timeout = 1;
@@ -213,6 +329,7 @@ static int npcm_wdt_probe(struct platform_device *pdev)
 		set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
 	}
 
+	npcm_get_reset_status(wdt, dev);
 	ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, "watchdog",
 			       wdt);
 	if (ret)
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 05/11] dt-binding: watchdog: Add DT restart priority and reset type
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (3 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 06/11] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add device tree restart priority documentation and
three reset types documentation.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 .../bindings/watchdog/nuvoton,npcm-wdt.txt    | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
index 6d593003c933..f6e0ea3e3c78 100644
--- a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
@@ -17,6 +17,34 @@ Required clocking property, have to be one of:
 
 Optional properties:
 - timeout-sec : Contains the watchdog timeout in seconds
+- nuvoton,restart-priority - Contains the card restart priority.
+- nuvoton,card-reset-type = "porst|corst|wd0|wd1|wd2|sw1|sw2|sw3|sw4"
+  Contains the card reset type for checking and indicating
+  the last card reset status (WDIOF_CARDRESET)
+
+  If 'nuvoton,card-reset-type' is not specified the default is porst
+
+  Reset types:
+       - porst: Power reset
+       - corst: Core reset
+	   - wdX : Watchdog reset X (X represante 0-2)
+	   - swX : Software reset X (X represante 1-4)
+
+- nuvoton,ext1-reset-type = "porst|corst|wd0|wd1|wd2|sw1|sw2|sw3|sw4"
+  Contains the external 2 reset type for checking and indicating
+  the last external 2 reset status (WDIOF_EXTERN1)
+
+  If 'nuvoton,card-reset-type' is not specified the default is wd0.
+
+  Reset types are the same as in nuvoton,card-reset-type property.
+
+- nuvoton,ext2-reset-type = "porst|corst|wd0|wd1|wd2|sw1|sw2|sw3|sw4"
+  Contains the external 2 reset type for checking and indicating
+  the last external 2 reset status (WDIOF_EXTERN2)
+
+  If 'nuvoton,card-reset-type' is not specified the default is sw1.
+
+  Reset types are the same as in nuvoton,card-reset-type property.
 
 Example:
 
@@ -25,4 +53,8 @@ timer@f000801c {
     interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
     reg = <0xf000801c 0x4>;
     clocks = <&clk NPCM7XX_CLK_TIMER>;
+	nuvoton,restart-priority = <155>;
+	nuvoton,card-reset-type = "porst";
+	nuvoton,ext1-reset-type = "wd1";
+	nuvoton,ext2-reset-type = "sw2";
 };
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 06/11] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (4 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 05/11] dt-binding: watchdog: Add DT restart priority and reset type Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-11  0:56   ` Joel Stanley
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 07/11] pinctrl: pinconf: add pin persist configuration Tomer Maimon
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 65 +++++++++++++++++------
 1 file changed, 49 insertions(+), 16 deletions(-)

diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
index a935065cdac4..e5f58ea89917 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
@@ -504,6 +504,15 @@ static const int lkgpo2_pins[] = { 9 };
 
 static const int nprd_smi_pins[] = { 190 };
 
+static const int hgpio0_pins[] = { 20 };
+static const int hgpio1_pins[] = { 21 };
+static const int hgpio2_pins[] = { 22 };
+static const int hgpio3_pins[] = { 23 };
+static const int hgpio4_pins[] = { 24 };
+static const int hgpio5_pins[] = { 25 };
+static const int hgpio6_pins[] = { 59 };
+static const int hgpio7_pins[] = { 60 };
+
 /*
  * pin:	     name, number
  * group:    name, npins,   pins
@@ -631,6 +640,14 @@ struct npcm7xx_group {
 	NPCM7XX_GRP(lkgpo1), \
 	NPCM7XX_GRP(lkgpo2), \
 	NPCM7XX_GRP(nprd_smi), \
+	NPCM7XX_GRP(hgpio0), \
+	NPCM7XX_GRP(hgpio1), \
+	NPCM7XX_GRP(hgpio2), \
+	NPCM7XX_GRP(hgpio3), \
+	NPCM7XX_GRP(hgpio4), \
+	NPCM7XX_GRP(hgpio5), \
+	NPCM7XX_GRP(hgpio6), \
+	NPCM7XX_GRP(hgpio7), \
 	\
 
 enum {
@@ -774,6 +791,14 @@ NPCM7XX_SFUNC(lkgpo0);
 NPCM7XX_SFUNC(lkgpo1);
 NPCM7XX_SFUNC(lkgpo2);
 NPCM7XX_SFUNC(nprd_smi);
+NPCM7XX_SFUNC(hgpio0);
+NPCM7XX_SFUNC(hgpio1);
+NPCM7XX_SFUNC(hgpio2);
+NPCM7XX_SFUNC(hgpio3);
+NPCM7XX_SFUNC(hgpio4);
+NPCM7XX_SFUNC(hgpio5);
+NPCM7XX_SFUNC(hgpio6);
+NPCM7XX_SFUNC(hgpio7);
 
 /* Function names */
 static struct npcm7xx_func npcm7xx_funcs[] = {
@@ -892,6 +917,14 @@ static struct npcm7xx_func npcm7xx_funcs[] = {
 	NPCM7XX_MKFUNC(lkgpo1),
 	NPCM7XX_MKFUNC(lkgpo2),
 	NPCM7XX_MKFUNC(nprd_smi),
+	NPCM7XX_MKFUNC(hgpio0),
+	NPCM7XX_MKFUNC(hgpio1),
+	NPCM7XX_MKFUNC(hgpio2),
+	NPCM7XX_MKFUNC(hgpio3),
+	NPCM7XX_MKFUNC(hgpio4),
+	NPCM7XX_MKFUNC(hgpio5),
+	NPCM7XX_MKFUNC(hgpio6),
+	NPCM7XX_MKFUNC(hgpio7),
 };
 
 #define NPCM7XX_PINCFG(a, b, c, d, e, f, g, h, i, j, k) \
@@ -944,12 +977,12 @@ static const struct npcm7xx_pincfg pincfg[] = {
 	NPCM7XX_PINCFG(17,      pspi2, MFSEL3, 13,     smb4den, I2CSEGSEL, 23,  none, NONE, 0,       DS(8, 12)),
 	NPCM7XX_PINCFG(18,      pspi2, MFSEL3, 13,	 smb4b, I2CSEGSEL, 14,  none, NONE, 0,	     DS(8, 12)),
 	NPCM7XX_PINCFG(19,      pspi2, MFSEL3, 13,	 smb4b, I2CSEGSEL, 14,  none, NONE, 0,	     DS(8, 12)),
-	NPCM7XX_PINCFG(20,	smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(21,	smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(22,      smb4d, I2CSEGSEL, 16,	 smb14, MFSEL3, 7,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(23,      smb4d, I2CSEGSEL, 16,	 smb14, MFSEL3, 7,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(24,	 ioxh, MFSEL3, 18,	  none, NONE, 0,	none, NONE, 0,	     DS(8, 12)),
-	NPCM7XX_PINCFG(25,	 ioxh, MFSEL3, 18,	  none, NONE, 0,	none, NONE, 0,	     DS(8, 12)),
+	NPCM7XX_PINCFG(20,	hgpio0, MFSEL2, 24,      smb15, MFSEL3, 8,      smb4c, I2CSEGSEL, 15,	     0),
+	NPCM7XX_PINCFG(21,	hgpio1, MFSEL2, 25,      smb15, MFSEL3, 8,      smb4c, I2CSEGSEL, 15,	     0),
+	NPCM7XX_PINCFG(22,      hgpio2, MFSEL2, 26,	 smb14, MFSEL3, 7,      smb4d, I2CSEGSEL, 16,	     0),
+	NPCM7XX_PINCFG(23,      hgpio3, MFSEL2, 27,	 smb14, MFSEL3, 7,      smb4d, I2CSEGSEL, 16,	     0),
+	NPCM7XX_PINCFG(24,	 hgpio4, MFSEL2, 28,	ioxh, MFSEL3, 18,	none, NONE, 0,	     DS(8, 12)),
+	NPCM7XX_PINCFG(25,	 hgpio5, MFSEL2, 29,	ioxh, MFSEL3, 18,	none, NONE, 0,	     DS(8, 12)),
 	NPCM7XX_PINCFG(26,	 smb5, MFSEL1, 2,	  none, NONE, 0,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(27,	 smb5, MFSEL1, 2,	  none, NONE, 0,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(28,	 smb4, MFSEL1, 1,	  none, NONE, 0,	none, NONE, 0,	     0),
@@ -982,8 +1015,8 @@ static const struct npcm7xx_pincfg pincfg[] = {
 	NPCM7XX_PINCFG(56,	r1err, MFSEL1, 12,	  none, NONE, 0,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(57,       r1md, MFSEL1, 13,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
 	NPCM7XX_PINCFG(58,       r1md, MFSEL1, 13,        none, NONE, 0,	none, NONE, 0,	     DS(2, 4)),
-	NPCM7XX_PINCFG(59,	smb3d, I2CSEGSEL, 13,	  none, NONE, 0,	none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(60,	smb3d, I2CSEGSEL, 13,	  none, NONE, 0,	none, NONE, 0,	     0),
+	NPCM7XX_PINCFG(59,	hgpio6, MFSEL2, 30,	  smb3d, I2CSEGSEL, 13,	none, NONE, 0,	     0),
+	NPCM7XX_PINCFG(60,	hgpio7, MFSEL2, 31,	  smb3d, I2CSEGSEL, 13,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(61,      uart1, MFSEL1, 10,	  none, NONE, 0,	none, NONE, 0,     GPO),
 	NPCM7XX_PINCFG(62,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,	none, NONE, 0,     GPO),
 	NPCM7XX_PINCFG(63,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,	none, NONE, 0,     GPO),
@@ -1188,12 +1221,12 @@ static const struct pinctrl_pin_desc npcm7xx_pins[] = {
 	PINCTRL_PIN(17, "GPIO17/PSPI2DI/SMB4DEN"),
 	PINCTRL_PIN(18, "GPIO18/PSPI2D0/SMB4BSDA"),
 	PINCTRL_PIN(19, "GPIO19/PSPI2CK/SMB4BSCL"),
-	PINCTRL_PIN(20, "GPIO20/SMB4CSDA/SMB15SDA"),
-	PINCTRL_PIN(21, "GPIO21/SMB4CSCL/SMB15SCL"),
-	PINCTRL_PIN(22, "GPIO22/SMB4DSDA/SMB14SDA"),
-	PINCTRL_PIN(23, "GPIO23/SMB4DSCL/SMB14SCL"),
-	PINCTRL_PIN(24, "GPIO24/IOXHDO"),
-	PINCTRL_PIN(25, "GPIO25/IOXHDI"),
+	PINCTRL_PIN(20, "GPIO20/HGPIO0/SMB4CSDA/SMB15SDA"),
+	PINCTRL_PIN(21, "GPIO21/HGPIO1/SMB4CSCL/SMB15SCL"),
+	PINCTRL_PIN(22, "GPIO22/HGPIO2/SMB4DSDA/SMB14SDA"),
+	PINCTRL_PIN(23, "GPIO23/HGPIO3/SMB4DSCL/SMB14SCL"),
+	PINCTRL_PIN(24, "GPIO24/HGPIO4/IOXHDO"),
+	PINCTRL_PIN(25, "GPIO25/HGPIO5/IOXHDI"),
 	PINCTRL_PIN(26, "GPIO26/SMB5SDA"),
 	PINCTRL_PIN(27, "GPIO27/SMB5SCL"),
 	PINCTRL_PIN(28, "GPIO28/SMB4SDA"),
@@ -1226,8 +1259,8 @@ static const struct pinctrl_pin_desc npcm7xx_pins[] = {
 	PINCTRL_PIN(56, "GPIO56/R1RXERR"),
 	PINCTRL_PIN(57, "GPIO57/R1MDC"),
 	PINCTRL_PIN(58, "GPIO58/R1MDIO"),
-	PINCTRL_PIN(59, "GPIO59/SMB3DSDA"),
-	PINCTRL_PIN(60, "GPIO60/SMB3DSCL"),
+	PINCTRL_PIN(59, "GPIO59/HGPIO6/SMB3DSDA"),
+	PINCTRL_PIN(60, "GPIO60/HGPIO7/SMB3DSCL"),
 	PINCTRL_PIN(61, "GPO61/nDTR1_BOUT1/STRAP6"),
 	PINCTRL_PIN(62, "GPO62/nRTST1/STRAP5"),
 	PINCTRL_PIN(63, "GPO63/TXD1/STRAP4"),
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 07/11] pinctrl: pinconf: add pin persist configuration
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (5 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 06/11] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 08/11] pinctrl: npcm7xx: Add pin persist configuration support Tomer Maimon
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add generic pin persist configuration support.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/pinctrl/pinconf-generic.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index dfef471201f6..c609a69bd37e 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -50,6 +50,7 @@ static const struct pin_config_item conf_items[] = {
 	PCONFDUMP(PIN_CONFIG_SLEEP_HARDWARE_STATE, "sleep hardware state", NULL, false),
 	PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true),
 	PCONFDUMP(PIN_CONFIG_SKEW_DELAY, "skew delay", NULL, true),
+	PCONFDUMP(PIN_CONFIG_PERSIST_STATE, "persist state", NULL, false),
 };
 
 static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
@@ -184,6 +185,8 @@ static const struct pinconf_generic_params dt_params[] = {
 	{ "sleep-hardware-state", PIN_CONFIG_SLEEP_HARDWARE_STATE, 0 },
 	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
 	{ "skew-delay", PIN_CONFIG_SKEW_DELAY, 0 },
+	{ "persist-state", PIN_CONFIG_PERSIST_STATE, 0 },
+	{ "reset-state", PIN_CONFIG_PERSIST_STATE, 1 },
 };
 
 /**
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 08/11] pinctrl: npcm7xx: Add pin persist configuration support
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (6 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 07/11] pinctrl: pinconf: add pin persist configuration Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support Tomer Maimon
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 65 +++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
index e5f58ea89917..ec12efd23bbe 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
@@ -36,6 +36,19 @@
 
 #define SRCNT_ESPI		BIT(3)
 
+/* reset registers */
+#define NPCM7XX_RST_WD0RCR	0x38
+#define NPCM7XX_RST_WD1RCR	0x3C
+#define NPCM7XX_RST_WD2RCR	0x40
+#define NPCM7XX_RST_SWRSTC1	0x44
+#define NPCM7XX_RST_SWRSTC2	0x48
+#define NPCM7XX_RST_SWRSTC3	0x4C
+#define NPCM7XX_RST_SWRSTC4	0x50
+#define NPCM7XX_RST_CORSTC	0x5C
+
+#define GPIOX_MODULE_RESET	BIT(16)
+#define CA9C_MODULE_RESET	BIT(0)
+
 /* GPIO registers */
 #define NPCM7XX_GP_N_TLOCK1	0x00
 #define NPCM7XX_GP_N_DIN	0x04 /* Data IN */
@@ -94,6 +107,7 @@ struct npcm7xx_pinctrl {
 	struct npcm7xx_gpio	gpio_bank[NPCM7XX_GPIO_BANK_NUM];
 	struct irq_domain	*domain;
 	struct regmap		*gcr_regmap;
+	struct regmap		*rst_regmap;
 	void __iomem		*regs;
 	u32			bank_num;
 };
@@ -1583,6 +1597,48 @@ static int npcm7xx_set_drive_strength(struct npcm7xx_pinctrl *npcm,
 	return -ENOTSUPP;
 }
 
+static int npcm7xx_gpio_reset_persist(struct npcm7xx_pinctrl *npcm,
+					unsigned int pin, int enable)
+{
+	struct npcm7xx_gpio *bank =
+		&npcm->gpio_bank[pin / NPCM7XX_GPIO_PER_BANK];
+	int banknum = pin / bank->gc.ngpio;
+
+	if (enable) {
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD0RCR,
+				   GPIOX_MODULE_RESET << banknum, 0);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD1RCR,
+				   GPIOX_MODULE_RESET << banknum, 0);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD2RCR,
+				   GPIOX_MODULE_RESET << banknum, 0);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_CORSTC,
+				   GPIOX_MODULE_RESET << banknum, 0);
+	} else {
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD0RCR,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD1RCR,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD2RCR,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_CORSTC,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+	}
+
+	return 0;
+}
+
 /* pinctrl_ops */
 static void npcm7xx_pin_dbg_show(struct pinctrl_dev *pctldev,
 				 struct seq_file *s, unsigned int offset)
@@ -1852,6 +1908,8 @@ static int npcm7xx_config_set_one(struct npcm7xx_pinctrl *npcm,
 		return npcm7xx_set_slew_rate(bank, npcm->gcr_regmap, pin, arg);
 	case PIN_CONFIG_DRIVE_STRENGTH:
 		return npcm7xx_set_drive_strength(npcm, pin, arg);
+	case PIN_CONFIG_PERSIST_STATE:
+		return npcm7xx_gpio_reset_persist(npcm, pin, arg);
 	default:
 		return -ENOTSUPP;
 	}
@@ -2051,6 +2109,13 @@ static int npcm7xx_pinctrl_probe(struct platform_device *pdev)
 		return PTR_ERR(pctrl->gcr_regmap);
 	}
 
+	pctrl->rst_regmap =
+		syscon_regmap_lookup_by_compatible("nuvoton,npcm750-rst");
+	if (IS_ERR(pctrl->rst_regmap)) {
+		dev_err(pctrl->dev, "didn't find nuvoton,npcm750-rst\n");
+		return PTR_ERR(pctrl->rst_regmap);
+	}
+
 	ret = npcm7xx_gpio_of(pctrl);
 	if (ret < 0) {
 		dev_err(pctrl->dev, "Failed to gpio dt-binding %u\n", ret);
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (7 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 08/11] pinctrl: npcm7xx: Add pin persist configuration support Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-11  1:04   ` Joel Stanley
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 10/11] dt-binding: bmc: add NPCM7XX JTAG master documentation Tomer Maimon
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Modify the IRQ handler in the NPCM PSPI
driver to support SPI full duplex communication.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/spi/spi-npcm-pspi.c | 75 +++++++++++++++----------------------
 1 file changed, 30 insertions(+), 45 deletions(-)

diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c
index 87cd0233c60b..92fae0b23eb1 100644
--- a/drivers/spi/spi-npcm-pspi.c
+++ b/drivers/spi/spi-npcm-pspi.c
@@ -197,22 +197,22 @@ static void npcm_pspi_setup_transfer(struct spi_device *spi,
 static void npcm_pspi_send(struct npcm_pspi *priv)
 {
 	int wsize;
-	u16 val;
+	u16 val = 0;
 
 	wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
 	priv->tx_bytes -= wsize;
 
-	if (!priv->tx_buf)
-		return;
-
 	switch (wsize) {
 	case 1:
-		val = *priv->tx_buf++;
+		if (priv->tx_buf)
+			val = *priv->tx_buf++;
 		iowrite8(val, NPCM_PSPI_DATA + priv->base);
 		break;
 	case 2:
-		val = *priv->tx_buf++;
-		val = *priv->tx_buf++ | (val << 8);
+		if (priv->tx_buf) {
+			val = *priv->tx_buf++;
+			val = *priv->tx_buf++ | (val << 8);
+		}
 		iowrite16(val, NPCM_PSPI_DATA + priv->base);
 		break;
 	default:
@@ -224,22 +224,24 @@ static void npcm_pspi_send(struct npcm_pspi *priv)
 static void npcm_pspi_recv(struct npcm_pspi *priv)
 {
 	int rsize;
-	u16 val;
+	u16 val_16;
+	u8  val_8;
 
 	rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
 	priv->rx_bytes -= rsize;
 
-	if (!priv->rx_buf)
-		return;
-
 	switch (rsize) {
 	case 1:
-		*priv->rx_buf++ = ioread8(priv->base + NPCM_PSPI_DATA);
+		val_8 = ioread8(priv->base + NPCM_PSPI_DATA);
+		if (priv->rx_buf)
+			*priv->rx_buf++ = val_8;
 		break;
 	case 2:
-		val = ioread16(priv->base + NPCM_PSPI_DATA);
-		*priv->rx_buf++ = (val >> 8);
-		*priv->rx_buf++ = val & 0xff;
+		val_16 = ioread16(priv->base + NPCM_PSPI_DATA);
+		if (priv->rx_buf) {
+			*priv->rx_buf++ = (val_16 >> 8);
+			*priv->rx_buf++ = val_16 & 0xff;
+		}
 		break;
 	default:
 		WARN_ON_ONCE(1);
@@ -298,43 +300,26 @@ static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
 	struct npcm_pspi *priv = dev_id;
 	u8 stat;
 
-	stat = ioread8(priv->base + NPCM_PSPI_STAT);
-
 	if (!priv->tx_buf && !priv->rx_buf)
 		return IRQ_NONE;
 
-	if (priv->tx_buf) {
-		if (stat & NPCM_PSPI_STAT_RBF) {
-			ioread8(NPCM_PSPI_DATA + priv->base);
-			if (priv->tx_bytes == 0) {
-				npcm_pspi_disable(priv);
-				complete(&priv->xfer_done);
-				return IRQ_HANDLED;
-			}
-		}
-
-		if ((stat & NPCM_PSPI_STAT_BSY) == 0)
-			if (priv->tx_bytes)
-				npcm_pspi_send(priv);
+	if (priv->tx_bytes == 0 && priv->rx_bytes == 0) {
+		npcm_pspi_disable(priv);
+		complete(&priv->xfer_done);
+		return IRQ_HANDLED;
 	}
 
-	if (priv->rx_buf) {
-		if (stat & NPCM_PSPI_STAT_RBF) {
-			if (!priv->rx_bytes)
-				return IRQ_NONE;
-
-			npcm_pspi_recv(priv);
+	stat = ioread8(priv->base + NPCM_PSPI_STAT);
 
-			if (!priv->rx_bytes) {
-				npcm_pspi_disable(priv);
-				complete(&priv->xfer_done);
-				return IRQ_HANDLED;
-			}
-		}
+	/*
+	 * first we do the read since if we do the write we previous read might
+	 * be lost (indeed low chances)
+	 */
+	if ((stat & NPCM_PSPI_STAT_RBF) && priv->rx_bytes)
+		npcm_pspi_recv(priv);
 
-		if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
-			iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
-	}
+	if (((stat & NPCM_PSPI_STAT_BSY) == 0) && priv->tx_bytes)
+		npcm_pspi_send(priv);
 
 	return IRQ_HANDLED;
 }
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 10/11] dt-binding: bmc: add NPCM7XX JTAG master documentation
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (8 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 11/11] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver Tomer Maimon
  2021-01-11  0:37 ` [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Joel Stanley
  11 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Stanley Chu, Tomer Maimon, benjaminfair

Added device tree binding documentation for
Nuvoton NPCM7XX JTAG master.

Signed-off-by: Stanley Chu <yschu@nuvoton.com>
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 .../bindings/bmc/npcm7xx-jtag-master.txt      | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt

diff --git a/Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt b/Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
new file mode 100644
index 000000000000..3ad7a18ba9a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
@@ -0,0 +1,38 @@
+Nuvoton NPCM7xx JTAG MASTER interface
+
+Nuvoton BMC NPCM7xx JTAG Master is used for debugging host CPU or programming
+CPLD device. The driver is implemented as an SPI device driver that enabling
+the option to transfer JTAG data with the assistance of SPI HW.
+
+Required properties for jtag_master node
+- compatible		: "nuvoton,npcm750-jtag-master" for Poleg NPCM7XX.
+- spi-max-frequency	: specify the max spi bus frequency.
+- reg 				: always 0
+- pinctrl-names		: contain 2 pinctrl states "pspi" and "gpio", which indicates
+					  the TCK/TDI/TDO pin state in HW mode(using PSPI hw) and
+					  SW mode (using GPIO bitbang) respectively.
+- tck-gpios			: specify the GPIO number of TCK pin
+- tdi-gpios			: specify the GPIO number of TDI pin
+- tdo-gpios			: specify the GPIO number of TDO pin
+- tms-gpios			: specify the GPIO number of TMS pin
+
+Example:
+spi1: spi@201000 {
+	...
+	jtag_master {
+		compatible = "nuvoton,npcm750-jtag-master";
+		spi-max-frequency = <25000000>;
+		reg = <0>;
+
+		pinctrl-names = "pspi", "gpio";
+		pinctrl-0 = <&pspi2_pins>;
+		pinctrl-1 = <&gpio17_pins &gpio18o_pins
+			&gpio19ol_pins>;
+
+		tck-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
+		tdi-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+		tdo-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+		tms-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+		status = "okay";
+	};
+};
-- 
2.22.0


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

* [PATCH linux dev-5.8 v2 11/11] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (9 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 10/11] dt-binding: bmc: add NPCM7XX JTAG master documentation Tomer Maimon
@ 2021-01-05 13:45 ` Tomer Maimon
  2021-01-11  0:37 ` [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Joel Stanley
  11 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-05 13:45 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Stanley Chu, Tomer Maimon, benjaminfair

Add NPCM7xx JTAG master driver,
The NPCM7xx JTAG master usign GPIO lines
and NPCM PSPI bus.

Signed-off-by: Stanley Chu <yschu@nuvoton.com>
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/misc/Kconfig               |   6 +
 drivers/misc/Makefile              |   1 +
 drivers/misc/npcm7xx-jtag-master.c | 840 +++++++++++++++++++++++++++++
 3 files changed, 847 insertions(+)
 create mode 100644 drivers/misc/npcm7xx-jtag-master.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index d8626a0d3e31..1b1876284fa6 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -478,6 +478,12 @@ config NPCM7XX_PCI_MBOX
 	  Expose the NPCM750/730/715/705 PCI MBOX registers found on
 	  Nuvoton SOCs to userspace.
 
+config NPCM7XX_JTAG_MASTER
+	tristate "NPCM7xx JTAG Master driver"
+	depends on (ARCH_NPCM7XX || COMPILE_TEST)
+	help
+	  Control PSPI/GPIO to transmit jtag signals to support jtag master function.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 183970192ced..b11d3c21fa03 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,4 +59,5 @@ obj-$(CONFIG_UACCE)		+= uacce/
 obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_NPCM7XX_LPC_BPC)	+= npcm7xx-lpc-bpc.o
 obj-$(CONFIG_NPCM7XX_PCI_MBOX)	+= npcm7xx-pci-mbox.o
+obj-$(CONFIG_NPCM7XX_JTAG_MASTER)	+= npcm7xx-jtag-master.o
 obj-$(CONFIG_MCTP_LPC)		+= mctp-lpc.o
diff --git a/drivers/misc/npcm7xx-jtag-master.c b/drivers/misc/npcm7xx-jtag-master.c
new file mode 100644
index 000000000000..4d254cc0e159
--- /dev/null
+++ b/drivers/misc/npcm7xx-jtag-master.c
@@ -0,0 +1,840 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Description   : JTAG Master driver
+ *
+ * Copyright (C) 2019 NuvoTon Corporation
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/spi/spi.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/gpio/consumer.h>
+
+#define JTAG_PSPI_SPEED		(10 * 1000000)
+#define JTAG_SCAN_LEN		256
+#define JTAG_MAX_XFER_DATA_LEN	65535
+
+struct tck_bitbang {
+	unsigned char     tms;
+	unsigned char     tdi; /* TDI bit value to write */
+	unsigned char     tdo; /* TDO bit value to read */
+};
+
+struct bitbang_packet {
+	struct tck_bitbang *data;
+	__u32	length;
+} __attribute__((__packed__));
+
+struct scan_xfer {
+	unsigned int     length;      /* number of bits */
+	unsigned char    tdi[JTAG_SCAN_LEN];
+	unsigned int     tdi_bytes;
+	unsigned char    tdo[JTAG_SCAN_LEN];
+	unsigned int     tdo_bytes;
+	unsigned int     end_tap_state;
+};
+
+struct jtag_xfer {
+	__u8	type;
+	__u8	direction;
+	__u8	from;
+	__u8	endstate;
+	__u32	padding;
+	__u32	length;
+	__u64	tdio;
+};
+
+struct jtag_tap_state {
+	__u8	reset;
+	__u8	from;
+	__u8	endstate;
+	__u8	tck;
+};
+
+enum jtagstates {
+	jtagtlr,
+	jtagrti,
+	jtagseldr,
+	jtagcapdr,
+	jtagshfdr,
+	jtagex1dr,
+	jtagpaudr,
+	jtagex2dr,
+	jtagupddr,
+	jtagselir,
+	jtagcapir,
+	jtagshfir,
+	jtagex1ir,
+	jtagpauir,
+	jtagex2ir,
+	jtagupdir,
+	JTAG_STATE_CURRENT
+};
+
+enum JTAG_PIN {
+	pin_TCK,
+	pin_TDI,
+	pin_TDO,
+	pin_TMS,
+	pin_NUM,
+};
+
+enum jtag_reset {
+	JTAG_NO_RESET = 0,
+	JTAG_FORCE_RESET = 1,
+};
+
+enum jtag_xfer_type {
+	JTAG_SIR_XFER = 0,
+	JTAG_SDR_XFER = 1,
+	JTAG_RUNTEST_XFER,
+};
+
+enum jtag_xfer_direction {
+	JTAG_READ_XFER = 1,
+	JTAG_WRITE_XFER = 2,
+	JTAG_READ_WRITE_XFER = 3,
+};
+
+#define __JTAG_IOCTL_MAGIC	0xb2
+#define JTAG_SIOCSTATE	_IOW(__JTAG_IOCTL_MAGIC, 0, struct jtag_tap_state)
+#define JTAG_SIOCFREQ	_IOW(__JTAG_IOCTL_MAGIC, 1, unsigned int)
+#define JTAG_GIOCFREQ	_IOR(__JTAG_IOCTL_MAGIC, 2, unsigned int)
+#define JTAG_IOCXFER	_IOWR(__JTAG_IOCTL_MAGIC, 3, struct jtag_xfer)
+#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtagstates)
+#define JTAG_SIOCMODE	_IOW(__JTAG_IOCTL_MAGIC, 5, unsigned int)
+#define JTAG_IOCBITBANG	_IOW(__JTAG_IOCTL_MAGIC, 6, unsigned int)
+#define JTAG_RUNTEST    _IOW(__JTAG_IOCTL_MAGIC, 7, unsigned int)
+
+static DEFINE_IDA(jtag_ida);
+
+static unsigned char reverse[16] = {
+	0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
+	0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
+};
+
+#define REVERSE(x)  ((reverse[((x) & 0x0f)] << 4) | reverse[((x) & 0xf0) >> 4])
+
+static DEFINE_SPINLOCK(jtag_file_lock);
+
+struct jtag_info {
+	struct device *dev;
+	struct spi_device	*spi;
+	struct miscdevice miscdev;
+	struct gpio_desc	*pins[pin_NUM];
+	struct pinctrl		*pinctrl;
+	u32 freq;
+	u8 tms_level;
+	u8 tapstate;
+	bool is_open;
+	int id;
+
+	/* transmit tck/tdi/tdo by pspi */
+	#define MODE_PSPI		0
+	/* transmit all signals by gpio */
+	#define MODE_GPIO		1
+	u8 mode;
+};
+
+/* this structure represents a TMS cycle, as expressed in a set of bits and
+ * a count of bits (note: there are no start->end state transitions that
+ * require more than 1 byte of TMS cycles)
+ */
+struct tmscycle {
+	unsigned char tmsbits;
+	unsigned char count;
+};
+
+/* this is the complete set TMS cycles for going from any TAP state to
+ * any other TAP state, following a “shortest path” rule
+ */
+const struct tmscycle _tmscyclelookup[][16] = {
+/*      TLR        RTI       SelDR      CapDR      SDR      */
+/*      Ex1DR      PDR       Ex2DR      UpdDR      SelIR    */
+/*      CapIR      SIR       Ex1IR      PIR        Ex2IR    */
+/*      UpdIR                                               */
+/* TLR */
+	{
+		{0x01, 1}, {0x00, 1}, {0x02, 2}, {0x02, 3}, {0x02, 4},
+		{0x0a, 4}, {0x0a, 5}, {0x2a, 6}, {0x1a, 5}, {0x06, 3},
+		{0x06, 4}, {0x06, 5}, {0x16, 5}, {0x16, 6}, {0x56, 7},
+		{0x36, 6}
+	},
+/* RTI */
+	{
+		{0x07, 3}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x01, 3},
+		{0x05, 3}, {0x05, 4}, {0x15, 5}, {0x0d, 4}, {0x03, 2},
+		{0x03, 3}, {0x03, 4}, {0x0b, 4}, {0x0b, 5}, {0x2b, 6},
+		{0x1b, 5}
+	},
+/* SelDR */
+	{
+		{0x03, 2}, {0x03, 3}, {0x00, 0}, {0x00, 1}, {0x00, 2},
+		{0x02, 2}, {0x02, 3}, {0x0a, 4}, {0x06, 3}, {0x01, 1},
+		{0x01, 2}, {0x01, 3}, {0x05, 3}, {0x05, 4}, {0x15, 5},
+		{0x0d, 4}
+	},
+/* CapDR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x00, 0}, {0x00, 1},
+		{0x01, 1}, {0x01, 2}, {0x05, 3}, {0x03, 2}, {0x0f, 4},
+		{0x0f, 5}, {0x0f, 6}, {0x2f, 6}, {0x2f, 7}, {0xaf, 8},
+		{0x6f, 7}
+	},
+/* SDR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x00, 0},
+		{0x01, 1}, {0x01, 2}, {0x05, 3}, {0x03, 2}, {0x0f, 4},
+		{0x0f, 5}, {0x0f, 6}, {0x2f, 6}, {0x2f, 7}, {0xaf, 8},
+		{0x6f, 7}
+	},
+/* Ex1DR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x02, 3},
+		{0x00, 0}, {0x00, 1}, {0x02, 2}, {0x01, 1}, {0x07, 3},
+		{0x07, 4}, {0x07, 5}, {0x17, 5}, {0x17, 6}, {0x57, 7},
+		{0x37, 6}
+	},
+/* PDR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x01, 2},
+		{0x05, 3}, {0x00, 1}, {0x01, 1}, {0x03, 2}, {0x0f, 4},
+		{0x0f, 5}, {0x0f, 6}, {0x2f, 6}, {0x2f, 7}, {0xaf, 8},
+		{0x6f, 7}
+	},
+/* Ex2DR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x00, 1},
+		{0x02, 2}, {0x02, 3}, {0x00, 0}, {0x01, 1}, {0x07, 3},
+		{0x07, 4}, {0x07, 5}, {0x17, 5}, {0x17, 6}, {0x57, 7},
+		{0x37, 6}
+	},
+/* UpdDR */
+	{
+		{0x07, 3}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x01, 3},
+		{0x05, 3}, {0x05, 4}, {0x15, 5}, {0x00, 0}, {0x03, 2},
+		{0x03, 3}, {0x03, 4}, {0x0b, 4}, {0x0b, 5}, {0x2b, 6},
+		{0x1b, 5}
+	},
+/* SelIR */
+	{
+		{0x01, 1}, {0x01, 2}, {0x05, 3}, {0x05, 4}, {0x05, 5},
+		{0x15, 5}, {0x15, 6}, {0x55, 7}, {0x35, 6}, {0x00, 0},
+		{0x00, 1}, {0x00, 2}, {0x02, 2}, {0x02, 3}, {0x0a, 4},
+		{0x06, 3}
+	},
+/* CapIR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x07, 5},
+		{0x17, 5}, {0x17, 6}, {0x57, 7}, {0x37, 6}, {0x0f, 4},
+		{0x00, 0}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x05, 3},
+		{0x03, 2}
+	},
+/* SIR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x07, 5},
+		{0x17, 5}, {0x17, 6}, {0x57, 7}, {0x37, 6}, {0x0f, 4},
+		{0x0f, 5}, {0x00, 0}, {0x01, 1}, {0x01, 2}, {0x05, 3},
+		{0x03, 2}
+	},
+/* Ex1IR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x03, 4},
+		{0x0b, 4}, {0x0b, 5}, {0x2b, 6}, {0x1b, 5}, {0x07, 3},
+		{0x07, 4}, {0x02, 3}, {0x00, 0}, {0x00, 1}, {0x02, 2},
+		{0x01, 1}
+	},
+/* PIR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x07, 5},
+		{0x17, 5}, {0x17, 6}, {0x57, 7}, {0x37, 6}, {0x0f, 4},
+		{0x0f, 5}, {0x01, 2}, {0x05, 3}, {0x00, 1}, {0x01, 1},
+		{0x03, 2}
+	},
+/* Ex2IR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x03, 4},
+		{0x0b, 4}, {0x0b, 5}, {0x2b, 6}, {0x1b, 5}, {0x07, 3},
+		{0x07, 4}, {0x00, 1}, {0x02, 2}, {0x02, 3}, {0x00, 0},
+		{0x01, 1}
+	},
+/* UpdIR */
+	{
+		{0x07, 3}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x01, 3},
+		{0x05, 3}, {0x05, 4}, {0x15, 5}, {0x0d, 4}, {0x03, 2},
+		{0x03, 3}, {0x03, 4}, {0x0b, 4}, {0x0b, 5}, {0x2b, 6},
+		{0x00, 0}
+	},
+};
+
+static u8 TCK_cycle(struct jtag_info *jtag,
+		    unsigned char no_tdo, unsigned char TMS,
+		    unsigned char TDI)
+{
+	u32 tdo = 0;
+
+	/* IEEE 1149.1
+	 * TMS & TDI shall be sampled by the test logic on the rising edge
+	 * test logic shall change TDO on the falling edge
+	 */
+	gpiod_set_value(jtag->pins[pin_TDI], (int)TDI);
+	if (jtag->tms_level != (int)TMS) {
+		gpiod_set_value(jtag->pins[pin_TMS], (int)TMS);
+		jtag->tms_level = (int)TMS;
+	}
+	gpiod_set_value(jtag->pins[pin_TCK], 1);
+	if (!no_tdo)
+		tdo = gpiod_get_value(jtag->pins[pin_TDO]);
+	gpiod_set_value(jtag->pins[pin_TCK], 0);
+
+	return tdo;
+}
+
+static inline void npcm7xx_jtag_bitbangs(struct jtag_info *jtag,
+					 struct bitbang_packet *bitbangs,
+					 struct tck_bitbang *bitbang_data)
+{
+	int i;
+
+	for (i = 0; i < bitbangs->length; i++) {
+		bitbang_data[i].tdo =
+			TCK_cycle(jtag, 0, bitbang_data[i].tms,
+				  bitbang_data[i].tdi);
+		cond_resched();
+	}
+}
+
+static int npcm7xx_jtag_set_tapstate(struct jtag_info *jtag,
+				     enum jtagstates from, enum jtagstates to)
+{
+	unsigned char i;
+	unsigned char tmsbits;
+	unsigned char count;
+
+	if (from == to)
+		return 0;
+	if (from == JTAG_STATE_CURRENT)
+		from = jtag->tapstate;
+
+	if (from > JTAG_STATE_CURRENT || to > JTAG_STATE_CURRENT)
+		return -1;
+
+	if (to == jtagtlr) {
+		for (i = 0; i < 9; i++)
+			TCK_cycle(jtag, 1, 1, 1);
+		jtag->tapstate = jtagtlr;
+		return 0;
+	}
+
+	tmsbits = _tmscyclelookup[from][to].tmsbits;
+	count   = _tmscyclelookup[from][to].count;
+
+	if (count == 0)
+		return 0;
+
+	for (i = 0; i < count; i++) {
+		TCK_cycle(jtag, 1, (tmsbits & 1), 1);
+		tmsbits >>= 1;
+	}
+	pr_debug("jtag: change state %d -> %d\n", from, to);
+	jtag->tapstate = to;
+	return 0;
+}
+
+static int npcm7xx_jtag_switch_pin_func(struct jtag_info *jtag, u8 mode)
+{
+	struct pinctrl_state	*state;
+
+	if (mode == MODE_PSPI) {
+		state = pinctrl_lookup_state(jtag->pinctrl, "pspi");
+		if (IS_ERR(state))
+			return -ENOENT;
+
+		pinctrl_gpio_free(desc_to_gpio(jtag->pins[pin_TCK]));
+		pinctrl_gpio_free(desc_to_gpio(jtag->pins[pin_TDI]));
+		pinctrl_gpio_free(desc_to_gpio(jtag->pins[pin_TDO]));
+		pinctrl_select_state(jtag->pinctrl, state);
+	} else if (mode == MODE_GPIO) {
+		state = pinctrl_lookup_state(jtag->pinctrl, "gpio");
+		if (IS_ERR(state))
+			return -ENOENT;
+
+		pinctrl_select_state(jtag->pinctrl, state);
+		pinctrl_gpio_request(desc_to_gpio(jtag->pins[pin_TCK]));
+		pinctrl_gpio_request(desc_to_gpio(jtag->pins[pin_TDI]));
+		pinctrl_gpio_request(desc_to_gpio(jtag->pins[pin_TDO]));
+		jtag->tms_level = gpiod_get_value(jtag->pins[pin_TMS]);
+	}
+
+	return 0;
+}
+
+static int npcm7xx_jtag_xfer_spi(struct jtag_info *jtag, u32 xfer_bytes,
+				 u8 *out, u8 *in)
+{
+	struct spi_message m;
+	struct spi_transfer spi_xfer;
+	int err;
+	int i;
+
+	err = npcm7xx_jtag_switch_pin_func(jtag, MODE_PSPI);
+	if (err)
+		return err;
+
+	for (i = 0; i < xfer_bytes; i++)
+		out[i] = REVERSE(out[i]);
+
+	memset(&spi_xfer, 0, sizeof(spi_xfer));
+	spi_xfer.speed_hz = jtag->freq;
+	spi_xfer.tx_buf = out;
+	spi_xfer.rx_buf = in;
+	spi_xfer.len = xfer_bytes;
+
+	spi_message_init(&m);
+	spi_message_add_tail(&spi_xfer, &m);
+	err = spi_sync(jtag->spi, &m);
+
+	for (i = 0; i < xfer_bytes; i++)
+		in[i] = REVERSE(in[i]);
+
+	err = npcm7xx_jtag_switch_pin_func(jtag, MODE_GPIO);
+
+	return err;
+}
+
+static int npcm7xx_jtag_xfer_gpio(struct jtag_info *jtag,
+				  struct jtag_xfer *xfer, u8 *out, u8 *in)
+{
+	unsigned long *bitmap_tdi = (unsigned long *)out;
+	unsigned long *bitmap_tdo = (unsigned long *)in;
+	u32 xfer_bits = xfer->length;
+	u32 bit_index = 0;
+	u8 tdi, tdo, tms;
+
+	while (bit_index < xfer_bits) {
+		tdi = 0;
+		tms = 0;
+
+		if (test_bit(bit_index, bitmap_tdi))
+			tdi = 1;
+
+		/* If this is the last bit, leave TMS high */
+		if ((bit_index == xfer_bits - 1) && xfer->endstate != jtagshfdr &&
+		    xfer->endstate != jtagshfir && xfer->endstate != JTAG_STATE_CURRENT)
+			tms = 1;
+
+		/* shift 1 bit */
+		tdo = TCK_cycle(jtag, 0, tms, tdi);
+		cond_resched();
+		/* If it was the last bit in the scan and the end_tap_state is
+		 * something other than shiftDR or shiftIR then go to Exit1.
+		 * IMPORTANT Note: if the end_tap_state is ShiftIR/DR and the
+		 * next call to this function is a shiftDR/IR then the driver
+		 * will not change state!
+		 */
+		if (tms)
+			jtag->tapstate = (jtag->tapstate == jtagshfdr) ?
+				jtagex1dr : jtagex1ir;
+
+		if (tdo)
+			bitmap_set(bitmap_tdo, bit_index, 1);
+
+		bit_index++;
+	}
+
+	return 0;
+}
+
+static int npcm7xx_jtag_readwrite_scan(struct jtag_info *jtag,
+				       struct jtag_xfer *xfer, u8 *tdi, u8 *tdo)
+{
+	u32 xfer_bytes = DIV_ROUND_UP(xfer->length, BITS_PER_BYTE);
+	u32 remain_bits = xfer->length;
+	u32 spi_xfer_bytes = 0;
+
+	if (xfer_bytes > 1 && jtag->mode == MODE_PSPI) {
+		/* The last byte should be sent using gpio bitbang
+		 * (TMS needed)
+		 */
+		spi_xfer_bytes = xfer_bytes - 1;
+		if (npcm7xx_jtag_xfer_spi(jtag, spi_xfer_bytes, tdi, tdo))
+			return -EIO;
+		remain_bits -= spi_xfer_bytes * 8;
+	}
+
+	if (remain_bits) {
+		xfer->length = remain_bits;
+		npcm7xx_jtag_xfer_gpio(jtag, xfer, tdi + spi_xfer_bytes,
+				       tdo + spi_xfer_bytes);
+	}
+
+	npcm7xx_jtag_set_tapstate(jtag, JTAG_STATE_CURRENT, xfer->endstate);
+
+	return 0;
+}
+
+static int npcm7xx_jtag_xfer(struct jtag_info *npcm7xx_jtag,
+			     struct jtag_xfer *xfer, u8 *data, u32 bytes)
+{
+	u8 *tdo;
+	int ret;
+
+	if (xfer->length == 0)
+		return 0;
+
+	tdo = kzalloc(bytes, GFP_KERNEL);
+	if (!tdo)
+		return -ENOMEM;
+
+	if (xfer->type == JTAG_SIR_XFER)
+		npcm7xx_jtag_set_tapstate(npcm7xx_jtag, xfer->from, jtagshfir);
+	else if (xfer->type == JTAG_SDR_XFER)
+		npcm7xx_jtag_set_tapstate(npcm7xx_jtag, xfer->from, jtagshfdr);
+
+	ret = npcm7xx_jtag_readwrite_scan(npcm7xx_jtag, xfer, data, tdo);
+	memcpy(data, tdo, bytes);
+	kfree(tdo);
+
+	return ret;
+}
+
+/* Run in current state for specific number of tcks */
+static int npcm7xx_jtag_runtest(struct jtag_info *jtag, unsigned int tcks)
+{
+	struct jtag_xfer xfer;
+	u32 bytes = DIV_ROUND_UP(tcks, BITS_PER_BYTE);
+	u8 *buf;
+	u32 i;
+	int err;
+
+	if (jtag->mode != MODE_PSPI) {
+		for (i = 0; i < tcks; i++) {
+			TCK_cycle(jtag, 0, 0, 1);
+			cond_resched();
+		}
+		return 0;
+	}
+
+	buf = kzalloc(bytes, GFP_KERNEL);
+	xfer.type = JTAG_RUNTEST_XFER;
+	xfer.direction = JTAG_WRITE_XFER;
+	xfer.from = JTAG_STATE_CURRENT;
+	xfer.endstate = JTAG_STATE_CURRENT;
+	xfer.length = tcks;
+
+	err = npcm7xx_jtag_xfer(jtag, &xfer, buf, bytes);
+	kfree(buf);
+
+	return err;
+}
+
+static long jtag_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct jtag_info *priv = file->private_data;
+	struct jtag_tap_state tapstate;
+	void __user *argp = (void __user *)arg;
+	struct jtag_xfer xfer;
+	struct bitbang_packet bitbang;
+	struct tck_bitbang *bitbang_data;
+	u8 *xfer_data;
+	u32 data_size;
+	u32 value;
+	int ret = 0;
+
+	switch (cmd) {
+	case JTAG_SIOCFREQ:
+		if (get_user(value, (__u32 __user *)arg))
+			return -EFAULT;
+		if (value <= priv->spi->max_speed_hz) {
+			priv->freq = value;
+		} else {
+			dev_err(priv->dev, "%s: invalid jtag freq %u\n",
+				__func__, value);
+			ret = -EINVAL;
+		}
+		break;
+	case JTAG_GIOCFREQ:
+		if (put_user(priv->freq, (__u32 __user *)arg))
+			return -EFAULT;
+		break;
+	case JTAG_IOCBITBANG:
+		if (copy_from_user(&bitbang, (const void __user *)arg,
+				   sizeof(struct bitbang_packet)))
+			return -EFAULT;
+
+		if (bitbang.length >= JTAG_MAX_XFER_DATA_LEN)
+			return -EINVAL;
+
+		data_size = bitbang.length * sizeof(struct tck_bitbang);
+		bitbang_data = memdup_user((void __user *)bitbang.data,
+					   data_size);
+		if (IS_ERR(bitbang_data))
+			return -EFAULT;
+
+		npcm7xx_jtag_bitbangs(priv, &bitbang, bitbang_data);
+		ret = copy_to_user((void __user *)bitbang.data,
+				   (void *)bitbang_data, data_size);
+		kfree(bitbang_data);
+		if (ret)
+			return -EFAULT;
+		break;
+	case JTAG_SIOCSTATE:
+		if (copy_from_user(&tapstate, (const void __user *)arg,
+				   sizeof(struct jtag_tap_state)))
+			return -EFAULT;
+
+		if (tapstate.from > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		if (tapstate.endstate > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		if (tapstate.reset > JTAG_FORCE_RESET)
+			return -EINVAL;
+		if (tapstate.reset == JTAG_FORCE_RESET)
+			npcm7xx_jtag_set_tapstate(priv, JTAG_STATE_CURRENT,
+						  jtagtlr);
+		npcm7xx_jtag_set_tapstate(priv, tapstate.from,
+					  tapstate.endstate);
+		break;
+	case JTAG_GIOCSTATUS:
+		ret = put_user(priv->tapstate, (__u32 __user *)arg);
+		break;
+	case JTAG_IOCXFER:
+		if (copy_from_user(&xfer, argp, sizeof(struct jtag_xfer)))
+			return -EFAULT;
+
+		if (xfer.length >= JTAG_MAX_XFER_DATA_LEN)
+			return -EINVAL;
+
+		if (xfer.type > JTAG_SDR_XFER)
+			return -EINVAL;
+
+		if (xfer.direction > JTAG_READ_WRITE_XFER)
+			return -EINVAL;
+
+		if (xfer.from > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		if (xfer.endstate > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		data_size = DIV_ROUND_UP(xfer.length, BITS_PER_BYTE);
+		xfer_data = memdup_user(u64_to_user_ptr(xfer.tdio), data_size);
+		if (IS_ERR(xfer_data))
+			return -EFAULT;
+		ret = npcm7xx_jtag_xfer(priv, &xfer, xfer_data, data_size);
+		if (ret) {
+			kfree(xfer_data);
+			return -EIO;
+		}
+		ret = copy_to_user(u64_to_user_ptr(xfer.tdio),
+				   (void *)xfer_data, data_size);
+		kfree(xfer_data);
+		if (ret)
+			return -EFAULT;
+
+		if (copy_to_user((void __user *)arg, (void *)&xfer,
+				 sizeof(struct jtag_xfer)))
+			return -EFAULT;
+		break;
+	case JTAG_SIOCMODE:
+		if (get_user(value, (__u32 __user *)arg))
+			return -EFAULT;
+		if (value != MODE_GPIO && value != MODE_PSPI)
+			return -EINVAL;
+		priv->mode = value;
+		break;
+	case JTAG_RUNTEST:
+		ret = npcm7xx_jtag_runtest(priv, (unsigned int)arg);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int jtag_open(struct inode *inode, struct file *file)
+{
+	struct jtag_info *jtag;
+
+	jtag = container_of(file->private_data, struct jtag_info, miscdev);
+
+	spin_lock(&jtag_file_lock);
+	if (jtag->is_open) {
+		spin_unlock(&jtag_file_lock);
+		return -EBUSY;
+	}
+
+	jtag->is_open = true;
+	file->private_data = jtag;
+
+	spin_unlock(&jtag_file_lock);
+
+	return 0;
+}
+
+static int jtag_release(struct inode *inode, struct file *file)
+{
+	struct jtag_info *jtag = file->private_data;
+
+	spin_lock(&jtag_file_lock);
+	jtag->is_open = false;
+	spin_unlock(&jtag_file_lock);
+
+	return 0;
+}
+
+const struct file_operations npcm_jtag_fops = {
+	.open              = jtag_open,
+	.unlocked_ioctl    = jtag_ioctl,
+	.release           = jtag_release,
+};
+
+static int jtag_register_device(struct jtag_info *jtag)
+{
+	struct device *dev = jtag->dev;
+	int err;
+	int id;
+
+	if (!dev)
+		return -ENODEV;
+
+	id = ida_simple_get(&jtag_ida, 0, 0, GFP_KERNEL);
+	if (id < 0)
+		return id;
+
+	jtag->id = id;
+	/* register miscdev */
+	jtag->miscdev.parent = dev;
+	jtag->miscdev.fops =  &npcm_jtag_fops;
+	jtag->miscdev.minor = MISC_DYNAMIC_MINOR;
+	jtag->miscdev.name = kasprintf(GFP_KERNEL, "jtag%d", id);
+	if (!jtag->miscdev.name) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	err = misc_register(&jtag->miscdev);
+	if (err) {
+		dev_err(jtag->miscdev.parent,
+			"Unable to register device, err %d\n", err);
+		kfree(jtag->miscdev.name);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	ida_simple_remove(&jtag_ida, id);
+	return err;
+}
+
+static int npcm7xx_jtag_init(struct device *dev, struct jtag_info *npcm7xx_jtag)
+{
+	struct pinctrl		*pinctrl;
+	int i;
+
+	pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(pinctrl))
+		return PTR_ERR(pinctrl);
+
+	npcm7xx_jtag->pinctrl = pinctrl;
+
+	/* jtag pins */
+	npcm7xx_jtag->pins[pin_TCK] = gpiod_get(dev, "tck", GPIOD_OUT_LOW);
+	npcm7xx_jtag->pins[pin_TDI] = gpiod_get(dev, "tdi", GPIOD_OUT_HIGH);
+	npcm7xx_jtag->pins[pin_TDO] = gpiod_get(dev, "tdo", GPIOD_IN);
+	npcm7xx_jtag->pins[pin_TMS] = gpiod_get(dev, "tms", GPIOD_OUT_HIGH);
+	for (i = 0; i < pin_NUM; i++) {
+		if (IS_ERR(npcm7xx_jtag->pins[i]))
+			return PTR_ERR(npcm7xx_jtag->pins[i]);
+	}
+
+	npcm7xx_jtag->freq = JTAG_PSPI_SPEED;
+	npcm7xx_jtag->tms_level = gpiod_get_value(npcm7xx_jtag->pins[pin_TMS]);
+	npcm7xx_jtag_set_tapstate(npcm7xx_jtag, JTAG_STATE_CURRENT, jtagtlr);
+	npcm7xx_jtag->mode = MODE_PSPI;
+
+	return 0;
+}
+
+static int npcm7xx_jtag_probe(struct spi_device *spi)
+{
+	struct jtag_info *npcm_jtag;
+	int ret;
+
+	dev_info(&spi->dev, "%s", __func__);
+
+	npcm_jtag = kzalloc(sizeof(struct jtag_info), GFP_KERNEL);
+	if (!npcm_jtag)
+		return -ENOMEM;
+
+	npcm_jtag->dev = &spi->dev;
+	npcm_jtag->spi = spi;
+	spi->mode = SPI_MODE_0 | SPI_NO_CS;
+
+	/* Initialize device*/
+	ret = npcm7xx_jtag_init(&spi->dev, npcm_jtag);
+	if (ret)
+		goto err;
+
+	/* Register a misc device */
+	ret = jtag_register_device(npcm_jtag);
+	if (ret) {
+		dev_err(&spi->dev, "failed to create device\n");
+		goto err;
+	}
+	spi_set_drvdata(spi, npcm_jtag);
+
+	return 0;
+err:
+	kfree(npcm_jtag);
+	return ret;
+}
+
+static int npcm7xx_jtag_remove(struct spi_device  *spi)
+{
+	struct jtag_info *jtag = spi_get_drvdata(spi);
+	int i;
+
+	if (!jtag)
+		return 0;
+
+	misc_deregister(&jtag->miscdev);
+	kfree(jtag->miscdev.name);
+	for (i = 0; i < pin_NUM; i++) {
+		gpiod_direction_input(jtag->pins[i]);
+		gpiod_put(jtag->pins[i]);
+	}
+	kfree(jtag);
+	ida_simple_remove(&jtag_ida, jtag->id);
+
+	return 0;
+}
+
+static const struct of_device_id npcm7xx_jtag_of_match[] = {
+	{ .compatible = "nuvoton,npcm750-jtag-master", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, npcm7xx_jtag_of_match);
+
+static struct spi_driver npcm7xx_jtag_driver = {
+	.driver = {
+		.name		= "npcm7xx_jtag",
+		.of_match_table = npcm7xx_jtag_of_match,
+	},
+	.probe		= npcm7xx_jtag_probe,
+	.remove		= npcm7xx_jtag_remove,
+};
+
+module_spi_driver(npcm7xx_jtag_driver);
+
+MODULE_AUTHOR("Stanley Chu <yschu@nuvoton.com>");
+MODULE_DESCRIPTION("NPCM7xx JTAG Master Driver");
+MODULE_LICENSE("GPL");
+
-- 
2.22.0


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

* Re: [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8
  2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (10 preceding siblings ...)
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 11/11] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver Tomer Maimon
@ 2021-01-11  0:37 ` Joel Stanley
  2021-01-11 19:30   ` Tomer Maimon
  11 siblings, 1 reply; 20+ messages in thread
From: Joel Stanley @ 2021-01-11  0:37 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

Hi Tomer,

On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> In this patch set we will like to align with relevant modifications
> in Nuvoton OpenBMC Linux kernel 5.4.

Thanks for sending the patches. I can merge them into 5.8, however I
have a v5.10 branch that I plan on moving to imminently.

>
> Linux upstream current status:
>         1. npcm7xx clock driver - adding read only
>                 flag to divider clocks, Will be sent to Linux community.
>         2. Adding NPCM ADC calibration - Will be sent to Linux vanilla,
>                 but I am not sure it will be approved.
>         3. Add DT restart priority and reset type support - sent to Linux
>                 community la but havent approved yet.
>         4. persist configuration to the pin control driver - asked by a costumer,
>                 didnt sent to Linux community.

Do you plan on sending it?

>         5. Add HGPIO pin support to NPCM7xx pinctrl driver - will be sent
>                 to Linux community
>         6. JTAG master driver - will be sent to Linux community once we will
>                 have BMC folder.

As you've noted, I recommend you submit them to mainline ASAP to avoid
extra handling of patches in the openbmc tree.

Cheers,

Joel

>
> Changes since version 1:
> - Address comments from Jonathan Neuschäfer: removing trailing whitespace
>         in NPCM watchdog documentation.
> - Adding Stanley Chu to NPCM JTAG master driver
>
> Tomer Maimon (11):
>   clk: npcm7xx: add read only flag to divider clocks
>   iio: adc: add calibration support to npcm ADC
>   dts: npcm750: add fuse regmap support node
>   watchdog: npcm: Add DT restart priority and reset type support
>   dt-binding: watchdog: Add DT restart priority and reset type
>   pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
>   pinctrl: pinconf: add pin persist configuration
>   pinctrl: npcm7xx: Add pin persist configuration support
>   spi: npcm-pspi: Add full duplex support
>   dt-binding: bmc: add NPCM7XX JTAG master documentation
>   misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver
>
>  .../bindings/bmc/npcm7xx-jtag-master.txt      |  38 +
>  .../bindings/watchdog/nuvoton,npcm-wdt.txt    |  32 +
>  arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi |   6 +
>  drivers/clk/clk-npcm7xx.c                     |  70 +-
>  drivers/iio/adc/npcm_adc.c                    | 191 ++++
>  drivers/misc/Kconfig                          |   6 +
>  drivers/misc/Makefile                         |   1 +
>  drivers/misc/npcm7xx-jtag-master.c            | 840 ++++++++++++++++++
>  drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c     | 130 ++-
>  drivers/pinctrl/pinconf-generic.c             |   3 +
>  drivers/spi/spi-npcm-pspi.c                   |  75 +-
>  drivers/watchdog/npcm_wdt.c                   | 121 ++-
>  12 files changed, 1418 insertions(+), 95 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
>  create mode 100644 drivers/misc/npcm7xx-jtag-master.c
>
> --
> 2.22.0
>

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

* Re: [PATCH linux dev-5.8 v2 02/11] iio: adc: add calibration support to npcm ADC
  2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 02/11] iio: adc: add calibration support to npcm ADC Tomer Maimon
@ 2021-01-11  0:52   ` Joel Stanley
  0 siblings, 0 replies; 20+ messages in thread
From: Joel Stanley @ 2021-01-11  0:52 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Add calibration to improve accuracy measurement when using
> internal referance voltage.

reference

>
> the calibration values taken from the FUSE module.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

I recommend taking a look at the proposed device tree changes before
we merge this one, so we don't have an incompatibility between future
code and device tree.

> ---
>  drivers/iio/adc/npcm_adc.c | 191 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 191 insertions(+)
>
> diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c
> index 83bad2d5575d..02628b7eaca1 100644
> --- a/drivers/iio/adc/npcm_adc.c
> +++ b/drivers/iio/adc/npcm_adc.c
> @@ -17,6 +17,8 @@
>  #include <linux/reset.h>
>
>  struct npcm_adc {
> +       u32 R05;
> +       u32 R15;
>         bool int_status;
>         u32 adc_sample_hz;
>         struct device *dev;
> @@ -51,6 +53,40 @@ struct npcm_adc {
>  #define NPCM_RESOLUTION_BITS           10
>  #define NPCM_INT_VREF_MV               2000
>
> +/* FUSE registers */
> +#define NPCM7XX_FST            0x00
> +#define NPCM7XX_FADDR          0x04
> +#define NPCM7XX_FDATA          0x08
> +#define NPCM7XX_FCFG           0x0C
> +#define NPCM7XX_FCTL           0x14
> +
> +/* FST Register Bits */
> +#define NPCM7XX_FST_RDY                BIT(0)
> +#define NPCM7XX_FST_RDST       BIT(1)
> +
> +/* FADDR Register Bits */
> +#define NPCM7XX_FADDR_BYTEADDR         BIT(0)
> +#define NPCM7XX_FADDR_BYTEADDR_MASK    GENMASK(9, 0)
> +
> +/* FADDR Register Bits */
> +#define NPCM7XX_FDATA_DATA             BIT(0)
> +#define NPCM7XX_FDATA_CLEAN_VALUE      BIT(1)
> +#define NPCM7XX_FDATA_DATA_MASK                GENMASK(7, 0)
> +
> +/* FCTL Register Bits */
> +#define NPCM7XX_FCTL_RDST              BIT(1)
> +
> +/* ADC Calibration Definition */
> +#define NPCM_INT_1500MV                768
> +#define NPCM_INT_1000MV                512
> +#define NPCM_ADC_MIN_VAL       0
> +#define NPCM_ADC_MAX_VAL       1023
> +
> +#define FUSE_CALIB_ADDR                24
> +#define FUSE_CALIB_SIZE                8
> +#define DATA_CALIB_SIZE                4
> +#define FUSE_READ_TIMEOUT      0xDEADBEEF
> +
>  #define NPCM_ADC_CHAN(ch) {                                    \
>         .type = IIO_VOLTAGE,                                    \
>         .indexed = 1,                                           \
> @@ -71,6 +107,133 @@ static const struct iio_chan_spec npcm_adc_iio_channels[] = {
>         NPCM_ADC_CHAN(7),
>  };
>
> +static int npcm750_fuse_wait_for_ready(struct regmap *fuse_regmap, u32 timeout)
> +{
> +       u32 time = timeout;
> +       u32 fstreg;
> +
> +       while (--time > 1) {
> +               regmap_read(fuse_regmap, NPCM7XX_FST, &fstreg);

regmap_read_poll_timeout

> +               if (fstreg & NPCM7XX_FST_RDY) {
> +                       regmap_write_bits(fuse_regmap, NPCM7XX_FST,
> +                                         NPCM7XX_FST_RDST, NPCM7XX_FST_RDST);
> +                       return 0;
> +               }
> +       }
> +
> +       /* try to clear the status in case it was set */
> +       regmap_write_bits(fuse_regmap, NPCM7XX_FST, NPCM7XX_FST_RDST,
> +                         NPCM7XX_FST_RDST);
> +
> +       return -EINVAL;
> +}
> +
> +static void npcm750_fuse_read(struct regmap *fuse_regmap, u32 addr, u8 *data)
> +{
> +       u32 val;
> +
> +       npcm750_fuse_wait_for_ready(fuse_regmap, FUSE_READ_TIMEOUT);

This ignores the time out.

> +
> +       regmap_write_bits(fuse_regmap, NPCM7XX_FADDR,
> +                         NPCM7XX_FADDR_BYTEADDR_MASK, addr);
> +       regmap_read(fuse_regmap, NPCM7XX_FADDR, &val);
> +       regmap_write(fuse_regmap, NPCM7XX_FCTL, NPCM7XX_FCTL_RDST);
> +
> +       npcm750_fuse_wait_for_ready(fuse_regmap, FUSE_READ_TIMEOUT);

...as does this.

> +       regmap_read(fuse_regmap, NPCM7XX_FDATA, &val);
> +       *data = (u8)val;
> +
> +       regmap_write_bits(fuse_regmap, NPCM7XX_FDATA, NPCM7XX_FDATA_DATA_MASK,
> +                         NPCM7XX_FDATA_CLEAN_VALUE);
> +}
> +
> +static int npcm750_ECC_to_nibble(u8 ECC, u8 nibble)
> +{
> +       u8 nibble_b0 = (nibble >> 0) & BIT(0);
> +       u8 nibble_b1 = (nibble >> 1) & BIT(0);
> +       u8 nibble_b2 = (nibble >> 2) & BIT(0);
> +       u8 nibble_b3 = (nibble >> 3) & BIT(0);
> +       u8 tmp_ECC = nibble;
> +
> +       tmp_ECC |= (nibble_b0 ^ nibble_b1) << 4 | (nibble_b2 ^ nibble_b3) << 5 |
> +               (nibble_b0 ^ nibble_b2) << 6  | (nibble_b1 ^ nibble_b3) << 7;
> +
> +       if (tmp_ECC != ECC)
> +               return -EINVAL;
> +
> +       return 0;
> +}
> +
> +static int npcm750_ECC_to_byte(u16 ECC, u8 *Byte)
> +{
> +       u8 nibble_L, nibble_H;
> +       u8 ECC_L, ECC_H;
> +
> +       ECC_H = ECC >> 8;
> +       nibble_H = ECC_H & 0x0F;
> +       ECC_L = ECC >> 0;
> +       nibble_L = ECC_L & 0x0F;
> +
> +       if (npcm750_ECC_to_nibble(ECC_H, nibble_H) != 0 ||
> +           npcm750_ECC_to_nibble(ECC_L, nibble_L) != 0)
> +               return -EINVAL;
> +
> +       *Byte = nibble_H << 4 | nibble_L << 0;
> +
> +       return 0;
> +}
> +
> +static int npcm750_read_nibble_parity(u8 *block_ECC, u8 *ADC_calib)
> +{
> +       int i;
> +       u16 ECC;
> +
> +       for (i = 0; i < DATA_CALIB_SIZE; i++) {
> +               memcpy(&ECC, block_ECC + (i * 2), 2);
> +               if (npcm750_ECC_to_byte(ECC, &ADC_calib[i]) != 0)
> +                       return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int npcm750_fuse_calibration_read(struct platform_device *pdev,
> +                                       struct npcm_adc *info)
> +{
> +       struct device_node *np = pdev->dev.of_node;
> +       struct regmap *fuse_regmap;
> +       ssize_t bytes_read = 0;
> +       u8 read_buf[8];
> +       u32 ADC_calib;
> +       u32 addr = FUSE_CALIB_ADDR;
> +
> +       if (of_device_is_compatible(np, "nuvoton,npcm750-adc")) {

This will always be true.

> +               fuse_regmap = syscon_regmap_lookup_by_compatible
> +                       ("nuvoton,npcm750-fuse");

If you use a phandle to the fuse node, you can have the one code base
support multiple families of chips. Use
syscon_regmap_lookup_by_phandle(np, "syscon")

and in your device tree:

                        adc: adc@c000 {
                                compatible = "nuvoton,npcm750-adc";
                                reg = <0xc000 0x8>;
                                interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk NPCM7XX_CLK_ADC>;
                                resets = <&rstc NPCM7XX_RESET_IPSRST1
NPCM7XX_RESET_ADC>;
                                syscon = <&fuse_syscon>;
                        };


> +               if (IS_ERR(fuse_regmap)) {
> +                       dev_warn(&pdev->dev, "Failed to find nuvoton,npcm750-fuse\n");
> +                       return PTR_ERR(fuse_regmap);
> +               }
> +
> +               while (bytes_read < FUSE_CALIB_SIZE) {
> +                       npcm750_fuse_read(fuse_regmap, addr,
> +                                         &read_buf[bytes_read]);
> +                       bytes_read++;
> +                       addr++;
> +               }
> +
> +               if (npcm750_read_nibble_parity(read_buf, (u8 *)&ADC_calib)) {
> +                       dev_warn(info->dev, "FUSE Clibration read failed\n");

calibration

> +                       return -EINVAL;
> +               }
> +
> +               info->R05 = ADC_calib & 0xFFFF;
> +               info->R15 = ADC_calib >> 16;
> +       }
> +
> +       return 0;
> +}
> +
>  static irqreturn_t npcm_adc_isr(int irq, void *data)
>  {
>         u32 regtemp;
> @@ -125,6 +288,29 @@ static int npcm_adc_read(struct npcm_adc *info, int *val, u8 channel)
>         return 0;
>  }
>
> +static void npcm_adc_calibration(int *val, struct npcm_adc *info)
> +{
> +       int mul_val;
> +       int offset_val;
> +
> +       mul_val = NPCM_INT_1000MV * (*val - info->R15);
> +       if (mul_val < 0) {
> +               mul_val = mul_val * -1;
> +               offset_val = DIV_ROUND_CLOSEST(mul_val,
> +                                              (info->R15 - info->R05));
> +               *val = NPCM_INT_1500MV - offset_val;
> +       } else {
> +               offset_val = DIV_ROUND_CLOSEST(mul_val,
> +                                              (info->R15 - info->R05));
> +               *val = NPCM_INT_1500MV + offset_val;
> +       }
> +
> +       if (*val < NPCM_ADC_MIN_VAL)
> +               *val = NPCM_ADC_MIN_VAL;
> +       if (*val > NPCM_ADC_MAX_VAL)
> +               *val = NPCM_ADC_MAX_VAL;
> +}
> +
>  static int npcm_adc_read_raw(struct iio_dev *indio_dev,
>                              struct iio_chan_spec const *chan, int *val,
>                              int *val2, long mask)
> @@ -142,6 +328,10 @@ static int npcm_adc_read_raw(struct iio_dev *indio_dev,
>                         dev_err(info->dev, "NPCM ADC read failed\n");
>                         return ret;
>                 }
> +
> +               if ((info->R05 || info->R15) && IS_ERR(info->vref))
> +                       npcm_adc_calibration(val, info);
> +
>                 return IIO_VAL_INT;
>         case IIO_CHAN_INFO_SCALE:
>                 if (!IS_ERR(info->vref)) {
> @@ -248,6 +438,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
>                           info->regs + NPCM_ADCCON);
>         }
>
> +       npcm750_fuse_calibration_read(pdev, info);
>         init_waitqueue_head(&info->wq);
>
>         reg_con = ioread32(info->regs + NPCM_ADCCON);
> --
> 2.22.0
>

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

* Re: [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support Tomer Maimon
@ 2021-01-11  0:55   ` Joel Stanley
  2021-01-11 19:22     ` Tomer Maimon
  0 siblings, 1 reply; 20+ messages in thread
From: Joel Stanley @ 2021-01-11  0:55 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Add Device tree restart priority and
> three reset types support.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

Can you remind me the history of this change. Was a similar patch
rejected by mainline?

> ---
>  drivers/watchdog/npcm_wdt.c | 121 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 119 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
> index 765577f11c8d..bbf27da34834 100644
> --- a/drivers/watchdog/npcm_wdt.c
> +++ b/drivers/watchdog/npcm_wdt.c
> @@ -11,7 +11,24 @@
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
>  #include <linux/watchdog.h>
> -
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +
> +/* NPCM7xx GCR module */
> +#define NPCM7XX_RESSR_OFFSET           0x6C
> +#define NPCM7XX_INTCR2_OFFSET          0x60
> +
> +#define NPCM7XX_PORST                  BIT(31)
> +#define NPCM7XX_CORST                  BIT(30)
> +#define NPCM7XX_WD0RST                 BIT(29)
> +#define NPCM7XX_WD1RST                 BIT(24)
> +#define NPCM7XX_WD2RST                 BIT(23)
> +#define NPCM7XX_SWR1RST                        BIT(28)
> +#define NPCM7XX_SWR2RST                        BIT(27)
> +#define NPCM7XX_SWR3RST                        BIT(26)
> +#define NPCM7XX_SWR4RST                        BIT(25)
> +
> + /* WD register */
>  #define NPCM_WTCR      0x1C
>
>  #define NPCM_WTCLK     (BIT(10) | BIT(11))     /* Clock divider */
> @@ -43,6 +60,10 @@
>  struct npcm_wdt {
>         struct watchdog_device  wdd;
>         void __iomem            *reg;
> +       u32                     card_reset;
> +       u32                     ext1_reset;
> +       u32                     ext2_reset;
> +
>  };
>
>  static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd)
> @@ -176,14 +197,70 @@ static const struct watchdog_ops npcm_wdt_ops = {
>         .restart = npcm_wdt_restart,
>  };
>
> +static void npcm_get_reset_status(struct npcm_wdt *wdt, struct device *dev)
> +{
> +       struct regmap *gcr_regmap;
> +       u32 rstval;
> +
> +       if (of_device_is_compatible(dev->of_node, "nuvoton,npcm750-wdt")) {
> +               gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");

This will have the same issues as the ADC with supporting multiple
families of chip with the same code. I suggest you adjust it to use
the phandle approach.



> +               if (IS_ERR(gcr_regmap)) {
> +                       dev_warn(dev, "Failed to find nuvoton,npcm750-gcr WD reset status not supported\n");
> +               }
> +
> +               regmap_read(gcr_regmap, NPCM7XX_RESSR_OFFSET, &rstval);
> +               if (!rstval) {
> +                       regmap_read(gcr_regmap, NPCM7XX_INTCR2_OFFSET, &rstval);
> +                       rstval = ~rstval;
> +               }
> +
> +               if(rstval & wdt->card_reset)
> +                       wdt->wdd.bootstatus |= WDIOF_CARDRESET;
> +               if(rstval & wdt->ext1_reset)
> +                       wdt->wdd.bootstatus |= WDIOF_EXTERN1;
> +               if(rstval & wdt->ext2_reset)
> +                       wdt->wdd.bootstatus |= WDIOF_EXTERN2;
> +       }
> +
> +}
> +
> +static u32 npcm_wdt_reset_type(const char *reset_type)
> +{
> +       if (!strcmp(reset_type, "porst"))
> +               return NPCM7XX_PORST;
> +       else if (!strcmp(reset_type, "corst"))
> +               return NPCM7XX_CORST;
> +       else if (!strcmp(reset_type, "wd0"))
> +               return NPCM7XX_WD0RST;
> +       else if (!strcmp(reset_type, "wd1"))
> +               return NPCM7XX_WD1RST;
> +       else if (!strcmp(reset_type, "wd2"))
> +               return NPCM7XX_WD2RST;
> +       else if (!strcmp(reset_type, "sw1"))
> +               return NPCM7XX_SWR1RST;
> +       else if (!strcmp(reset_type, "sw2"))
> +               return NPCM7XX_SWR2RST;
> +       else if (!strcmp(reset_type, "sw3"))
> +               return NPCM7XX_SWR3RST;
> +       else if (!strcmp(reset_type, "sw4"))
> +               return NPCM7XX_SWR4RST;
> +
> +       return 0;
> +}
> +
>  static int npcm_wdt_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> +       const char *card_reset_type;
> +       const char *ext1_reset_type;
> +       const char *ext2_reset_type;
>         struct npcm_wdt *wdt;
> +       struct resource *res;
> +       u32 priority;
>         int irq;
>         int ret;
>
> -       wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
> +       wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
>         if (!wdt)
>                 return -ENOMEM;
>
> @@ -195,6 +272,45 @@ static int npcm_wdt_probe(struct platform_device *pdev)
>         if (irq < 0)
>                 return irq;
>
> +       if (of_property_read_u32(pdev->dev.of_node, "nuvoton,restart-priority",
> +                                &priority))
> +               watchdog_set_restart_priority(&wdt->wdd, 128);
> +       else
> +               watchdog_set_restart_priority(&wdt->wdd, priority);
> +
> +       ret = of_property_read_string(pdev->dev.of_node,
> +                                     "nuvoton,card-reset-type",
> +                                     &card_reset_type);
> +       if (ret)
> +               wdt->card_reset = NPCM7XX_PORST;
> +       else {
> +               wdt->card_reset = npcm_wdt_reset_type(card_reset_type);
> +               if (!wdt->card_reset)
> +                       wdt->card_reset = NPCM7XX_PORST;
> +       }
> +
> +       ret = of_property_read_string(pdev->dev.of_node,
> +                                     "nuvoton,ext1-reset-type",
> +                                     &ext1_reset_type);
> +       if (ret)
> +               wdt->ext1_reset = NPCM7XX_WD0RST;
> +       else {
> +               wdt->ext1_reset = npcm_wdt_reset_type(ext1_reset_type);
> +               if (!wdt->ext1_reset)
> +                       wdt->ext1_reset = NPCM7XX_WD0RST;
> +       }
> +
> +       ret = of_property_read_string(pdev->dev.of_node,
> +                                     "nuvoton,ext2-reset-type",
> +                                     &ext2_reset_type);
> +       if (ret)
> +               wdt->ext2_reset = NPCM7XX_SWR1RST;
> +       else {
> +               wdt->ext2_reset = npcm_wdt_reset_type(ext2_reset_type);
> +               if (!wdt->ext2_reset)
> +                       wdt->ext2_reset = NPCM7XX_SWR1RST;
> +       }
> +
>         wdt->wdd.info = &npcm_wdt_info;
>         wdt->wdd.ops = &npcm_wdt_ops;
>         wdt->wdd.min_timeout = 1;
> @@ -213,6 +329,7 @@ static int npcm_wdt_probe(struct platform_device *pdev)
>                 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
>         }
>
> +       npcm_get_reset_status(wdt, dev);
>         ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, "watchdog",
>                                wdt);
>         if (ret)
> --
> 2.22.0
>

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

* Re: [PATCH linux dev-5.8 v2 06/11] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 06/11] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
@ 2021-01-11  0:56   ` Joel Stanley
  0 siblings, 0 replies; 20+ messages in thread
From: Joel Stanley @ 2021-01-11  0:56 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

Reviewed-by: Joel Stanley <joel@jms.id.au>

This one should go upstream asap.

> ---
>  drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 65 +++++++++++++++++------
>  1 file changed, 49 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> index a935065cdac4..e5f58ea89917 100644
> --- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> +++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> @@ -504,6 +504,15 @@ static const int lkgpo2_pins[] = { 9 };
>
>  static const int nprd_smi_pins[] = { 190 };
>
> +static const int hgpio0_pins[] = { 20 };
> +static const int hgpio1_pins[] = { 21 };
> +static const int hgpio2_pins[] = { 22 };
> +static const int hgpio3_pins[] = { 23 };
> +static const int hgpio4_pins[] = { 24 };
> +static const int hgpio5_pins[] = { 25 };
> +static const int hgpio6_pins[] = { 59 };
> +static const int hgpio7_pins[] = { 60 };
> +
>  /*
>   * pin:             name, number
>   * group:    name, npins,   pins
> @@ -631,6 +640,14 @@ struct npcm7xx_group {
>         NPCM7XX_GRP(lkgpo1), \
>         NPCM7XX_GRP(lkgpo2), \
>         NPCM7XX_GRP(nprd_smi), \
> +       NPCM7XX_GRP(hgpio0), \
> +       NPCM7XX_GRP(hgpio1), \
> +       NPCM7XX_GRP(hgpio2), \
> +       NPCM7XX_GRP(hgpio3), \
> +       NPCM7XX_GRP(hgpio4), \
> +       NPCM7XX_GRP(hgpio5), \
> +       NPCM7XX_GRP(hgpio6), \
> +       NPCM7XX_GRP(hgpio7), \
>         \
>
>  enum {
> @@ -774,6 +791,14 @@ NPCM7XX_SFUNC(lkgpo0);
>  NPCM7XX_SFUNC(lkgpo1);
>  NPCM7XX_SFUNC(lkgpo2);
>  NPCM7XX_SFUNC(nprd_smi);
> +NPCM7XX_SFUNC(hgpio0);
> +NPCM7XX_SFUNC(hgpio1);
> +NPCM7XX_SFUNC(hgpio2);
> +NPCM7XX_SFUNC(hgpio3);
> +NPCM7XX_SFUNC(hgpio4);
> +NPCM7XX_SFUNC(hgpio5);
> +NPCM7XX_SFUNC(hgpio6);
> +NPCM7XX_SFUNC(hgpio7);
>
>  /* Function names */
>  static struct npcm7xx_func npcm7xx_funcs[] = {
> @@ -892,6 +917,14 @@ static struct npcm7xx_func npcm7xx_funcs[] = {
>         NPCM7XX_MKFUNC(lkgpo1),
>         NPCM7XX_MKFUNC(lkgpo2),
>         NPCM7XX_MKFUNC(nprd_smi),
> +       NPCM7XX_MKFUNC(hgpio0),
> +       NPCM7XX_MKFUNC(hgpio1),
> +       NPCM7XX_MKFUNC(hgpio2),
> +       NPCM7XX_MKFUNC(hgpio3),
> +       NPCM7XX_MKFUNC(hgpio4),
> +       NPCM7XX_MKFUNC(hgpio5),
> +       NPCM7XX_MKFUNC(hgpio6),
> +       NPCM7XX_MKFUNC(hgpio7),
>  };
>
>  #define NPCM7XX_PINCFG(a, b, c, d, e, f, g, h, i, j, k) \
> @@ -944,12 +977,12 @@ static const struct npcm7xx_pincfg pincfg[] = {
>         NPCM7XX_PINCFG(17,      pspi2, MFSEL3, 13,     smb4den, I2CSEGSEL, 23,  none, NONE, 0,       DS(8, 12)),
>         NPCM7XX_PINCFG(18,      pspi2, MFSEL3, 13,       smb4b, I2CSEGSEL, 14,  none, NONE, 0,       DS(8, 12)),
>         NPCM7XX_PINCFG(19,      pspi2, MFSEL3, 13,       smb4b, I2CSEGSEL, 14,  none, NONE, 0,       DS(8, 12)),
> -       NPCM7XX_PINCFG(20,      smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(21,      smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(22,      smb4d, I2CSEGSEL, 16,    smb14, MFSEL3, 7,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(23,      smb4d, I2CSEGSEL, 16,    smb14, MFSEL3, 7,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(24,       ioxh, MFSEL3, 18,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
> -       NPCM7XX_PINCFG(25,       ioxh, MFSEL3, 18,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
> +       NPCM7XX_PINCFG(20,      hgpio0, MFSEL2, 24,      smb15, MFSEL3, 8,      smb4c, I2CSEGSEL, 15,        0),
> +       NPCM7XX_PINCFG(21,      hgpio1, MFSEL2, 25,      smb15, MFSEL3, 8,      smb4c, I2CSEGSEL, 15,        0),
> +       NPCM7XX_PINCFG(22,      hgpio2, MFSEL2, 26,      smb14, MFSEL3, 7,      smb4d, I2CSEGSEL, 16,        0),
> +       NPCM7XX_PINCFG(23,      hgpio3, MFSEL2, 27,      smb14, MFSEL3, 7,      smb4d, I2CSEGSEL, 16,        0),
> +       NPCM7XX_PINCFG(24,       hgpio4, MFSEL2, 28,    ioxh, MFSEL3, 18,       none, NONE, 0,       DS(8, 12)),
> +       NPCM7XX_PINCFG(25,       hgpio5, MFSEL2, 29,    ioxh, MFSEL3, 18,       none, NONE, 0,       DS(8, 12)),
>         NPCM7XX_PINCFG(26,       smb5, MFSEL1, 2,         none, NONE, 0,        none, NONE, 0,       0),
>         NPCM7XX_PINCFG(27,       smb5, MFSEL1, 2,         none, NONE, 0,        none, NONE, 0,       0),
>         NPCM7XX_PINCFG(28,       smb4, MFSEL1, 1,         none, NONE, 0,        none, NONE, 0,       0),
> @@ -982,8 +1015,8 @@ static const struct npcm7xx_pincfg pincfg[] = {
>         NPCM7XX_PINCFG(56,      r1err, MFSEL1, 12,        none, NONE, 0,        none, NONE, 0,       0),
>         NPCM7XX_PINCFG(57,       r1md, MFSEL1, 13,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
>         NPCM7XX_PINCFG(58,       r1md, MFSEL1, 13,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
> -       NPCM7XX_PINCFG(59,      smb3d, I2CSEGSEL, 13,     none, NONE, 0,        none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(60,      smb3d, I2CSEGSEL, 13,     none, NONE, 0,        none, NONE, 0,       0),
> +       NPCM7XX_PINCFG(59,      hgpio6, MFSEL2, 30,       smb3d, I2CSEGSEL, 13, none, NONE, 0,       0),
> +       NPCM7XX_PINCFG(60,      hgpio7, MFSEL2, 31,       smb3d, I2CSEGSEL, 13, none, NONE, 0,       0),
>         NPCM7XX_PINCFG(61,      uart1, MFSEL1, 10,        none, NONE, 0,        none, NONE, 0,     GPO),
>         NPCM7XX_PINCFG(62,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,     none, NONE, 0,     GPO),
>         NPCM7XX_PINCFG(63,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,     none, NONE, 0,     GPO),
> @@ -1188,12 +1221,12 @@ static const struct pinctrl_pin_desc npcm7xx_pins[] = {
>         PINCTRL_PIN(17, "GPIO17/PSPI2DI/SMB4DEN"),
>         PINCTRL_PIN(18, "GPIO18/PSPI2D0/SMB4BSDA"),
>         PINCTRL_PIN(19, "GPIO19/PSPI2CK/SMB4BSCL"),
> -       PINCTRL_PIN(20, "GPIO20/SMB4CSDA/SMB15SDA"),
> -       PINCTRL_PIN(21, "GPIO21/SMB4CSCL/SMB15SCL"),
> -       PINCTRL_PIN(22, "GPIO22/SMB4DSDA/SMB14SDA"),
> -       PINCTRL_PIN(23, "GPIO23/SMB4DSCL/SMB14SCL"),
> -       PINCTRL_PIN(24, "GPIO24/IOXHDO"),
> -       PINCTRL_PIN(25, "GPIO25/IOXHDI"),
> +       PINCTRL_PIN(20, "GPIO20/HGPIO0/SMB4CSDA/SMB15SDA"),
> +       PINCTRL_PIN(21, "GPIO21/HGPIO1/SMB4CSCL/SMB15SCL"),
> +       PINCTRL_PIN(22, "GPIO22/HGPIO2/SMB4DSDA/SMB14SDA"),
> +       PINCTRL_PIN(23, "GPIO23/HGPIO3/SMB4DSCL/SMB14SCL"),
> +       PINCTRL_PIN(24, "GPIO24/HGPIO4/IOXHDO"),
> +       PINCTRL_PIN(25, "GPIO25/HGPIO5/IOXHDI"),
>         PINCTRL_PIN(26, "GPIO26/SMB5SDA"),
>         PINCTRL_PIN(27, "GPIO27/SMB5SCL"),
>         PINCTRL_PIN(28, "GPIO28/SMB4SDA"),
> @@ -1226,8 +1259,8 @@ static const struct pinctrl_pin_desc npcm7xx_pins[] = {
>         PINCTRL_PIN(56, "GPIO56/R1RXERR"),
>         PINCTRL_PIN(57, "GPIO57/R1MDC"),
>         PINCTRL_PIN(58, "GPIO58/R1MDIO"),
> -       PINCTRL_PIN(59, "GPIO59/SMB3DSDA"),
> -       PINCTRL_PIN(60, "GPIO60/SMB3DSCL"),
> +       PINCTRL_PIN(59, "GPIO59/HGPIO6/SMB3DSDA"),
> +       PINCTRL_PIN(60, "GPIO60/HGPIO7/SMB3DSCL"),
>         PINCTRL_PIN(61, "GPO61/nDTR1_BOUT1/STRAP6"),
>         PINCTRL_PIN(62, "GPO62/nRTST1/STRAP5"),
>         PINCTRL_PIN(63, "GPO63/TXD1/STRAP4"),
> --
> 2.22.0
>

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

* Re: [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support
  2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support Tomer Maimon
@ 2021-01-11  1:04   ` Joel Stanley
  2021-01-11 10:58     ` Avi Fishman
  0 siblings, 1 reply; 20+ messages in thread
From: Joel Stanley @ 2021-01-11  1:04 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Modify the IRQ handler in the NPCM PSPI
> driver to support SPI full duplex communication.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
>  drivers/spi/spi-npcm-pspi.c | 75 +++++++++++++++----------------------
>  1 file changed, 30 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c
> index 87cd0233c60b..92fae0b23eb1 100644
> --- a/drivers/spi/spi-npcm-pspi.c
> +++ b/drivers/spi/spi-npcm-pspi.c
> @@ -197,22 +197,22 @@ static void npcm_pspi_setup_transfer(struct spi_device *spi,
>  static void npcm_pspi_send(struct npcm_pspi *priv)
>  {
>         int wsize;
> -       u16 val;
> +       u16 val = 0;
>
>         wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
>         priv->tx_bytes -= wsize;
>
> -       if (!priv->tx_buf)
> -               return;

It looks like you're removing this check and instead doing it inside
each case. That seems like a waste, why not leave the single check in?

> -
>         switch (wsize) {
>         case 1:
> -               val = *priv->tx_buf++;
> +               if (priv->tx_buf)
> +                       val = *priv->tx_buf++;
>                 iowrite8(val, NPCM_PSPI_DATA + priv->base);
>                 break;
>         case 2:
> -               val = *priv->tx_buf++;
> -               val = *priv->tx_buf++ | (val << 8);
> +               if (priv->tx_buf) {
> +                       val = *priv->tx_buf++;
> +                       val = *priv->tx_buf++ | (val << 8);
> +               }
>                 iowrite16(val, NPCM_PSPI_DATA + priv->base);
>                 break;
>         default:
> @@ -224,22 +224,24 @@ static void npcm_pspi_send(struct npcm_pspi *priv)
>  static void npcm_pspi_recv(struct npcm_pspi *priv)
>  {
>         int rsize;
> -       u16 val;
> +       u16 val_16;
> +       u8  val_8;
>
>         rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
>         priv->rx_bytes -= rsize;
>
> -       if (!priv->rx_buf)
> -               return;
> -
>         switch (rsize) {
>         case 1:
> -               *priv->rx_buf++ = ioread8(priv->base + NPCM_PSPI_DATA);
> +               val_8 = ioread8(priv->base + NPCM_PSPI_DATA);
> +               if (priv->rx_buf)
> +                       *priv->rx_buf++ = val_8;
>                 break;
>         case 2:
> -               val = ioread16(priv->base + NPCM_PSPI_DATA);
> -               *priv->rx_buf++ = (val >> 8);
> -               *priv->rx_buf++ = val & 0xff;
> +               val_16 = ioread16(priv->base + NPCM_PSPI_DATA);
> +               if (priv->rx_buf) {
> +                       *priv->rx_buf++ = (val_16 >> 8);
> +                       *priv->rx_buf++ = val_16 & 0xff;
> +               }
>                 break;
>         default:
>                 WARN_ON_ONCE(1);
> @@ -298,43 +300,26 @@ static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
>         struct npcm_pspi *priv = dev_id;
>         u8 stat;
>
> -       stat = ioread8(priv->base + NPCM_PSPI_STAT);
> -
>         if (!priv->tx_buf && !priv->rx_buf)
>                 return IRQ_NONE;
>
> -       if (priv->tx_buf) {
> -               if (stat & NPCM_PSPI_STAT_RBF) {
> -                       ioread8(NPCM_PSPI_DATA + priv->base);
> -                       if (priv->tx_bytes == 0) {
> -                               npcm_pspi_disable(priv);
> -                               complete(&priv->xfer_done);
> -                               return IRQ_HANDLED;
> -                       }
> -               }
> -
> -               if ((stat & NPCM_PSPI_STAT_BSY) == 0)
> -                       if (priv->tx_bytes)
> -                               npcm_pspi_send(priv);
> +       if (priv->tx_bytes == 0 && priv->rx_bytes == 0) {
> +               npcm_pspi_disable(priv);
> +               complete(&priv->xfer_done);
> +               return IRQ_HANDLED;
>         }
>
> -       if (priv->rx_buf) {
> -               if (stat & NPCM_PSPI_STAT_RBF) {
> -                       if (!priv->rx_bytes)
> -                               return IRQ_NONE;
> -
> -                       npcm_pspi_recv(priv);
> +       stat = ioread8(priv->base + NPCM_PSPI_STAT);
>
> -                       if (!priv->rx_bytes) {
> -                               npcm_pspi_disable(priv);
> -                               complete(&priv->xfer_done);
> -                               return IRQ_HANDLED;
> -                       }
> -               }
> +       /*
> +        * first we do the read since if we do the write we previous read might
> +        * be lost (indeed low chances)
> +        */
> +       if ((stat & NPCM_PSPI_STAT_RBF) && priv->rx_bytes)
> +               npcm_pspi_recv(priv);
>
> -               if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
> -                       iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
> -       }
> +       if (((stat & NPCM_PSPI_STAT_BSY) == 0) && priv->tx_bytes)
> +               npcm_pspi_send(priv);
>
>         return IRQ_HANDLED;
>  }
> --
> 2.22.0
>

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

* Re: [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support
  2021-01-11  1:04   ` Joel Stanley
@ 2021-01-11 10:58     ` Avi Fishman
  0 siblings, 0 replies; 20+ messages in thread
From: Avi Fishman @ 2021-01-11 10:58 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Andrew Jeffery, OpenBMC Maillist, Tomer Maimon, Benjamin Fair

On Mon, Jan 11, 2021 at 3:05 AM Joel Stanley <joel@jms.id.au> wrote:
>
> On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
> >
> > Modify the IRQ handler in the NPCM PSPI
> > driver to support SPI full duplex communication.
> >
> > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> > ---
> >  drivers/spi/spi-npcm-pspi.c | 75 +++++++++++++++----------------------
> >  1 file changed, 30 insertions(+), 45 deletions(-)
> >
> > diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c
> > index 87cd0233c60b..92fae0b23eb1 100644
> > --- a/drivers/spi/spi-npcm-pspi.c
> > +++ b/drivers/spi/spi-npcm-pspi.c
> > @@ -197,22 +197,22 @@ static void npcm_pspi_setup_transfer(struct spi_device *spi,
> >  static void npcm_pspi_send(struct npcm_pspi *priv)
> >  {
> >         int wsize;
> > -       u16 val;
> > +       u16 val = 0;
> >
> >         wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
> >         priv->tx_bytes -= wsize;
> >
> > -       if (!priv->tx_buf)
> > -               return;
>
> It looks like you're removing this check and instead doing it inside
> each case. That seems like a waste, why not leave the single check in?

Even if the tx_buf is NULL, I still need to do the write to
NPCM_PSPI_DATA, since only this write triggers the clock and I need
the clocks for the rx_buf.
and this is why I initialized 'val = 0'

>
> > -
> >         switch (wsize) {
> >         case 1:
> > -               val = *priv->tx_buf++;
> > +               if (priv->tx_buf)
> > +                       val = *priv->tx_buf++;
> >                 iowrite8(val, NPCM_PSPI_DATA + priv->base);
> >                 break;
> >         case 2:
> > -               val = *priv->tx_buf++;
> > -               val = *priv->tx_buf++ | (val << 8);
> > +               if (priv->tx_buf) {
> > +                       val = *priv->tx_buf++;
> > +                       val = *priv->tx_buf++ | (val << 8);
> > +               }
> >                 iowrite16(val, NPCM_PSPI_DATA + priv->base);
> >                 break;
> >         default:
> > @@ -224,22 +224,24 @@ static void npcm_pspi_send(struct npcm_pspi *priv)
> >  static void npcm_pspi_recv(struct npcm_pspi *priv)
> >  {
> >         int rsize;
> > -       u16 val;
> > +       u16 val_16;
> > +       u8  val_8;
> >
> >         rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
> >         priv->rx_bytes -= rsize;
> >
> > -       if (!priv->rx_buf)
> > -               return;
> > -
> >         switch (rsize) {
> >         case 1:
> > -               *priv->rx_buf++ = ioread8(priv->base + NPCM_PSPI_DATA);
> > +               val_8 = ioread8(priv->base + NPCM_PSPI_DATA);
> > +               if (priv->rx_buf)
> > +                       *priv->rx_buf++ = val_8;
> >                 break;
> >         case 2:
> > -               val = ioread16(priv->base + NPCM_PSPI_DATA);
> > -               *priv->rx_buf++ = (val >> 8);
> > -               *priv->rx_buf++ = val & 0xff;
> > +               val_16 = ioread16(priv->base + NPCM_PSPI_DATA);
> > +               if (priv->rx_buf) {
> > +                       *priv->rx_buf++ = (val_16 >> 8);
> > +                       *priv->rx_buf++ = val_16 & 0xff;
> > +               }
> >                 break;
> >         default:
> >                 WARN_ON_ONCE(1);
> > @@ -298,43 +300,26 @@ static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
> >         struct npcm_pspi *priv = dev_id;
> >         u8 stat;
> >
> > -       stat = ioread8(priv->base + NPCM_PSPI_STAT);
> > -
> >         if (!priv->tx_buf && !priv->rx_buf)
> >                 return IRQ_NONE;
> >
> > -       if (priv->tx_buf) {
> > -               if (stat & NPCM_PSPI_STAT_RBF) {
> > -                       ioread8(NPCM_PSPI_DATA + priv->base);
> > -                       if (priv->tx_bytes == 0) {
> > -                               npcm_pspi_disable(priv);
> > -                               complete(&priv->xfer_done);
> > -                               return IRQ_HANDLED;
> > -                       }
> > -               }
> > -
> > -               if ((stat & NPCM_PSPI_STAT_BSY) == 0)
> > -                       if (priv->tx_bytes)
> > -                               npcm_pspi_send(priv);
> > +       if (priv->tx_bytes == 0 && priv->rx_bytes == 0) {
> > +               npcm_pspi_disable(priv);
> > +               complete(&priv->xfer_done);
> > +               return IRQ_HANDLED;
> >         }
> >
> > -       if (priv->rx_buf) {
> > -               if (stat & NPCM_PSPI_STAT_RBF) {
> > -                       if (!priv->rx_bytes)
> > -                               return IRQ_NONE;
> > -
> > -                       npcm_pspi_recv(priv);
> > +       stat = ioread8(priv->base + NPCM_PSPI_STAT);
> >
> > -                       if (!priv->rx_bytes) {
> > -                               npcm_pspi_disable(priv);
> > -                               complete(&priv->xfer_done);
> > -                               return IRQ_HANDLED;
> > -                       }
> > -               }
> > +       /*
> > +        * first we do the read since if we do the write we previous read might
> > +        * be lost (indeed low chances)
> > +        */
> > +       if ((stat & NPCM_PSPI_STAT_RBF) && priv->rx_bytes)
> > +               npcm_pspi_recv(priv);
> >
> > -               if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
> > -                       iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
> > -       }
> > +       if (((stat & NPCM_PSPI_STAT_BSY) == 0) && priv->tx_bytes)
> > +               npcm_pspi_send(priv);
> >
> >         return IRQ_HANDLED;
> >  }
> > --
> > 2.22.0
> >



-- 
Regards,
Avi

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

* Re: [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support
  2021-01-11  0:55   ` Joel Stanley
@ 2021-01-11 19:22     ` Tomer Maimon
  0 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-11 19:22 UTC (permalink / raw)
  To: Joel Stanley; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

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

On Mon, 11 Jan 2021 at 02:55, Joel Stanley <joel@jms.id.au> wrote:

> On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
> >
> > Add Device tree restart priority and
> > three reset types support.
> >
> > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
>
> Can you remind me the history of this change. Was a similar patch
> rejected by mainline?
>
https://www.spinics.net/lists/kernel/msg3425926.html

>
> > ---
> >  drivers/watchdog/npcm_wdt.c | 121 +++++++++++++++++++++++++++++++++++-
> >  1 file changed, 119 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
> > index 765577f11c8d..bbf27da34834 100644
> > --- a/drivers/watchdog/npcm_wdt.c
> > +++ b/drivers/watchdog/npcm_wdt.c
> > @@ -11,7 +11,24 @@
> >  #include <linux/platform_device.h>
> >  #include <linux/slab.h>
> >  #include <linux/watchdog.h>
> > -
> > +#include <linux/regmap.h>
> > +#include <linux/mfd/syscon.h>
> > +
> > +/* NPCM7xx GCR module */
> > +#define NPCM7XX_RESSR_OFFSET           0x6C
> > +#define NPCM7XX_INTCR2_OFFSET          0x60
> > +
> > +#define NPCM7XX_PORST                  BIT(31)
> > +#define NPCM7XX_CORST                  BIT(30)
> > +#define NPCM7XX_WD0RST                 BIT(29)
> > +#define NPCM7XX_WD1RST                 BIT(24)
> > +#define NPCM7XX_WD2RST                 BIT(23)
> > +#define NPCM7XX_SWR1RST                        BIT(28)
> > +#define NPCM7XX_SWR2RST                        BIT(27)
> > +#define NPCM7XX_SWR3RST                        BIT(26)
> > +#define NPCM7XX_SWR4RST                        BIT(25)
> > +
> > + /* WD register */
> >  #define NPCM_WTCR      0x1C
> >
> >  #define NPCM_WTCLK     (BIT(10) | BIT(11))     /* Clock divider */
> > @@ -43,6 +60,10 @@
> >  struct npcm_wdt {
> >         struct watchdog_device  wdd;
> >         void __iomem            *reg;
> > +       u32                     card_reset;
> > +       u32                     ext1_reset;
> > +       u32                     ext2_reset;
> > +
> >  };
> >
> >  static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd)
> > @@ -176,14 +197,70 @@ static const struct watchdog_ops npcm_wdt_ops = {
> >         .restart = npcm_wdt_restart,
> >  };
> >
> > +static void npcm_get_reset_status(struct npcm_wdt *wdt, struct device
> *dev)
> > +{
> > +       struct regmap *gcr_regmap;
> > +       u32 rstval;
> > +
> > +       if (of_device_is_compatible(dev->of_node,
> "nuvoton,npcm750-wdt")) {
> > +               gcr_regmap =
> syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
>
> This will have the same issues as the ADC with supporting multiple
> families of chip with the same code. I suggest you adjust it to use
> the phandle approach.
>
> Do you mean by having a gcr phandle property in the wdt npcm device tree
node?

>
> > +               if (IS_ERR(gcr_regmap)) {
> > +                       dev_warn(dev, "Failed to find
> nuvoton,npcm750-gcr WD reset status not supported\n");
> > +               }
> > +
> > +               regmap_read(gcr_regmap, NPCM7XX_RESSR_OFFSET, &rstval);
> > +               if (!rstval) {
> > +                       regmap_read(gcr_regmap, NPCM7XX_INTCR2_OFFSET,
> &rstval);
> > +                       rstval = ~rstval;
> > +               }
> > +
> > +               if(rstval & wdt->card_reset)
> > +                       wdt->wdd.bootstatus |= WDIOF_CARDRESET;
> > +               if(rstval & wdt->ext1_reset)
> > +                       wdt->wdd.bootstatus |= WDIOF_EXTERN1;
> > +               if(rstval & wdt->ext2_reset)
> > +                       wdt->wdd.bootstatus |= WDIOF_EXTERN2;
> > +       }
> > +
> > +}
> > +
> > +static u32 npcm_wdt_reset_type(const char *reset_type)
> > +{
> > +       if (!strcmp(reset_type, "porst"))
> > +               return NPCM7XX_PORST;
> > +       else if (!strcmp(reset_type, "corst"))
> > +               return NPCM7XX_CORST;
> > +       else if (!strcmp(reset_type, "wd0"))
> > +               return NPCM7XX_WD0RST;
> > +       else if (!strcmp(reset_type, "wd1"))
> > +               return NPCM7XX_WD1RST;
> > +       else if (!strcmp(reset_type, "wd2"))
> > +               return NPCM7XX_WD2RST;
> > +       else if (!strcmp(reset_type, "sw1"))
> > +               return NPCM7XX_SWR1RST;
> > +       else if (!strcmp(reset_type, "sw2"))
> > +               return NPCM7XX_SWR2RST;
> > +       else if (!strcmp(reset_type, "sw3"))
> > +               return NPCM7XX_SWR3RST;
> > +       else if (!strcmp(reset_type, "sw4"))
> > +               return NPCM7XX_SWR4RST;
> > +
> > +       return 0;
> > +}
> > +
> >  static int npcm_wdt_probe(struct platform_device *pdev)
> >  {
> >         struct device *dev = &pdev->dev;
> > +       const char *card_reset_type;
> > +       const char *ext1_reset_type;
> > +       const char *ext2_reset_type;
> >         struct npcm_wdt *wdt;
> > +       struct resource *res;
> > +       u32 priority;
> >         int irq;
> >         int ret;
> >
> > -       wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
> > +       wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
> >         if (!wdt)
> >                 return -ENOMEM;
> >
> > @@ -195,6 +272,45 @@ static int npcm_wdt_probe(struct platform_device
> *pdev)
> >         if (irq < 0)
> >                 return irq;
> >
> > +       if (of_property_read_u32(pdev->dev.of_node,
> "nuvoton,restart-priority",
> > +                                &priority))
> > +               watchdog_set_restart_priority(&wdt->wdd, 128);
> > +       else
> > +               watchdog_set_restart_priority(&wdt->wdd, priority);
> > +
> > +       ret = of_property_read_string(pdev->dev.of_node,
> > +                                     "nuvoton,card-reset-type",
> > +                                     &card_reset_type);
> > +       if (ret)
> > +               wdt->card_reset = NPCM7XX_PORST;
> > +       else {
> > +               wdt->card_reset = npcm_wdt_reset_type(card_reset_type);
> > +               if (!wdt->card_reset)
> > +                       wdt->card_reset = NPCM7XX_PORST;
> > +       }
> > +
> > +       ret = of_property_read_string(pdev->dev.of_node,
> > +                                     "nuvoton,ext1-reset-type",
> > +                                     &ext1_reset_type);
> > +       if (ret)
> > +               wdt->ext1_reset = NPCM7XX_WD0RST;
> > +       else {
> > +               wdt->ext1_reset = npcm_wdt_reset_type(ext1_reset_type);
> > +               if (!wdt->ext1_reset)
> > +                       wdt->ext1_reset = NPCM7XX_WD0RST;
> > +       }
> > +
> > +       ret = of_property_read_string(pdev->dev.of_node,
> > +                                     "nuvoton,ext2-reset-type",
> > +                                     &ext2_reset_type);
> > +       if (ret)
> > +               wdt->ext2_reset = NPCM7XX_SWR1RST;
> > +       else {
> > +               wdt->ext2_reset = npcm_wdt_reset_type(ext2_reset_type);
> > +               if (!wdt->ext2_reset)
> > +                       wdt->ext2_reset = NPCM7XX_SWR1RST;
> > +       }
> > +
> >         wdt->wdd.info = &npcm_wdt_info;
> >         wdt->wdd.ops = &npcm_wdt_ops;
> >         wdt->wdd.min_timeout = 1;
> > @@ -213,6 +329,7 @@ static int npcm_wdt_probe(struct platform_device
> *pdev)
> >                 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
> >         }
> >
> > +       npcm_get_reset_status(wdt, dev);
> >         ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0,
> "watchdog",
> >                                wdt);
> >         if (ret)
> > --
> > 2.22.0
> >
>

[-- Attachment #2: Type: text/html, Size: 10771 bytes --]

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

* Re: [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8
  2021-01-11  0:37 ` [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Joel Stanley
@ 2021-01-11 19:30   ` Tomer Maimon
  0 siblings, 0 replies; 20+ messages in thread
From: Tomer Maimon @ 2021-01-11 19:30 UTC (permalink / raw)
  To: Joel Stanley; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

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

Hi Joel,

First tahnks a lot for reviewing the patches.

On Mon, 11 Jan 2021 at 02:37, Joel Stanley <joel@jms.id.au> wrote:

> Hi Tomer,
>
> On Tue, 5 Jan 2021 at 13:45, Tomer Maimon <tmaimon77@gmail.com> wrote:
> >
> > In this patch set we will like to align with relevant modifications
> > in Nuvoton OpenBMC Linux kernel 5.4.
>
> Thanks for sending the patches. I can merge them into 5.8, however I
> have a v5.10 branch that I plan on moving to imminently.
>
> >
> > Linux upstream current status:
> >         1. npcm7xx clock driver - adding read only
> >                 flag to divider clocks, Will be sent to Linux community.
> >         2. Adding NPCM ADC calibration - Will be sent to Linux vanilla,
> >                 but I am not sure it will be approved.
> >         3. Add DT restart priority and reset type support - sent to Linux
> >                 community la but havent approved yet.
> >         4. persist configuration to the pin control driver - asked by a
> costumer,
> >                 didnt sent to Linux community.
>
> Do you plan on sending it?
>
I need you advise on this one, I pretty sure that the pin
cntroller maintainer will refuse to add it
what do you think?

>
> >         5. Add HGPIO pin support to NPCM7xx pinctrl driver - will be sent
> >                 to Linux community
> >         6. JTAG master driver - will be sent to Linux community once we
> will
> >                 have BMC folder.
>
What about the JTAG driver? can you add it please? do I need to move it to
soc folder or to leave it in
misc?

>
> As you've noted, I recommend you submit them to mainline ASAP to avoid
> extra handling of patches in the openbmc tree.
>
you right, I will do my best...

>
> Cheers,
>
> Joel
>
> >
> > Changes since version 1:
> > - Address comments from Jonathan Neuschäfer: removing trailing whitespace
> >         in NPCM watchdog documentation.
> > - Adding Stanley Chu to NPCM JTAG master driver
> >
> > Tomer Maimon (11):
> >   clk: npcm7xx: add read only flag to divider clocks
> >   iio: adc: add calibration support to npcm ADC
> >   dts: npcm750: add fuse regmap support node
> >   watchdog: npcm: Add DT restart priority and reset type support
> >   dt-binding: watchdog: Add DT restart priority and reset type
> >   pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
> >   pinctrl: pinconf: add pin persist configuration
> >   pinctrl: npcm7xx: Add pin persist configuration support
> >   spi: npcm-pspi: Add full duplex support
> >   dt-binding: bmc: add NPCM7XX JTAG master documentation
> >   misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver
> >
> >  .../bindings/bmc/npcm7xx-jtag-master.txt      |  38 +
> >  .../bindings/watchdog/nuvoton,npcm-wdt.txt    |  32 +
> >  arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi |   6 +
> >  drivers/clk/clk-npcm7xx.c                     |  70 +-
> >  drivers/iio/adc/npcm_adc.c                    | 191 ++++
> >  drivers/misc/Kconfig                          |   6 +
> >  drivers/misc/Makefile                         |   1 +
> >  drivers/misc/npcm7xx-jtag-master.c            | 840 ++++++++++++++++++
> >  drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c     | 130 ++-
> >  drivers/pinctrl/pinconf-generic.c             |   3 +
> >  drivers/spi/spi-npcm-pspi.c                   |  75 +-
> >  drivers/watchdog/npcm_wdt.c                   | 121 ++-
> >  12 files changed, 1418 insertions(+), 95 deletions(-)
> >  create mode 100644
> Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
> >  create mode 100644 drivers/misc/npcm7xx-jtag-master.c
> >
> > --
> > 2.22.0
> >
>

cheers,

Tomer

[-- Attachment #2: Type: text/html, Size: 5105 bytes --]

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

end of thread, other threads:[~2021-01-11 19:17 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-05 13:44 [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Tomer Maimon
2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 01/11] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
2021-01-05 13:44 ` [PATCH linux dev-5.8 v2 02/11] iio: adc: add calibration support to npcm ADC Tomer Maimon
2021-01-11  0:52   ` Joel Stanley
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 03/11] dts: npcm750: add fuse regmap support node Tomer Maimon
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support Tomer Maimon
2021-01-11  0:55   ` Joel Stanley
2021-01-11 19:22     ` Tomer Maimon
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 05/11] dt-binding: watchdog: Add DT restart priority and reset type Tomer Maimon
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 06/11] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
2021-01-11  0:56   ` Joel Stanley
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 07/11] pinctrl: pinconf: add pin persist configuration Tomer Maimon
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 08/11] pinctrl: npcm7xx: Add pin persist configuration support Tomer Maimon
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support Tomer Maimon
2021-01-11  1:04   ` Joel Stanley
2021-01-11 10:58     ` Avi Fishman
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 10/11] dt-binding: bmc: add NPCM7XX JTAG master documentation Tomer Maimon
2021-01-05 13:45 ` [PATCH linux dev-5.8 v2 11/11] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver Tomer Maimon
2021-01-11  0:37 ` [PATCH linux dev-5.8 v2 00/11] Add NPCM7xx patches to dev-5.8 Joel Stanley
2021-01-11 19:30   ` Tomer Maimon

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.