Esempio n. 1
0
static int do_release(struct inode * inode, struct file * filp)
{
	struct apm_user *	as;

	as = filp->private_data;
	if (check_apm_user(as, "release"))
		return 0;
	filp->private_data = NULL;
	lock_kernel();
	if (as->suspends_pending > 0) {
		suspends_pending -= as->suspends_pending;
		if (suspends_pending <= 0)
			wake_up(&apm_suspend_waitqueue);
	}
	if (user_list == as)
		user_list = as->next;
	else {
		struct apm_user *	as1;

		for (as1 = user_list;
		     (as1 != NULL) && (as1->next != as);
		     as1 = as1->next)
			;
		if (as1 == NULL)
			printk(KERN_ERR "apm: filp not in user list\n");
		else
			as1->next = as->next;
	}
	unlock_kernel();
	kfree(as);
	return 0;
}
Esempio n. 2
0
static int do_release(struct inode * inode, struct file * filp)
{
	struct apm_user *	as;

	as = filp->private_data;
	if (check_apm_user(as, "release"))
		return 0;
	filp->private_data = NULL;
	lock_kernel();

	/*
	 * by zxf, 11/11/2002
	 * free memory malloced when open correctly
	 */
	if (user_list == as)
		user_list = as->next;
	else {
		struct apm_user *	as1;

		for (as1 = user_list;
		     (as1 != NULL) && (as1->next != as);
		     as1 = as1->next)
			;
		if (as1 == NULL)
			printk(KERN_ERR "apm: filp not in user list\n");
		else
			as1->next = as->next;
	}

	unlock_kernel();
	APM_DPRINTK("do_release: free mem at 0x%x\n", (unsigned int)as);
	kfree(as);
	return 0;
}
Esempio n. 3
0
static unsigned int do_poll(struct file *fp, poll_table * wait)
{
	struct apm_user * as;

	as = fp->private_data;
	if (check_apm_user(as, "poll"))
		return 0;
	poll_wait(fp, &apm_waitqueue, wait);
	if (!queue_empty(as))
		return POLLIN | POLLRDNORM;
	return 0;
}
Esempio n. 4
0
static ssize_t do_read(struct file *fp, char *buf, size_t count, loff_t *ppos)
{
	struct apm_user *	as;
	int			i;
	apm_event_t		event;
	DECLARE_WAITQUEUE(wait, current);

	as = fp->private_data;
	if (check_apm_user(as, "read"))
		return -EIO;
	if (count < sizeof(apm_event_t))
		return -EINVAL;
	if (queue_empty(as)) {
		if (fp->f_flags & O_NONBLOCK)
			return -EAGAIN;
		add_wait_queue(&apm_waitqueue, &wait);
repeat:
		set_current_state(TASK_INTERRUPTIBLE);
		if (queue_empty(as) && !signal_pending(current)) {
			schedule();
			goto repeat;
		}
		set_current_state(TASK_RUNNING);
		remove_wait_queue(&apm_waitqueue, &wait);
	}
	i = count;
	while ((i >= sizeof(event)) && !queue_empty(as)) {
		event = get_queued_event(as);
		DBG("apm_emu: do_read, returning: %s\n", apm_event_name[event-1]);
		if (copy_to_user(buf, &event, sizeof(event))) {
			if (i < count)
				break;
			return -EFAULT;
		}
		switch (event) {
		case APM_SYS_SUSPEND:
		case APM_USER_SUSPEND:
			as->suspends_read++;
			break;
		}
		buf += sizeof(event);
		i -= sizeof(event);
	}
	if (i < count)
		return count - i;
	if (signal_pending(current))
		return -ERESTARTSYS;
	return 0;
}
Esempio n. 5
0
static int do_ioctl(struct inode * inode, struct file *filp,
		    u_int cmd, u_long arg)
{
	struct apm_user *	as;
	DECLARE_WAITQUEUE(wait, current);

	as = filp->private_data;
	if (check_apm_user(as, "ioctl"))
		return -EIO;
	if (!as->suser)
		return -EPERM;
	switch (cmd) {
	case APM_IOC_SUSPEND:
		/* If a suspend message was sent to userland, we
		 * consider this as a confirmation message
		 */
		if (as->suspends_read > 0) {
			as->suspends_read--;
			as->suspends_pending--;
			suspends_pending--;
		} else {
			// Route to PMU suspend ?
			break;
		}
		as->suspend_waiting = 1;
		add_wait_queue(&apm_waitqueue, &wait);
		DBG("apm_emu: ioctl waking up sleep waiter !\n");
		wake_up(&apm_suspend_waitqueue);
		mb();
		while(as->suspend_waiting && !signal_pending(current)) {
			set_current_state(TASK_INTERRUPTIBLE);
			schedule();
		}
		set_current_state(TASK_RUNNING);
		remove_wait_queue(&apm_waitqueue, &wait);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
Esempio n. 6
0
static int do_ioctl(struct inode * inode, struct file *filp,
		    u_int cmd, u_long arg)
{
	struct apm_user *	as;
	struct pm_dev *		pm;
	struct ipm_config	conf;

	as = filp->private_data;
	if (check_apm_user(as, "ioctl"))
		return -EIO;

	memset(&conf, 0, sizeof(conf));

	switch (cmd) {
        case APM_IOC_SUSPEND:
		pm_do_suspend(CPUMODE_SLEEP);
		break;
        case APM_IOC_SET_WAKEUP:
		if ((pm = pm_find((pm_dev_t)arg,NULL)) == NULL)
			return -EINVAL;
		pm_send(pm,PM_SET_WAKEUP,NULL);
		break;
	case APM_IOC_SLEEP:
		pm_go_sleep(arg);
		break;
	case APM_IOC_SET_SPROF_WIN:
		sleep_to = arg * HZ;
		APM_DPRINTK("do_ioctl: sleep timeout %ld\n", arg);
		break;
	case APM_IOC_WAKEUP_ENABLE:
		PWER |= arg;
		APM_DPRINTK("do_ioctl: enable wakeup source:PWER=0x%x\n", PWER);
		break;
	case APM_IOC_WAKEUP_DISABLE:
		PWER &= ~arg;
		APM_DPRINTK("do_ioctl: disable wakeup source:PWER=0x%x\n", PWER);
		break;
	case APM_IOC_POWEROFF:
		APM_DPRINTK("do_ioctl: do power off\n");
		/* here all device should response ok */
		pm_send_all(PM_SUSPEND, (void *)3);
		pm_do_poweroff();
		pm_send_all(PM_RESUME, (void *)0);
		break;
	case APM_IOC_RESET_BP:
		APM_DPRINTK("do_ioctl: reset bp\n");
		GPCR(GPIO_BB_RESET) = GPIO_bit(GPIO_BB_RESET);
		mdelay(1);
		GPSR(GPIO_BB_RESET) = GPIO_bit(GPIO_BB_RESET);
		break;
	case APM_IOC_USEROFF_ENABLE:
		APM_DPRINTK("do_ioctl: useroff support enable\n");
		user_off_available = (int)arg;
		break;
	case APM_IOC_NOTIFY_BP:
                break;
        case APM_IOC_REFLASH:
                cpu_proc_fin();
                *(unsigned long *)(phys_to_virt(FLAG_ADDR)) = REFLASH_FLAG;

//		power_ic_periph_set_usb_pull_up(0);
//LIN           mdelay(1000);
//LIN let GPIO control the connectivity
#include <linux/power_ic.h>
		set_GPIO_mode(GPIO_USB_READY|GPIO_OUT);
		clr_GPIO(GPIO_USB_READY);
		power_ic_periph_set_usb_pull_up(0);
		mdelay(10);
		power_ic_set_reg_bit(POWER_IC_REG_EOC_CONN_CONTROL,19,1);//LIN set USB_CNTRL(bit19) to disable emu control
		mdelay(1000);
//LIN		power_ic_periph_set_usb_pull_up(1);

                /* Initialize the watchdog and let it fire */
                OWER = OWER_WME;
                OSSR = OSSR_M3;
		OSMR3 = OSCR + CLOCK_TICK_RATE/100;	/* ... in 10 ms */
                MDREFR |= MDREFR_SLFRSH;
		while(1);
                break;
        case APM_IOC_PASSTHRU:
                cpu_proc_fin();
                *(unsigned long *)(phys_to_virt(FLAG_ADDR)) = PASS_THRU_FLAG;

		power_ic_periph_set_usb_pull_up(0);
                mdelay(1000);
		power_ic_periph_set_usb_pull_up(1);

                /* Initialize the watchdog and let it fire */
                OWER = OWER_WME;
                OSSR = OSSR_M3;
		OSMR3 = OSCR + CLOCK_TICK_RATE/100;	/* ... in 10 ms */
                MDREFR |= MDREFR_SLFRSH;
		while(1);
                break;
	case APM_IOC_SET_IPROF_WIN:
		/* set profile window size */
		break;
	case APM_IOC_STARTPMU:
		if( pipm_start_pmu !=NULL )
			pipm_start_pmu();
		break;
	case APM_IOC_GET_IPM_CONFIG:
		get_ipm_config(&conf);
		return (copy_to_user((void *)arg, &conf,sizeof(conf)))? -EFAULT:0;
		break;
	case APM_IOC_SET_IPM_CONFIG:
		if(copy_from_user(&conf,(void *)arg,sizeof(conf)))
			return -EFAULT;
		
		return set_ipm_config(&conf);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}