From patchwork Fri Jan 11 23:46:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 14010 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 0C96923ED1 for ; Fri, 11 Jan 2013 23:46:39 +0000 (UTC) Received: from mail-vc0-f175.google.com (mail-vc0-f175.google.com [209.85.220.175]) by fiordland.canonical.com (Postfix) with ESMTP id A1151A18A08 for ; Fri, 11 Jan 2013 23:46:38 +0000 (UTC) Received: by mail-vc0-f175.google.com with SMTP id fy7so1954474vcb.20 for ; Fri, 11 Jan 2013 15:46:38 -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:cc:subject:date:message-id:x-mailer :in-reply-to:references:mime-version:content-type :content-transfer-encoding:x-gm-message-state; bh=xAa8MeMMmRPILX05+mDSW805ug244DqDuhB9JieKPbk=; b=nOPUYN4hU6QLhtUHNmyVLJvHIpJro5KV/Pk22W8fNLCxCb/SpI0RnMZzK8TNzenzh+ qlXyNjIE3wOY7sy2pj/FVFSIDIDEQycdD7AmUsV0GPlYM6nhggsfphheK+HtB0FZXlt+ 1aHjWzGMTUtloCXD05nnJDxR8fg1m6E166SYQzHKZpOqFkwjdRUWyPk4YlzVKnbP5W5R RM0kXVW7BR5l1de/l0Q7Zjwz6PmbbFDEN5lKxq3UKbSg1B6wHosTdUMth4F/uou8wM2w CyG1MdLbhK+8BSX4L9JJdWugIq3gFRyboyKbUcBRFoMCngGKzTI7z2WnJmjZAEfEfENv Sgtg== X-Received: by 10.220.238.139 with SMTP id ks11mr93706824vcb.49.1357947998085; Fri, 11 Jan 2013 15:46:38 -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 st5csp137218veb; Fri, 11 Jan 2013 15:46:37 -0800 (PST) X-Received: by 10.66.80.65 with SMTP id p1mr210599794pax.20.1357947996932; Fri, 11 Jan 2013 15:46:36 -0800 (PST) Received: from mail-pa0-f41.google.com (mail-pa0-f41.google.com [209.85.220.41]) by mx.google.com with ESMTPS id px7si6469190pbb.140.2013.01.11.15.46.36 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 11 Jan 2013 15:46:36 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.41 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=209.85.220.41; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.41 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-pa0-f41.google.com with SMTP id bj3so1285742pad.28 for ; Fri, 11 Jan 2013 15:46:36 -0800 (PST) X-Received: by 10.68.251.233 with SMTP id zn9mr56925582pbc.7.1357947996531; Fri, 11 Jan 2013 15:46:36 -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 ir4sm3558611pbc.41.2013.01.11.15.46.35 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 11 Jan 2013 15:46:35 -0800 (PST) From: John Stultz To: linux-kernel@vger.kernel.org Cc: John Stultz , Greg KH , Serban Constantinescu , =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= , Colin Cross , Android Kernel Team Subject: [RFC][PATCH 2/3] staging: alarm-dev: Refactor alarm-dev ioctl code in prep for compat_ioctl Date: Fri, 11 Jan 2013 15:46:23 -0800 Message-Id: <1357947984-15611-3-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1357947984-15611-1-git-send-email-john.stultz@linaro.org> References: <1357947984-15611-1-git-send-email-john.stultz@linaro.org> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQm4PDu8H+FOkAsyWOQOhmh/h0bdRz5NwY7rStJn2nm5WT/sMuJFLWcf3DGWK7xCwDtbssR0 Cleanup the Android alarm-dev driver's ioctl code to refactor it in preparation for compat_ioctl support. Cc: Greg KH Cc: Serban Constantinescu Cc: Arve Hjønnevåg Cc: Colin Cross Cc: Android Kernel Team Signed-off-by: John Stultz --- drivers/staging/android/alarm-dev.c | 228 +++++++++++++++++++++-------------- 1 file changed, 139 insertions(+), 89 deletions(-) diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index d423850..43af3b3 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -92,18 +92,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) +{ + uint32_t alarm_type_mask = 1U << alarm_type; + unsigned long flags; + + 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) { - int rv = 0; unsigned long flags; - struct timespec new_alarm_time; - struct timespec new_rtc_time; - struct timespec tmp_time; + 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; @@ -126,102 +224,54 @@ 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_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; - } - 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)) - break; + alarm_set(alarm_type, ts); + break; + case ANDROID_ALARM_SET_AND_WAIT(0): + 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_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; }