drivers/net/ethernet/freescale/fec_ptp.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/freescale/fec_ptp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/freescale/fec_ptp.c- Extension
.c- Size
- 24611 bytes
- Lines
- 867
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitops.hlinux/clk.hlinux/delay.hlinux/errno.hlinux/etherdevice.hlinux/fec.hlinux/interrupt.hlinux/io.hlinux/ioport.hlinux/irq.hlinux/kernel.hlinux/module.hlinux/netdevice.hlinux/of.hlinux/of_net.hlinux/pci.hlinux/phy.hlinux/platform_device.hlinux/ptrace.hlinux/skbuff.hlinux/slab.hlinux/spinlock.hlinux/string.hlinux/workqueue.hfec.h
Detected Declarations
function Controllerfunction fec_ptp_enable_ppsfunction fec_ptp_pps_peroutfunction fec_ptp_pps_perout_handlerfunction fec_ptp_start_cyclecounterfunction fec_ptp_adjfinefunction fec_ptp_adjtimefunction fec_ptp_gettimefunction fec_ptp_settimefunction fec_ptp_pps_disablefunction fec_ptp_enablefunction fec_ptp_setfunction fec_ptp_getfunction fec_time_keepfunction fec_pps_interruptfunction fec_ptp_initfunction fec_ptp_save_statefunction fec_ptp_restore_statefunction fec_ptp_stop
Annotated Snippet
if (lhs >= rhs) {
corr_inc = i;
corr_period = div_u64(lhs, rhs);
break;
}
lhs += NSEC_PER_SEC;
}
/* Not found? Set it to high value - double speed
* correct in every clock step.
*/
if (i > fep->ptp_inc) {
corr_inc = fep->ptp_inc;
corr_period = 1;
}
if (neg_adj)
corr_ns = fep->ptp_inc - corr_inc;
else
corr_ns = fep->ptp_inc + corr_inc;
spin_lock_irqsave(&fep->tmreg_lock, flags);
tmp = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK;
tmp |= corr_ns << FEC_T_INC_CORR_OFFSET;
writel(tmp, fep->hwp + FEC_ATIME_INC);
corr_period = corr_period > 1 ? corr_period - 1 : corr_period;
writel(corr_period, fep->hwp + FEC_ATIME_CORR);
/* dummy read to update the timer. */
timecounter_read(&fep->tc);
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
return 0;
}
/**
* fec_ptp_adjtime
* @ptp: the ptp clock structure
* @delta: offset to adjust the cycle counter by
*
* adjust the timer by resetting the timecounter structure.
*/
static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct fec_enet_private *fep =
container_of(ptp, struct fec_enet_private, ptp_caps);
unsigned long flags;
spin_lock_irqsave(&fep->tmreg_lock, flags);
timecounter_adjtime(&fep->tc, delta);
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
return 0;
}
/**
* fec_ptp_gettime
* @ptp: the ptp clock structure
* @ts: timespec structure to hold the current time value
*
* read the timecounter and return the correct value on ns,
* after converting it into a struct timespec.
*/
static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
struct fec_enet_private *fep =
container_of(ptp, struct fec_enet_private, ptp_caps);
u64 ns;
unsigned long flags;
mutex_lock(&fep->ptp_clk_mutex);
/* Check the ptp clock */
if (!fep->ptp_clk_on) {
mutex_unlock(&fep->ptp_clk_mutex);
return -EINVAL;
}
spin_lock_irqsave(&fep->tmreg_lock, flags);
ns = timecounter_read(&fep->tc);
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
mutex_unlock(&fep->ptp_clk_mutex);
*ts = ns_to_timespec64(ns);
return 0;
}
/**
* fec_ptp_settime
* @ptp: the ptp clock structure
* @ts: the timespec containing the new time for the cycle counter
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/clk.h`, `linux/delay.h`, `linux/errno.h`, `linux/etherdevice.h`, `linux/fec.h`, `linux/interrupt.h`, `linux/io.h`.
- Detected declarations: `function Controller`, `function fec_ptp_enable_pps`, `function fec_ptp_pps_perout`, `function fec_ptp_pps_perout_handler`, `function fec_ptp_start_cyclecounter`, `function fec_ptp_adjfine`, `function fec_ptp_adjtime`, `function fec_ptp_gettime`, `function fec_ptp_settime`, `function fec_ptp_pps_disable`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.