drivers/net/ethernet/microchip/lan743x_ptp.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan743x_ptp.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/lan743x_ptp.c
Extension
.c
Size
51620 bytes
Lines
1797
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (event_channel == 0) {
			/* use channel A */
			gpio->gpio_cfg3 &= ~GPIO_CFG3_1588_CH_SEL_BIT_(pin);
		} else {
			/* use channel B */
			gpio->gpio_cfg3 |= GPIO_CFG3_1588_CH_SEL_BIT_(pin);
		}
		gpio->gpio_cfg3 |= GPIO_CFG3_1588_OE_BIT_(pin);
		lan743x_csr_write(adapter, GPIO_CFG3, gpio->gpio_cfg3);

		ret = pin;
	}
	spin_unlock_irqrestore(&gpio->gpio_lock, irq_flags);
	return ret;
}

static void lan743x_gpio_release(struct lan743x_adapter *adapter, int pin)
{
	struct lan743x_gpio *gpio = &adapter->gpio;
	unsigned long irq_flags = 0;
	int bit_mask = BIT(pin);

	spin_lock_irqsave(&gpio->gpio_lock, irq_flags);
	if (gpio->used_bits & bit_mask) {
		gpio->used_bits &= ~bit_mask;
		if (gpio->output_bits & bit_mask) {
			gpio->output_bits &= ~bit_mask;

			if (gpio->ptp_bits & bit_mask) {
				gpio->ptp_bits &= ~bit_mask;
				/* disable ptp output */
				gpio->gpio_cfg3 &= ~GPIO_CFG3_1588_OE_BIT_(pin);
				lan743x_csr_write(adapter, GPIO_CFG3,
						  gpio->gpio_cfg3);
			}
			/* release gpio output */

			/* disable gpio */
			gpio->gpio_cfg1 |= GPIO_CFG1_GPIOEN_BIT_(pin);
			gpio->gpio_cfg1 &= ~GPIO_CFG1_GPIOBUF_BIT_(pin);
			lan743x_csr_write(adapter, GPIO_CFG1, gpio->gpio_cfg1);

			/* reset back to input */
			gpio->gpio_cfg0 &= ~GPIO_CFG0_GPIO_DIR_BIT_(pin);
			gpio->gpio_cfg0 &= ~GPIO_CFG0_GPIO_DATA_BIT_(pin);
			lan743x_csr_write(adapter, GPIO_CFG0, gpio->gpio_cfg0);

			/* assign pin to original function */
			lan743x_led_mux_enable(adapter, pin, true);
		}
	}
	spin_unlock_irqrestore(&gpio->gpio_lock, irq_flags);
}

static int lan743x_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm)
{
	struct lan743x_ptp *ptp =
		container_of(ptpci, struct lan743x_ptp, ptp_clock_info);
	struct lan743x_adapter *adapter =
		container_of(ptp, struct lan743x_adapter, ptp);
	u32 lan743x_rate_adj = 0;
	u64 u64_delta;

	if ((scaled_ppm < (-LAN743X_PTP_MAX_FINE_ADJ_IN_SCALED_PPM)) ||
	    scaled_ppm > LAN743X_PTP_MAX_FINE_ADJ_IN_SCALED_PPM) {
		return -EINVAL;
	}

	/* diff_by_scaled_ppm returns true if the difference is negative */
	if (diff_by_scaled_ppm(1ULL << 35, scaled_ppm, &u64_delta))
		lan743x_rate_adj = (u32)u64_delta;
	else
		lan743x_rate_adj = (u32)u64_delta | PTP_CLOCK_RATE_ADJ_DIR_;

	lan743x_csr_write(adapter, PTP_CLOCK_RATE_ADJ,
			  lan743x_rate_adj);

	return 0;
}

static int lan743x_ptpci_adjtime(struct ptp_clock_info *ptpci, s64 delta)
{
	struct lan743x_ptp *ptp =
		container_of(ptpci, struct lan743x_ptp, ptp_clock_info);
	struct lan743x_adapter *adapter =
		container_of(ptp, struct lan743x_adapter, ptp);

	lan743x_ptp_clock_step(adapter, delta);

	return 0;

Annotation

Implementation Notes