arch/powerpc/sysdev/fsl_gtm.c

Source file repositories/reference/linux-study-clean/arch/powerpc/sysdev/fsl_gtm.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/sysdev/fsl_gtm.c
Extension
.c
Size
11786 bytes
Lines
435
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct gtm_timers_regs {
	u8	gtcfr1;		/* Timer 1, Timer 2 global config register */
	u8	res0[0x3];
	u8	gtcfr2;		/* Timer 3, timer 4 global config register */
	u8	res1[0xB];
	__be16	gtmdr1;		/* Timer 1 mode register */
	__be16	gtmdr2;		/* Timer 2 mode register */
	__be16	gtrfr1;		/* Timer 1 reference register */
	__be16	gtrfr2;		/* Timer 2 reference register */
	__be16	gtcpr1;		/* Timer 1 capture register */
	__be16	gtcpr2;		/* Timer 2 capture register */
	__be16	gtcnr1;		/* Timer 1 counter */
	__be16	gtcnr2;		/* Timer 2 counter */
	__be16	gtmdr3;		/* Timer 3 mode register */
	__be16	gtmdr4;		/* Timer 4 mode register */
	__be16	gtrfr3;		/* Timer 3 reference register */
	__be16	gtrfr4;		/* Timer 4 reference register */
	__be16	gtcpr3;		/* Timer 3 capture register */
	__be16	gtcpr4;		/* Timer 4 capture register */
	__be16	gtcnr3;		/* Timer 3 counter */
	__be16	gtcnr4;		/* Timer 4 counter */
	__be16	gtevr1;		/* Timer 1 event register */
	__be16	gtevr2;		/* Timer 2 event register */
	__be16	gtevr3;		/* Timer 3 event register */
	__be16	gtevr4;		/* Timer 4 event register */
	__be16	gtpsr1;		/* Timer 1 prescale register */
	__be16	gtpsr2;		/* Timer 2 prescale register */
	__be16	gtpsr3;		/* Timer 3 prescale register */
	__be16	gtpsr4;		/* Timer 4 prescale register */
	u8 res2[0x40];
} __attribute__ ((packed));

struct gtm {
	unsigned int clock;
	struct gtm_timers_regs __iomem *regs;
	struct gtm_timer timers[4];
	spinlock_t lock;
	struct list_head list_node;
};

static LIST_HEAD(gtms);

/**
 * gtm_get_timer16 - request GTM timer to use it with the rest of GTM API
 * Context:	non-IRQ
 *
 * This function reserves GTM timer for later use. It returns gtm_timer
 * structure to use with the rest of GTM API, you should use timer->irq
 * to manage timer interrupt.
 */
struct gtm_timer *gtm_get_timer16(void)
{
	struct gtm *gtm;
	int i;

	list_for_each_entry(gtm, &gtms, list_node) {
		spin_lock_irq(&gtm->lock);

		for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) {
			if (!gtm->timers[i].requested) {
				gtm->timers[i].requested = true;
				spin_unlock_irq(&gtm->lock);
				return &gtm->timers[i];
			}
		}

		spin_unlock_irq(&gtm->lock);
	}

	if (!list_empty(&gtms))
		return ERR_PTR(-EBUSY);
	return ERR_PTR(-ENODEV);
}
EXPORT_SYMBOL(gtm_get_timer16);

/**
 * gtm_get_specific_timer16 - request specific GTM timer
 * @gtm:	specific GTM, pass here GTM's device_node->data
 * @timer:	specific timer number, Timer1 is 0.
 * Context:	non-IRQ
 *
 * This function reserves GTM timer for later use. It returns gtm_timer
 * structure to use with the rest of GTM API, you should use timer->irq
 * to manage timer interrupt.
 */
struct gtm_timer *gtm_get_specific_timer16(struct gtm *gtm,
					   unsigned int timer)
{
	struct gtm_timer *ret = ERR_PTR(-EBUSY);

Annotation

Implementation Notes