Received: by 2002:a05:6a10:a852:0:0:0:0 with SMTP id d18csp156649pxy; Fri, 30 Apr 2021 02:34:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyBjbdZ6OHwZFZXtfN2m9iyoAnpLf/khYK/dp5BgKQSifzc3IO0KV8z+Lx0GVELRh7OIpBT X-Received: by 2002:a63:e13:: with SMTP id d19mr3862594pgl.36.1619775294959; Fri, 30 Apr 2021 02:34:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1619775294; cv=none; d=google.com; s=arc-20160816; b=hM79Dlao8ZTzS44WUp5s3z/3KVp/JKqgnx+j7fPf9MY6N3g3G8vEP2U7gr2CM2+CFK rR4Edsnc5+6n3vceTpMhgl1ZGj+x/JOAAMtqU5H24a2d4ZI/xRcAOhyzHs/+Lf+uWRaw alm2lsDct65BPmUlMnEIuvvsHUa6GzMoleJARSb6uoVteyY2+uqJeSaUNKuxbRsNhdsK htlruwJdDuF4n9aI4jydtr6sLdHQ4nWF3KrQYzSoEi9nRZfObl5D1qrm8sj76Fs1mkP7 tpUNyNBoPEalVVwD8eMDr6VkFL7fASgaycEm7h634jJt4Npa9yzwh/h5Nc+1nSittC2+ dcuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=Zz29mWGcdAjSCfzb8fI5OxfxXjS+UHDGvV3GwieUTfQ=; b=ikCeHBqDWmxaqRkpDfurJOksbBCigweMZjpFWyV3oD6xwhYfV7ES0gmH9GSzP+jlDo MWZZtdwOrfvrDUdGc/b4Gp/K+ErUv96jVJueZJy9XOeNvl4Uo+1lwnBCw+wKtHzGJ3ta htsuQrxzXgJZr+WbKNaTFbnB5v+hyBtmqIlCXudoqaehv1Q19Wgxk/CBm6y8W+GwxFOb 4eLJL6mj9wrmqj59uOpinb9pNPN/RVpC5u+b8s97yzAC7cHHnlR9gqQrYX/2ny+A+WAF Bo3hCrEVRk75/SzoqoF+IUKGrkYDBJIQ+ydkS3WhSp4cqwpvxc18Oz5oYMKc+O27kCde 3G/g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o27si2816574pgm.555.2021.04.30.02.34.39; Fri, 30 Apr 2021 02:34:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229606AbhD3JdT (ORCPT + 99 others); Fri, 30 Apr 2021 05:33:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229507AbhD3JdS (ORCPT ); Fri, 30 Apr 2021 05:33:18 -0400 Received: from viti.kaiser.cx (viti.kaiser.cx [IPv6:2a01:238:43fe:e600:cd0c:bd4a:7a3:8e9f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2B63C06174A for ; Fri, 30 Apr 2021 02:32:30 -0700 (PDT) Received: from dslb-084-059-234-193.084.059.pools.vodafone-ip.de ([84.59.234.193] helo=martin-debian-2.paytec.ch) by viti.kaiser.cx with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1lcPVW-0007DS-J6; Fri, 30 Apr 2021 11:32:22 +0200 From: Martin Kaiser To: Alessandro Zummo , Alexandre Belloni , Shawn Guo , Pengutronix Kernel Team , Fabio Estevam Cc: linux-rtc@vger.kernel.org, linux-kernel@vger.kernel.org, Martin Kaiser Subject: [PATCH] rtc: imxdi: add wakeup support Date: Fri, 30 Apr 2021 11:32:10 +0200 Message-Id: <20210430093210.7034-1-martin@kaiser.cx> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The DryIce-based RTC supports alarms that trigger an interrupt. Add an option to configure this interrupt as a wakeup source that wakes the system up from standby mode. Signed-off-by: Martin Kaiser --- simple test [root@board ]# echo enabled > /sys/class/rtc/rtc0/device/power/wakeup [root@board ]# rtcwake -s 3 -m mem wakeup from "mem" at Fri Apr 30 09:23:52 2021 ... [root@board ]# drivers/rtc/rtc-imxdi.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index c1806f4d68e7..63957be25759 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -98,6 +98,7 @@ * @pdev: pointer to platform dev * @rtc: pointer to rtc struct * @ioaddr: IO registers pointer + * @norm_irq: irq number of the "normal" irq * @clk: input reference clock * @dsr: copy of the DSR register * @irq_lock: interrupt enable register (DIER) lock @@ -109,6 +110,7 @@ struct imxdi_dev { struct platform_device *pdev; struct rtc_device *rtc; void __iomem *ioaddr; + int norm_irq; struct clk *clk; u32 dsr; spinlock_t irq_lock; @@ -741,7 +743,7 @@ static void dryice_work(struct work_struct *work) static int __init dryice_rtc_probe(struct platform_device *pdev) { struct imxdi_dev *imxdi; - int norm_irq, sec_irq; + int sec_irq; int rc; imxdi = devm_kzalloc(&pdev->dev, sizeof(*imxdi), GFP_KERNEL); @@ -756,9 +758,9 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) spin_lock_init(&imxdi->irq_lock); - norm_irq = platform_get_irq(pdev, 0); - if (norm_irq < 0) - return norm_irq; + imxdi->norm_irq = platform_get_irq(pdev, 0); + if (imxdi->norm_irq < 0) + return imxdi->norm_irq; /* the 2nd irq is the security violation irq * make this optional, don't break the device tree ABI @@ -795,7 +797,7 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) if (rc != 0) goto err; - rc = devm_request_irq(&pdev->dev, norm_irq, dryice_irq, + rc = devm_request_irq(&pdev->dev, imxdi->norm_irq, dryice_irq, IRQF_SHARED, pdev->name, imxdi); if (rc) { dev_warn(&pdev->dev, "interrupt not available.\n"); @@ -811,6 +813,8 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imxdi); + device_set_wakeup_capable(&pdev->dev, true); + imxdi->rtc->ops = &dryice_rtc_ops; imxdi->rtc->range_max = U32_MAX; @@ -830,6 +834,8 @@ static int __exit dryice_rtc_remove(struct platform_device *pdev) { struct imxdi_dev *imxdi = platform_get_drvdata(pdev); + device_set_wakeup_capable(&pdev->dev, false); + flush_work(&imxdi->work); /* mask all interrupts */ @@ -847,10 +853,33 @@ static const struct of_device_id dryice_dt_ids[] = { MODULE_DEVICE_TABLE(of, dryice_dt_ids); +#ifdef CONFIG_PM_SLEEP +static int dryice_suspend(struct device *dev) +{ + struct imxdi_dev *imxdi = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(imxdi->norm_irq); + return 0; +} + +static int dryice_resume(struct device *dev) +{ + struct imxdi_dev *imxdi = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(imxdi->norm_irq); + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(dryice_pm, dryice_suspend, dryice_resume); + static struct platform_driver dryice_rtc_driver = { .driver = { .name = "imxdi_rtc", .of_match_table = dryice_dt_ids, + .pm = &dryice_pm, }, .remove = __exit_p(dryice_rtc_remove), }; -- 2.20.1