From patchwork Wed Aug 12 05:53:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsheng Wang X-Patchwork-Id: 6995861 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A6CAFC05AC for ; Wed, 12 Aug 2015 06:01:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8B5FD20707 for ; Wed, 12 Aug 2015 06:01:30 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 691E2206DC for ; Wed, 12 Aug 2015 06:01:29 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZPP4O-0008N2-JI; Wed, 12 Aug 2015 05:59:24 +0000 Received: from mail-bn1on0138.outbound.protection.outlook.com ([157.56.110.138] helo=na01-bn1-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZPP4H-0008Hu-4s for linux-arm-kernel@lists.infradead.org; Wed, 12 Aug 2015 05:59:19 +0000 Received: from BLUPR0301CA0026.namprd03.prod.outlook.com (10.162.113.164) by BY2PR0301MB1607.namprd03.prod.outlook.com (10.163.28.25) with Microsoft SMTP Server (TLS) id 15.1.225.19; Wed, 12 Aug 2015 05:58:52 +0000 Received: from BN1AFFO11FD028.protection.gbl (2a01:111:f400:7c10::184) by BLUPR0301CA0026.outlook.office365.com (2a01:111:e400:5259::36) with Microsoft SMTP Server (TLS) id 15.1.231.21 via Frontend Transport; Wed, 12 Aug 2015 05:58:52 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BN1AFFO11FD028.mail.protection.outlook.com (10.58.52.88) with Microsoft SMTP Server (TLS) id 15.1.243.9 via Frontend Transport; Wed, 12 Aug 2015 05:58:52 +0000 Received: from titan.ap.freescale.net ([10.192.208.233]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id t7C5wgfV014724; Tue, 11 Aug 2015 22:58:49 -0700 From: Dongsheng Wang To: Subject: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform Date: Wed, 12 Aug 2015 13:53:27 +0800 Message-ID: <1439358807-9024-2-git-send-email-dongsheng.wang@freescale.com> X-Mailer: git-send-email 2.1.0.27.g96db324 In-Reply-To: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com> References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11FD028; 1:FUbcoUo2hNftw0ln+Ezy8pUiv/V4UBt2iuNUzPkNudAgyHPmJKPYX/Wih139lKTzi/tBJznRrXuserXVJ09vQTKlmDPp42tBGtmMPT8oY6AeOO/h5U9BWKsE58Qzbyl0Etjc5x3ag++8btsixc6VqvCRlVYgNcBd89VDJEQaGG52kek9mfKKz84X+0ZuBZvtSqz4UatKblfVdjpzJ6/o9jI2rxLiZyrkK0yP33rNEDn5s+9zLp4vt50A0KZLar1IukA7aftFwQMs13Yfku+n3DuuogpDdQTuWiu0xt0i4NV1wkTy76xdhDquOAZQap9rglph7T1Z2MWZK8F5iMh6tcTVqDAYH5wirkj9f2NEEDabYORST0NdaFzwK7q3HBnFC7L+CZ+AzRxx8oquwfFf4w== X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(2980300002)(339900001)(3050300001)(189002)(199003)(97736004)(5001860100001)(5001830100001)(46102003)(69596002)(81156007)(85426001)(4001540100001)(87936001)(68736005)(6806004)(77096005)(5003940100001)(2950100001)(50226001)(19580395003)(19580405001)(76176999)(50986999)(92566002)(50466002)(48376002)(189998001)(86362001)(77156002)(62966003)(33646002)(105606002)(36756003)(229853001)(2351001)(104016003)(106466001)(64706001)(110136002)(107886002)(5001960100002)(47776003)(2004002)(4001430100001); DIR:OUT; SFP:1102; SCL:1; SRVR:BY2PR0301MB1607; H:az84smr01.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BY2PR0301MB1607; 2:p+N2WZdLmAkKNmAvfgC1n3alWwI++kkn2v4eiEptKRtMWVXVJEZY5E0M+zxA6MyiWeW0R88R/ekkhXnVp+Bj9aR+7z2jnFw8EYMn2UZedsMVjX6bpDmexgpXJ/gNmHhOOnahM8EjADGuI8dsUp/P4uXhL11G5mPedYKV5Hfjiho=; 3:I4sApT3PberjFJ9eGrHp/M+65SWLJBD2G1U4aqxjPvGRCwsnUH+vTaGa9fAYsazLR0cuUpE3qDHyS/9XCjzc0pTbQD918XYC6HmK/ff37JX9C7d3JXQg+CEQMgxeSh4J+VXLyWYy7GfdCg3Z1NkycFQMljkRTCbdsrWF7PeFEFbBQTMQ6yiBjee9lHgEhOO5SXefXioxs0F21AUdYFFLct6mbrj2OxRKQUpzllyvi7g=; 25:D3+neT0vmNCiKTI8OdVVda+QO9aSEiAvXAaquRWeVARsPoEz1o+nFITt0U/95UbgNzEy3C5+uXw5/V4hoGyWTraqA66ie0MPLdmpkzauW6sZ5/UQIXqG5aEul91+6sjlFPsn718QpvBL3N/GeeZ76kqYxSDP+fh7aNXzQKUg1CyoHO9EK9erQ1ZyFpyoKs+yX38qtdQnRF9MhzPkwacXgMk1AH6gbl8wmS3W3bgZU6egoexrurFoAfquxewm0X0P X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR0301MB1607; X-Microsoft-Exchange-Diagnostics: 1; BY2PR0301MB1607; 20:dA/Sfvs5ZpVeFp8BphnVvNMzAXAqUBScXqRPR5HcuP+AmmkyaGsokmtFj8FWTVWpBKvNqGXQWgIr1uznie3epKxxGIXR+w7t0a3/x/Di5z7F6EQef73yfpU9yNwSDYstRTjBQM40/sDuWAtluItX0jEJltuThMVvkKDl8rTOrsLa+6MV0urQEF6kgk+27bdWKMDm13JfYYOe2RxKIFcOfsAnsHSyxqAlTl1hEQm0+3898FHdX0YQmk5pZaMBIvHGfg97P/rTkI85WG+STcwr5B3NoN0/m4zBUKKEEBiWXpjVfz4ZlOWlly4UXixt01gYNiojgy+XJ2nzcmydc7fTuRfvpETjTwuOlqR1FbIJt4E=; 4:hBCfvBlYHwaPin92WT2+zIyU1VTu3W8iH9XuwLS0PpyStvB3dm/Fdutu+AHA+IhRBJvJoT2tX0JgDMwLYrLVW3O76vIHv2fZxKM/JpRnQ3fgES1eMHbThoLA8CdIY3ApD9rktxqn2Wx9f+fsVzEFdgXFADRQ+KprOmI0Lq/Yzget35i0tBCaTYv17hM348FXJpBXQCpJpwgtaWLSJo5kdHm3X2mtO44JgSLuAF/ne+0789s0wBld7g8JWXTUaiIh9rTSXxotzpm5qfKobZJ8c1D6yb5jjBH0/Vf4kb2WpIc= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:BY2PR0301MB1607; BCL:0; PCL:0; RULEID:; SRVR:BY2PR0301MB1607; X-Forefront-PRVS: 0666E15D35 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR0301MB1607; 23:UJrvui9kWvYsxOCG1Iurvc9HgevcwWr5Fa7d1yT?= =?us-ascii?Q?eRdJtd1mtV/huZygKvwyWkxx/NuEL82RiEPTNm66SV1EHMznrUUiXgXDs6Q6?= =?us-ascii?Q?U+8+Va0aTpHXak7c1us7oogkK2LUwCMV8QZ9MP+JiCBgWs0a/mrwZpO2Zmtt?= =?us-ascii?Q?BMay6/7qVOgzV8jwxVmibFasvE4RR/N5h6o3Pa8AAPbIgN4rdVneFo1LfmKE?= =?us-ascii?Q?POBlAFK1rI1ce2slfW79HObKu6TACuQjVb2VBCnWI/CBUvhx4scLcFkUu60b?= =?us-ascii?Q?AizFUJKFs0MC2XIlnoDM6nYX9QVFL0oJB2KLx+i+SZi7OsNxV6AxH280wtfe?= =?us-ascii?Q?po1SfGDLV1ciCdKwNK0tFqzc8p3hxGKd047/y1zk0qCd2GNrg5vp1gRWQEJO?= =?us-ascii?Q?RNVkHAjURBwOh6VVqoz3+9C5nA5sUppbhs4nlZtaIDHGZI44QMvG8UgHBWT1?= =?us-ascii?Q?0ws2TXmS1128d9cOAdapJFCibuH0OwmDLYy31AG6qnRpOYQUoiKhGvw3nwHz?= =?us-ascii?Q?vrIOUmRowBdLSLkk709SRrf4rZD7W0uo4AmVDb4Q0xjAy7619UuyHTiZ2YJN?= =?us-ascii?Q?U3Yyst/wBM+ybUSbKucfitks84WnWOq5GKyV+8WKQ+6Kne/LqilNwnphaenZ?= =?us-ascii?Q?WTabrTBvI9voWudFB16vg5jJMvuLBbGH7bSpt4pc6m3eQx/SD1SCL4bL6WL4?= =?us-ascii?Q?j2ihv+m9nAP7ROFkhfVP3/nCkNy9cyR4dBtciINhPnwM02FochiFb71IEykF?= =?us-ascii?Q?O6xWLKOAHMJTD1ai38KqIZFgY/zxL34mJYC+wAH8hOtXwzsrC85QPpmBNG2+?= =?us-ascii?Q?rHWBsNwjEskCljIEbaGuYq9vtbEs5otb/rBYF1Hb+rLx134fNk71OYJST3Dl?= =?us-ascii?Q?yVuBaTjgrxyJCIt45TLXUcDzlitV4mxf6Hqc2yG6d1LCMd/N51oNlEKwCSC2?= =?us-ascii?Q?Oh6yRGYWMHI7waZBQe9Tv4Ldk73+GhYYQ7jv7cQ97WW6N33CWhQzb7Yxobnq?= =?us-ascii?Q?imcG/FgNi7rvr87BEZze5DK45RiZxtTtLiN5zxX+RVSzUVDbS/uBhqWnVjPo?= =?us-ascii?Q?qcXYj2D1qIeDpZUws1NYBIs4qr0pdorDJApxIPgx2PkdGado4XZHo2RbUkHI?= =?us-ascii?Q?NimXy7qShrMvQRZ4TQhBPNOCMMcniRYg8n0hVRCDaHhzAXrmJxG6qYUFMu0k?= =?us-ascii?Q?KWmTF6fOWDBJ5tWhfoR0WFLRkyraDi6GE8bm5?= X-Microsoft-Exchange-Diagnostics: 1; BY2PR0301MB1607; 5:WI8f49u5p/iCAkWm9G28hO8ZgWGEorFQIEIZ/3NL+Ba+EXaE/dYgGeJWoangiZo2EzgaNMqUuf0LxxCjVi0BDc/PJSXY854BeJfdxZCW5UGZyHbT8BprQox17RyO+uJRssopQmqGDwaHg7ONfLRlIQ==; 24:mPZuzhu28rXR4+FbmtebyKhFAbtpBb+km1UMXOc0Jsic7HxwfJEEZk+7OJY3QyOpVzQscLQ2j3FyryDx371xO2Ojmwj46UdntiYhPQwPgs0=; 20:SotJHKI41dKf3lHlHKGawet0NfanTWem0M+/0791WwXF2b5sBsKwRLn/qfj/px+35lys14mKh2h7Z9V9Vw+t7A== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Aug 2015 05:58:52.3513 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR0301MB1607 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150811_225917_593900_6DEB202F X-CRM114-Status: GOOD ( 24.18 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Wang Dongsheng , alison.wang@freescale.com, linus.walleij@linaro.org, linux-kernel@vger.kernel.org, sandeep_n@ti.com, hdegoede@redhat.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wang Dongsheng Only Ftm0 can be used when system going to deep sleep. So this driver to support ftm0 as a wakeup source. Signed-off-by: Wang Dongsheng --- *V2* Change Copyright 2014 to 2015. diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig index 7556f44..e6282dc 100644 --- a/drivers/soc/fsl/ls1/Kconfig +++ b/drivers/soc/fsl/ls1/Kconfig @@ -1,3 +1,11 @@ # # LS-1 Soc drivers # +config FTM_ALARM + bool "FTM alarm driver" + depends on SOC_LS1021A + default n + help + Say y here to enable FTM alarm support. The FTM alarm provides + alarm functions for wakeup system from deep sleep. There is only + one FTM can be used in ALARM(FTM 0). diff --git a/drivers/soc/fsl/ls1/Makefile b/drivers/soc/fsl/ls1/Makefile new file mode 100644 index 0000000..6299aa1 --- /dev/null +++ b/drivers/soc/fsl/ls1/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o diff --git a/drivers/soc/fsl/ls1/ftm_alarm.c b/drivers/soc/fsl/ls1/ftm_alarm.c new file mode 100644 index 0000000..f7629cd --- /dev/null +++ b/drivers/soc/fsl/ls1/ftm_alarm.c @@ -0,0 +1,272 @@ +/* + * Freescale FlexTimer Module (FTM) Alarm driver. + * + * Copyright 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define FTM_SC 0x00 +#define FTM_SC_CLK_SHIFT 3 +#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT) +#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT) +#define FTM_SC_PS_MASK 0x7 +#define FTM_SC_TOIE BIT(6) +#define FTM_SC_TOF BIT(7) + +#define FTM_SC_CLKS_FIXED_FREQ 0x02 + +#define FTM_CNT 0x04 +#define FTM_MOD 0x08 +#define FTM_CNTIN 0x4C + +#define FIXED_FREQ_CLK 32000 +#define MAX_FREQ_DIV (1 << FTM_SC_PS_MASK) +#define MAX_COUNT_VAL 0xffff + +static void __iomem *ftm1_base; +static u32 alarm_freq; +static bool big_endian; + +static inline u32 ftm_readl(void __iomem *addr) +{ + if (big_endian) + return ioread32be(addr); + + return ioread32(addr); +} + +static inline void ftm_writel(u32 val, void __iomem *addr) +{ + if (big_endian) + iowrite32be(val, addr); + else + iowrite32(val, addr); +} + +static inline void ftm_counter_enable(void __iomem *base) +{ + u32 val; + + /* select and enable counter clock source */ + val = ftm_readl(base + FTM_SC); + val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); + val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ)); + ftm_writel(val, base + FTM_SC); +} + +static inline void ftm_counter_disable(void __iomem *base) +{ + u32 val; + + /* disable counter clock source */ + val = ftm_readl(base + FTM_SC); + val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); + ftm_writel(val, base + FTM_SC); +} + +static inline void ftm_irq_acknowledge(void __iomem *base) +{ + u32 val; + + val = ftm_readl(base + FTM_SC); + val &= ~FTM_SC_TOF; + ftm_writel(val, base + FTM_SC); +} + +static inline void ftm_irq_enable(void __iomem *base) +{ + u32 val; + + val = ftm_readl(base + FTM_SC); + val |= FTM_SC_TOIE; + ftm_writel(val, base + FTM_SC); +} + +static inline void ftm_irq_disable(void __iomem *base) +{ + u32 val; + + val = ftm_readl(base + FTM_SC); + val &= ~FTM_SC_TOIE; + ftm_writel(val, base + FTM_SC); +} + +static inline void ftm_reset_counter(void __iomem *base) +{ + /* + * The CNT register contains the FTM counter value. + * Reset clears the CNT register. Writing any value to COUNT + * updates the counter with its initial value, CNTIN. + */ + ftm_writel(0x00, base + FTM_CNT); +} + +static u32 time_to_cycle(unsigned long time) +{ + u32 cycle; + + cycle = time * alarm_freq; + if (cycle > MAX_COUNT_VAL) { + pr_err("Out of alarm range.\n"); + cycle = 0; + } + + return cycle; +} + +static u32 cycle_to_time(u32 cycle) +{ + return cycle / alarm_freq + 1; +} + +static void ftm_clean_alarm(void) +{ + ftm_counter_disable(ftm1_base); + + ftm_writel(0x00, ftm1_base + FTM_CNTIN); + ftm_writel(~0UL, ftm1_base + FTM_MOD); + + ftm_reset_counter(ftm1_base); +} + +static int ftm_set_alarm(u64 cycle) +{ + ftm_irq_disable(ftm1_base); + + /* + * The counter increments until the value of MOD is reached, + * at which point the counter is reloaded with the value of CNTIN. + * The TOF (the overflow flag) bit is set when the FTM counter + * changes from MOD to CNTIN. So we should using the cycle - 1. + */ + ftm_writel(cycle - 1, ftm1_base + FTM_MOD); + + ftm_counter_enable(ftm1_base); + + ftm_irq_enable(ftm1_base); + + return 0; +} + +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id) +{ + ftm_irq_acknowledge(ftm1_base); + ftm_irq_disable(ftm1_base); + ftm_clean_alarm(); + + return IRQ_HANDLED; +} + +static ssize_t ftm_alarm_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 count, val; + + count = ftm_readl(ftm1_base + FTM_MOD); + val = ftm_readl(ftm1_base + FTM_CNT); + val = (count & MAX_COUNT_VAL) - val; + val = cycle_to_time(val); + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ftm_alarm_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u32 cycle; + unsigned long time; + + if (kstrtoul(buf, 0, &time)) + return -EINVAL; + + ftm_clean_alarm(); + + cycle = time_to_cycle(time); + if (!cycle) + return -EINVAL; + + ftm_set_alarm(cycle); + + return count; +} + +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644, + ftm_alarm_show, ftm_alarm_store); + +static int ftm_alarm_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct resource *r; + int irq; + int ret; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + + ftm1_base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(ftm1_base)) + return PTR_ERR(ftm1_base); + + irq = irq_of_parse_and_map(np, 0); + if (irq <= 0) { + pr_err("ftm: unable to get IRQ from DT, %d\n", irq); + return -EINVAL; + } + + big_endian = of_property_read_bool(np, "big-endian"); + + ret = devm_request_irq(&pdev->dev, irq, ftm_alarm_interrupt, + IRQF_NO_SUSPEND, dev_name(&pdev->dev), NULL); + if (ret < 0) { + dev_err(&pdev->dev, "failed to request irq\n"); + return ret; + } + + ret = device_create_file(&pdev->dev, &ftm_alarm_attributes); + if (ret) { + dev_err(&pdev->dev, "create sysfs fail.\n"); + return ret; + } + + alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV; + + ftm_clean_alarm(); + + return ret; +} + +static const struct of_device_id ftm_alarm_match[] = { + { .compatible = "fsl,ftm-alarm", }, + { .compatible = "fsl,ftm-timer", }, + { }, +}; + +static struct platform_driver ftm_alarm_driver = { + .probe = ftm_alarm_probe, + .driver = { + .name = "ftm-alarm", + .owner = THIS_MODULE, + .of_match_table = ftm_alarm_match, + }, +}; + +static int __init ftm_alarm_init(void) +{ + return platform_driver_register(&ftm_alarm_driver); +} +device_initcall(ftm_alarm_init);