diff options
author | Andre Guedes <andre.guedes@intel.com> | 2016-01-06 16:59:18 -0200 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2016-02-05 20:25:16 -0500 |
commit | 7b0076a7778099f00b249ff0278350d0368deece (patch) | |
tree | ce2bf41938bb1353a177d7ec6caeaf0588cab3b9 | |
parent | db2d48b66f89eeaffd1df50e3994c1a21ee8702b (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>
-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; |