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

📄 via-pmu.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
				break;		}	}recheck:	if (pmu_state == idle) {		if (adb_int_pending) {			if (int_data_state[0] == int_data_empty)				int_data_last = 0;			else if (int_data_state[1] == int_data_empty)				int_data_last = 1;			else				goto no_free_slot;			pmu_state = intack;			int_data_state[int_data_last] = int_data_fill;			/* Sounds safer to make sure ACK is high before writing.			 * This helped kill a problem with ADB and some iBooks			 */			wait_for_ack();			send_byte(PMU_INT_ACK);			adb_int_pending = 0;		} else if (current_req)			pmu_start();	}no_free_slot:				/* Mark the oldest buffer for flushing */	if (int_data_state[!int_data_last] == int_data_ready) {		int_data_state[!int_data_last] = int_data_flush;		int_data = !int_data_last;	} else if (int_data_state[int_data_last] == int_data_ready) {		int_data_state[int_data_last] = int_data_flush;		int_data = int_data_last;	}	--disable_poll;	spin_unlock_irqrestore(&pmu_lock, flags);	/* Deal with completed PMU requests outside of the lock */	if (req) {		pmu_done(req);		req = NULL;	}			/* Deal with interrupt datas outside of the lock */	if (int_data >= 0) {		pmu_handle_data(interrupt_data[int_data], interrupt_data_len[int_data], regs);		spin_lock_irqsave(&pmu_lock, flags);		++disable_poll;		int_data_state[int_data] = int_data_empty;		int_data = -1;		goto recheck;	}	return IRQ_RETVAL(handled);}void __pmacpmu_unlock(void){	unsigned long flags;	spin_lock_irqsave(&pmu_lock, flags);	if (pmu_state == locked)		pmu_state = idle;	adb_int_pending = 1;	spin_unlock_irqrestore(&pmu_lock, flags);}static irqreturn_t __pmacgpio1_interrupt(int irq, void *arg, struct pt_regs *regs){	unsigned long flags;	if ((in_8(gpio_reg + 0x9) & 0x02) == 0) {		spin_lock_irqsave(&pmu_lock, flags);		if (gpio_irq_enabled > 0) {			disable_irq_nosync(gpio_irq);			gpio_irq_enabled = 0;		}		pmu_irq_stats[1]++;		adb_int_pending = 1;		spin_unlock_irqrestore(&pmu_lock, flags);		via_pmu_interrupt(0, NULL, NULL);		return IRQ_HANDLED;	}	return IRQ_NONE;}#ifdef CONFIG_PMAC_BACKLIGHTstatic int backlight_to_bright[] __pmacdata = {	0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e,	0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e}; static int __openfirmwarepmu_set_backlight_enable(int on, int level, void* data){	struct adb_request req;		if (vias == NULL)		return -ENODEV;	if (on) {		pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT,			    backlight_to_bright[level]);		pmu_wait_complete(&req);	}	pmu_request(&req, NULL, 2, PMU_POWER_CTRL,		    PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF));       	pmu_wait_complete(&req);	return 0;}static void __openfirmwarepmu_bright_complete(struct adb_request *req){	if (req == &bright_req_1)		clear_bit(1, &async_req_locks);	if (req == &bright_req_2)		clear_bit(2, &async_req_locks);}static int __openfirmwarepmu_set_backlight_level(int level, void* data){	if (vias == NULL)		return -ENODEV;	if (test_and_set_bit(1, &async_req_locks))		return -EAGAIN;	pmu_request(&bright_req_1, pmu_bright_complete, 2, PMU_BACKLIGHT_BRIGHT,		backlight_to_bright[level]);	if (test_and_set_bit(2, &async_req_locks))		return -EAGAIN;	pmu_request(&bright_req_2, pmu_bright_complete, 2, PMU_POWER_CTRL,		    PMU_POW_BACKLIGHT | (level > BACKLIGHT_OFF ?					 PMU_POW_ON : PMU_POW_OFF));	return 0;}#endif /* CONFIG_PMAC_BACKLIGHT */void __pmacpmu_enable_irled(int on){	struct adb_request req;	if (vias == NULL)		return ;	if (pmu_kind == PMU_KEYLARGO_BASED)		return ;	pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |	    (on ? PMU_POW_ON : PMU_POW_OFF));	pmu_wait_complete(&req);}void __pmacpmu_restart(void){	struct adb_request req;	local_irq_disable();	drop_interrupts = 1;		if (pmu_kind != PMU_KEYLARGO_BASED) {		pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |						PMU_INT_TICK );		while(!req.complete)			pmu_poll();	}	pmu_request(&req, NULL, 1, PMU_RESET);	pmu_wait_complete(&req);	for (;;)		;}void __pmacpmu_shutdown(void){	struct adb_request req;	local_irq_disable();	drop_interrupts = 1;	if (pmu_kind != PMU_KEYLARGO_BASED) {		pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |						PMU_INT_TICK );		pmu_wait_complete(&req);	} else {		/* Disable server mode on shutdown or we'll just		 * wake up again		 */		pmu_set_server_mode(0);	}	pmu_request(&req, NULL, 5, PMU_SHUTDOWN,		    'M', 'A', 'T', 'T');	pmu_wait_complete(&req);	for (;;)		;}intpmu_present(void){	return via != 0;}struct pmu_i2c_hdr {	u8	bus;	u8	mode;	u8	bus2;	u8	address;	u8	sub_addr;	u8	comb_addr;	u8	count;};intpmu_i2c_combined_read(int bus, int addr, int subaddr,  u8* data, int len){	struct adb_request	req;	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];	int retry;	int rc;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		hdr->bus = bus;		hdr->address = addr & 0xfe;		hdr->mode = PMU_I2C_MODE_COMBINED;		hdr->bus2 = 0;		hdr->sub_addr = subaddr;		hdr->comb_addr = addr | 1;		hdr->count = len;				req.nbytes = sizeof(struct pmu_i2c_hdr) + 1;		req.reply_expected = 0;		req.reply_len = 0;		req.data[0] = PMU_I2C_CMD;		req.reply[0] = 0xff;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_OK)			break;		mdelay(15);	}	if (req.reply[0] != PMU_I2C_STATUS_OK)		return -1;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		mdelay(15);		hdr->bus = PMU_I2C_BUS_STATUS;		req.reply[0] = 0xff;				req.nbytes = 2;		req.reply_expected = 0;		req.reply_len = 0;		req.data[0] = PMU_I2C_CMD;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) {			memcpy(data, &req.reply[1], req.reply_len - 1);			return req.reply_len - 1;		}	}	return -1;}intpmu_i2c_stdsub_write(int bus, int addr, int subaddr,  u8* data, int len){	struct adb_request	req;	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];	int retry;	int rc;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		hdr->bus = bus;		hdr->address = addr & 0xfe;		hdr->mode = PMU_I2C_MODE_STDSUB;		hdr->bus2 = 0;		hdr->sub_addr = subaddr;		hdr->comb_addr = addr & 0xfe;		hdr->count = len;		req.data[0] = PMU_I2C_CMD;		memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len);		req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1;		req.reply_expected = 0;		req.reply_len = 0;		req.reply[0] = 0xff;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_OK)			break;		mdelay(15);	}	if (req.reply[0] != PMU_I2C_STATUS_OK)		return -1;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		mdelay(15);		hdr->bus = PMU_I2C_BUS_STATUS;		req.reply[0] = 0xff;				req.nbytes = 2;		req.reply_expected = 0;		req.reply_len = 0;		req.data[0] = PMU_I2C_CMD;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_OK)			return len;	}	return -1;}intpmu_i2c_simple_read(int bus, int addr,  u8* data, int len){	struct adb_request	req;	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];	int retry;	int rc;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		hdr->bus = bus;		hdr->address = addr | 1;		hdr->mode = PMU_I2C_MODE_SIMPLE;		hdr->bus2 = 0;		hdr->sub_addr = 0;		hdr->comb_addr = 0;		hdr->count = len;		req.data[0] = PMU_I2C_CMD;		req.nbytes = sizeof(struct pmu_i2c_hdr) + 1;		req.reply_expected = 0;		req.reply_len = 0;		req.reply[0] = 0xff;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_OK)			break;		mdelay(15);	}	if (req.reply[0] != PMU_I2C_STATUS_OK)		return -1;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		mdelay(15);		hdr->bus = PMU_I2C_BUS_STATUS;		req.reply[0] = 0xff;				req.nbytes = 2;		req.reply_expected = 0;		req.reply_len = 0;		req.data[0] = PMU_I2C_CMD;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) {			memcpy(data, &req.reply[1], req.reply_len - 1);			return req.reply_len - 1;		}	}	return -1;}intpmu_i2c_simple_write(int bus, int addr,  u8* data, int len){	struct adb_request	req;	struct pmu_i2c_hdr	*hdr = (struct pmu_i2c_hdr *)&req.data[1];	int retry;	int rc;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		hdr->bus = bus;		hdr->address = addr & 0xfe;		hdr->mode = PMU_I2C_MODE_SIMPLE;		hdr->bus2 = 0;		hdr->sub_addr = 0;		hdr->comb_addr = 0;		hdr->count = len;		req.data[0] = PMU_I2C_CMD;		memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len);		req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1;		req.reply_expected = 0;		req.reply_len = 0;		req.reply[0] = 0xff;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_OK)			break;		mdelay(15);	}	if (req.reply[0] != PMU_I2C_STATUS_OK)		return -1;	for (retry=0; retry<16; retry++) {		memset(&req, 0, sizeof(req));		mdelay(15);		hdr->bus = PMU_I2C_BUS_STATUS;		req.reply[0] = 0xff;				req.nbytes = 2;		req.reply_expected = 0;		req.reply_len = 0;		req.data[0] = PMU_I2C_CMD;		rc = pmu_queue_request(&req);		if (rc)			return rc;		while(!req.complete)			pmu_poll();		if (req.reply[0] == PMU_I2C_STATUS_OK)			return len;	}	return -1;}#ifdef CONFIG_PMAC_PBOOKstatic LIST_HEAD(sleep_notifiers);intpmu_register_sleep_notifier(struct pmu_sleep_notifier *n){	struct list_head *list;	struct pmu_sleep_notifier *notifier;	for (list = sleep_notifiers.next; list != &sleep_notifiers;	     list = list->next) {		notifier = list_entry(list, struct pmu_sleep_notifier, list);		if (n->priority > notifier->priority)			break;	}	__list_add(&n->list, list->prev, list);	return 0;}intpmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n){	if (n->list.next == 0)		return -ENOENT;	list_del(&n->list);	n->list.next = NULL;	return 0;}/* Sleep is broadcast last-to-first */static int __pmacbroadcast_sleep(int when, int fallback){	int ret = PBOOK_SLEEP_OK;	struct list_head *list;	struct pmu_sleep_notifier *notifier;	for (list = sleep_notifiers.prev; list != &sleep_notifiers;	     list = list->prev) {		notifier = list_entry(list, struct pmu_sleep_notifier, list);		ret = notifier->notifier_call(notifier, when);		if (ret != PBOOK_SLEEP_OK) {			printk(KERN_DEBUG "sleep %d rejected by %p (%p)\n",			       when, notifier, notifier->notifier_call);			for (; list != &sleep_notifiers; list = list->next) {				notifier = list_entry(list, struct pmu_sleep_notifier, list);				notifier->notifier_call(notifier, fallback);			}			return ret;		}	}	return ret;}/* Wake is broadcast first-to-last */static int __pmacbroadcast_wake(void){	int ret = PBOOK_SLEEP_OK;	struct list_head *list;	struct pmu_sleep_notifier *notifier;

⌨️ 快捷键说明

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