summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2011-02-03 03:55:19 +0300
committerJohn Stultz <john.stultz@linaro.org>2011-02-04 00:02:18 +0300
commitac54cd2bd5b4db4f1c03392d63daf355627ea180 (patch)
tree32a1ff604bfebf873f6f586aceba16d1b565fe1a
parent83a06bf50bdf2074b9404951ff60e142d159d93b (diff)
downloadlinux-ac54cd2bd5b4db4f1c03392d63daf355627ea180.tar.xz
RTC: Fix rtc driver ioctl specific shortcutting
Some RTC drivers enable functionality directly via their ioctl method instead of using the generic ioctl handling code. With the recent virtualization of the RTC layer, its now important that the generic layer always be used. This patch moved the rtc driver ioctl method call to after the generic ioctl processing is done. This allows hardware specific features or ioctls to still function, while relying on the generic code for handling everything else. This patch on its own may more obviously break rtc drivers that implement the alarm irq enablement via their ioctl method instead of implementing the alarm_irq_eanble method. Those drivers will be fixed in a following patch. Additionaly, those drivers are already likely to not be functioning reliably without this patch. CC: Alessandro Zummo <a.zummo@towertech.it> CC: Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> CC: Thomas Gleixner <tglx@linutronix.de> Reported-by: Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> Tested-by: Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> Signed-off-by: John Stultz <john.stultz@linaro.org>
-rw-r--r--drivers/rtc/rtc-dev.c21
1 files changed, 7 insertions, 14 deletions
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 212b16edafc0..37c3cc1b3dd5 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -154,19 +154,7 @@ static long rtc_dev_ioctl(struct file *file,
if (err)
goto done;
- /* try the driver's ioctl interface */
- if (ops->ioctl) {
- err = ops->ioctl(rtc->dev.parent, cmd, arg);
- if (err != -ENOIOCTLCMD) {
- mutex_unlock(&rtc->ops_lock);
- return err;
- }
- }
-
- /* if the driver does not provide the ioctl interface
- * or if that particular ioctl was not implemented
- * (-ENOIOCTLCMD), we will try to emulate here.
- *
+ /*
* Drivers *SHOULD NOT* provide ioctl implementations
* for these requests. Instead, provide methods to
* support the following code, so that the RTC's main
@@ -329,7 +317,12 @@ static long rtc_dev_ioctl(struct file *file,
return err;
default:
- err = -ENOTTY;
+ /* Finally try the driver's ioctl interface */
+ if (ops->ioctl) {
+ err = ops->ioctl(rtc->dev.parent, cmd, arg);
+ if (err == -ENOIOCTLCMD)
+ err = -ENOTTY;
+ }
break;
}