From patchwork Fri Jan 11 21:10:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 14005 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 191D123FC8 for ; Fri, 11 Jan 2013 21:10:37 +0000 (UTC) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by fiordland.canonical.com (Postfix) with ESMTP id A4444A1851C for ; Fri, 11 Jan 2013 21:10:36 +0000 (UTC) Received: by mail-vc0-f173.google.com with SMTP id f13so1875616vcb.18 for ; Fri, 11 Jan 2013 13:10:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-received:from:to:subject:date:message-id:x-mailer :mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=XsJb8yc+pSNknWfoRhGDQxYENHu/qjGYFcDyIWdXzEM=; b=AHdh5VTpDqm0uk+3o63j9tjgxnQsH22vsYs6M3GR6TrxJtwdAJSX1l/iHIg0LQeqhU 5lbpBUD8VOYnC4Tm45m06l38JVd8HsfHnCvNA/jLDdj33BGWMm/jzTJd3RAi0P+7aOPA 42iydyikEys339qP0dGzGp4YiD/z/PIFNITPUz6ftMJQpQFnaio+pJSqjnrYs1+euh0P +Q0WL8BBEf3HGzYpfYksc7CeAB2kRrYDlv6umLDH1a8iym8lXhE0/n33zA/dNPCooHeF xvq9+w7bTgZC8zYqmvaNXyLRUC8ctX/rpKPRJauv5jyP4LuOB1E3EKloMGxWf9aCRiRP k+4A== X-Received: by 10.52.18.147 with SMTP id w19mr83666040vdd.94.1357938636155; Fri, 11 Jan 2013 13:10:36 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp132126veb; Fri, 11 Jan 2013 13:10:35 -0800 (PST) X-Received: by 10.68.251.136 with SMTP id zk8mr229338750pbc.82.1357938634750; Fri, 11 Jan 2013 13:10:34 -0800 (PST) Received: from mail-pb0-f48.google.com (mail-pb0-f48.google.com [209.85.160.48]) by mx.google.com with ESMTPS id b9si6417090pax.165.2013.01.11.13.10.34 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 11 Jan 2013 13:10:34 -0800 (PST) Received-SPF: neutral (google.com: 209.85.160.48 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=209.85.160.48; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.160.48 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) smtp.mail=john.stultz@linaro.org Received: by mail-pb0-f48.google.com with SMTP id rq13so1164635pbb.21 for ; Fri, 11 Jan 2013 13:10:34 -0800 (PST) X-Received: by 10.68.233.196 with SMTP id ty4mr233856702pbc.23.1357938633855; Fri, 11 Jan 2013 13:10:33 -0800 (PST) Received: from localhost.localdomain (c-24-21-54-107.hsd1.or.comcast.net. [24.21.54.107]) by mx.google.com with ESMTPS id t6sm3717845paz.11.2013.01.11.13.10.32 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 11 Jan 2013 13:10:33 -0800 (PST) From: John Stultz To: john.stultz@linaro.org Subject: [PATCH 1/2] staging: alarm-dev: Refactor alarm-dev ioctl code in prep for compat_ioctl Date: Fri, 11 Jan 2013 13:10:24 -0800 Message-Id: <1357938624-14519-1-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.7.10.4 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQneTsGbnNcK8HS13jn33pyYm97LRQ5p5qQ14girlugmsahRPiwo54tjgSOua4QNAa7f2k77 Cleanup the Android alarm-dev driver's ioctl code to refactor it in preparation for compat_ioctl support. Signed-off-by: John Stultz --- drivers/staging/android/alarm-dev.c | 242 +++++++++++++++++++++-------------- 1 file changed, 146 insertions(+), 96 deletions(-) diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index a9b293f..12c570d 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -96,18 +96,116 @@ static void devalarm_cancel(struct devalarm *alrm) hrtimer_cancel(&alrm->u.hrt); } +static void alarm_clear(enum android_alarm_type alarm_type) +{ + uint32_t alarm_type_mask = 1U << alarm_type; + unsigned long flags; -static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + spin_lock_irqsave(&alarm_slock, flags); + alarm_dbg(IO, "alarm %d clear\n", alarm_type); + devalarm_try_to_cancel(&alarms[alarm_type]); + if (alarm_pending) { + alarm_pending &= ~alarm_type_mask; + if (!alarm_pending && !wait_pending) + __pm_relax(&alarm_wake_lock); + } + alarm_enabled &= ~alarm_type_mask; + spin_unlock_irqrestore(&alarm_slock, flags); + +} + +static void alarm_set(enum android_alarm_type alarm_type, + struct timespec *ts) { - int rv = 0; + uint32_t alarm_type_mask = 1U << alarm_type; unsigned long flags; - struct timespec new_alarm_time; - struct timespec new_rtc_time; - struct timespec tmp_time; + + spin_lock_irqsave(&alarm_slock, flags); + alarm_dbg(IO, "alarm %d set %ld.%09ld\n", + alarm_type, ts->tv_sec, ts->tv_nsec); + alarm_enabled |= alarm_type_mask; + devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts)); + spin_unlock_irqrestore(&alarm_slock, flags); +} + +static int alarm_wait(void) +{ + unsigned long flags; + int rv = 0; + + spin_lock_irqsave(&alarm_slock, flags); + alarm_dbg(IO, "alarm wait\n"); + if (!alarm_pending && wait_pending) { + __pm_relax(&alarm_wake_lock); + wait_pending = 0; + } + spin_unlock_irqrestore(&alarm_slock, flags); + + rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); + if (rv) + return rv; + + spin_lock_irqsave(&alarm_slock, flags); + rv = alarm_pending; + wait_pending = 1; + alarm_pending = 0; + spin_unlock_irqrestore(&alarm_slock, flags); + + return rv; +} + +static int alarm_set_rtc(struct timespec *ts) +{ struct rtc_time new_rtc_tm; struct rtc_device *rtc_dev; + unsigned long flags; + int rv = 0; + + rtc_time_to_tm(ts->tv_sec, &new_rtc_tm); + rtc_dev = alarmtimer_get_rtcdev(); + rv = do_settimeofday(ts); + if (rv < 0) + return rv; + if (rtc_dev) + rv = rtc_set_time(rtc_dev, &new_rtc_tm); + + spin_lock_irqsave(&alarm_slock, flags); + alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; + wake_up(&alarm_wait_queue); + spin_unlock_irqrestore(&alarm_slock, flags); + + return rv; +} + +static int alarm_get_time(enum android_alarm_type alarm_type, + struct timespec *ts) +{ + int rv = 0; + + switch (alarm_type) { + case ANDROID_ALARM_RTC_WAKEUP: + case ANDROID_ALARM_RTC: + getnstimeofday(ts); + break; + case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: + case ANDROID_ALARM_ELAPSED_REALTIME: + get_monotonic_boottime(ts); + break; + case ANDROID_ALARM_SYSTEMTIME: + ktime_get_ts(ts); + break; + default: + rv = -EINVAL; + } + return rv; +} + +static long alarm_do_ioctl(struct file *file, unsigned int cmd, + struct timespec *ts) +{ + int rv = 0; + unsigned long flags; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); - uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; @@ -130,112 +228,64 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): - spin_lock_irqsave(&alarm_slock, flags); - alarm_dbg(IO, "alarm %d clear\n", alarm_type); - devalarm_try_to_cancel(&alarms[alarm_type]); - if (alarm_pending) { - alarm_pending &= ~alarm_type_mask; - if (!alarm_pending && !wait_pending) - __pm_relax(&alarm_wake_lock); - } - alarm_enabled &= ~alarm_type_mask; - spin_unlock_irqrestore(&alarm_slock, flags); + alarm_clear(alarm_type); break; case ANDROID_ALARM_SET_OLD: + case ANDROID_ALARM_SET(0): + alarm_set(alarm_type, ts); + break; case ANDROID_ALARM_SET_AND_WAIT_OLD: - if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { - rv = -EFAULT; - goto err1; - } - new_alarm_time.tv_nsec = 0; - goto from_old_alarm_set; - case ANDROID_ALARM_SET_AND_WAIT(0): - case ANDROID_ALARM_SET(0): - if (copy_from_user(&new_alarm_time, (void __user *)arg, - sizeof(new_alarm_time))) { - rv = -EFAULT; - goto err1; - } -from_old_alarm_set: - spin_lock_irqsave(&alarm_slock, flags); - alarm_dbg(IO, "alarm %d set %ld.%09ld\n", - alarm_type, - new_alarm_time.tv_sec, new_alarm_time.tv_nsec); - alarm_enabled |= alarm_type_mask; - devalarm_start(&alarms[alarm_type], - timespec_to_ktime(new_alarm_time)); - spin_unlock_irqrestore(&alarm_slock, flags); - if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) - && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) - break; + alarm_set(alarm_type, ts); /* fall though */ case ANDROID_ALARM_WAIT: - spin_lock_irqsave(&alarm_slock, flags); - alarm_dbg(IO, "alarm wait\n"); - if (!alarm_pending && wait_pending) { - __pm_relax(&alarm_wake_lock); - wait_pending = 0; - } - spin_unlock_irqrestore(&alarm_slock, flags); - rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); - if (rv) - goto err1; - spin_lock_irqsave(&alarm_slock, flags); - rv = alarm_pending; - wait_pending = 1; - alarm_pending = 0; - spin_unlock_irqrestore(&alarm_slock, flags); + rv = alarm_wait(); break; case ANDROID_ALARM_SET_RTC: - if (copy_from_user(&new_rtc_time, (void __user *)arg, - sizeof(new_rtc_time))) { - rv = -EFAULT; - goto err1; - } - rtc_time_to_tm(new_rtc_time.tv_sec, &new_rtc_tm); - rtc_dev = alarmtimer_get_rtcdev(); - rv = do_settimeofday(&new_rtc_time); - if (rv < 0) - goto err1; - if (rtc_dev) - rv = rtc_set_time(rtc_dev, &new_rtc_tm); - spin_lock_irqsave(&alarm_slock, flags); - alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; - wake_up(&alarm_wait_queue); - spin_unlock_irqrestore(&alarm_slock, flags); - if (rv < 0) - goto err1; + rv = alarm_set_rtc(ts); break; case ANDROID_ALARM_GET_TIME(0): - switch (alarm_type) { - case ANDROID_ALARM_RTC_WAKEUP: - case ANDROID_ALARM_RTC: - getnstimeofday(&tmp_time); - break; - case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: - case ANDROID_ALARM_ELAPSED_REALTIME: - get_monotonic_boottime(&tmp_time); - break; - case ANDROID_ALARM_SYSTEMTIME: - ktime_get_ts(&tmp_time); - break; - default: - rv = -EINVAL; - goto err1; - } - if (copy_to_user((void __user *)arg, &tmp_time, - sizeof(tmp_time))) { - rv = -EFAULT; - goto err1; - } + rv = alarm_get_time(alarm_type, ts); break; default: rv = -EINVAL; } -err1: + return rv; +} + +static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + + struct timespec ts; + int rv; + + switch (ANDROID_ALARM_BASE_CMD(cmd)) { + case ANDROID_ALARM_SET_OLD: + case ANDROID_ALARM_SET_AND_WAIT_OLD: + if (get_user(ts.tv_sec, (int __user *)arg)) + return -EFAULT; + + ts.tv_nsec = 0; + break; + case ANDROID_ALARM_SET_AND_WAIT(0): + case ANDROID_ALARM_SET(0): + case ANDROID_ALARM_SET_RTC: + if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) + return -EFAULT; + break; + } + + rv = alarm_do_ioctl(file, cmd, &ts); + + switch (ANDROID_ALARM_BASE_CMD(cmd)) { + case ANDROID_ALARM_GET_TIME(0): + if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) + return -EFAULT; + break; + } + return rv; }