diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 08cbdb9..21f5630 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -135,6 +135,16 @@ config RTC_DRV_88PM860X
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-88pm860x.
 
+config RTC_DRV_DA9058
+	tristate "Dialog DA9058"
+	depends on MFD_DA9058
+	help
+	  If you say yes here you will get support for the
+	  RTC of the Dialog DA9058 PMIC.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-da9058.
+
 config RTC_DRV_DS1307
 	tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
 	help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2973921..b772f05 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_COH901331)	+= rtc-coh901331.o
 obj-$(CONFIG_RTC_DRV_DA9052)	+= rtc-da9052.o
 obj-$(CONFIG_RTC_DRV_DAVINCI)	+= rtc-davinci.o
+obj-$(CONFIG_RTC_DRV_DA9058)	+= rtc-da9058.o
 obj-$(CONFIG_RTC_DRV_DM355EVM)	+= rtc-dm355evm.o
 obj-$(CONFIG_RTC_DRV_VRTC)	+= rtc-mrst.o
 obj-$(CONFIG_RTC_DRV_DS1216)	+= rtc-ds1216.o
diff --git a/drivers/rtc/rtc-da9058.c b/drivers/rtc/rtc-da9058.c
new file mode 100644
index 0000000..1b4e05b
--- /dev/null
+++ b/drivers/rtc/rtc-da9058.c
@@ -0,0 +1,458 @@
+/*
+ *  Copyright (C) 2012 Dialog Semiconductor Ltd.
+ *
+ *  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 <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/regmap.h>
+#include <linux/mfd/core.h>
+
+#include <linux/mfd/da9058/version.h>
+#include <linux/mfd/da9058/registers.h>
+#include <linux/mfd/da9058/core.h>
+#include <linux/mfd/da9058/irq.h>
+#include <linux/mfd/da9058/rtc.h>
+
+/*
+ *  Limit values
+ */
+#define DA9058_RTC_SECONDS_LIMIT		59
+#define DA9058_RTC_MINUTES_LIMIT		59
+#define DA9058_RTC_HOURS_LIMIT			23
+#define DA9058_RTC_DAYS_LIMIT			31
+#define DA9058_RTC_MONTHS_LIMIT			12
+#define DA9058_RTC_YEARS_LIMIT			63
+
+struct da9058_rtc {
+	struct da9058 *da9058;
+	struct platform_device *pdev;
+	struct rtc_device *rtc_dev;
+	int alarm_irq;
+	int tick_irq;
+	int alarm_enabled;	/* used over suspend/resume */
+};
+
+static int da9058_rtc_check_param(struct rtc_time *rtc_tm)
+{
+	if ((rtc_tm->tm_sec > DA9058_RTC_SECONDS_LIMIT) || (rtc_tm->tm_sec < 0))
+		return -EIO;
+
+	if ((rtc_tm->tm_min > DA9058_RTC_MINUTES_LIMIT) || (rtc_tm->tm_min < 0))
+		return -EIO;
+
+	if ((rtc_tm->tm_hour > DA9058_RTC_HOURS_LIMIT) || (rtc_tm->tm_hour < 0))
+		return -EIO;
+
+	if ((rtc_tm->tm_mday > DA9058_RTC_DAYS_LIMIT) || (rtc_tm->tm_mday <= 0))
+		return -EIO;
+
+	if ((rtc_tm->tm_mon > DA9058_RTC_MONTHS_LIMIT) || (rtc_tm->tm_mon <= 0))
+		return -EIO;
+
+	if ((rtc_tm->tm_year > DA9058_RTC_YEARS_LIMIT) || (rtc_tm->tm_year < 0))
+		return -EIO;
+
+	return 0;
+}
+
+static int da9058_rtc_readtime(struct device *dev, struct rtc_time *tm)
+{
+	struct da9058_rtc *rtc = dev_get_drvdata(dev);
+	struct da9058 *da9058 = rtc->da9058;
+	u8 rtc_time[6];
+	int ret;
+
+	ret = da9058_bulk_read(da9058, DA9058_COUNTS_REG, rtc_time, 6);
+	if (ret)
+		return ret;
+
+	tm->tm_sec = rtc_time[0] & DA9058_RTC_SECS_MASK;
+
+	tm->tm_min = rtc_time[1] & DA9058_RTC_MINS_MASK;
+
+	tm->tm_hour = rtc_time[2] & DA9058_RTC_HRS_MASK;
+
+	tm->tm_mday = (rtc_time[3] & DA9058_RTC_DAY_MASK);
+
+	tm->tm_mon = (rtc_time[4] & DA9058_RTC_MTH_MASK);
+
+	tm->tm_year = (rtc_time[5] & DA9058_RTC_YRS_MASK);
+
+	ret = da9058_rtc_check_param(tm);
+
+	if (ret)
+		return ret;
+
+	tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon,
+						tm->tm_year);
+	tm->tm_year += 100;
+	tm->tm_mon -= 1;
+
+	return 0;
+}
+
+static int da9058_rtc_settime(struct device *dev, struct rtc_time *tm)
+{
+	struct da9058_rtc *rtc = dev_get_drvdata(dev);
+	struct da9058 *da9058 = rtc->da9058;
+	unsigned int rtc_ctrl, val;
+	u8 rtc_time[6];
+	int ret;
+
+	tm->tm_year -= 100;
+	tm->tm_mon += 1;
+
+	ret = da9058_rtc_check_param(tm);
+	if (ret < 0)
+		return ret;
+
+	ret = da9058_reg_read(da9058, DA9058_COUNTS_REG, &rtc_ctrl);
+	if (ret)
+		return ret;
+	rtc_ctrl &= ~DA9058_RTC_SECS_MASK;
+
+	rtc_time[0] = rtc_ctrl | tm->tm_sec;
+	rtc_time[1] = tm->tm_min;
+	rtc_time[2] = tm->tm_hour;
+	rtc_time[3] = tm->tm_mday;
+	rtc_time[4] = tm->tm_mon;
+	rtc_time[5] = tm->tm_year;
+
+	ret = da9058_bulk_write(da9058, DA9058_COUNTS_REG, rtc_time, 6);
+	if (ret) {
+		dev_dbg(dev, "failed %d to write to RTC\n", ret);
+		return ret;
+	}
+	ret = da9058_reg_read(da9058, DA9058_COUNTY_REG, &val);
+	if (ret)
+		return ret;
+
+	val &= DA9058_COUNTY_MONITOR;
+	if (val)
+		return 0;
+
+	ret = da9058_set_bits(da9058, DA9058_COUNTY_REG, DA9058_COUNTY_MONITOR);
+
+	return ret;
+}
+
+static int da9058_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct da9058_rtc *rtc = dev_get_drvdata(dev);
+	struct da9058 *da9058 = rtc->da9058;
+	struct rtc_time *tm = &alrm->time;
+	unsigned int val;
+	u8 alm_time[6];
+	int ret;
+
+	ret = da9058_bulk_read(da9058, DA9058_ALARMS_REG, alm_time, 6);
+	if (ret)
+		return ret;
+
+	tm->tm_min = alm_time[0] & DA9058_RTC_ALMSECS_MASK;
+
+	tm->tm_min = alm_time[1] & DA9058_RTC_ALMMINS_MASK;
+
+	tm->tm_hour = alm_time[2] & DA9058_RTC_ALMHRS_MASK;
+
+	tm->tm_mday = alm_time[3] & DA9058_RTC_ALMDAY_MASK;
+
+	tm->tm_mon = alm_time[4] & DA9058_RTC_ALMMTH_MASK;
+
+	tm->tm_year = alm_time[5] & DA9058_RTC_ALMYRS_MASK;
+
+	ret = da9058_rtc_check_param(tm);
+	if (ret < 0)
+		return ret;
+
+	ret = da9058_reg_read(da9058, DA9058_ALARMY_REG, &val);
+	if (ret)
+		return ret;
+
+	alrm->enabled = val & DA9058_ALARMY_ALARMON;
+
+	tm->tm_year += 100;
+	tm->tm_mon -= 1;
+
+	return 0;
+}
+
+static int da9058_rtc_stop_alarm(struct da9058_rtc *rtc)
+{
+	return da9058_clear_bits(rtc->da9058, DA9058_ALARMY_REG,
+						DA9058_ALARMY_ALARMON);
+}
+
+static int da9058_rtc_start_alarm(struct da9058_rtc *rtc)
+{
+	return da9058_set_bits(rtc->da9058, DA9058_ALARMY_REG,
+						DA9058_ALARMY_ALARMON);
+}
+
+static int da9058_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct da9058_rtc *rtc = dev_get_drvdata(dev);
+	struct da9058 *da9058 = rtc->da9058;
+	struct rtc_time *tm = &alrm->time;
+	unsigned int rtc_ctrl;
+	u8 alm_time[6];
+	int ret;
+
+	tm->tm_year -= 100;
+	tm->tm_mon += 1;
+
+	ret = da9058_rtc_check_param(tm);
+	if (ret < 0)
+		return ret;
+
+	memset(alm_time, 0, sizeof(alm_time));
+
+	if (tm->tm_sec != -1)
+		alm_time[0] |= tm->tm_sec;
+	else
+		alm_time[0] |= DA9058_RTC_ALMSECS_MASK;
+
+	ret = da9058_reg_read(da9058, DA9058_ALARMMI_REG, &rtc_ctrl);
+	if (ret)
+		return ret;
+	rtc_ctrl &= ~DA9058_RTC_ALMMINS_MASK;
+
+	if (tm->tm_min != -1)
+		alm_time[1] = rtc_ctrl | tm->tm_min;
+	else
+		alm_time[1] = rtc_ctrl | DA9058_RTC_ALMMINS_MASK;
+
+	if (tm->tm_hour != -1)
+		alm_time[2] |= tm->tm_hour;
+	else
+		alm_time[2] |= DA9058_RTC_ALMHRS_MASK;
+
+	if (tm->tm_mday != -1)
+		alm_time[3] |= tm->tm_mday;
+	else
+		alm_time[3] |= DA9058_RTC_ALMDAY_MASK;
+
+	if (tm->tm_mon != -1)
+		alm_time[4] |= tm->tm_mon;
+	else
+		alm_time[4] |= DA9058_RTC_ALMMTH_MASK;
+
+	ret = da9058_reg_read(da9058, DA9058_ALARMY_REG, &rtc_ctrl);
+	if (ret)
+		return ret;
+
+	rtc_ctrl &= ~DA9058_RTC_ALMYRS_MASK;
+
+	if (tm->tm_year != -1)
+		alm_time[5] = rtc_ctrl | tm->tm_year;
+	else
+		alm_time[5] = rtc_ctrl | DA9058_RTC_ALMYRS_MASK;
+
+	ret = da9058_rtc_stop_alarm(rtc);
+	if (ret < 0)
+		return ret;
+
+	ret = da9058_bulk_write(da9058, DA9058_ALARMS_REG, alm_time, 6);
+	if (ret)
+		return ret;
+
+	if (alrm->enabled)
+		ret = da9058_rtc_start_alarm(rtc);
+
+	return ret;
+}
+
+static int da9058_rtc_alarm_irq_enable(struct device *dev,
+						unsigned int enabled)
+{
+	struct da9058_rtc *rtc = dev_get_drvdata(dev);
+
+	if (enabled)
+		return da9058_rtc_start_alarm(rtc);
+	else
+		return da9058_rtc_stop_alarm(rtc);
+}
+
+static irqreturn_t da9058_rtc_timer_alarm_handler(int irq, void *data)
+{
+	struct da9058_rtc *rtc = data;
+
+	da9058_rtc_stop_alarm(rtc);
+	rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t da9058_rtc_tick_alarm_handler(int irq, void *data)
+{
+	struct da9058_rtc *rtc = data;
+
+	rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
+
+	return IRQ_HANDLED;
+}
+static int da9058_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+	struct da9058_rtc *rtc = dev_get_drvdata(dev);
+	struct da9058 *da9058 = rtc->da9058;
+	unsigned int rtc_ctrl;
+	int ret;
+
+	ret = da9058_reg_read(da9058, DA9058_ALARMY_REG, &rtc_ctrl);
+
+	seq_printf(seq, rtc_ctrl & DA9058_ALARMY_ALARMON ?
+		"ALRM is running\n" : "ALRM is not running\n");
+
+	return 0;
+}
+
+static const struct rtc_class_ops da9058_rtc_ops = {
+	.read_time = da9058_rtc_readtime,
+	.set_time = da9058_rtc_settime,
+	.read_alarm = da9058_rtc_readalarm,
+	.set_alarm = da9058_rtc_setalarm,
+	.proc = da9058_rtc_proc,
+	.alarm_irq_enable = da9058_rtc_alarm_irq_enable,
+};
+
+static int da9058_rtc_probe(struct platform_device *pdev)
+{
+	struct da9058 *da9058 = dev_get_drvdata(pdev->dev.parent);
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct da9058_rtc_pdata *rtc_pdata;
+	struct da9058_rtc *rtc;
+	int ret;
+
+	if (cell == NULL) {
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	rtc_pdata = cell->platform_data;
+
+	if (rtc_pdata == NULL) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9058_rtc), GFP_KERNEL);
+	if (!rtc) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	platform_set_drvdata(pdev, rtc);
+
+	rtc->da9058 = da9058;
+	rtc->pdev = pdev;
+	ret = da9058_clear_bits(da9058, DA9058_WAITCONT_REG,
+						DA9058_WAITCONT_RTCCLOCK);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to set RTC running: %d\n", ret);
+		goto unable_to_init_device;
+	}
+
+	ret = da9058_set_bits(da9058, DA9058_COUNTY_REG, DA9058_COUNTY_MONITOR);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed No gating RTC: %d\n", ret);
+		goto unable_to_init_device;
+	}
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	rtc->rtc_dev = rtc_device_register("da9058", &pdev->dev,
+						&da9058_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc->rtc_dev)) {
+		ret = PTR_ERR(rtc->rtc_dev);
+		dev_err(&pdev->dev, "failed to register RTC: %d\n", ret);
+		goto unable_to_register_device;
+	}
+
+	rtc->alarm_irq = platform_get_irq(pdev, 0);
+	if (rtc->alarm_irq < 0) {
+		dev_err(&pdev->dev, "can not get RTC ALARM IRQ error=%d\n",
+				rtc->alarm_irq);
+		ret = -ENODEV;
+		goto failed_to_get_alarm_irq;
+	}
+
+	ret = request_threaded_irq(da9058_to_virt_irq_num(da9058,
+							rtc->alarm_irq),
+				NULL, da9058_rtc_timer_alarm_handler,
+				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+				"DA9058 RTC Timer Alarm", rtc);
+
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to get rtc timer alarm IRQ %d: %d\n",
+			rtc->alarm_irq, ret);
+		goto unable_to_setup_timer_irq;
+	}
+
+	rtc->tick_irq = platform_get_irq(pdev, 1);
+	if (rtc->tick_irq < 0) {
+		dev_err(&pdev->dev, "can not get RTC TICK IRQ error=%d\n",
+				rtc->tick_irq);
+		ret = -ENODEV;
+		goto failed_to_get_tick_irq;
+	}
+	ret = request_threaded_irq(da9058_to_virt_irq_num(da9058,
+							rtc->tick_irq),
+				NULL, da9058_rtc_tick_alarm_handler,
+				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+				"DA9058 RTC Tick Alarm", rtc);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to get rtc timer alarm IRQ %d: %d\n",
+			DA9058_IRQ_ETICK, ret);
+		goto unable_to_setup_alarm_irq;
+	}
+	goto exit;
+
+failed_to_get_tick_irq:
+unable_to_setup_alarm_irq:
+	free_irq(da9058_to_virt_irq_num(da9058, rtc->alarm_irq), rtc);
+failed_to_get_alarm_irq:
+unable_to_setup_timer_irq:
+	rtc_device_unregister(rtc->rtc_dev);
+unable_to_register_device:
+unable_to_init_device:
+	platform_set_drvdata(pdev, NULL);
+exit:
+	return ret;
+}
+
+static int __devexit da9058_rtc_remove(struct platform_device *pdev)
+{
+	struct da9058_rtc *rtc = platform_get_drvdata(pdev);
+	struct da9058 *da9058 = rtc->da9058;
+
+	free_irq(da9058_to_virt_irq_num(da9058, rtc->alarm_irq), rtc);
+	free_irq(da9058_to_virt_irq_num(da9058, rtc->tick_irq), rtc);
+
+	rtc_device_unregister(rtc->rtc_dev);
+
+	return 0;
+}
+
+static struct platform_driver da9058_rtc_driver = {
+	.probe = da9058_rtc_probe,
+	.remove = __devexit_p(da9058_rtc_remove),
+	.driver = {
+		.name = "da9058-rtc",
+		.owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(da9058_rtc_driver);
+
+MODULE_DESCRIPTION("Dialog DA9058 PMIC Real Time Clock Driver");
+MODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:da9058-rtc");
