summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/ti/cpts.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/ti/cpts.c')
-rw-r--r--drivers/net/ethernet/ti/cpts.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 8db9efdf1708..339796c87bf6 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -99,6 +99,7 @@ static void cpts_purge_txq(struct cpts *cpts)
*/
static int cpts_fifo_read(struct cpts *cpts, int match)
{
+ bool need_schedule = false;
struct cpts_event *event;
unsigned long flags;
int i, type = -1;
@@ -131,6 +132,8 @@ static int cpts_fifo_read(struct cpts *cpts, int match)
cpts->cc.mult = cpts->mult_new;
cpts->mult_new = 0;
}
+ if (!cpts->irq_poll)
+ complete(&cpts->ts_push_complete);
break;
case CPTS_EV_TX:
case CPTS_EV_RX:
@@ -139,6 +142,7 @@ static int cpts_fifo_read(struct cpts *cpts, int match)
list_del_init(&event->list);
list_add_tail(&event->list, &cpts->events);
+ need_schedule = true;
break;
case CPTS_EV_ROLL:
case CPTS_EV_HALF:
@@ -154,9 +158,18 @@ static int cpts_fifo_read(struct cpts *cpts, int match)
spin_unlock_irqrestore(&cpts->lock, flags);
+ if (!cpts->irq_poll && need_schedule)
+ ptp_schedule_worker(cpts->clock, 0);
+
return type == match ? 0 : -1;
}
+void cpts_misc_interrupt(struct cpts *cpts)
+{
+ cpts_fifo_read(cpts, -1);
+}
+EXPORT_SYMBOL_GPL(cpts_misc_interrupt);
+
static u64 cpts_systim_read(const struct cyclecounter *cc)
{
struct cpts *cpts = container_of(cc, struct cpts, cc);
@@ -169,6 +182,8 @@ static void cpts_update_cur_time(struct cpts *cpts, int match,
{
unsigned long flags;
+ reinit_completion(&cpts->ts_push_complete);
+
/* use spin_lock_irqsave() here as it has to run very fast */
spin_lock_irqsave(&cpts->lock, flags);
ptp_read_system_prets(sts);
@@ -177,8 +192,12 @@ static void cpts_update_cur_time(struct cpts *cpts, int match,
ptp_read_system_postts(sts);
spin_unlock_irqrestore(&cpts->lock, flags);
- if (cpts_fifo_read(cpts, match) && match != -1)
+ if (cpts->irq_poll && cpts_fifo_read(cpts, match) && match != -1)
dev_err(cpts->dev, "cpts: unable to obtain a time stamp\n");
+
+ if (!cpts->irq_poll &&
+ !wait_for_completion_timeout(&cpts->ts_push_complete, HZ))
+ dev_err(cpts->dev, "cpts: obtain a time stamp timeout\n");
}
/* PTP clock operations */
@@ -708,8 +727,10 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
cpts->dev = dev;
cpts->reg = (struct cpsw_cpts __iomem *)regs;
+ cpts->irq_poll = true;
spin_lock_init(&cpts->lock);
mutex_init(&cpts->ptp_clk_mutex);
+ init_completion(&cpts->ts_push_complete);
ret = cpts_of_parse(cpts, node);
if (ret)