⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 feature.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int i;	/* Save state & config of DBDMA channels */	for (i = 0; i < 13; i++) {		volatile struct dbdma_regs __iomem * chan = (void __iomem *)			(macio->base + ((0x8000+i*0x100)>>2));		save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);		save[i].cmdptr = in_le32(&chan->cmdptr);		save[i].intr_sel = in_le32(&chan->intr_sel);		save[i].br_sel = in_le32(&chan->br_sel);		save[i].wait_sel = in_le32(&chan->wait_sel);	}}static void dbdma_restore(struct macio_chip *macio, struct dbdma_regs *save){	int i;	/* Save state & config of DBDMA channels */	for (i = 0; i < 13; i++) {		volatile struct dbdma_regs __iomem * chan = (void __iomem *)			(macio->base + ((0x8000+i*0x100)>>2));		out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);		while (in_le32(&chan->status) & ACTIVE)			mb();		out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);		out_le32(&chan->cmdptr, save[i].cmdptr);		out_le32(&chan->intr_sel, save[i].intr_sel);		out_le32(&chan->br_sel, save[i].br_sel);		out_le32(&chan->wait_sel, save[i].wait_sel);	}}static void heathrow_sleep(struct macio_chip *macio, int secondary){	if (secondary) {		dbdma_save(macio, save_alt_dbdma);		save_fcr[2] = MACIO_IN32(0x38);		save_fcr[3] = MACIO_IN32(0x3c);	} else {		dbdma_save(macio, save_dbdma);		save_fcr[0] = MACIO_IN32(0x38);		save_fcr[1] = MACIO_IN32(0x3c);		save_mbcr = MACIO_IN32(0x34);		/* Make sure sound is shut down */		MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);		MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);		/* This seems to be necessary as well or the fan		 * keeps coming up and battery drains fast */		MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);		MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);		/* Make sure eth is down even if module or sleep		 * won't work properly */		MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);	}	/* Make sure modem is shut down */	MACIO_OUT8(HRW_GPIO_MODEM_RESET,		MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);	MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);	MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);	/* Let things settle */	(void)MACIO_IN32(HEATHROW_FCR);}static void heathrow_wakeup(struct macio_chip *macio, int secondary){	if (secondary) {		MACIO_OUT32(0x38, save_fcr[2]);		(void)MACIO_IN32(0x38);		mdelay(1);		MACIO_OUT32(0x3c, save_fcr[3]);		(void)MACIO_IN32(0x38);		mdelay(10);		dbdma_restore(macio, save_alt_dbdma);	} else {		MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);		(void)MACIO_IN32(0x38);		mdelay(1);		MACIO_OUT32(0x3c, save_fcr[1]);		(void)MACIO_IN32(0x38);		mdelay(1);		MACIO_OUT32(0x34, save_mbcr);		(void)MACIO_IN32(0x38);		mdelay(10);		dbdma_restore(macio, save_dbdma);	}}static long heathrow_sleep_state(struct device_node *node, long param,				 long value){	if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)		return -EPERM;	if (value == 1) {		if (macio_chips[1].type == macio_gatwick)			heathrow_sleep(&macio_chips[0], 1);		heathrow_sleep(&macio_chips[0], 0);	} else if (value == 0) {		heathrow_wakeup(&macio_chips[0], 0);		if (macio_chips[1].type == macio_gatwick)			heathrow_wakeup(&macio_chips[0], 1);	}	return 0;}static long core99_scc_enable(struct device_node *node, long param, long value){	struct macio_chip*	macio;	unsigned long		flags;	unsigned long		chan_mask;	u32			fcr;	macio = macio_find(node, 0);	if (!macio)		return -ENODEV;	if (!strcmp(node->name, "ch-a"))		chan_mask = MACIO_FLAG_SCCA_ON;	else if (!strcmp(node->name, "ch-b"))		chan_mask = MACIO_FLAG_SCCB_ON;	else		return -ENODEV;	if (value) {		int need_reset_scc = 0;		int need_reset_irda = 0;		LOCK(flags);		fcr = MACIO_IN32(KEYLARGO_FCR0);		/* Check if scc cell need enabling */		if (!(fcr & KL0_SCC_CELL_ENABLE)) {			fcr |= KL0_SCC_CELL_ENABLE;			need_reset_scc = 1;		}		if (chan_mask & MACIO_FLAG_SCCA_ON) {			fcr |= KL0_SCCA_ENABLE;			/* Don't enable line drivers for I2S modem */			if ((param & 0xfff) == PMAC_SCC_I2S1)				fcr &= ~KL0_SCC_A_INTF_ENABLE;			else				fcr |= KL0_SCC_A_INTF_ENABLE;		}		if (chan_mask & MACIO_FLAG_SCCB_ON) {			fcr |= KL0_SCCB_ENABLE;			/* Perform irda specific inits */			if ((param & 0xfff) == PMAC_SCC_IRDA) {				fcr &= ~KL0_SCC_B_INTF_ENABLE;				fcr |= KL0_IRDA_ENABLE;				fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;				fcr |= KL0_IRDA_SOURCE1_SEL;				fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);				fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);				need_reset_irda = 1;			} else				fcr |= KL0_SCC_B_INTF_ENABLE;		}		MACIO_OUT32(KEYLARGO_FCR0, fcr);		macio->flags |= chan_mask;		if (need_reset_scc)  {			MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);			(void)MACIO_IN32(KEYLARGO_FCR0);			UNLOCK(flags);			mdelay(15);			LOCK(flags);			MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);		}		if (need_reset_irda)  {			MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);			(void)MACIO_IN32(KEYLARGO_FCR0);			UNLOCK(flags);			mdelay(15);			LOCK(flags);			MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);		}		UNLOCK(flags);		if (param & PMAC_SCC_FLAG_XMON)			macio->flags |= MACIO_FLAG_SCC_LOCKED;	} else {		if (macio->flags & MACIO_FLAG_SCC_LOCKED)			return -EPERM;		LOCK(flags);		fcr = MACIO_IN32(KEYLARGO_FCR0);		if (chan_mask & MACIO_FLAG_SCCA_ON)			fcr &= ~KL0_SCCA_ENABLE;		if (chan_mask & MACIO_FLAG_SCCB_ON) {			fcr &= ~KL0_SCCB_ENABLE;			/* Perform irda specific clears */			if ((param & 0xfff) == PMAC_SCC_IRDA) {				fcr &= ~KL0_IRDA_ENABLE;				fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);				fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);				fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);			}		}		MACIO_OUT32(KEYLARGO_FCR0, fcr);		if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {			fcr &= ~KL0_SCC_CELL_ENABLE;			MACIO_OUT32(KEYLARGO_FCR0, fcr);		}		macio->flags &= ~(chan_mask);		UNLOCK(flags);		mdelay(10);	}	return 0;}static longcore99_modem_enable(struct device_node *node, long param, long value){	struct macio_chip*	macio;	u8			gpio;	unsigned long		flags;	/* Hack for internal USB modem */	if (node == NULL) {		if (macio_chips[0].type != macio_keylargo)			return -ENODEV;		node = macio_chips[0].of_node;	}	macio = macio_find(node, 0);	if (!macio)		return -ENODEV;	gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);	gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;	gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;	if (!value) {		LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);		UNLOCK(flags);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		mdelay(250);	}	LOCK(flags);	if (value) {		MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);		UNLOCK(flags);		(void)MACIO_IN32(KEYLARGO_FCR2);		mdelay(250);	} else {		MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);		UNLOCK(flags);	}	if (value) {		LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		UNLOCK(flags); mdelay(250); LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		UNLOCK(flags); mdelay(250); LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		UNLOCK(flags); mdelay(250);	}	return 0;}static longpangea_modem_enable(struct device_node *node, long param, long value){	struct macio_chip*	macio;	u8			gpio;	unsigned long		flags;	/* Hack for internal USB modem */	if (node == NULL) {		if (macio_chips[0].type != macio_pangea &&		    macio_chips[0].type != macio_intrepid)			return -ENODEV;		node = macio_chips[0].of_node;	}	macio = macio_find(node, 0);	if (!macio)		return -ENODEV;	gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);	gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;	gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;	if (!value) {		LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);		UNLOCK(flags);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		mdelay(250);	}	LOCK(flags);	if (value) {		MACIO_OUT8(KL_GPIO_MODEM_POWER,			KEYLARGO_GPIO_OUTPUT_ENABLE);		UNLOCK(flags);		(void)MACIO_IN32(KEYLARGO_FCR2);		mdelay(250);	} else {		MACIO_OUT8(KL_GPIO_MODEM_POWER,			KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);		UNLOCK(flags);	}	if (value) {		LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		UNLOCK(flags); mdelay(250); LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		UNLOCK(flags); mdelay(250); LOCK(flags);		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);		UNLOCK(flags); mdelay(250);	}	return 0;}static longcore99_ata100_enable(struct device_node *node, long value){	unsigned long flags;	struct pci_dev *pdev = NULL;	u8 pbus, pid;	int rc;	if (uninorth_rev < 0x24)		return -ENODEV;	LOCK(flags);	if (value)		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);	else		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);	(void)UN_IN(UNI_N_CLOCK_CNTL);	UNLOCK(flags);	udelay(20);	if (value) {		if (pci_device_from_OF_node(node, &pbus, &pid) == 0)			pdev = pci_get_bus_and_slot(pbus, pid);		if (pdev == NULL)			return 0;		rc = pci_enable_device(pdev);		if (rc == 0)			pci_set_master(pdev);		pci_dev_put(pdev);		if (rc)			return rc;	}	return 0;}static longcore99_ide_enable(struct device_node *node, long param, long value){	/* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2	 * based ata-100	 */	switch(param) {	    case 0:		return simple_feature_tweak(node, macio_unknown,			KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);	    case 1:		return simple_feature_tweak(node, macio_unknown,			KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);	    case 2:		return simple_feature_tweak(node, macio_unknown,			KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);	    case 3:		return core99_ata100_enable(node, value);	    default:		return -ENODEV;	}}static longcore99_ide_reset(struct device_node *node, long param, long value){	switch(param) {	    case 0:		return simple_feature_tweak(node, macio_unknown,			KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);	    case 1:		return simple_feature_tweak(node, macio_unknown,			KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);	    case 2:		return simple_feature_tweak(node, macio_unknown,			KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);	    default:		return -ENODEV;	}}static longcore99_gmac_enable(struct device_node *node, long param, long value){	unsigned long flags;	LOCK(flags);	if (value)		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);	else		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);	(void)UN_IN(UNI_N_CLOCK_CNTL);	UNLOCK(flags);	udelay(20);	return 0;}static longcore99_gmac_phy_reset(struct device_node *node, long param, long value){	unsigned long flags;	struct macio_chip *macio;	macio = &macio_chips[0];	if (macio->type != macio_keylargo && macio->type != macio_pangea &&	    macio->type != macio_intrepid)		return -ENODEV;	LOCK(flags);	MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);	(void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);	UNLOCK(flags);	mdelay(10);	LOCK(flags);	MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */		KEYLARGO_GPIO_OUTOUT_DATA);	UNLOCK(flags);	mdelay(10);	return 0;}static longcore99_sound_chip_enable(struct device_node *node, long param, long value){	struct macio_chip*	macio;	unsigned long		flags;	macio = macio_find(node, 0);	if (!macio)		return -ENODEV;	/* Do a better probe code, screamer G4 desktops &	 * iMacs can do that too, add a recalibrate  in	 * the driver as well	 */	if (pmac_mb.model_id == PMAC_TYPE_PISMO ||	    pmac_mb.model_id == PMAC_TYPE_TITANIUM) {		LOCK(flags);		if (value)			MACIO_OUT8(KL_GPIO_SOUND_POWER,				KEYLARGO_GPIO_OUTPUT_ENABLE |				KEYLARGO_GPIO_OUTOUT_DATA);		else			MACIO_OUT8(KL_GPIO_SOUND_POWER,				KEYLARGO_GPIO_OUTPUT_ENABLE);		(void)MACIO_IN8(KL_GPIO_SOUND_POWER);		UNLOCK(flags);	}	return 0;}static longcore99_airport_enable(struct device_node *node, long param, long value){	struct macio_chip*	macio;	unsigned long		flags;	int			state;	macio = macio_find(node, 0);	if (!macio)		return -ENODEV;	/* Hint: we allow passing of macio itself for the sake of the	 * sleep code	 */	if (node != macio->of_node &&	    (!node->parent || node->parent != macio->of_node))		return -ENODEV;	state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;	if (value == state)		return 0;	if (value) {		/* This code is a reproduction of OF enable-cardslot		 * and init-wireless methods, slightly hacked until		 * I got it working.		 */		LOCK(flags);		MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);		(void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);		UNLOCK(flags);		mdelay(10);		LOCK(flags);		MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -