Exemple #1
0
irqreturn_t ptp_qoriq_isr(int irq, void *priv)
{
	struct ptp_qoriq *ptp_qoriq = priv;
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	struct ptp_clock_event event;
	u64 ns;
	u32 ack = 0, lo, hi, mask, val, irqs;

	spin_lock(&ptp_qoriq->lock);

	val = ptp_qoriq->read(&regs->ctrl_regs->tmr_tevent);
	mask = ptp_qoriq->read(&regs->ctrl_regs->tmr_temask);

	spin_unlock(&ptp_qoriq->lock);

	irqs = val & mask;

	if (irqs & ETS1) {
		ack |= ETS1;
		extts_clean_up(ptp_qoriq, 0, true);
	}

	if (irqs & ETS2) {
		ack |= ETS2;
		extts_clean_up(ptp_qoriq, 1, true);
	}

	if (irqs & ALM2) {
		ack |= ALM2;
		if (ptp_qoriq->alarm_value) {
			event.type = PTP_CLOCK_ALARM;
			event.index = 0;
			event.timestamp = ptp_qoriq->alarm_value;
			ptp_clock_event(ptp_qoriq->clock, &event);
		}
		if (ptp_qoriq->alarm_interval) {
			ns = ptp_qoriq->alarm_value + ptp_qoriq->alarm_interval;
			hi = ns >> 32;
			lo = ns & 0xffffffff;
			ptp_qoriq->write(&regs->alarm_regs->tmr_alarm2_l, lo);
			ptp_qoriq->write(&regs->alarm_regs->tmr_alarm2_h, hi);
			ptp_qoriq->alarm_value = ns;
		} else {
Exemple #2
0
static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
			  bool update_event)
{
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	struct ptp_clock_event event;
	void __iomem *reg_etts_l;
	void __iomem *reg_etts_h;
	u32 valid, stat, lo, hi;

	switch (index) {
	case 0:
		valid = ETS1_VLD;
		reg_etts_l = &regs->etts_regs->tmr_etts1_l;
		reg_etts_h = &regs->etts_regs->tmr_etts1_h;
		break;
	case 1:
		valid = ETS2_VLD;
		reg_etts_l = &regs->etts_regs->tmr_etts2_l;
		reg_etts_h = &regs->etts_regs->tmr_etts2_h;
		break;
	default:
		return -EINVAL;
	}

	event.type = PTP_CLOCK_EXTTS;
	event.index = index;

	do {
		lo = ptp_qoriq->read(reg_etts_l);
		hi = ptp_qoriq->read(reg_etts_h);

		if (update_event) {
			event.timestamp = ((u64) hi) << 32;
			event.timestamp |= lo;
			ptp_clock_event(ptp_qoriq->clock, &event);
		}

		stat = ptp_qoriq->read(&regs->ctrl_regs->tmr_stat);
	} while (ptp_qoriq->extts_fifo_support && (stat & valid));

	return 0;
}
Exemple #3
0
/**
 * ixgbe_ptp_check_pps_event
 * @adapter - the private adapter structure
 * @eicr - the interrupt cause register value
 *
 * This function is called by the interrupt routine when checking for
 * interrupts. It will check and handle a pps event.
 */
void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr)
{
	struct ixgbe_hw *hw = &adapter->hw;
	struct ptp_clock_event event;

	event.type = PTP_CLOCK_PPS;

	/* Make sure ptp clock is valid, and PPS event enabled */
	if (!adapter->ptp_clock ||
	    !(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED))
		return;

	switch (hw->mac.type) {
	case ixgbe_mac_X540:
		if (eicr & IXGBE_EICR_TIMESYNC)
			ptp_clock_event(adapter->ptp_clock, &event);
		break;
	default:
		break;
	}
}
/**
 * ixgbe_ptp_check_pps_event
 * @adapter: the private adapter structure
 * @eicr: the interrupt cause register value
 *
 * This function is called by the interrupt routine when checking for
 * interrupts. It will check and handle a pps event.
 */
void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter)
{
	struct ixgbe_hw *hw = &adapter->hw;
	struct ptp_clock_event event;

	event.type = PTP_CLOCK_PPS;

	/* this check is necessary in case the interrupt was enabled via some
	 * alternative means (ex. debug_fs). Better to check here than
	 * everywhere that calls this function.
	 */
	if (!adapter->ptp_clock)
		return;

	switch (hw->mac.type) {
	case ixgbe_mac_X540:
		ptp_clock_event(adapter->ptp_clock, &event);
		break;
	default:
		break;
	}
}