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

📄 au1xxx_pm.patch

📁 patches for linux-2.6.
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+			ret = call_usermodehelper(modprobe_path_pm, argv, envp, 1);+			break;++		case AU1XXX_PM_WAKEUP:+			argv[2] = add;+			ret = call_usermodehelper(modprobe_path_pm, argv, envp, 1);+			break;++		case AU1XXX_PM_ACCESS:+			if (dev->cur_state != AWAKE_STATE) {+				/* do nothing */+			}+			else+				ret = -1;+			break;++		case AU1XXX_PM_GETSTATUS:+			ret = dev->cur_state;+			break;++		default:+		case AU1XXX_PM_IDLE:+		case AU1XXX_PM_CLEANUP:+			break;+	}++	return ret;+}+++/***********************************************************************+ *                     PROC INTERFACE FUNCTIONS+ ***********************************************************************/+static int proc_read(char *page, char **start, off_t off, +	int count, int *eof, void *data)+{+	int size = 0;+	int i;+	au1xxx_power_dev_t *power_dev = (au1xxx_power_dev_t *)data;+	struct au1xxx_pm_bin_header bin_hdr;+	au1xxx_pm_bin_header_t *bin_header = &bin_hdr;++	if (!power_dev->valid) {+		printk(KERN_ERR "Kernel Error: Attempted to read from an invalid power device.\n");+		return -EFAULT;+	}++	if (au1xxx_pm_setup->feedback_mode == ASCII_FEEDBACK) {+		/* print out the info on the current device */+		size = sprintf((page + size), "Device Name: %s\nPower State: %d\nDevice Status: %d\nPending Transitions: %d\nError Code: %d\n", +			power_dev->name, +			power_dev->cur_state, +			power_dev->callback(power_dev, AU1XXX_PM_GETSTATUS, NULL),+			power_dev->state_change_pending,+			power_dev->last_error);+	+		/* print all the devices' info if reading the system entry */+		if (power_dev == system_dev) {+			for (i = 1; i < MAX_SUPPORTED_DEVICES; i++) {+				if (sys_power_pointers[i]->valid) {+					size += sprintf((page + size), "-----------------------------\n");+					size += sprintf((page + size), "Device Name: %s\nPower State: %d\nDevice Status: %d\nPending Transitions: %d\nError Code: %d\n", +						sys_power_pointers[i]->name, +						sys_power_pointers[i]->cur_state, +						sys_power_pointers[i]->callback(sys_power_pointers[i], +							AU1XXX_PM_GETSTATUS, NULL),+						sys_power_pointers[i]->state_change_pending,+						sys_power_pointers[i]->last_error);+				}+			} 		}-		if (copy_from_user(buf, buffer, *len)) {-			spin_unlock_irqrestore(&pm_lock, flags);-			return -EFAULT;++		/* handle the buffer */+  	if (size <= off + count) +			*eof = 1;+  	*start = page + off;+  	size -= off;+  	if (size > count) +			size = count;+  	if (size < 0) +			size = 0;++	} else if (au1xxx_pm_setup->feedback_mode == BINARY_FEEDBACK) {+		DPRINTK("Starting BINARY_FEEDBACK output method\n");++		if (power_dev != system_dev) {+			/* copy a header for a single binary report */+			bin_header->report_type = AU1XXX_PM_DEVICE;+			bin_header->num_reports = 1;+			size = sizeof(au1xxx_pm_bin_header_t);+			memcpy(page, bin_header, size);++			/* copy the actual report */+			memcpy((page + size), power_dev, sizeof(au1xxx_pm_public_dev_t));+			size += sizeof(au1xxx_pm_public_dev_t);++			DPRINTK("report_type Size: %d\t\tValue: %d\n", sizeof(bin_header->report_type), (int) bin_header->report_type);+			DPRINTK("num_reports Size: %d\t\tValue: %d\n", sizeof(bin_header->num_reports), (int) bin_header->num_reports);+			DPRINTK("Total size returned: %d\n", size);+		} else {+			/* copy a header for a full system report */+			bin_header->report_type = AU1XXX_PM_DEVICE;+			bin_header->num_reports = MAX_SUPPORTED_DEVICES;+			size = sizeof(au1xxx_pm_bin_header_t);+			memcpy(page, bin_header, size);++			/* copy the full system report */+			for (i = 0; i < MAX_SUPPORTED_DEVICES; i++) {+				memcpy((page + size), sys_power_pointers[i], sizeof(au1xxx_pm_public_dev_t));+				size += sizeof(au1xxx_pm_public_dev_t);+			}+		}+	} else {+		/* reset feedback mode in the error case */+		printk(KERN_WARNING "Invalid power management feedback setting; resetting to default.\n");+		spin_lock_irqsave(&au1xxx_pm_lock, spin_lock_flags);+		au1xxx_pm_setup->feedback_mode = DEFAULT_FEEDBACK;+		spin_unlock_irqrestore(&au1xxx_pm_lock, spin_lock_flags);+		return -EFAULT;+	}++	return size;+}++static int proc_write(struct file *file, const char *buffer, +	unsigned long count, void *data)+{+	int len;+	int callback_ret_val;+	char data_in[MAX_POWER_CONF_LEN];+	au1xxx_power_dev_t *power_dev = (au1xxx_power_dev_t *)data;+	int power_level;++	DPRINTK("Entering proc_write\n");++	if (!power_dev->valid) {+		printk(KERN_ERR "Kernel Error: Attempted write to an invalid power device.\n");+		return -EFAULT;+	}++	if (count > MAX_POWER_CONF_LEN)+		len = MAX_POWER_CONF_LEN;+	else+		len = count;++	if (copy_from_user(data_in, buffer, len))+		return -EFAULT;++	if (au1xxx_pm_setup->feedback_mode == ASCII_FEEDBACK) {+		power_level = simple_strtoul(data_in, NULL, 0);+		DPRINTK("Used ASCII_FEEDBACK to get power_level of %d\n", power_level);+	} else if (au1xxx_pm_setup->feedback_mode == BINARY_FEEDBACK) {+		memcpy(&power_level, data_in, sizeof(int));+		DPRINTK("Used BINARY_FEEDBACK to get power_level of %d\n", power_level);+	} else {+		/* reset feedback mode in the error case */+		printk(KERN_WARNING "Invalid power management feedback setting; resetting to default.\n");+		spin_lock_irqsave(&au1xxx_pm_lock, spin_lock_flags);+		au1xxx_pm_setup->feedback_mode = DEFAULT_FEEDBACK;+		spin_unlock_irqrestore(&au1xxx_pm_lock, spin_lock_flags);+		return -EFAULT;+	}++	spin_lock_irqsave(&au1xxx_pm_lock, spin_lock_flags);+	if (power_level != SLEEP_STATE) {+		power_dev->prev_state = power_dev->cur_state;+		power_dev->prev_state_timestamp = power_dev->cur_state_timestamp;+		do_gettimeofday(&(power_dev->cur_state_timestamp));+		power_dev->cur_state = power_level;  +		power_dev->state_change_pending = TRUE;+		DPRINTK("Waking up %s device.\n", power_dev->name);+		callback_ret_val = power_dev->callback(power_dev, AU1XXX_PM_WAKEUP, &power_level);+		power_dev->state_change_pending = FALSE;+		power_dev->last_error = callback_ret_val;+	} else {+		power_dev->prev_state = power_dev->cur_state;+		power_dev->prev_state_timestamp = power_dev->cur_state_timestamp;+		do_gettimeofday(&(power_dev->cur_state_timestamp));+		power_dev->cur_state = power_level;+		power_dev->state_change_pending = TRUE;+		DPRINTK("Putting %s device to sleep.\n", power_dev->name);+		callback_ret_val = power_dev->callback(power_dev, AU1XXX_PM_SLEEP, &power_level);+		power_dev->state_change_pending = FALSE;+		power_dev->last_error = callback_ret_val;+	}+	spin_unlock_irqrestore(&au1xxx_pm_lock, spin_lock_flags);++	return len;+}++static int proc_read_settings(char *page, char **start, off_t off, +	int count, int *eof, void *data)+{+	int size = 0;++	if ((!au1xxx_pm_setup->valid) || +		(au1xxx_pm_setup != (au1xxx_pm_settings_t *)data))+	{+		printk(KERN_ERR "Kernel Error: Power Management settings are invalid.\n");+		return -EFAULT;+	}++	if (au1xxx_pm_setup->feedback_mode == ASCII_FEEDBACK) {+		size = sprintf((page + size), "Au1xxx Power Management Settings:\n");+		size += sprintf((page + size), "=================================\n");++		size += sprintf((page + size), "Current wakeup method is: ");+		if (au1xxx_pm_setup->wakeup_mode == GPIO_WAKEUP)  +			size += sprintf((page + size), "GPIO 5 controlled.\n");+		else if (au1xxx_pm_setup->wakeup_mode == TIMER_WAKEUP) {+			size += sprintf((page + size), "TOY timer controlled.\n");+			size += sprintf((page + size), "  Current sleep time: %d seconds.\n", +					au1xxx_pm_setup->sleep_time); 		}-		buf[*len] = 0;-		p = buf;-		val = simple_strtoul(p, &p, 0);-		if (val > MAX_CPU_FREQ) {-			spin_unlock_irqrestore(&pm_lock, flags);+		else+			size += sprintf((page + size), "invalid.\n");+	+		size += sprintf((page + size), "Current feedback method is: ");+		if (au1xxx_pm_setup->feedback_mode == ASCII_FEEDBACK)+			size += sprintf((page + size), "ASCII text file.\n");+		else if (au1xxx_pm_setup->feedback_mode == BINARY_FEEDBACK)+			size += sprintf((page + size), "Binary file.\n");+		else+			size += sprintf((page + size), "invalid.\n");++		/* handle the buffer */+  	if (size <= off + count) +			*eof = 1;+  	*start = page + off;+  	size -= off;+  	if (size > count) +			size = count;+  	if (size < 0) +			size = 0;+	} else if (au1xxx_pm_setup->feedback_mode == BINARY_FEEDBACK) {+		DPRINTK("Attempting to read settings via BINARY_FEEDBACK method.\n");+		memcpy((page + size), &au1xxx_pm_setup->wakeup_mode, sizeof(int));+		size += sizeof(int);+		memcpy((page + size), &au1xxx_pm_setup->sleep_time, size);+		size += sizeof(int);+		memcpy((page + size), &au1xxx_pm_setup->feedback_mode, size);+		size += sizeof(int);+	} else {+		/* reset feedback mode in the error case */+		printk(KERN_WARNING "Invalid power management feedback setting; resetting to default.\n");+		spin_lock_irqsave(&au1xxx_pm_lock, spin_lock_flags);+		au1xxx_pm_setup->feedback_mode = DEFAULT_FEEDBACK;+		spin_unlock_irqrestore(&au1xxx_pm_lock, spin_lock_flags);+		return -EFAULT;+	}++	return size;+}++static int proc_write_settings(struct file *file, const char *buffer, +	unsigned long count, void *data)+{+	int len, wakeup_int, feedback_int;+	unsigned int sleep_int;+	int size = 0;+	char data_in[MAX_POWER_CONF_LEN];+	struct { +		unsigned int wakeup_uns;+		unsigned int sleep_uns;+		unsigned int feedback_uns;+	} binary_reader;++	DPRINTK("Entering proc_write_settings\n");++	if ((!au1xxx_pm_setup->valid) ||+		(au1xxx_pm_setup != (au1xxx_pm_settings_t *)data))+	{+		printk(KERN_ERR "Kernel Error: Power Management settings are invalid.\n");+		return -EFAULT;+	}++	if (count > MAX_POWER_CONF_LEN)+		len = MAX_POWER_CONF_LEN;+	else+		len = count;++	DPRINTK("Doing copy_from_user with len: %d\n", len);+	if (copy_from_user(data_in, buffer, len))+		return -EFAULT;++	/* read in the thre values according to the feedback mode */+	if (au1xxx_pm_setup->feedback_mode == ASCII_FEEDBACK) {+		if (sscanf(data_in, "%d:%d, %u\n", &wakeup_int, &sleep_int, +					&feedback_int) != 3) {+			printk(KERN_ERR "Kernel Error: Cannot read new power management settings.\n"); 			return -EFAULT; 		}+	} else if (au1xxx_pm_setup->feedback_mode == BINARY_FEEDBACK) {+		DPRINTK("Attempting to write settings via BINARY_FEEDBACK method.\n");+		/* For some reason it doesn't work when you try and do this piece by piece+		 * so I've simply created a structure to do it all at once. */+		memcpy(&binary_reader, &data_in, sizeof(binary_reader));+		size = sizeof(binary_reader);+		wakeup_int = (int) binary_reader.wakeup_uns;+		sleep_int = (int) binary_reader.sleep_uns;+		feedback_int = (int) binary_reader.feedback_uns;+	} else {+		/* reset feedback mode in the error case */+		printk(KERN_WARNING "Invalid power management feedback setting; resetting to default.\n");+		spin_lock_irqsave(&au1xxx_pm_lock, spin_lock_flags);+		au1xxx_pm_setup->feedback_mode = DEFAULT_FEEDBACK;+		spin_unlock_irqrestore(&au1xxx_pm_lock, spin_lock_flags);+		return -EFAULT;+	}+	+	/* actually record the changes */+	spin_lock_irqsave(&au1xxx_pm_lock, spin_lock_flags);+	if (wakeup_int == GPIO_WAKEUP)+		au1xxx_pm_setup->wakeup_mode = GPIO_WAKEUP;+	else if (wakeup_int == TIMER_WAKEUP) {+		au1xxx_pm_setup->wakeup_mode = TIMER_WAKEUP;+		au1xxx_pm_setup->sleep_time = (int) sleep_int;+	}+	else {+		au1xxx_pm_setup->wakeup_mode = DEFAULT_WAKEUP;+		printk(KERN_WARNING "Invalid power management wakeup mode; resetting to default.\n");+	} -		pll = val / 12;-		if ((pll > 33) || (pll < 7)) {	/* 396 MHz max, 84 MHz min */-			/* revisit this for higher speed cpus */-			spin_unlock_irqrestore(&pm_lock, flags);+	if (feedback_int == ASCII_FEEDBACK)+		au1xxx_pm_setup->feedback_mode = ASCII_FEEDBACK;+	else if (feedback_int == BINARY_FEEDBACK)+		au1xxx_pm_setup->feedback_mode = BINARY_FEEDBACK;+	else {+		au1xxx_pm_setup->feedback_mode = DEFAULT_FEEDBACK;+		printk(KERN_WARNING "Invalid power management feedback mode; resetting to default.\n");+	}+	spin_unlock_irqrestore(&au1xxx_pm_lock, spin_lock_flags);++	return len;+}++static int proc_read_timer(char *page, char **start, off_t off, +	int count, int *eof, void *data)+{+	int size = 0;+	au1xxx_power_dev_t *dev = (au1xxx_power_dev_t *)data;+	au1xxx_pm_bin_header_t my_bin_hdr;++	if (au1xxx_pm_setup->feedback_mode == ASCII_FEEDBACK) {+		size += sprintf((page + size), "Timeout: %lu\n", dev->timeout);++		/* handle the buffer */+  	if (size <= off + count) +			*eof = 1;+  	*start = page + off;+  	size -= off;+  	if (size > count) +			size = count;+  	if (size < 0) +			size = 0;+	} else if (au1xxx_pm_setup->feedback_mode == BINARY_FEEDBACK) {+		my_bin_hdr.report_type = AU1XXX_PM_TIMEOUT;+		my_bin_hdr.num_reports = 1;+		memcpy((page + size), &my_bin_hdr, sizeof(au1xxx_pm_bin_header_t));+		size += sizeof(au1xxx_pm_bin_header_t);+		memcpy((page + size), &dev->timeout, sizeof(unsigned long));+		size += sizeof(unsigned long);+	} else {+		/* reset feedback mode in the error case */+		printk(KERN_WARNING "Invalid power management feedback setting; resetting to default.\n");+		spin_lock_irqsave(&au1xxx_pm_lock, spin_lock_flags);+		au1xxx_pm_setup->feedback_mode = DEFAULT_FEEDBACK;+		spin_unlock_irqrestore(&au1xxx_pm_lock, spin_lock_flags);+		return -EFAULT;+	}++	return size;+}++static int proc_write_timer(struct file *file, const char *buffer, +	unsigned long count, void *data)+{+	int len;+	unsigned long timeout_val = 0;+	int size = 0;

⌨️ 快捷键说明

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