diff options
-rw-r--r-- | arch/x86/soc/quark_d2000/Kconfig | 5 | ||||
-rw-r--r-- | arch/x86/soc/quark_se/Kconfig | 4 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 47 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 3 | ||||
-rw-r--r-- | drivers/rtc/rtc_dw.c | 10 | ||||
-rw-r--r-- | drivers/rtc/rtc_qmsi.c | 103 | ||||
-rw-r--r-- | drivers/rtc/rtc_static_irq_stubs.S | 6 | ||||
-rw-r--r-- | samples/nanokernel/apps/rtc/src/main.c | 4 |
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; |