From patchwork Mon Jun 27 11:43:26 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: MyungJoo Ham X-Patchwork-Id: 920502 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5RBncol016606 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 27 Jun 2011 11:50:01 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QbAJk-0001Ee-Cj; Mon, 27 Jun 2011 11:49:28 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QbAEy-00058K-4x; Mon, 27 Jun 2011 11:44:32 +0000 Received: from mailout4.samsung.com ([203.254.224.34]) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QbAE5-0004xf-Vn for linux-arm-kernel@lists.infradead.org; Mon, 27 Jun 2011 11:43:39 +0000 Received: from epcpsbgm2.samsung.com (mailout4.samsung.com [203.254.224.34]) by mailout4.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTP id <0LNG00KVN5WEQO70@mailout4.samsung.com> for linux-arm-kernel@lists.infradead.org; Mon, 27 Jun 2011 20:43:28 +0900 (KST) X-AuditID: cbfee61b-b7bfdae000006d51-b4-4e086ce0c85f Received: from epmmp1 ( [203.254.227.16]) by epcpsbgm2.samsung.com (MMPCPMTA) with SMTP id E3.13.27985.0EC680E4; Mon, 27 Jun 2011 20:43:28 +0900 (KST) Received: from TNRNDGASPAPP1.tn.corp.samsungelectronics.net ([165.213.149.150]) by mmp1.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTPA id <0LNG00A2Y5WFRX@mmp1.samsung.com> for linux-arm-kernel@lists.infradead.org; Mon, 27 Jun 2011 20:43:27 +0900 (KST) Received: from localhost.localdomain ([165.213.219.116]) by TNRNDGASPAPP1.tn.corp.samsungelectronics.net with Microsoft SMTPSVC(6.0.3790.4675); Mon, 27 Jun 2011 20:43:42 +0900 Date: Mon, 27 Jun 2011 20:43:26 +0900 From: MyungJoo Ham Subject: [PATCH 3/3] rtc: rtc-s3c: allow multiple open / allow no-ioctl-open'ed rtc to have irq. In-reply-to: <1309175006-9218-1-git-send-email-myungjoo.ham@samsung.com> To: linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, rtc-linux@googlegroups.com Message-id: <1309175006-9218-4-git-send-email-myungjoo.ham@samsung.com> X-Mailer: git-send-email 1.7.4.1 References: <1309175006-9218-1-git-send-email-myungjoo.ham@samsung.com> X-OriginalArrivalTime: 27 Jun 2011 11:43:42.0878 (UTC) FILETIME=[771E63E0:01CC34BF] X-Brightmail-Tracker: AAAAAA== X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110627_074338_372725_DB58B69B X-CRM114-Status: GOOD ( 20.44 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [203.254.224.34 listed in list.dnswl.org] -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain Cc: a.zummo@towertech.it, Kukjin Kim , dg77.kim@samsung.com, kyungmin.park@samsung.com, myungjoo.ham@gmail.com, ben-linux@fluff.org, Changhwan Youn X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 27 Jun 2011 11:50:01 +0000 (UTC) The previous rtc-s3c had two issues related with its IRQ. 1. Users cannot open rtc multiple times because an open operation calls request_irq on the same IRQ. (e.g., two user processes wants to open and read RTC time from rtc-s3c at the same time) 2. If alarm is set and no one has the rtc opened with filesystem (either the alarm is set by kernel/boot-loader or user set an alarm and closed rtc dev file), the pending bit is not cleared and no further interrupt is invoked. When the alarm is used by the system itself such as a resume from suspend-to-RAM or other Low-power modes/idle, this is a critical issue. This patch mitigates these issue by calling request_irq at probe and free_irq at remove. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park --- drivers/rtc/rtc-s3c.c | 63 ++++++++++++++---------------------------------- 1 files changed, 19 insertions(+), 44 deletions(-) diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index be85ea5..8d2807f 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -320,50 +320,7 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -static int s3c_rtc_open(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - int ret; - - ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, - IRQF_DISABLED, "s3c2410-rtc alarm", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); - return ret; - } - - ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, - IRQF_DISABLED, "s3c2410-rtc tick", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); - goto tick_err; - } - - return ret; - - tick_err: - free_irq(s3c_rtc_alarmno, rtc_dev); - return ret; -} - -static void s3c_rtc_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - - /* do not clear AIE here, it may be needed for wake */ - - free_irq(s3c_rtc_alarmno, rtc_dev); - free_irq(s3c_rtc_tickno, rtc_dev); -} - - static const struct rtc_class_ops s3c_rtcops = { - .open = s3c_rtc_open, - .release = s3c_rtc_release, .read_time = s3c_rtc_gettime, .set_time = s3c_rtc_settime, .read_alarm = s3c_rtc_getalarm, @@ -427,6 +384,9 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) { struct rtc_device *rtc = platform_get_drvdata(dev); + free_irq(s3c_rtc_alarmno, rtc); + free_irq(s3c_rtc_tickno, rtc); + platform_set_drvdata(dev, NULL); rtc_device_unregister(rtc); @@ -553,8 +513,23 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) clk_disable(rtc_clk); - return 0; + ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, + IRQF_DISABLED, "s3c2410-rtc alarm", rtc); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); + return ret; + } + + ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, + IRQF_DISABLED, "s3c2410-rtc tick", rtc); + + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); + free_irq(s3c_rtc_alarmno, rtc); + } + + return ret; err_nortc: s3c_rtc_enable(pdev, 0); clk_disable(rtc_clk);