diff options
| -rw-r--r-- | MAINTAINERS | 1 | ||||
| -rw-r--r-- | drivers/ptp/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/ptp/Makefile | 4 | ||||
| -rw-r--r-- | drivers/ptp/ptp_clock.c | 69 | ||||
| -rw-r--r-- | drivers/ptp/ptp_netc.c | 25 | ||||
| -rw-r--r-- | drivers/ptp/ptp_qoriq.c | 24 | ||||
| -rw-r--r-- | drivers/ptp/ptp_qoriq_debugfs.c | 101 | ||||
| -rw-r--r-- | include/linux/fsl/ptp_qoriq.h | 10 | ||||
| -rw-r--r-- | include/linux/ptp_clock_kernel.h | 10 |
9 files changed, 128 insertions, 118 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index b81595e9ea95..e3907f0c1243 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9817,7 +9817,6 @@ F: drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp* F: drivers/net/ethernet/freescale/dpaa2/dprtc* F: drivers/net/ethernet/freescale/enetc/enetc_ptp.c F: drivers/ptp/ptp_qoriq.c -F: drivers/ptp/ptp_qoriq_debugfs.c F: include/linux/fsl/ptp_qoriq.h FREESCALE QUAD SPI DRIVER diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index 9256bf2e8ad4..5f8ea34d11d6 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig @@ -67,7 +67,7 @@ config PTP_1588_CLOCK_QORIQ packets using the SO_TIMESTAMPING API. To compile this driver as a module, choose M here: the module - will be called ptp-qoriq. + will be called ptp_qoriq. comment "Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks." depends on PHYLIB=n || NETWORK_PHY_TIMESTAMPING=n diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile index 8985d723d29c..bdc47e284f14 100644 --- a/drivers/ptp/Makefile +++ b/drivers/ptp/Makefile @@ -12,9 +12,7 @@ obj-$(CONFIG_PTP_1588_CLOCK_INES) += ptp_ines.o obj-$(CONFIG_PTP_1588_CLOCK_PCH) += ptp_pch.o obj-$(CONFIG_PTP_1588_CLOCK_KVM) += ptp_kvm.o obj-$(CONFIG_PTP_1588_CLOCK_VMCLOCK) += ptp_vmclock.o -obj-$(CONFIG_PTP_1588_CLOCK_QORIQ) += ptp-qoriq.o -ptp-qoriq-y += ptp_qoriq.o -ptp-qoriq-$(CONFIG_DEBUG_FS) += ptp_qoriq_debugfs.o +obj-$(CONFIG_PTP_1588_CLOCK_QORIQ) += ptp_qoriq.o obj-$(CONFIG_PTP_1588_CLOCK_IDTCM) += ptp_clockmatrix.o obj-$(CONFIG_PTP_1588_CLOCK_FC3W) += ptp_fc3.o obj-$(CONFIG_PTP_1588_CLOCK_IDT82P33) += ptp_idt82p33.o diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 5739a57958c7..1d920f8e20a8 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -248,6 +248,69 @@ static void ptp_aux_kworker(struct kthread_work *work) kthread_queue_delayed_work(ptp->kworker, &ptp->aux_work, delay); } +static ssize_t ptp_n_perout_loopback_read(struct file *filep, + char __user *buffer, + size_t count, loff_t *pos) +{ + struct ptp_clock *ptp = filep->private_data; + char buf[12] = {}; + + snprintf(buf, sizeof(buf), "%d\n", ptp->info->n_per_lp); + + return simple_read_from_buffer(buffer, count, pos, buf, strlen(buf)); +} + +static const struct file_operations ptp_n_perout_loopback_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ptp_n_perout_loopback_read, +}; + +static ssize_t ptp_perout_loopback_write(struct file *filep, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct ptp_clock *ptp = filep->private_data; + struct ptp_clock_info *ops = ptp->info; + unsigned int index, enable; + int len, cnt, err; + char buf[32] = {}; + + if (*ppos || !count) + return -EINVAL; + + if (count >= sizeof(buf)) + return -ENOSPC; + + len = simple_write_to_buffer(buf, sizeof(buf) - 1, + ppos, buffer, count); + if (len < 0) + return len; + + buf[len] = '\0'; + cnt = sscanf(buf, "%u %u", &index, &enable); + if (cnt != 2) + return -EINVAL; + + if (index >= ops->n_per_lp) + return -EINVAL; + + if (enable != 0 && enable != 1) + return -EINVAL; + + err = ops->perout_loopback(ops, index, enable); + if (err) + return err; + + return count; +} + +static const struct file_operations ptp_perout_loopback_ops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = ptp_perout_loopback_write, +}; + /* public interface */ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, @@ -389,6 +452,12 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, /* Debugfs initialization */ snprintf(debugfsname, sizeof(debugfsname), "ptp%d", ptp->index); ptp->debugfs_root = debugfs_create_dir(debugfsname, NULL); + if (info->n_per_lp > 0 && info->perout_loopback) { + debugfs_create_file("n_perout_loopback", 0400, ptp->debugfs_root, + ptp, &ptp_n_perout_loopback_fops); + debugfs_create_file("perout_loopback", 0200, ptp->debugfs_root, + ptp, &ptp_perout_loopback_ops); + } return ptp; diff --git a/drivers/ptp/ptp_netc.c b/drivers/ptp/ptp_netc.c index 8c5fea1f43fa..75594f47807d 100644 --- a/drivers/ptp/ptp_netc.c +++ b/drivers/ptp/ptp_netc.c @@ -21,6 +21,7 @@ #define TMR_ETEP(i) BIT(8 + (i)) #define TMR_COMP_MODE BIT(15) #define TMR_CTRL_TCLK_PERIOD GENMASK(25, 16) +#define TMR_CTRL_PPL(i) BIT(27 - (i)) #define TMR_CTRL_FS BIT(28) #define NETC_TMR_TEVENT 0x0084 @@ -609,6 +610,28 @@ static int netc_timer_enable(struct ptp_clock_info *ptp, } } +static int netc_timer_perout_loopback(struct ptp_clock_info *ptp, + unsigned int index, int on) +{ + struct netc_timer *priv = ptp_to_netc_timer(ptp); + unsigned long flags; + u32 tmr_ctrl; + + spin_lock_irqsave(&priv->lock, flags); + + tmr_ctrl = netc_timer_rd(priv, NETC_TMR_CTRL); + if (on) + tmr_ctrl |= TMR_CTRL_PPL(index); + else + tmr_ctrl &= ~TMR_CTRL_PPL(index); + + netc_timer_wr(priv, NETC_TMR_CTRL, tmr_ctrl); + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + static void netc_timer_adjust_period(struct netc_timer *priv, u64 period) { u32 fractional_period = lower_32_bits(period); @@ -717,6 +740,7 @@ static const struct ptp_clock_info netc_timer_ptp_caps = { .pps = 1, .n_per_out = 3, .n_ext_ts = 2, + .n_per_lp = 2, .supported_extts_flags = PTP_RISING_EDGE | PTP_FALLING_EDGE | PTP_STRICT_FLAGS, .adjfine = netc_timer_adjfine, @@ -724,6 +748,7 @@ static const struct ptp_clock_info netc_timer_ptp_caps = { .gettimex64 = netc_timer_gettimex64, .settime64 = netc_timer_settime64, .enable = netc_timer_enable, + .perout_loopback = netc_timer_perout_loopback, }; static void netc_timer_init(struct netc_timer *priv) diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c index 4d488c1f1941..8da995e36aeb 100644 --- a/drivers/ptp/ptp_qoriq.c +++ b/drivers/ptp/ptp_qoriq.c @@ -465,6 +465,25 @@ static int ptp_qoriq_auto_config(struct ptp_qoriq *ptp_qoriq, return 0; } +static int ptp_qoriq_perout_loopback(struct ptp_clock_info *ptp, + unsigned int index, int on) +{ + struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); + struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; + u32 loopback_bit = index ? PP2L : PP1L; + u32 tmr_ctrl; + + tmr_ctrl = ptp_qoriq->read(®s->ctrl_regs->tmr_ctrl); + if (on) + tmr_ctrl |= loopback_bit; + else + tmr_ctrl &= ~loopback_bit; + + ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl, tmr_ctrl); + + return 0; +} + int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base, const struct ptp_clock_info *caps) { @@ -479,6 +498,8 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base, ptp_qoriq->base = base; ptp_qoriq->caps = *caps; + ptp_qoriq->caps.n_per_lp = 2; + ptp_qoriq->caps.perout_loopback = ptp_qoriq_perout_loopback; if (of_property_read_u32(node, "fsl,cksel", &ptp_qoriq->cksel)) ptp_qoriq->cksel = DEFAULT_CKSEL; @@ -568,7 +589,7 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base, return PTR_ERR(ptp_qoriq->clock); ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock); - ptp_qoriq_create_debugfs(ptp_qoriq); + return 0; } EXPORT_SYMBOL_GPL(ptp_qoriq_init); @@ -580,7 +601,6 @@ void ptp_qoriq_free(struct ptp_qoriq *ptp_qoriq) ptp_qoriq->write(®s->ctrl_regs->tmr_temask, 0); ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl, 0); - ptp_qoriq_remove_debugfs(ptp_qoriq); ptp_clock_unregister(ptp_qoriq->clock); iounmap(ptp_qoriq->base); free_irq(ptp_qoriq->irq, ptp_qoriq); diff --git a/drivers/ptp/ptp_qoriq_debugfs.c b/drivers/ptp/ptp_qoriq_debugfs.c deleted file mode 100644 index e8dddcedf288..000000000000 --- a/drivers/ptp/ptp_qoriq_debugfs.c +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* Copyright 2019 NXP - */ -#include <linux/device.h> -#include <linux/debugfs.h> -#include <linux/fsl/ptp_qoriq.h> - -static int ptp_qoriq_fiper1_lpbk_get(void *data, u64 *val) -{ - struct ptp_qoriq *ptp_qoriq = data; - struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; - u32 ctrl; - - ctrl = ptp_qoriq->read(®s->ctrl_regs->tmr_ctrl); - *val = ctrl & PP1L ? 1 : 0; - - return 0; -} - -static int ptp_qoriq_fiper1_lpbk_set(void *data, u64 val) -{ - struct ptp_qoriq *ptp_qoriq = data; - struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; - u32 ctrl; - - ctrl = ptp_qoriq->read(®s->ctrl_regs->tmr_ctrl); - if (val == 0) - ctrl &= ~PP1L; - else - ctrl |= PP1L; - - ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl, ctrl); - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(ptp_qoriq_fiper1_fops, ptp_qoriq_fiper1_lpbk_get, - ptp_qoriq_fiper1_lpbk_set, "%llu\n"); - -static int ptp_qoriq_fiper2_lpbk_get(void *data, u64 *val) -{ - struct ptp_qoriq *ptp_qoriq = data; - struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; - u32 ctrl; - - ctrl = ptp_qoriq->read(®s->ctrl_regs->tmr_ctrl); - *val = ctrl & PP2L ? 1 : 0; - - return 0; -} - -static int ptp_qoriq_fiper2_lpbk_set(void *data, u64 val) -{ - struct ptp_qoriq *ptp_qoriq = data; - struct ptp_qoriq_registers *regs = &ptp_qoriq->regs; - u32 ctrl; - - ctrl = ptp_qoriq->read(®s->ctrl_regs->tmr_ctrl); - if (val == 0) - ctrl &= ~PP2L; - else - ctrl |= PP2L; - - ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl, ctrl); - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(ptp_qoriq_fiper2_fops, ptp_qoriq_fiper2_lpbk_get, - ptp_qoriq_fiper2_lpbk_set, "%llu\n"); - -void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq) -{ - struct dentry *root; - - root = debugfs_create_dir(dev_name(ptp_qoriq->dev), NULL); - if (IS_ERR(root)) - return; - if (!root) - goto err_root; - - ptp_qoriq->debugfs_root = root; - - if (!debugfs_create_file_unsafe("fiper1-loopback", 0600, root, - ptp_qoriq, &ptp_qoriq_fiper1_fops)) - goto err_node; - if (!debugfs_create_file_unsafe("fiper2-loopback", 0600, root, - ptp_qoriq, &ptp_qoriq_fiper2_fops)) - goto err_node; - return; - -err_node: - debugfs_remove_recursive(root); - ptp_qoriq->debugfs_root = NULL; -err_root: - dev_err(ptp_qoriq->dev, "failed to initialize debugfs\n"); -} - -void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq) -{ - debugfs_remove_recursive(ptp_qoriq->debugfs_root); - ptp_qoriq->debugfs_root = NULL; -} diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h index b301bf7199d3..3601e25779ba 100644 --- a/include/linux/fsl/ptp_qoriq.h +++ b/include/linux/fsl/ptp_qoriq.h @@ -145,7 +145,6 @@ struct ptp_qoriq { struct ptp_clock *clock; struct ptp_clock_info caps; struct resource *rsrc; - struct dentry *debugfs_root; struct device *dev; bool extts_fifo_support; bool fiper3_support; @@ -195,14 +194,5 @@ int ptp_qoriq_settime(struct ptp_clock_info *ptp, int ptp_qoriq_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *rq, int on); int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index, bool update_event); -#ifdef CONFIG_DEBUG_FS -void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq); -void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq); -#else -static inline void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq) -{ } -static inline void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq) -{ } -#endif #endif diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index 7dd7951b23d5..884364596dd3 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -67,6 +67,8 @@ struct ptp_system_timestamp { * @n_ext_ts: The number of external time stamp channels. * @n_per_out: The number of programmable periodic signals. * @n_pins: The number of programmable pins. + * @n_per_lp: The number of channels that support loopback the periodic + * output signal. * @pps: Indicates whether the clock supports a PPS callback. * * @supported_perout_flags: The set of flags the driver supports for the @@ -175,6 +177,11 @@ struct ptp_system_timestamp { * scheduling time (>=0) or negative value in case further * scheduling is not required. * + * @perout_loopback: Request driver to enable or disable the periodic output + * signal loopback. + * parameter index: index of the periodic output signal channel. + * parameter on: caller passes one to enable or zero to disable. + * * Drivers should embed their ptp_clock_info within a private * structure, obtaining a reference to it using container_of(). * @@ -189,6 +196,7 @@ struct ptp_clock_info { int n_ext_ts; int n_per_out; int n_pins; + int n_per_lp; int pps; unsigned int supported_perout_flags; unsigned int supported_extts_flags; @@ -213,6 +221,8 @@ struct ptp_clock_info { int (*verify)(struct ptp_clock_info *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan); long (*do_aux_work)(struct ptp_clock_info *ptp); + int (*perout_loopback)(struct ptp_clock_info *ptp, unsigned int index, + int on); }; struct ptp_clock; |
