summaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@intel.com>2016-01-06 16:59:18 -0200
committerAnas Nashif <anas.nashif@intel.com>2016-02-05 20:25:16 -0500
commit7b0076a7778099f00b249ff0278350d0368deece (patch)
treece2bf41938bb1353a177d7ec6caeaf0588cab3b9 /drivers/rtc
parentdb2d48b66f89eeaffd1df50e3994c1a21ee8702b (diff)
rtc: Introduce QMSI RTC device driver
This patch introduces the 'QMSI RTC device driver' which is simply a shim driver based on RTC driver provided by QMSI BSP. Some config options are independent of the driver implementation used, so use a consistent name for them. In this case RTC Interrupt number and Priority use the same config options for both the QMSI and DesignWare drivers. In order to enable this driver, the following options should be set: CONFIG_QMSI_DRIVERS=y CONFIG_QMSI_INSTALL_PATH="/path/to/libqmsi/directory" CONFIG_RTC=y CONFIG_RTC_QMSI=y Change-Id: I48292406e5472e5786f3b9abbeb71016a273bfec Signed-off-by: Andre Guedes <andre.guedes@intel.com> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig47
-rw-r--r--drivers/rtc/Makefile3
-rw-r--r--drivers/rtc/rtc_dw.c10
-rw-r--r--drivers/rtc/rtc_qmsi.c103
-rw-r--r--drivers/rtc/rtc_static_irq_stubs.S6
5 files changed, 144 insertions, 25 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 94d065f10..20519b278 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -27,19 +27,39 @@ menuconfig RTC
if RTC
+config RTC_IRQ
+ int "Interrupt number"
+ default 0
+ help
+ RTC interrupt number
+
+config RTC_IRQ_PRI
+ int "Interrupt priority"
+ default 2
+ help
+ RTC interrupt priority.
+
+config RTC_DRV_NAME
+ string "Driver instance name"
+ default "RTC_0"
+ depends on RTC
+ help
+ RTC driver instance name
+
+config RTC_QMSI
+ depends on QMSI_DRIVERS
+ bool "QMSI RTC Driver"
+ default n
+ help
+ Build QMSI RTC driver.
+
config RTC_DW
+ depends on !RTC_QMSI
bool "Build Designware RTC Driver"
default n
help
Designware RTC driver.
-config RTC_DW_DRV_NAME
- string "Driver instance name"
- default "RTC_DW"
- depends on RTC_DW
- help
- Designware RTC driver instance name
-
config RTC_DW_CLOCK_GATE
bool "Enable clock gating"
depends on RTC_DW
@@ -65,17 +85,4 @@ config RTC_DW_BASE_ADDR
help
Base address to access RTC DesignWare controller registers
-config RTC_DW_IRQ
- int "Interrupt number"
- default 0
- depends on RTC_DW
- help
- DesignWare RTC interrupt number
-
-config RTC_DW_IRQ_PRI
- int "Interrupt priority"
- default 2
- depends on RTC_DW
- help
- DesignWare RTC interrupt priority.
endif # RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 00be5cdeb..35115e65f 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -1,2 +1,5 @@
+ccflags-$(CONFIG_RTC_QMSI) += -I$(CONFIG_QMSI_INSTALL_PATH)/include
+
obj-$(CONFIG_RTC) += rtc_static_irq_stubs.o
obj-$(CONFIG_RTC_DW) += rtc_dw.o
+obj-$(CONFIG_RTC_QMSI) += rtc_qmsi.o
diff --git a/drivers/rtc/rtc_dw.c b/drivers/rtc/rtc_dw.c
index 9e2a1cd86..e10613716 100644
--- a/drivers/rtc/rtc_dw.c
+++ b/drivers/rtc/rtc_dw.c
@@ -190,13 +190,13 @@ static struct rtc_driver_api funcs = {
};
/* IRQ_CONFIG needs the flags variable declared by IRQ_CONNECT_STATIC */
-IRQ_CONNECT_STATIC(rtc, CONFIG_RTC_DW_IRQ,
- CONFIG_RTC_DW_IRQ_PRI, rtc_dw_isr, 0, 0);
+IRQ_CONNECT_STATIC(rtc, CONFIG_RTC_IRQ,
+ CONFIG_RTC_IRQ_PRI, rtc_dw_isr, 0, 0);
int rtc_dw_init(struct device *dev)
{
- IRQ_CONFIG(rtc, CONFIG_RTC_DW_IRQ);
- irq_enable(CONFIG_RTC_DW_IRQ);
+ IRQ_CONFIG(rtc, CONFIG_RTC_IRQ);
+ irq_enable(CONFIG_RTC_IRQ);
_rtc_dw_int_unmask();
@@ -216,7 +216,7 @@ struct rtc_dw_dev_config rtc_dev = {
#endif
};
-DECLARE_DEVICE_INIT_CONFIG(rtc, CONFIG_RTC_DW_DRV_NAME,
+DECLARE_DEVICE_INIT_CONFIG(rtc, CONFIG_RTC_DRV_NAME,
&rtc_dw_init, &rtc_dev);
SYS_DEFINE_DEVICE(rtc, &rtc_runtime, SECONDARY,
diff --git a/drivers/rtc/rtc_qmsi.c b/drivers/rtc/rtc_qmsi.c
new file mode 100644
index 000000000..d319a54e7
--- /dev/null
+++ b/drivers/rtc/rtc_qmsi.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <device.h>
+#include <drivers/ioapic.h>
+#include <init.h>
+#include <nanokernel.h>
+#include <rtc.h>
+
+#include "qm_rtc.h"
+
+IRQ_CONNECT_STATIC(rtc, CONFIG_RTC_IRQ, CONFIG_RTC_IRQ_PRI, qm_rtc_isr_0,
+ 0, IOAPIC_EDGE | IOAPIC_HIGH);
+
+static struct device *rtc_qmsi_dev;
+
+static void (*user_callback)(struct device *dev);
+
+static void rtc_qmsi_enable(struct device *dev)
+{
+ clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);
+}
+
+static void rtc_qmsi_disable(struct device *dev)
+{
+ clk_periph_disable(CLK_PERIPH_RTC_REGISTER);
+}
+
+static void rtc_callback(void)
+{
+ if (user_callback)
+ user_callback(rtc_qmsi_dev);
+}
+
+static int rtc_qmsi_set_config(struct device *dev, struct rtc_config *cfg)
+{
+ qm_rtc_config_t qm_cfg;
+
+ qm_cfg.init_val = cfg->init_val;
+ qm_cfg.alarm_en = cfg->alarm_enable;
+ qm_cfg.alarm_val = cfg->alarm_val;
+ qm_cfg.callback = rtc_callback;
+
+ user_callback = cfg->cb_fn;
+
+ if (qm_rtc_set_config(QM_RTC_0, &qm_cfg) != QM_RC_OK)
+ return DEV_FAIL;
+
+ return DEV_OK;
+}
+
+static int rtc_qmsi_set_alarm(struct device *dev, const uint32_t alarm_val)
+{
+ return qm_rtc_set_alarm(QM_RTC_0, alarm_val) == QM_RC_OK ? DEV_OK : DEV_FAIL;
+}
+
+static uint32_t rtc_qmsi_read(struct device *dev)
+{
+ return QM_RTC[QM_RTC_0].rtc_ccvr;
+}
+
+static struct rtc_driver_api api = {
+ .enable = rtc_qmsi_enable,
+ .disable = rtc_qmsi_disable,
+ .read = rtc_qmsi_read,
+ .set_config = rtc_qmsi_set_config,
+ .set_alarm = rtc_qmsi_set_alarm,
+};
+
+static int rtc_qmsi_init(struct device *dev)
+{
+ IRQ_CONFIG(rtc, CONFIG_RTC_IRQ);
+
+ /* Unmask RTC interrupt */
+ irq_enable(CONFIG_RTC_IRQ);
+
+ /* Route RTC interrupt to Lakemont */
+ QM_SCSS_INT->int_rtc_mask &= ~BIT(0);
+
+ dev->driver_api = &api;
+ return DEV_OK;
+}
+
+DECLARE_DEVICE_INIT_CONFIG(rtc, CONFIG_RTC_DRV_NAME,
+ &rtc_qmsi_init, NULL);
+
+SYS_DEFINE_DEVICE(rtc, NULL, SECONDARY,
+ CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
+
+static struct device *rtc_qmsi_dev = SYS_GET_DEVICE(rtc);
diff --git a/drivers/rtc/rtc_static_irq_stubs.S b/drivers/rtc/rtc_static_irq_stubs.S
index 84a69a7a9..516912d11 100644
--- a/drivers/rtc/rtc_static_irq_stubs.S
+++ b/drivers/rtc/rtc_static_irq_stubs.S
@@ -26,6 +26,12 @@
#endif
#endif
+#if defined(CONFIG_RTC_QMSI)
+#if defined(CONFIG_IOAPIC) || defined(CONFIG_MVIC)
+ ioapic_mkstub rtc qm_rtc_isr_0 0
+#endif
+#endif /* CONFIG_RTC_QMSI */
+
/* externs (internal APIs) */
GTEXT(_IntEnt)