summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/soc/quark_d2000/Kconfig5
-rw-r--r--arch/x86/soc/quark_se/Kconfig4
-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
-rw-r--r--samples/nanokernel/apps/rtc/src/main.c4
8 files changed, 150 insertions, 32 deletions
diff --git a/arch/x86/soc/quark_d2000/Kconfig b/arch/x86/soc/quark_d2000/Kconfig
index a3b5a39b7..d72f4b4b0 100644
--- a/arch/x86/soc/quark_d2000/Kconfig
+++ b/arch/x86/soc/quark_d2000/Kconfig
@@ -169,11 +169,12 @@ endif
if RTC
+config RTC_IRQ
+ default 2
+
if RTC_DW
config RTC_DW_BASE_ADDR
default 0xB0000400
-config RTC_DW_IRQ
- default 2
endif
endif
diff --git a/arch/x86/soc/quark_se/Kconfig b/arch/x86/soc/quark_se/Kconfig
index 273b5307d..6c0c9bc1a 100644
--- a/arch/x86/soc/quark_se/Kconfig
+++ b/arch/x86/soc/quark_se/Kconfig
@@ -190,6 +190,8 @@ endif
endif
if RTC
+config RTC_IRQ
+ default 11
if RTC_DW
config RTC_DW_CLOCK_GATE
def_bool n
@@ -199,8 +201,6 @@ config RTC_DW_CLOCK_GATE_SUBSYS
default 11
config RTC_DW_BASE_ADDR
default 0xB0000400
-config RTC_DW_IRQ
- default 11
endif
endif
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)
diff --git a/samples/nanokernel/apps/rtc/src/main.c b/samples/nanokernel/apps/rtc/src/main.c
index 218b3836a..4a3e76da2 100644
--- a/samples/nanokernel/apps/rtc/src/main.c
+++ b/samples/nanokernel/apps/rtc/src/main.c
@@ -20,9 +20,7 @@
#include <rtc.h>
#include <misc/printk.h>
-
#define ALARM (RTC_ALARM_MINUTE / 6)
-#define RTC_DRIVER CONFIG_RTC_DW_DRV_NAME
void test_rtc_interrupt_fn(struct device *rtc_dev)
{
@@ -38,7 +36,7 @@ void main(void)
struct device *rtc_dev;
printk("Test RTC driver\n");
- rtc_dev = device_get_binding(RTC_DRIVER);
+ rtc_dev = device_get_binding(CONFIG_RTC_DRV_NAME);
config.init_val = 0;
config.alarm_enable = 1;