arch/arm/mach-s3c/s3c64xx.c

Source file repositories/reference/linux-study-clean/arch/arm/mach-s3c/s3c64xx.c

File Facts

System
Linux kernel
Corpus path
arch/arm/mach-s3c/s3c64xx.c
Extension
.c
Size
10441 bytes
Lines
428
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern 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

static const struct bus_type s3c64xx_subsys = {
	.name		= "s3c64xx-core",
	.dev_name	= "s3c64xx-core",
};

static struct device s3c64xx_dev = {
	.bus	= &s3c64xx_subsys,
};

static struct samsung_pwm_variant s3c64xx_pwm_variant = {
	.bits		= 32,
	.div_base	= 0,
	.has_tint_cstat	= true,
	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
};

void __init s3c64xx_set_timer_source(enum s3c64xx_timer_mode event,
				     enum s3c64xx_timer_mode source)
{
	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
}

void __init s3c64xx_timer_init(void)
{
	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
	};

	samsung_pwm_clocksource_init(S3C_VA_TIMER,
					timer_irqs, &s3c64xx_pwm_variant);
}

/* read cpu identification code */

void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
{
	/* initialise the io descriptors we need for initialisation */
	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
	iotable_init(mach_desc, size);

	/* detect cpu id */
	s3c64xx_init_cpu();

	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));

	samsung_pwm_set_platdata(&s3c64xx_pwm_variant);
}

static __init int s3c64xx_dev_init(void)
{
	/* Not applicable when using DT. */
	if (of_have_populated_dt() || !soc_is_s3c64xx())
		return 0;

	subsys_system_register(&s3c64xx_subsys, NULL);
	return device_register(&s3c64xx_dev);
}
core_initcall(s3c64xx_dev_init);

/*
 * setup the sources the vic should advertise resume
 * for, even though it is not doing the wake
 * (set_irq_wake needs to be valid)
 */
#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) |	\
			 1 << (IRQ_PENDN - IRQ_VIC1_BASE) |	\
			 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) |	\
			 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) |	\
			 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE))

void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
{
	s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);

	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);

	/* initialise the pair of VICs */
	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
}

#define eint_offset(irq)	((irq) - IRQ_EINT(0))
#define eint_irq_to_bit(irq)	((u32)(1 << eint_offset(irq)))

static inline void s3c_irq_eint_mask(struct irq_data *data)
{
	u32 mask;

Annotation

Implementation Notes