summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/ptp/Kconfig2
-rw-r--r--drivers/ptp/Makefile4
-rw-r--r--drivers/ptp/ptp_clock.c69
-rw-r--r--drivers/ptp/ptp_netc.c25
-rw-r--r--drivers/ptp/ptp_qoriq.c24
-rw-r--r--drivers/ptp/ptp_qoriq_debugfs.c101
-rw-r--r--include/linux/fsl/ptp_qoriq.h10
-rw-r--r--include/linux/ptp_clock_kernel.h10
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(&regs->ctrl_regs->tmr_ctrl);
+ if (on)
+ tmr_ctrl |= loopback_bit;
+ else
+ tmr_ctrl &= ~loopback_bit;
+
+ ptp_qoriq->write(&regs->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(&regs->ctrl_regs->tmr_temask, 0);
ptp_qoriq->write(&regs->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(&regs->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(&regs->ctrl_regs->tmr_ctrl);
- if (val == 0)
- ctrl &= ~PP1L;
- else
- ctrl |= PP1L;
-
- ptp_qoriq->write(&regs->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(&regs->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(&regs->ctrl_regs->tmr_ctrl);
- if (val == 0)
- ctrl &= ~PP2L;
- else
- ctrl |= PP2L;
-
- ptp_qoriq->write(&regs->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;