* [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).