arch/powerpc/platforms/powermac/feature.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powermac/feature.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/powermac/feature.c
Extension
.c
Size
81071 bytes
Lines
3022
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 feature_table_entry {
	unsigned int	selector;
	feature_call	function;
};

struct pmac_mb_def
{
	const char*			model_string;
	const char*			model_name;
	int				model_id;
	struct feature_table_entry*	features;
	unsigned long			board_flags;
};
static struct pmac_mb_def pmac_mb;

/*
 * Here are the chip specific feature functions
 */

#ifndef CONFIG_PPC64

static int simple_feature_tweak(struct device_node *node, int type, int reg,
				u32 mask, int value)
{
	struct macio_chip*	macio;
	unsigned long		flags;

	macio = macio_find(node, type);
	if (!macio)
		return -ENODEV;
	LOCK(flags);
	if (value)
		MACIO_BIS(reg, mask);
	else
		MACIO_BIC(reg, mask);
	(void)MACIO_IN32(reg);
	UNLOCK(flags);

	return 0;
}

static long ohare_htw_scc_enable(struct device_node *node, long param,
				 long value)
{
	struct macio_chip*	macio;
	unsigned long		chan_mask;
	unsigned long		fcr;
	unsigned long		flags;
	int			htw, trans;
	unsigned long		rmask;

	macio = macio_find(node, 0);
	if (!macio)
		return -ENODEV;
	if (of_node_name_eq(node, "ch-a"))
		chan_mask = MACIO_FLAG_SCCA_ON;
	else if (of_node_name_eq(node, "ch-b"))
		chan_mask = MACIO_FLAG_SCCB_ON;
	else
		return -ENODEV;

	htw = (macio->type == macio_heathrow || macio->type == macio_paddington
		|| macio->type == macio_gatwick);
	/* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
	trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
		 pmac_mb.model_id != PMAC_TYPE_YIKES);
	if (value) {
#ifdef CONFIG_ADB_PMU
		if ((param & 0xfff) == PMAC_SCC_IRDA)
			pmu_enable_irled(1);
#endif /* CONFIG_ADB_PMU */
		LOCK(flags);
		fcr = MACIO_IN32(OHARE_FCR);
		/* Check if scc cell need enabling */
		if (!(fcr & OH_SCC_ENABLE)) {
			fcr |= OH_SCC_ENABLE;
			if (htw) {
				/* Side effect: this will also power up the
				 * modem, but it's too messy to figure out on which
				 * ports this controls the transceiver and on which
				 * it controls the modem
				 */
				if (trans)
					fcr &= ~HRW_SCC_TRANS_EN_N;
				MACIO_OUT32(OHARE_FCR, fcr);
				fcr |= (rmask = HRW_RESET_SCC);
				MACIO_OUT32(OHARE_FCR, fcr);
			} else {
				fcr |= (rmask = OH_SCC_RESET);
				MACIO_OUT32(OHARE_FCR, fcr);

Annotation

Implementation Notes