📄 patch-2.6.0-rmk2
字号:
+ DECLARE_WAITQUEUE(wait, current);+ unsigned long data;+ ssize_t ret;++ if (count < sizeof(unsigned long))+ return -EINVAL;++ add_wait_queue(&rtc_wait, &wait);+ do {+ __set_current_state(TASK_INTERRUPTIBLE);++ spin_lock_irq(&rtc_lock);+ data = rtc_irq_data;+ rtc_irq_data = 0;+ spin_unlock_irq(&rtc_lock);++ if (data != 0) {+ ret = 0;+ break;+ }+ if (file->f_flags & O_NONBLOCK) {+ ret = -EAGAIN;+ break;+ }+ if (signal_pending(current)) {+ ret = -ERESTARTSYS;+ break;+ }+ schedule();+ } while (1);+ set_current_state(TASK_RUNNING);+ remove_wait_queue(&rtc_wait, &wait);++ if (ret == 0) {+ ret = put_user(data, (unsigned long *)buf);+ if (ret == 0)+ ret = sizeof(unsigned long);+ }+ return ret;+}++static unsigned int rtc_poll(struct file *file, poll_table *wait)+{+ unsigned long data;++ poll_wait(file, &rtc_wait, wait);++ spin_lock_irq(&rtc_lock);+ data = rtc_irq_data;+ spin_unlock_irq(&rtc_lock);++ return data != 0 ? POLLIN | POLLRDNORM : 0;+}++static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,+ unsigned long arg)+{+ struct rtc_ops *ops = file->private_data;+ struct rtc_time tm;+ struct rtc_wkalrm alrm;+ int ret;++ switch (cmd) {+ case RTC_ALM_READ:+ rtc_read_alarm(ops, &alrm);+ ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm));+ if (ret)+ ret = -EFAULT;+ break;++ case RTC_ALM_SET:+ ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm));+ alrm.enabled = 0;+ alrm.pending = 0;+ alrm.time.tm_mday = -1;+ alrm.time.tm_mon = -1;+ alrm.time.tm_year = -1;+ alrm.time.tm_wday = -1;+ alrm.time.tm_yday = -1;+ alrm.time.tm_isdst = -1;+ if (ret == 0)+ ret = rtc_set_alarm(ops, &alrm);+ else+ ret = -EFAULT;+ break;++ case RTC_RD_TIME:+ rtc_read_time(ops, &tm);+ ret = copy_to_user((void *)arg, &tm, sizeof(tm));+ if (ret)+ ret = -EFAULT;+ break;++ case RTC_SET_TIME:+ if (!capable(CAP_SYS_TIME)) {+ ret = -EACCES;+ break;+ }+ ret = copy_from_user(&tm, (void *)arg, sizeof(tm));+ if (ret == 0)+ ret = rtc_set_time(ops, &tm);+ else+ ret = -EFAULT;+ break;++#ifndef rtc_epoch+ case RTC_EPOCH_SET:+ /*+ * There were no RTC clocks before 1900.+ */+ if (arg < 1900) {+ ret = -EINVAL;+ break;+ }+ if (!capable(CAP_SYS_TIME)) {+ ret = -EACCES;+ break;+ }+ rtc_epoch = arg;+ ret = 0;+ break;+#endif++ case RTC_EPOCH_READ:+ ret = put_user(rtc_epoch, (unsigned long *)arg);+ break;++ case RTC_WKALM_SET:+ ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm));+ if (ret == 0)+ ret = rtc_set_alarm(ops, &alrm);+ else+ ret = -EFAULT;+ break;++ case RTC_WKALM_RD:+ rtc_read_alarm(ops, &alrm);+ ret = copy_to_user((void *)arg, &alrm, sizeof(alrm));+ if (ret)+ ret = -EFAULT;+ break;++ default:+ ret = ops->ioctl(cmd, arg);+ }+ return ret;+}++static int rtc_open(struct inode *inode, struct file *file)+{+ int ret;++ down(&rtc_sem);++ if (rtc_inuse) {+ ret = -EBUSY;+ } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {+ ret = -ENODEV;+ } else {+ file->private_data = rtc_ops;++ ret = rtc_ops->open ? rtc_ops->open() : 0;+ if (ret == 0) {+ spin_lock_irq(&rtc_lock);+ rtc_irq_data = 0;+ spin_unlock_irq(&rtc_lock);++ rtc_inuse = 1;+ }+ }+ up(&rtc_sem);++ return ret;+}++static int rtc_release(struct inode *inode, struct file *file)+{+ struct rtc_ops *ops = file->private_data;++ if (ops->release)+ ops->release();++ spin_lock_irq(&rtc_lock);+ rtc_irq_data = 0;+ spin_unlock_irq(&rtc_lock);++ module_put(rtc_ops->owner);+ rtc_inuse = 0;++ return 0;+}++static int rtc_fasync(int fd, struct file *file, int on)+{+ return fasync_helper(fd, file, on, &rtc_async_queue);+}++static struct file_operations rtc_fops = {+ .owner = THIS_MODULE,+ .llseek = no_llseek,+ .read = rtc_read,+ .poll = rtc_poll,+ .ioctl = rtc_ioctl,+ .open = rtc_open,+ .release = rtc_release,+ .fasync = rtc_fasync,+};++static struct miscdevice rtc_miscdev = {+ .minor = RTC_MINOR,+ .name = "rtc",+ .fops = &rtc_fops,+};+++static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)+{+ struct rtc_ops *ops = data;+ struct rtc_wkalrm alrm;+ struct rtc_time tm;+ char *p = page;+ int len;++ rtc_read_time(ops, &tm);++ p += sprintf(p,+ "rtc_time\t: %02d:%02d:%02d\n"+ "rtc_date\t: %04d-%02d-%02d\n"+ "rtc_epoch\t: %04lu\n",+ tm.tm_hour, tm.tm_min, tm.tm_sec,+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,+ rtc_epoch);++ rtc_read_alarm(ops, &alrm);+ p += sprintf(p, "alrm_time\t: ");+ if ((unsigned int)alrm.time.tm_hour <= 24)+ p += sprintf(p, "%02d:", alrm.time.tm_hour);+ else+ p += sprintf(p, "**:");+ if ((unsigned int)alrm.time.tm_min <= 59)+ p += sprintf(p, "%02d:", alrm.time.tm_min);+ else+ p += sprintf(p, "**:");+ if ((unsigned int)alrm.time.tm_sec <= 59)+ p += sprintf(p, "%02d\n", alrm.time.tm_sec);+ else+ p += sprintf(p, "**\n");++ p += sprintf(p, "alrm_date\t: ");+ if ((unsigned int)alrm.time.tm_year <= 200)+ p += sprintf(p, "%04d-", alrm.time.tm_year + 1900);+ else+ p += sprintf(p, "****-");+ if ((unsigned int)alrm.time.tm_mon <= 11)+ p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);+ else+ p += sprintf(p, "**-");+ if ((unsigned int)alrm.time.tm_mday <= 31)+ p += sprintf(p, "%02d\n", alrm.time.tm_mday);+ else+ p += sprintf(p, "**\n");+ p += sprintf(p, "alrm_wakeup\t: %s\n", alrm.enabled ? "yes" : "no");+ p += sprintf(p, "alrm_pending\t: %s\n", alrm.pending ? "yes" : "no");++ if (ops->proc)+ p += ops->proc(p);++ len = (p - page) - off;+ if (len < 0)+ len = 0;+ *eof = len <= count;+ *start = page + off;++ return len;+}++int register_rtc(struct rtc_ops *ops)+{+ int ret = -EBUSY;++ down(&rtc_sem);+ if (rtc_ops == NULL) {+ rtc_ops = ops;++ ret = misc_register(&rtc_miscdev);+ if (ret == 0)+ create_proc_read_entry("driver/rtc", 0, 0,+ rtc_read_proc, ops);+ }+ up(&rtc_sem);++ return ret;+}++void unregister_rtc(struct rtc_ops *rtc)+{+ down(&rtc_sem);+ if (rtc == rtc_ops) {+ remove_proc_entry("driver/rtc", NULL);+ misc_deregister(&rtc_miscdev);+ rtc_ops = NULL;+ }+ up(&rtc_sem);+}++EXPORT_SYMBOL(rtc_time_to_tm);+EXPORT_SYMBOL(rtc_tm_to_time);+EXPORT_SYMBOL(rtc_update);+EXPORT_SYMBOL(register_rtc);+EXPORT_SYMBOL(unregister_rtc);diff -urN orig/arch/arm/common/sa1111.c linux/arch/arm/common/sa1111.c--- orig/arch/arm/common/sa1111.c Sun Sep 28 09:53:47 2003+++ linux/arch/arm/common/sa1111.c Sat Sep 20 10:16:17 2003@@ -824,6 +824,8 @@ if (level != SUSPEND_DISABLE) return 0; + BUG_ON(dev->saved_state);+ dev->saved_state = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); if (!dev->saved_state) return -ENOMEM;@@ -940,15 +942,12 @@ static int sa1111_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev);- struct resource *mem = NULL, *irq = NULL;- int i;+ struct resource *mem, *irq = NULL;++ mem = &pdev->resource[0];+ if (pdev->num_resources == 2)+ irq = &pdev->resource[1]; - for (i = 0; i < pdev->num_resources; i++) {- if (pdev->resource[i].flags & IORESOURCE_MEM)- mem = &pdev->resource[i];- if (pdev->resource[i].flags & IORESOURCE_IRQ)- irq = &pdev->resource[i];- } return __sa1111_probe(dev, mem, irq ? irq->start : NO_IRQ); } @@ -1096,6 +1095,139 @@ return __sa1111_pll_clock(sachip) / (256 * div); } +/**+ * sa1111_pwm_enable - enable a PWM channel+ * @channel: PWM channel+ */+void sa1111_pwm_enable(int channel)+{+ struct sa1111 *sachip = g_sa1111;+ unsigned long flags;+ unsigned int val;+ char *reg = sachip->base;++ switch (channel) {+ case 0:+ reg += SA1111_SKPEN0;+ break;+ case 1:+ reg += SA1111_SKPEN1;+ break;+ default:+ return;+ }+ sa1111_writel(1, reg);++ spin_lock_irqsave(&sachip->lock, flags);+ val = sa1111_readl(sachip->base + SA1111_SKPCR);+ sa1111_writel(val | SKPCR_PWMCLKEN, sachip->base + SA1111_SKPCR);+ spin_unlock_irqrestore(&sachip->lock, flags);+}++/**+ * sa1111_pwm_disable - disable a PWM channel+ * @channel: PWM channel+ */+void sa1111_pwm_disable(int channel)+{+ struct sa1111 *sachip = g_sa1111;+ char *reg = sachip->base;++ switch (channel) {+ case 0:+ reg += SA1111_SKPEN0;+ break;+ case 1:+ reg += SA1111_SKPEN1;+ break;+ default:+ return;+ }+ sa1111_writel(0, reg);+}++/**+ * sa1111_pwm_dutycycle - set the PWM duty cycle+ * @channel: PWM channel+ * @duty: duty cycle, 0 to 127+ *+ * Note: the duty cycle is preserved over a sleep,+ * however, the enable is NOT preserved.+ */+void sa1111_pwm_dutycycle(int channel, int duty)+{+ struct sa1111 *sachip = g_sa1111;+ char *reg = sachip->base;++ switch (channel) {+ case 0:+ reg += SA1111_SKPWM0;+ break;+ case 1:+ reg += SA1111_SKPWM1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -