linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 net-next 0/5] ptp_clockmatrix bug fix and improvement
@ 2020-11-17 16:05 min.li.xe
  2020-11-17 16:05 ` [PATCH v2 net-next 1/5] ptp: clockmatrix: bug fix for idtcm_strverscmp min.li.xe
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: min.li.xe @ 2020-11-17 16:05 UTC (permalink / raw)
  To: richardcochran; +Cc: netdev, linux-kernel, Min Li

From: Min Li <min.li.xe@renesas.com>

This patch series is aiming at submitting the latest bug fixes and code
improvements of PHC driver for Renesas CLOCKMATRIX timing card. The code
has been thouroughly tested in both customer labs and Renesas internal
lab using the latest linuxptp program on Xilinx ZCU102 platform.

Changes since v1:
-Only strcpy 15 characters to leave 1 space for '\0'

Min Li (5):
  ptp: clockmatrix: bug fix for idtcm_strverscmp
  ptp: clockmatrix: reset device and check BOOT_STATUS
  ptp: clockmatrix: remove 5 second delay before entering write phase
    mode
  ptp: clockmatrix: Fix non-zero phase_adj is lost after snap
  ptp: clockmatrix: deprecate firmware older than 4.8.7

 drivers/ptp/idt8a340_reg.h    |   1 +
 drivers/ptp/ptp_clockmatrix.c | 477 ++++++++++++++++++++++++++++++++----------
 drivers/ptp/ptp_clockmatrix.h |  24 ++-
 3 files changed, 384 insertions(+), 118 deletions(-)

-- 
2.7.4


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

* [PATCH v2 net-next 1/5] ptp: clockmatrix: bug fix for idtcm_strverscmp
  2020-11-17 16:05 [PATCH v2 net-next 0/5] ptp_clockmatrix bug fix and improvement min.li.xe
@ 2020-11-17 16:05 ` min.li.xe
  2020-11-17 16:05 ` [PATCH v2 net-next 2/5] ptp: clockmatrix: reset device and check BOOT_STATUS min.li.xe
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: min.li.xe @ 2020-11-17 16:05 UTC (permalink / raw)
  To: richardcochran; +Cc: netdev, linux-kernel, Min Li

From: Min Li <min.li.xe@renesas.com>

Feed kstrtou8 with NULL terminated string.

Changes since v1:
-Only strcpy 15 characters to leave 1 space for '\0'

Signed-off-by: Min Li <min.li.xe@renesas.com>
---
 drivers/ptp/ptp_clockmatrix.c | 52 +++++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 14 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index e020faf..efe5639 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -103,42 +103,66 @@ static int timespec_to_char_array(struct timespec64 const *ts,
 	return 0;
 }
 
-static int idtcm_strverscmp(const char *ver1, const char *ver2)
+static int idtcm_strverscmp(const char *version1, const char *version2)
 {
 	u8 num1;
 	u8 num2;
 	int result = 0;
+	char ver1[16];
+	char ver2[16];
+	char *cur1;
+	char *cur2;
+	char *next1;
+	char *next2;
+
+	strncpy(ver1, version1, 15);
+	strncpy(ver2, version2, 15);
+	cur1 = ver1;
+	cur2 = ver2;
 
 	/* loop through each level of the version string */
 	while (result == 0) {
+		next1 = strchr(cur1, '.');
+		next2 = strchr(cur2, '.');
+
+		/* kstrtou8 could fail for dot */
+		if (next1) {
+			*next1 = '\0';
+			next1++;
+		}
+
+		if (next2) {
+			*next2 = '\0';
+			next2++;
+		}
+
 		/* extract leading version numbers */
-		if (kstrtou8(ver1, 10, &num1) < 0)
+		if (kstrtou8(cur1, 10, &num1) < 0)
 			return -1;
 
-		if (kstrtou8(ver2, 10, &num2) < 0)
+		if (kstrtou8(cur2, 10, &num2) < 0)
 			return -1;
 
 		/* if numbers differ, then set the result */
-		if (num1 < num2)
+		if (num1 < num2) {
 			result = -1;
-		else if (num1 > num2)
+		} else if (num1 > num2) {
 			result = 1;
-		else {
+		} else {
 			/* if numbers are the same, go to next level */
-			ver1 = strchr(ver1, '.');
-			ver2 = strchr(ver2, '.');
-			if (!ver1 && !ver2)
+			if (!next1 && !next2)
 				break;
-			else if (!ver1)
+			else if (!next1) {
 				result = -1;
-			else if (!ver2)
+			} else if (!next2) {
 				result = 1;
-			else {
-				ver1++;
-				ver2++;
+			} else {
+				cur1 = next1;
+				cur2 = next2;
 			}
 		}
 	}
+
 	return result;
 }
 
-- 
2.7.4


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

* [PATCH v2 net-next 2/5] ptp: clockmatrix: reset device and check BOOT_STATUS
  2020-11-17 16:05 [PATCH v2 net-next 0/5] ptp_clockmatrix bug fix and improvement min.li.xe
  2020-11-17 16:05 ` [PATCH v2 net-next 1/5] ptp: clockmatrix: bug fix for idtcm_strverscmp min.li.xe
@ 2020-11-17 16:05 ` min.li.xe
  2020-11-17 16:06 ` [PATCH v2 net-next 3/5] ptp: clockmatrix: remove 5 second delay before entering write phase mode min.li.xe
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: min.li.xe @ 2020-11-17 16:05 UTC (permalink / raw)
  To: richardcochran; +Cc: netdev, linux-kernel, Min Li

From: Min Li <min.li.xe@renesas.com>

SM_RESET device only when loading full configuration and check
for BOOT_STATUS. Also remove polling for write trigger done in
_idtcm_settime().

Signed-off-by: Min Li <min.li.xe@renesas.com>
---
 drivers/ptp/idt8a340_reg.h    |   1 +
 drivers/ptp/ptp_clockmatrix.c | 152 ++++++++++++++++++++++++++++++++----------
 drivers/ptp/ptp_clockmatrix.h |   9 ++-
 3 files changed, 126 insertions(+), 36 deletions(-)

diff --git a/drivers/ptp/idt8a340_reg.h b/drivers/ptp/idt8a340_reg.h
index b297c4a..a664dfe 100644
--- a/drivers/ptp/idt8a340_reg.h
+++ b/drivers/ptp/idt8a340_reg.h
@@ -103,6 +103,7 @@
 #define SM_RESET_CMD                      0x5A
 
 #define GENERAL_STATUS                    0xc014
+#define BOOT_STATUS                       0x0000
 #define HW_REV_ID                         0x000A
 #define BOND_ID                           0x000B
 #define HW_CSR_ID                         0x000C
diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index efe5639..6a3d02b 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -33,6 +33,45 @@ module_param(firmware, charp, 0);
 
 #define SETTIME_CORRECTION (0)
 
+static int contains_full_configuration(const struct firmware *fw)
+{
+	s32 full_count = FULL_FW_CFG_BYTES - FULL_FW_CFG_SKIPPED_BYTES;
+	struct idtcm_fwrc *rec = (struct idtcm_fwrc *) fw->data;
+	s32 count = 0;
+	u16 regaddr;
+	u8 loaddr;
+	s32 len;
+
+	/* If the firmware contains 'full configuration' SM_RESET can be used
+	 * to ensure proper configuration.
+	 *
+	 * Full configuration is defined as the number of programmable
+	 * bytes within the configuration range minus page offset addr range.
+	 */
+	for (len = fw->size; len > 0; len -= sizeof(*rec)) {
+		regaddr = rec->hiaddr << 8;
+		regaddr |= rec->loaddr;
+
+		loaddr = rec->loaddr;
+
+		rec++;
+
+		/* Top (status registers) and bottom are read-only */
+		if ((regaddr < GPIO_USER_CONTROL)
+		    || (regaddr >= SCRATCH))
+			continue;
+
+		/* Page size 128, last 4 bytes of page skipped */
+		if (((loaddr > 0x7b) && (loaddr <= 0x7f))
+		     || loaddr > 0xfb)
+			continue;
+
+		count++;
+	}
+
+	return (count >= full_count);
+}
+
 static long set_write_phase_ready(struct ptp_clock_info *ptp)
 {
 	struct idtcm_channel *channel =
@@ -302,6 +341,53 @@ static int idtcm_write(struct idtcm *idtcm,
 	return _idtcm_rdwr(idtcm, module + regaddr, buf, count, true);
 }
 
+static int clear_boot_status(struct idtcm *idtcm)
+{
+	int err;
+	u8 buf[4] = {0};
+
+	err = idtcm_write(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));
+
+	return err;
+}
+
+static int read_boot_status(struct idtcm *idtcm, u32 *status)
+{
+	int err;
+	u8 buf[4] = {0};
+
+	err = idtcm_read(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));
+
+	*status = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+
+	return err;
+}
+
+static int wait_for_boot_status_ready(struct idtcm *idtcm)
+{
+	u32 status = 0;
+	u8 i = 30;	/* 30 * 100ms = 3s */
+	int err;
+
+	do {
+		err = read_boot_status(idtcm, &status);
+
+		if (err)
+			return err;
+
+		if (status == 0xA0)
+			return 0;
+
+		msleep(100);
+		i--;
+
+	} while (i);
+
+	dev_warn(&idtcm->client->dev, "%s timed out\n", __func__);
+
+	return -EBUSY;
+}
+
 static int _idtcm_gettime(struct idtcm_channel *channel,
 			  struct timespec64 *ts)
 {
@@ -711,7 +797,7 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
 		if (err)
 			return err;
 
-		if (cmd == 0)
+		if ((cmd & TOD_WRITE_SELECTION_MASK) == 0)
 			break;
 
 		if (++count > 20) {
@@ -725,39 +811,16 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
 }
 
 static int _idtcm_settime(struct idtcm_channel *channel,
-			  struct timespec64 const *ts,
-			  enum hw_tod_write_trig_sel wr_trig)
+			  struct timespec64 const *ts)
 {
 	struct idtcm *idtcm = channel->idtcm;
 	int err;
-	int i;
-	u8 trig_sel;
-
-	err = _idtcm_set_dpll_hw_tod(channel, ts, wr_trig);
-
-	if (err)
-		return err;
-
-	/* Wait for the operation to complete. */
-	for (i = 0; i < 10000; i++) {
-		err = idtcm_read(idtcm, channel->hw_dpll_n,
-				 HW_DPLL_TOD_CTRL_1, &trig_sel,
-				 sizeof(trig_sel));
-
-		if (err)
-			return err;
 
-		if (trig_sel == 0x4a)
-			break;
-
-		err = 1;
-	}
+	err = _idtcm_set_dpll_hw_tod(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);
 
 	if (err) {
 		dev_err(&idtcm->client->dev,
-			"Failed at line %d in func %s!\n",
-			__LINE__,
-			__func__);
+			"%s: Set HW ToD failed\n", __func__);
 		return err;
 	}
 
@@ -932,7 +995,7 @@ static int _idtcm_adjtime(struct idtcm_channel *channel, s64 delta)
 
 		ts = ns_to_timespec64(now);
 
-		err = _idtcm_settime(channel, &ts, HW_TOD_WR_TRIG_SEL_MSB);
+		err = _idtcm_settime(channel, &ts);
 	}
 
 	return err;
@@ -940,13 +1003,31 @@ static int _idtcm_adjtime(struct idtcm_channel *channel, s64 delta)
 
 static int idtcm_state_machine_reset(struct idtcm *idtcm)
 {
-	int err;
 	u8 byte = SM_RESET_CMD;
+	u32 status = 0;
+	int err;
+	u8 i;
+
+	clear_boot_status(idtcm);
 
 	err = idtcm_write(idtcm, RESET_CTRL, SM_RESET, &byte, sizeof(byte));
 
-	if (!err)
-		msleep_interruptible(POST_SM_RESET_DELAY_MS);
+	if (!err) {
+		for (i = 0; i < 30; i++) {
+			msleep_interruptible(100);
+			read_boot_status(idtcm, &status);
+
+			if (status == 0xA0) {
+				dev_dbg(&idtcm->client->dev,
+					"SM_RESET completed in %d ms\n",
+					i * 100);
+				break;
+			}
+		}
+
+		if (!status)
+			dev_err(&idtcm->client->dev, "Timed out waiting for CM_RESET to complete\n");
+	}
 
 	return err;
 }
@@ -1140,7 +1221,7 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
 
 	rec = (struct idtcm_fwrc *) fw->data;
 
-	if (fw->size > 0)
+	if (contains_full_configuration(fw))
 		idtcm_state_machine_reset(idtcm);
 
 	for (len = fw->size; len > 0; len -= sizeof(*rec)) {
@@ -1420,7 +1501,7 @@ static int idtcm_settime(struct ptp_clock_info *ptp,
 
 	mutex_lock(&idtcm->reg_lock);
 
-	err = _idtcm_settime(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);
+	err = _idtcm_settime(channel, ts);
 
 	if (err)
 		dev_err(&idtcm->client->dev,
@@ -1851,7 +1932,7 @@ static int idtcm_enable_tod(struct idtcm_channel *channel)
 	if (err)
 		return err;
 
-	return _idtcm_settime(channel, &ts, HW_TOD_WR_TRIG_SEL_MSB);
+	return _idtcm_settime(channel, &ts);
 }
 
 static void idtcm_display_version_info(struct idtcm *idtcm)
@@ -2143,6 +2224,9 @@ static int idtcm_probe(struct i2c_client *client,
 		dev_warn(&idtcm->client->dev,
 			 "loading firmware failed with %d\n", err);
 
+	if (wait_for_boot_status_ready(idtcm))
+		dev_warn(&idtcm->client->dev, "BOOT_STATUS != 0xA0\n");
+
 	if (idtcm->tod_mask) {
 		for (i = 0; i < MAX_TOD; i++) {
 			if (idtcm->tod_mask & (1 << i)) {
diff --git a/drivers/ptp/ptp_clockmatrix.h b/drivers/ptp/ptp_clockmatrix.h
index 82840d7..713e41a 100644
--- a/drivers/ptp/ptp_clockmatrix.h
+++ b/drivers/ptp/ptp_clockmatrix.h
@@ -53,9 +53,14 @@
 
 #define OUTPUT_MODULE_FROM_INDEX(index)	(OUTPUT_0 + (index) * 0x10)
 
-#define PEROUT_ENABLE_OUTPUT_MASK		(0xdeadbeef)
+#define PEROUT_ENABLE_OUTPUT_MASK	(0xdeadbeef)
 
-#define IDTCM_MAX_WRITE_COUNT			(512)
+#define IDTCM_MAX_WRITE_COUNT		(512)
+
+#define FULL_FW_CFG_BYTES		(SCRATCH - GPIO_USER_CONTROL)
+#define FULL_FW_CFG_SKIPPED_BYTES	(((SCRATCH >> 7) \
+					  - (GPIO_USER_CONTROL >> 7)) \
+					 * 4) /* 4 bytes skipped every 0x80 */
 
 /* Values of DPLL_N.DPLL_MODE.PLL_MODE */
 enum pll_mode {
-- 
2.7.4


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

* [PATCH v2 net-next 3/5] ptp: clockmatrix: remove 5 second delay before entering write phase mode
  2020-11-17 16:05 [PATCH v2 net-next 0/5] ptp_clockmatrix bug fix and improvement min.li.xe
  2020-11-17 16:05 ` [PATCH v2 net-next 1/5] ptp: clockmatrix: bug fix for idtcm_strverscmp min.li.xe
  2020-11-17 16:05 ` [PATCH v2 net-next 2/5] ptp: clockmatrix: reset device and check BOOT_STATUS min.li.xe
@ 2020-11-17 16:06 ` min.li.xe
  2020-11-17 16:06 ` [PATCH v2 net-next 4/5] ptp: clockmatrix: Fix non-zero phase_adj is lost after snap min.li.xe
  2020-11-17 16:06 ` [PATCH v2 net-next 5/5] ptp: clockmatrix: deprecate firmware older than 4.8.7 min.li.xe
  4 siblings, 0 replies; 7+ messages in thread
From: min.li.xe @ 2020-11-17 16:06 UTC (permalink / raw)
  To: richardcochran; +Cc: netdev, linux-kernel, Min Li

From: Min Li <min.li.xe@renesas.com>

Remove write phase mode 5 second setup delay, not needed.

Signed-off-by: Min Li <min.li.xe@renesas.com>
---
 drivers/ptp/ptp_clockmatrix.c | 22 ----------------------
 drivers/ptp/ptp_clockmatrix.h |  1 -
 2 files changed, 23 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index 6a3d02b..c06df61 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -72,16 +72,6 @@ static int contains_full_configuration(const struct firmware *fw)
 	return (count >= full_count);
 }
 
-static long set_write_phase_ready(struct ptp_clock_info *ptp)
-{
-	struct idtcm_channel *channel =
-		container_of(ptp, struct idtcm_channel, caps);
-
-	channel->write_phase_ready = 1;
-
-	return 0;
-}
-
 static int char_array_to_timespec(u8 *buf,
 				  u8 count,
 				  struct timespec64 *ts)
@@ -1382,16 +1372,8 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
 
 		if (err)
 			return err;
-
-		channel->write_phase_ready = 0;
-
-		ptp_schedule_worker(channel->ptp_clock,
-				    msecs_to_jiffies(WR_PHASE_SETUP_MS));
 	}
 
-	if (!channel->write_phase_ready)
-		delta_ns = 0;
-
 	offset_ps = (s64)delta_ns * 1000;
 
 	/*
@@ -1971,7 +1953,6 @@ static const struct ptp_clock_info idtcm_caps_v487 = {
 	.gettime64	= &idtcm_gettime,
 	.settime64	= &idtcm_settime_v487,
 	.enable		= &idtcm_enable,
-	.do_aux_work	= &set_write_phase_ready,
 };
 
 static const struct ptp_clock_info idtcm_caps = {
@@ -1984,7 +1965,6 @@ static const struct ptp_clock_info idtcm_caps = {
 	.gettime64	= &idtcm_gettime,
 	.settime64	= &idtcm_settime,
 	.enable		= &idtcm_enable,
-	.do_aux_work	= &set_write_phase_ready,
 };
 
 static int configure_channel_pll(struct idtcm_channel *channel)
@@ -2154,8 +2134,6 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
 	if (!channel->ptp_clock)
 		return -ENOTSUPP;
 
-	channel->write_phase_ready = 0;
-
 	dev_info(&idtcm->client->dev, "PLL%d registered as ptp%d\n",
 		 index, channel->ptp_clock->index);
 
diff --git a/drivers/ptp/ptp_clockmatrix.h b/drivers/ptp/ptp_clockmatrix.h
index 713e41a..dd3436e 100644
--- a/drivers/ptp/ptp_clockmatrix.h
+++ b/drivers/ptp/ptp_clockmatrix.h
@@ -125,7 +125,6 @@ struct idtcm_channel {
 	enum pll_mode		pll_mode;
 	u8			pll;
 	u16			output_mask;
-	int			write_phase_ready;
 };
 
 struct idtcm {
-- 
2.7.4


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

* [PATCH v2 net-next 4/5] ptp: clockmatrix: Fix non-zero phase_adj is lost after snap
  2020-11-17 16:05 [PATCH v2 net-next 0/5] ptp_clockmatrix bug fix and improvement min.li.xe
                   ` (2 preceding siblings ...)
  2020-11-17 16:06 ` [PATCH v2 net-next 3/5] ptp: clockmatrix: remove 5 second delay before entering write phase mode min.li.xe
@ 2020-11-17 16:06 ` min.li.xe
  2020-11-17 16:06 ` [PATCH v2 net-next 5/5] ptp: clockmatrix: deprecate firmware older than 4.8.7 min.li.xe
  4 siblings, 0 replies; 7+ messages in thread
From: min.li.xe @ 2020-11-17 16:06 UTC (permalink / raw)
  To: richardcochran; +Cc: netdev, linux-kernel, Min Li

From: Min Li <min.li.xe@renesas.com>

Fix non-zero phase_adj is lost after snap. Use ktime_sub
to do ktime_t subtraction.

Signed-off-by: Min Li <min.li.xe@renesas.com>
---
 drivers/ptp/ptp_clockmatrix.c | 210 +++++++++++++++++++++++++++++++++++++-----
 drivers/ptp/ptp_clockmatrix.h |   5 +-
 2 files changed, 190 insertions(+), 25 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index c06df61..b10c6b9 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -716,8 +716,9 @@ static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
 
 		if (idtcm->calculate_overhead_flag) {
 			/* Assumption: I2C @ 400KHz */
-			total_overhead_ns =  ktime_to_ns(ktime_get_raw()
-							 - idtcm->start_time)
+			ktime_t diff = ktime_sub(ktime_get_raw(),
+						 idtcm->start_time);
+			total_overhead_ns =  ktime_to_ns(diff)
 					     + idtcm->tod_write_overhead_ns
 					     + SETTIME_CORRECTION;
 
@@ -800,12 +801,154 @@ static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
 	return 0;
 }
 
+static int get_output_base_addr(u8 outn)
+{
+	int base;
+
+	switch (outn) {
+	case 0:
+		base = OUTPUT_0;
+		break;
+	case 1:
+		base = OUTPUT_1;
+		break;
+	case 2:
+		base = OUTPUT_2;
+		break;
+	case 3:
+		base = OUTPUT_3;
+		break;
+	case 4:
+		base = OUTPUT_4;
+		break;
+	case 5:
+		base = OUTPUT_5;
+		break;
+	case 6:
+		base = OUTPUT_6;
+		break;
+	case 7:
+		base = OUTPUT_7;
+		break;
+	case 8:
+		base = OUTPUT_8;
+		break;
+	case 9:
+		base = OUTPUT_9;
+		break;
+	case 10:
+		base = OUTPUT_10;
+		break;
+	case 11:
+		base = OUTPUT_11;
+		break;
+	default:
+		base = -EINVAL;
+	}
+
+	return base;
+}
+
+static void save_and_clear_output_phase_adj(struct idtcm_channel *channel)
+{
+	u16 output_mask = channel->output_mask;
+	struct idtcm *idtcm = channel->idtcm;
+	int delay_needed = 0;
+	u8 zero[4] = {0};
+	u8 outn = 0;
+	int base;
+
+	while (output_mask) {
+
+		if (output_mask & 1) {
+
+			base = get_output_base_addr(outn);
+
+			if (!(base > 0)) {
+				dev_err(&idtcm->client->dev,
+					"%s - Unsupported out%d",
+					__func__, outn);
+				return;
+			}
+
+			/* Save output_phase_adj for outn */
+			idtcm_read(idtcm, (u16)base, OUT_PHASE_ADJ,
+				   &channel->output_phase_adj[outn][0],
+				   sizeof(channel->output_phase_adj[outn]));
+
+			if (channel->output_phase_adj[outn][0] |
+			    channel->output_phase_adj[outn][1] |
+			    channel->output_phase_adj[outn][2] |
+			    channel->output_phase_adj[outn][3]) {
+				delay_needed = 1;
+
+				idtcm_write(idtcm, base, OUT_PHASE_ADJ,
+					    &zero[0], sizeof(zero));
+			}
+		}
+
+		output_mask = output_mask >> 1;
+		outn += 1;
+	}
+
+	/* Ensure output phase adjust has settled */
+	if (delay_needed)
+		msleep(5000);
+}
+
+
+static void restore_output_phase_adj(struct idtcm_channel *channel)
+{
+	u16 output_mask = channel->output_mask;
+	struct idtcm *idtcm = channel->idtcm;
+	u8 wait_once = 0;
+	u8 outn = 0;
+	int base;
+
+	while (output_mask) {
+
+		if ((output_mask & 1) &&
+		    (channel->output_phase_adj[outn][0] |
+		     channel->output_phase_adj[outn][1] |
+		     channel->output_phase_adj[outn][2] |
+		     channel->output_phase_adj[outn][3])) {
+
+			if (!wait_once) {
+				/* Ensure idtcm_sync_pps_output() is done */
+				msleep(5000);
+				wait_once = 1;
+			}
+
+			base = get_output_base_addr(outn);
+
+			if (!(base > 0)) {
+				dev_err(&idtcm->client->dev,
+					"%s - Unsupported out%d",
+					__func__, outn);
+				return;
+			}
+
+			/* Restore non-zero output_phase_adj */
+			idtcm_write(idtcm, base, OUT_PHASE_ADJ,
+				    &channel->output_phase_adj[outn][0],
+				    sizeof(channel->output_phase_adj[outn]));
+		}
+
+		output_mask = output_mask >> 1;
+		outn += 1;
+	}
+}
+
 static int _idtcm_settime(struct idtcm_channel *channel,
 			  struct timespec64 const *ts)
 {
 	struct idtcm *idtcm = channel->idtcm;
+	int retval;
 	int err;
 
+	/* Save and clear out_phase_adj */
+	save_and_clear_output_phase_adj(channel);
+
 	err = _idtcm_set_dpll_hw_tod(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);
 
 	if (err) {
@@ -814,7 +957,12 @@ static int _idtcm_settime(struct idtcm_channel *channel,
 		return err;
 	}
 
-	return idtcm_sync_pps_output(channel);
+	retval = idtcm_sync_pps_output(channel);
+
+	/* Restore out_phase_adj */
+	restore_output_phase_adj(channel);
+
+	return retval;
 }
 
 static int _idtcm_settime_v487(struct idtcm_channel *channel,
@@ -924,6 +1072,7 @@ static int set_tod_write_overhead(struct idtcm_channel *channel)
 
 	ktime_t start;
 	ktime_t stop;
+	ktime_t diff;
 
 	char buf[TOD_BYTE_COUNT] = {0};
 
@@ -943,7 +1092,9 @@ static int set_tod_write_overhead(struct idtcm_channel *channel)
 
 		stop = ktime_get_raw();
 
-		current_ns = ktime_to_ns(stop - start);
+		diff = ktime_sub(stop, start);
+
+		current_ns = ktime_to_ns(diff);
 
 		if (i == 0) {
 			lowest_ns = current_ns;
@@ -1263,11 +1414,19 @@ static int idtcm_output_enable(struct idtcm_channel *channel,
 			       bool enable, unsigned int outn)
 {
 	struct idtcm *idtcm = channel->idtcm;
+	int base;
 	int err;
 	u8 val;
 
-	err = idtcm_read(idtcm, OUTPUT_MODULE_FROM_INDEX(outn),
-			 OUT_CTRL_1, &val, sizeof(val));
+	base = get_output_base_addr(outn);
+
+	if (!(base > 0)) {
+		dev_err(&idtcm->client->dev,
+			"%s - Unsupported out%d", __func__, outn);
+		return base;
+	}
+
+	err = idtcm_read(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));
 
 	if (err)
 		return err;
@@ -1277,8 +1436,7 @@ static int idtcm_output_enable(struct idtcm_channel *channel,
 	else
 		val &= ~SQUELCH_DISABLE;
 
-	return idtcm_write(idtcm, OUTPUT_MODULE_FROM_INDEX(outn),
-			   OUT_CTRL_1, &val, sizeof(val));
+	return idtcm_write(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));
 }
 
 static int idtcm_output_mask_enable(struct idtcm_channel *channel,
@@ -1321,6 +1479,23 @@ static int idtcm_perout_enable(struct idtcm_channel *channel,
 	return idtcm_output_enable(channel, enable, perout->index);
 }
 
+static int idtcm_get_pll_mode(struct idtcm_channel *channel,
+			      enum pll_mode *pll_mode)
+{
+	struct idtcm *idtcm = channel->idtcm;
+	int err;
+	u8 dpll_mode;
+
+	err = idtcm_read(idtcm, channel->dpll_n, DPLL_MODE,
+			 &dpll_mode, sizeof(dpll_mode));
+	if (err)
+		return err;
+
+	*pll_mode = (dpll_mode >> PLL_MODE_SHIFT) & PLL_MODE_MASK;
+
+	return 0;
+}
+
 static int idtcm_set_pll_mode(struct idtcm_channel *channel,
 			      enum pll_mode pll_mode)
 {
@@ -1386,7 +1561,7 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
 	else if (offset_ps < -MAX_ABS_WRITE_PHASE_PICOSECONDS)
 		offset_ps = -MAX_ABS_WRITE_PHASE_PICOSECONDS;
 
-	phase_50ps = DIV_ROUND_CLOSEST(div64_s64(offset_ps, 50), 1);
+	phase_50ps = div_s64(offset_ps, 50);
 
 	for (i = 0; i < 4; i++) {
 		buf[i] = phase_50ps & 0xff;
@@ -1403,7 +1578,6 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)
 {
 	struct idtcm *idtcm = channel->idtcm;
 	u8 i;
-	bool neg_adj = 0;
 	int err;
 	u8 buf[6] = {0};
 	s64 fcw;
@@ -1427,18 +1601,11 @@ static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)
 	 * FCW = -------------
 	 *         111 * 2^4
 	 */
-	if (scaled_ppm < 0) {
-		neg_adj = 1;
-		scaled_ppm = -scaled_ppm;
-	}
 
 	/* 2 ^ -53 = 1.1102230246251565404236316680908e-16 */
 	fcw = scaled_ppm * 244140625ULL;
 
-	fcw = div_u64(fcw, 1776);
-
-	if (neg_adj)
-		fcw = -fcw;
+	fcw = div_s64(fcw, 1776);
 
 	for (i = 0; i < 6; i++) {
 		buf[i] = fcw & 0xff;
@@ -2105,12 +2272,11 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
 		}
 	}
 
-	err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_FREQUENCY);
+	/* Sync pll mode with hardware */
+	err = idtcm_get_pll_mode(channel, &channel->pll_mode);
 	if (err) {
 		dev_err(&idtcm->client->dev,
-			"Failed at line %d in func %s!\n",
-			__LINE__,
-			__func__);
+			"Error: %s - Unable to read pll mode\n", __func__);
 		return err;
 	}
 
diff --git a/drivers/ptp/ptp_clockmatrix.h b/drivers/ptp/ptp_clockmatrix.h
index dd3436e..3790dfa 100644
--- a/drivers/ptp/ptp_clockmatrix.h
+++ b/drivers/ptp/ptp_clockmatrix.h
@@ -15,6 +15,7 @@
 #define FW_FILENAME	"idtcm.bin"
 #define MAX_TOD		(4)
 #define MAX_PLL		(8)
+#define MAX_OUTPUT	(12)
 
 #define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL)
 
@@ -49,9 +50,6 @@
 #define PHASE_PULL_IN_THRESHOLD_NS_V487	(15000)
 #define TOD_WRITE_OVERHEAD_COUNT_MAX	(2)
 #define TOD_BYTE_COUNT			(11)
-#define WR_PHASE_SETUP_MS		(5000)
-
-#define OUTPUT_MODULE_FROM_INDEX(index)	(OUTPUT_0 + (index) * 0x10)
 
 #define PEROUT_ENABLE_OUTPUT_MASK	(0xdeadbeef)
 
@@ -125,6 +123,7 @@ struct idtcm_channel {
 	enum pll_mode		pll_mode;
 	u8			pll;
 	u16			output_mask;
+	u8			output_phase_adj[MAX_OUTPUT][4];
 };
 
 struct idtcm {
-- 
2.7.4


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

* [PATCH v2 net-next 5/5] ptp: clockmatrix: deprecate firmware older than 4.8.7
  2020-11-17 16:05 [PATCH v2 net-next 0/5] ptp_clockmatrix bug fix and improvement min.li.xe
                   ` (3 preceding siblings ...)
  2020-11-17 16:06 ` [PATCH v2 net-next 4/5] ptp: clockmatrix: Fix non-zero phase_adj is lost after snap min.li.xe
@ 2020-11-17 16:06 ` min.li.xe
  2020-11-17 20:44   ` kernel test robot
  4 siblings, 1 reply; 7+ messages in thread
From: min.li.xe @ 2020-11-17 16:06 UTC (permalink / raw)
  To: richardcochran; +Cc: netdev, linux-kernel, Min Li

From: Min Li <min.li.xe@renesas.com>

Add deprecated flag to indicate < v4.8.7.
Fix idtcm_enable_tod() call correct settime().

Signed-off-by: Min Li <min.li.xe@renesas.com>
---
 drivers/ptp/ptp_clockmatrix.c | 69 ++++++++++++++++++++++++-------------------
 drivers/ptp/ptp_clockmatrix.h | 11 +++----
 2 files changed, 45 insertions(+), 35 deletions(-)

diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index b10c6b9..007d3e0 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -939,8 +939,8 @@ static void restore_output_phase_adj(struct idtcm_channel *channel)
 	}
 }
 
-static int _idtcm_settime(struct idtcm_channel *channel,
-			  struct timespec64 const *ts)
+static int _idtcm_settime_deprecated(struct idtcm_channel *channel,
+				     struct timespec64 const *ts)
 {
 	struct idtcm *idtcm = channel->idtcm;
 	int retval;
@@ -965,9 +965,9 @@ static int _idtcm_settime(struct idtcm_channel *channel,
 	return retval;
 }
 
-static int _idtcm_settime_v487(struct idtcm_channel *channel,
-			       struct timespec64 const *ts,
-			       enum scsr_tod_write_type_sel wr_type)
+static int _idtcm_settime(struct idtcm_channel *channel,
+			  struct timespec64 const *ts,
+			  enum scsr_tod_write_type_sel wr_type)
 {
 	return _idtcm_set_dpll_scsr_tod(channel, ts,
 					SCSR_TOD_WR_TRIG_SEL_IMMEDIATE,
@@ -1109,14 +1109,14 @@ static int set_tod_write_overhead(struct idtcm_channel *channel)
 	return err;
 }
 
-static int _idtcm_adjtime(struct idtcm_channel *channel, s64 delta)
+static int _idtcm_adjtime_deprecated(struct idtcm_channel *channel, s64 delta)
 {
 	int err;
 	struct idtcm *idtcm = channel->idtcm;
 	struct timespec64 ts;
 	s64 now;
 
-	if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS) {
+	if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS_DEPRECATED) {
 		err = idtcm_do_phase_pull_in(channel, delta, 0);
 	} else {
 		idtcm->calculate_overhead_flag = 1;
@@ -1136,7 +1136,7 @@ static int _idtcm_adjtime(struct idtcm_channel *channel, s64 delta)
 
 		ts = ns_to_timespec64(now);
 
-		err = _idtcm_settime(channel, &ts);
+		err = _idtcm_settime_deprecated(channel, &ts);
 	}
 
 	return err;
@@ -1640,8 +1640,8 @@ static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
 	return err;
 }
 
-static int idtcm_settime(struct ptp_clock_info *ptp,
-			 const struct timespec64 *ts)
+static int idtcm_settime_deprecated(struct ptp_clock_info *ptp,
+				    const struct timespec64 *ts)
 {
 	struct idtcm_channel *channel =
 		container_of(ptp, struct idtcm_channel, caps);
@@ -1650,7 +1650,7 @@ static int idtcm_settime(struct ptp_clock_info *ptp,
 
 	mutex_lock(&idtcm->reg_lock);
 
-	err = _idtcm_settime(channel, ts);
+	err = _idtcm_settime_deprecated(channel, ts);
 
 	if (err)
 		dev_err(&idtcm->client->dev,
@@ -1663,7 +1663,7 @@ static int idtcm_settime(struct ptp_clock_info *ptp,
 	return err;
 }
 
-static int idtcm_settime_v487(struct ptp_clock_info *ptp,
+static int idtcm_settime(struct ptp_clock_info *ptp,
 			 const struct timespec64 *ts)
 {
 	struct idtcm_channel *channel =
@@ -1673,7 +1673,7 @@ static int idtcm_settime_v487(struct ptp_clock_info *ptp,
 
 	mutex_lock(&idtcm->reg_lock);
 
-	err = _idtcm_settime_v487(channel, ts, SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);
+	err = _idtcm_settime(channel, ts, SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);
 
 	if (err)
 		dev_err(&idtcm->client->dev,
@@ -1686,7 +1686,7 @@ static int idtcm_settime_v487(struct ptp_clock_info *ptp,
 	return err;
 }
 
-static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
+static int idtcm_adjtime_deprecated(struct ptp_clock_info *ptp, s64 delta)
 {
 	struct idtcm_channel *channel =
 		container_of(ptp, struct idtcm_channel, caps);
@@ -1695,7 +1695,7 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
 
 	mutex_lock(&idtcm->reg_lock);
 
-	err = _idtcm_adjtime(channel, delta);
+	err = _idtcm_adjtime_deprecated(channel, delta);
 
 	if (err)
 		dev_err(&idtcm->client->dev,
@@ -1708,7 +1708,7 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
 	return err;
 }
 
-static int idtcm_adjtime_v487(struct ptp_clock_info *ptp, s64 delta)
+static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
 {
 	struct idtcm_channel *channel =
 		container_of(ptp, struct idtcm_channel, caps);
@@ -1717,7 +1717,7 @@ static int idtcm_adjtime_v487(struct ptp_clock_info *ptp, s64 delta)
 	enum scsr_tod_write_type_sel type;
 	int err;
 
-	if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS_V487) {
+	if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS) {
 		err = idtcm_do_phase_pull_in(channel, delta, 0);
 		if (err)
 			dev_err(&idtcm->client->dev,
@@ -1737,7 +1737,7 @@ static int idtcm_adjtime_v487(struct ptp_clock_info *ptp, s64 delta)
 
 	mutex_lock(&idtcm->reg_lock);
 
-	err = _idtcm_settime_v487(channel, &ts, type);
+	err = _idtcm_settime(channel, &ts, type);
 
 	if (err)
 		dev_err(&idtcm->client->dev,
@@ -2081,10 +2081,14 @@ static int idtcm_enable_tod(struct idtcm_channel *channel)
 	if (err)
 		return err;
 
-	return _idtcm_settime(channel, &ts);
+	if (idtcm->deprecated)
+		return _idtcm_settime_deprecated(channel, &ts);
+	else
+		return _idtcm_settime(channel, &ts,
+				      SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);
 }
 
-static void idtcm_display_version_info(struct idtcm *idtcm)
+static void idtcm_set_version_info(struct idtcm *idtcm)
 {
 	u8 major;
 	u8 minor;
@@ -2106,31 +2110,36 @@ static void idtcm_display_version_info(struct idtcm *idtcm)
 	snprintf(idtcm->version, sizeof(idtcm->version), "%u.%u.%u",
 		 major, minor, hotfix);
 
+	if (idtcm_strverscmp(idtcm->version, "4.8.7") >= 0)
+		idtcm->deprecated = 0;
+	else
+		idtcm->deprecated = 1;
+
 	dev_info(&idtcm->client->dev, fmt, major, minor, hotfix,
 		 product_id, hw_rev_id, config_select);
 }
 
-static const struct ptp_clock_info idtcm_caps_v487 = {
+static const struct ptp_clock_info idtcm_caps = {
 	.owner		= THIS_MODULE,
 	.max_adj	= 244000,
 	.n_per_out	= 12,
 	.adjphase	= &idtcm_adjphase,
 	.adjfine	= &idtcm_adjfine,
-	.adjtime	= &idtcm_adjtime_v487,
+	.adjtime	= &idtcm_adjtime,
 	.gettime64	= &idtcm_gettime,
-	.settime64	= &idtcm_settime_v487,
+	.settime64	= &idtcm_settime,
 	.enable		= &idtcm_enable,
 };
 
-static const struct ptp_clock_info idtcm_caps = {
+static const struct ptp_clock_info idtcm_caps_deprecated = {
 	.owner		= THIS_MODULE,
 	.max_adj	= 244000,
 	.n_per_out	= 12,
 	.adjphase	= &idtcm_adjphase,
 	.adjfine	= &idtcm_adjfine,
-	.adjtime	= &idtcm_adjtime,
+	.adjtime	= &idtcm_adjtime_deprecated,
 	.gettime64	= &idtcm_gettime,
-	.settime64	= &idtcm_settime,
+	.settime64	= &idtcm_settime_deprecated,
 	.enable		= &idtcm_enable,
 };
 
@@ -2253,15 +2262,15 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
 
 	channel->idtcm = idtcm;
 
-	if (idtcm_strverscmp(idtcm->version, "4.8.7") >= 0)
-		channel->caps = idtcm_caps_v487;
+	if (idtcm->deprecated)
+		channel->caps = idtcm_caps_deprecated;
 	else
 		channel->caps = idtcm_caps;
 
 	snprintf(channel->caps.name, sizeof(channel->caps.name),
 		 "IDT CM TOD%u", index);
 
-	if (idtcm_strverscmp(idtcm->version, "4.8.7") >= 0) {
+	if (!idtcm->deprecated) {
 		err = idtcm_enable_tod_sync(channel);
 		if (err) {
 			dev_err(&idtcm->client->dev,
@@ -2360,7 +2369,7 @@ static int idtcm_probe(struct i2c_client *client,
 	mutex_init(&idtcm->reg_lock);
 	mutex_lock(&idtcm->reg_lock);
 
-	idtcm_display_version_info(idtcm);
+	idtcm_set_version_info(idtcm);
 
 	err = idtcm_load_firmware(idtcm, &client->dev);
 
diff --git a/drivers/ptp/ptp_clockmatrix.h b/drivers/ptp/ptp_clockmatrix.h
index 3790dfa..645de2c 100644
--- a/drivers/ptp/ptp_clockmatrix.h
+++ b/drivers/ptp/ptp_clockmatrix.h
@@ -45,11 +45,11 @@
 #define DEFAULT_TOD2_PTP_PLL		(2)
 #define DEFAULT_TOD3_PTP_PLL		(3)
 
-#define POST_SM_RESET_DELAY_MS		(3000)
-#define PHASE_PULL_IN_THRESHOLD_NS	(150000)
-#define PHASE_PULL_IN_THRESHOLD_NS_V487	(15000)
-#define TOD_WRITE_OVERHEAD_COUNT_MAX	(2)
-#define TOD_BYTE_COUNT			(11)
+#define POST_SM_RESET_DELAY_MS			(3000)
+#define PHASE_PULL_IN_THRESHOLD_NS_DEPRECATED	(150000)
+#define PHASE_PULL_IN_THRESHOLD_NS		(15000)
+#define TOD_WRITE_OVERHEAD_COUNT_MAX		(2)
+#define TOD_BYTE_COUNT				(11)
 
 #define PEROUT_ENABLE_OUTPUT_MASK	(0xdeadbeef)
 
@@ -132,6 +132,7 @@ struct idtcm {
 	u8			page_offset;
 	u8			tod_mask;
 	char			version[16];
+	u8			deprecated;
 
 	/* Overhead calculation for adjtime */
 	u8			calculate_overhead_flag;
-- 
2.7.4


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

* Re: [PATCH v2 net-next 5/5] ptp: clockmatrix: deprecate firmware older than 4.8.7
  2020-11-17 16:06 ` [PATCH v2 net-next 5/5] ptp: clockmatrix: deprecate firmware older than 4.8.7 min.li.xe
@ 2020-11-17 20:44   ` kernel test robot
  0 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2020-11-17 20:44 UTC (permalink / raw)
  To: min.li.xe, richardcochran; +Cc: kbuild-all, netdev, linux-kernel, Min Li

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

Hi,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/min-li-xe-renesas-com/ptp_clockmatrix-bug-fix-and-improvement/20201118-004135
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 72308ecbf33b145641aba61071be31a85ebfd92c
config: sparc-allyesconfig (attached as .config)
compiler: sparc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/2b6e446631ab9940f935bc0299d01cb323e35389
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review min-li-xe-renesas-com/ptp_clockmatrix-bug-fix-and-improvement/20201118-004135
        git checkout 2b6e446631ab9940f935bc0299d01cb323e35389
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sparc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In function 'idtcm_strverscmp',
       inlined from 'idtcm_set_version_info' at drivers/ptp/ptp_clockmatrix.c:2113:6,
       inlined from 'idtcm_probe' at drivers/ptp/ptp_clockmatrix.c:2372:2:
>> drivers/ptp/ptp_clockmatrix.c:147:2: warning: 'strncpy' output may be truncated copying 15 bytes from a string of length 15 [-Wstringop-truncation]
     147 |  strncpy(ver1, version1, 15);
         |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/strncpy +147 drivers/ptp/ptp_clockmatrix.c

3a6ba7dc7799355 Vincent Cheng 2019-10-31  134  
bdb09b91d9a2f66 Min Li        2020-11-17  135  static int idtcm_strverscmp(const char *version1, const char *version2)
7ea5fda2b1325e1 Min Li        2020-07-28  136  {
7ea5fda2b1325e1 Min Li        2020-07-28  137  	u8 num1;
7ea5fda2b1325e1 Min Li        2020-07-28  138  	u8 num2;
7ea5fda2b1325e1 Min Li        2020-07-28  139  	int result = 0;
bdb09b91d9a2f66 Min Li        2020-11-17  140  	char ver1[16];
bdb09b91d9a2f66 Min Li        2020-11-17  141  	char ver2[16];
bdb09b91d9a2f66 Min Li        2020-11-17  142  	char *cur1;
bdb09b91d9a2f66 Min Li        2020-11-17  143  	char *cur2;
bdb09b91d9a2f66 Min Li        2020-11-17  144  	char *next1;
bdb09b91d9a2f66 Min Li        2020-11-17  145  	char *next2;
bdb09b91d9a2f66 Min Li        2020-11-17  146  
bdb09b91d9a2f66 Min Li        2020-11-17 @147  	strncpy(ver1, version1, 15);
bdb09b91d9a2f66 Min Li        2020-11-17  148  	strncpy(ver2, version2, 15);
bdb09b91d9a2f66 Min Li        2020-11-17  149  	cur1 = ver1;
bdb09b91d9a2f66 Min Li        2020-11-17  150  	cur2 = ver2;
7ea5fda2b1325e1 Min Li        2020-07-28  151  
7ea5fda2b1325e1 Min Li        2020-07-28  152  	/* loop through each level of the version string */
7ea5fda2b1325e1 Min Li        2020-07-28  153  	while (result == 0) {
bdb09b91d9a2f66 Min Li        2020-11-17  154  		next1 = strchr(cur1, '.');
bdb09b91d9a2f66 Min Li        2020-11-17  155  		next2 = strchr(cur2, '.');
bdb09b91d9a2f66 Min Li        2020-11-17  156  
bdb09b91d9a2f66 Min Li        2020-11-17  157  		/* kstrtou8 could fail for dot */
bdb09b91d9a2f66 Min Li        2020-11-17  158  		if (next1) {
bdb09b91d9a2f66 Min Li        2020-11-17  159  			*next1 = '\0';
bdb09b91d9a2f66 Min Li        2020-11-17  160  			next1++;
bdb09b91d9a2f66 Min Li        2020-11-17  161  		}
bdb09b91d9a2f66 Min Li        2020-11-17  162  
bdb09b91d9a2f66 Min Li        2020-11-17  163  		if (next2) {
bdb09b91d9a2f66 Min Li        2020-11-17  164  			*next2 = '\0';
bdb09b91d9a2f66 Min Li        2020-11-17  165  			next2++;
bdb09b91d9a2f66 Min Li        2020-11-17  166  		}
bdb09b91d9a2f66 Min Li        2020-11-17  167  
7ea5fda2b1325e1 Min Li        2020-07-28  168  		/* extract leading version numbers */
bdb09b91d9a2f66 Min Li        2020-11-17  169  		if (kstrtou8(cur1, 10, &num1) < 0)
7ea5fda2b1325e1 Min Li        2020-07-28  170  			return -1;
7ea5fda2b1325e1 Min Li        2020-07-28  171  
bdb09b91d9a2f66 Min Li        2020-11-17  172  		if (kstrtou8(cur2, 10, &num2) < 0)
7ea5fda2b1325e1 Min Li        2020-07-28  173  			return -1;
7ea5fda2b1325e1 Min Li        2020-07-28  174  
7ea5fda2b1325e1 Min Li        2020-07-28  175  		/* if numbers differ, then set the result */
bdb09b91d9a2f66 Min Li        2020-11-17  176  		if (num1 < num2) {
7ea5fda2b1325e1 Min Li        2020-07-28  177  			result = -1;
bdb09b91d9a2f66 Min Li        2020-11-17  178  		} else if (num1 > num2) {
7ea5fda2b1325e1 Min Li        2020-07-28  179  			result = 1;
bdb09b91d9a2f66 Min Li        2020-11-17  180  		} else {
7ea5fda2b1325e1 Min Li        2020-07-28  181  			/* if numbers are the same, go to next level */
bdb09b91d9a2f66 Min Li        2020-11-17  182  			if (!next1 && !next2)
7ea5fda2b1325e1 Min Li        2020-07-28  183  				break;
bdb09b91d9a2f66 Min Li        2020-11-17  184  			else if (!next1) {
7ea5fda2b1325e1 Min Li        2020-07-28  185  				result = -1;
bdb09b91d9a2f66 Min Li        2020-11-17  186  			} else if (!next2) {
7ea5fda2b1325e1 Min Li        2020-07-28  187  				result = 1;
bdb09b91d9a2f66 Min Li        2020-11-17  188  			} else {
bdb09b91d9a2f66 Min Li        2020-11-17  189  				cur1 = next1;
bdb09b91d9a2f66 Min Li        2020-11-17  190  				cur2 = next2;
7ea5fda2b1325e1 Min Li        2020-07-28  191  			}
7ea5fda2b1325e1 Min Li        2020-07-28  192  		}
7ea5fda2b1325e1 Min Li        2020-07-28  193  	}
bdb09b91d9a2f66 Min Li        2020-11-17  194  
7ea5fda2b1325e1 Min Li        2020-07-28  195  	return result;
7ea5fda2b1325e1 Min Li        2020-07-28  196  }
7ea5fda2b1325e1 Min Li        2020-07-28  197  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67816 bytes --]

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

end of thread, other threads:[~2020-11-17 20:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-17 16:05 [PATCH v2 net-next 0/5] ptp_clockmatrix bug fix and improvement min.li.xe
2020-11-17 16:05 ` [PATCH v2 net-next 1/5] ptp: clockmatrix: bug fix for idtcm_strverscmp min.li.xe
2020-11-17 16:05 ` [PATCH v2 net-next 2/5] ptp: clockmatrix: reset device and check BOOT_STATUS min.li.xe
2020-11-17 16:06 ` [PATCH v2 net-next 3/5] ptp: clockmatrix: remove 5 second delay before entering write phase mode min.li.xe
2020-11-17 16:06 ` [PATCH v2 net-next 4/5] ptp: clockmatrix: Fix non-zero phase_adj is lost after snap min.li.xe
2020-11-17 16:06 ` [PATCH v2 net-next 5/5] ptp: clockmatrix: deprecate firmware older than 4.8.7 min.li.xe
2020-11-17 20:44   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).