summaryrefslogtreecommitdiff
path: root/drivers/ptp/ptp_ocp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-05-19 18:50:29 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2022-05-19 18:50:29 +0300
commitd904c8cc0302393640bc29ee62193f88ddc53126 (patch)
treea8c72d018d7bd0a9682a88d8e7199bfb306f52ae /drivers/ptp/ptp_ocp.c
parentf993aed406eaf968ba3867a76bb46c95336a33d0 (diff)
parentfbb3abdf2223cd0dfc07de85fe5a43ba7f435bdf (diff)
downloadlinux-d904c8cc0302393640bc29ee62193f88ddc53126.tar.xz
Merge tag 'net-5.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni: "Including fixes from can, xfrm and netfilter subtrees. Notably this reverts a recent TCP/DCCP netns-related change to address a possible UaF. Current release - regressions: - tcp: revert "tcp/dccp: get rid of inet_twsk_purge()" - xfrm: set dst dev to blackhole_netdev instead of loopback_dev in ifdown Previous releases - regressions: - netfilter: flowtable: fix TCP flow teardown - can: revert "can: m_can: pci: use custom bit timings for Elkhart Lake" - xfrm: check encryption module availability consistency - eth: vmxnet3: fix possible use-after-free bugs in vmxnet3_rq_alloc_rx_buf() - eth: mlx5: initialize flow steering during driver probe - eth: ice: fix crash when writing timestamp on RX rings Previous releases - always broken: - mptcp: fix checksum byte order - eth: lan966x: fix assignment of the MAC address - eth: mlx5: remove HW-GRO from reported features - eth: ftgmac100: disable hardware checksum on AST2600" * tag 'net-5.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (50 commits) net: bridge: Clear offload_fwd_mark when passing frame up bridge interface. ptp: ocp: change sysfs attr group handling selftests: forwarding: fix missing backslash netfilter: nf_tables: disable expression reduction infra netfilter: flowtable: move dst_check to packet path netfilter: flowtable: fix TCP flow teardown net: ftgmac100: Disable hardware checksum on AST2600 igb: skip phy status check where unavailable nfc: pn533: Fix buggy cleanup order mptcp: Do TCP fallback on early DSS checksum failure mptcp: fix checksum byte order net: af_key: check encryption module availability consistency net: af_key: add check for pfkey_broadcast in function pfkey_process net/mlx5: Drain fw_reset when removing device net/mlx5e: CT: Fix setting flow_source for smfs ct tuples net/mlx5e: CT: Fix support for GRE tuples net/mlx5e: Remove HW-GRO from reported features net/mlx5e: Properly block HW GRO when XDP is enabled net/mlx5e: Properly block LRO when XDP is enabled net/mlx5e: Block rx-gro-hw feature in switchdev mode ...
Diffstat (limited to 'drivers/ptp/ptp_ocp.c')
-rw-r--r--drivers/ptp/ptp_ocp.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
index dd45471f6780..860672d6a03c 100644
--- a/drivers/ptp/ptp_ocp.c
+++ b/drivers/ptp/ptp_ocp.c
@@ -300,7 +300,7 @@ struct ptp_ocp {
struct platform_device *spi_flash;
struct clk_hw *i2c_clk;
struct timer_list watchdog;
- const struct ocp_attr_group *attr_tbl;
+ const struct attribute_group **attr_group;
const struct ptp_ocp_eeprom_map *eeprom_map;
struct dentry *debug_root;
time64_t gnss_lost;
@@ -841,7 +841,7 @@ __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u32 adj_val)
}
static void
-ptp_ocp_adjtime_coarse(struct ptp_ocp *bp, u64 delta_ns)
+ptp_ocp_adjtime_coarse(struct ptp_ocp *bp, s64 delta_ns)
{
struct timespec64 ts;
unsigned long flags;
@@ -850,7 +850,8 @@ ptp_ocp_adjtime_coarse(struct ptp_ocp *bp, u64 delta_ns)
spin_lock_irqsave(&bp->lock, flags);
err = __ptp_ocp_gettime_locked(bp, &ts, NULL);
if (likely(!err)) {
- timespec64_add_ns(&ts, delta_ns);
+ set_normalized_timespec64(&ts, ts.tv_sec,
+ ts.tv_nsec + delta_ns);
__ptp_ocp_settime_locked(bp, &ts);
}
spin_unlock_irqrestore(&bp->lock, flags);
@@ -1836,6 +1837,42 @@ ptp_ocp_signal_init(struct ptp_ocp *bp)
}
static void
+ptp_ocp_attr_group_del(struct ptp_ocp *bp)
+{
+ sysfs_remove_groups(&bp->dev.kobj, bp->attr_group);
+ kfree(bp->attr_group);
+}
+
+static int
+ptp_ocp_attr_group_add(struct ptp_ocp *bp,
+ const struct ocp_attr_group *attr_tbl)
+{
+ int count, i;
+ int err;
+
+ count = 0;
+ for (i = 0; attr_tbl[i].cap; i++)
+ if (attr_tbl[i].cap & bp->fw_cap)
+ count++;
+
+ bp->attr_group = kcalloc(count + 1, sizeof(struct attribute_group *),
+ GFP_KERNEL);
+ if (!bp->attr_group)
+ return -ENOMEM;
+
+ count = 0;
+ for (i = 0; attr_tbl[i].cap; i++)
+ if (attr_tbl[i].cap & bp->fw_cap)
+ bp->attr_group[count++] = attr_tbl[i].group;
+
+ err = sysfs_create_groups(&bp->dev.kobj, bp->attr_group);
+ if (err)
+ bp->attr_group[0] = NULL;
+
+ return err;
+}
+
+static void
ptp_ocp_sma_init(struct ptp_ocp *bp)
{
u32 reg;
@@ -1904,7 +1941,6 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
bp->flash_start = 1024 * 4096;
bp->eeprom_map = fb_eeprom_map;
bp->fw_version = ioread32(&bp->image->version);
- bp->attr_tbl = fb_timecard_groups;
bp->fw_cap = OCP_CAP_BASIC;
ver = bp->fw_version & 0xffff;
@@ -1918,6 +1954,10 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
ptp_ocp_sma_init(bp);
ptp_ocp_signal_init(bp);
+ err = ptp_ocp_attr_group_add(bp, fb_timecard_groups);
+ if (err)
+ return err;
+
err = ptp_ocp_fb_set_pins(bp);
if (err)
return err;
@@ -3388,7 +3428,6 @@ ptp_ocp_complete(struct ptp_ocp *bp)
{
struct pps_device *pps;
char buf[32];
- int i, err;
if (bp->gnss_port != -1) {
sprintf(buf, "ttyS%d", bp->gnss_port);
@@ -3413,14 +3452,6 @@ ptp_ocp_complete(struct ptp_ocp *bp)
if (pps)
ptp_ocp_symlink(bp, pps->dev, "pps");
- for (i = 0; bp->attr_tbl[i].cap; i++) {
- if (!(bp->attr_tbl[i].cap & bp->fw_cap))
- continue;
- err = sysfs_create_group(&bp->dev.kobj, bp->attr_tbl[i].group);
- if (err)
- return err;
- }
-
ptp_ocp_debugfs_add_device(bp);
return 0;
@@ -3492,15 +3523,11 @@ static void
ptp_ocp_detach_sysfs(struct ptp_ocp *bp)
{
struct device *dev = &bp->dev;
- int i;
sysfs_remove_link(&dev->kobj, "ttyGNSS");
sysfs_remove_link(&dev->kobj, "ttyMAC");
sysfs_remove_link(&dev->kobj, "ptp");
sysfs_remove_link(&dev->kobj, "pps");
- if (bp->attr_tbl)
- for (i = 0; bp->attr_tbl[i].cap; i++)
- sysfs_remove_group(&dev->kobj, bp->attr_tbl[i].group);
}
static void
@@ -3510,6 +3537,7 @@ ptp_ocp_detach(struct ptp_ocp *bp)
ptp_ocp_debugfs_remove_device(bp);
ptp_ocp_detach_sysfs(bp);
+ ptp_ocp_attr_group_del(bp);
if (timer_pending(&bp->watchdog))
del_timer_sync(&bp->watchdog);
if (bp->ts0)