All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
To: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: linux-kernel@vger.kernel.org, Paul Bolle <pebolle@tiscali.nl>,
	Arnd Bergmann <arnd@arndb.de>, Joe Perches <joe@perches.com>,
	Geert Uytterhoeven <geert@linux-m68k.org>
Subject: Re: [PATCHv 1/1] RTC:driver for Cortina's SOC
Date: Sat, 30 May 2015 23:47:41 +0200	[thread overview]
Message-ID: <20150530214741.GK2185@piout.net> (raw)
In-Reply-To: <1432136971-26628-2-git-send-email-ulli.kroll@googlemail.com>

Hi,

On 20/05/2015 at 17:49:31 +0200, Hans Ulli Kroll wrote :
> Driver for the on chip RTC found on Cortina's SoC Gemini.
> 
> Signed-off-by: Hans Ulli Kroll <ulli.kroll@googlemail.com>

I've applied it with a few modifications:
https://git.kernel.org/cgit/linux/kernel/git/abelloni/linux.git/commit/?h=rtc-next&id=a0928c40a908d18f06c05c9db4bdc8e3f0761179

I've removed the need for goto and labels by using devm_request_irq().

> ---
>  MAINTAINERS              |   1 +
>  drivers/rtc/Kconfig      |  11 +++
>  drivers/rtc/Makefile     |   1 +
>  drivers/rtc/rtc-gemini.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 203 insertions(+)
>  create mode 100644 drivers/rtc/rtc-gemini.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f0d922b..3cff87e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -977,6 +977,7 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
>  T:	git git://github.com/ulli-kroll/linux.git
>  S:	Maintained
>  F:	arch/arm/mach-gemini/
> +F:	drivers/rtc/rtc-gemini.c
>  
>  ARM/CSR SIRFPRIMA2 MACHINE SUPPORT
>  M:	Barry Song <baohua@kernel.org>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 0fe4ad8..4a37931 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1372,6 +1372,17 @@ config RTC_DRV_ARMADA38X
>  	  This driver can also be built as a module. If so, the module
>  	  will be called armada38x-rtc.
>  
> +config RTC_DRV_GEMINI
> +	tristate "Gemini SoC RTC"
> +	depends on ARCH_GEMINI || COMPILE_TEST
> +	depends on HAS_IOMEM
> +	help
> +	  If you say Y here you will get support for the
> +	  RTC found on Gemini SoC's.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called rtc-gemini.
> +
>  config RTC_DRV_PS3
>  	tristate "PS3 RTC"
>  	depends on PPC_PS3
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 2b82e2b..ed4057a 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -65,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_EFI)	+= rtc-efi.o
>  obj-$(CONFIG_RTC_DRV_EM3027)	+= rtc-em3027.o
>  obj-$(CONFIG_RTC_DRV_EP93XX)	+= rtc-ep93xx.o
>  obj-$(CONFIG_RTC_DRV_FM3130)	+= rtc-fm3130.o
> +obj-$(CONFIG_RTC_DRV_GEMINI)	+= rtc-gemini.o
>  obj-$(CONFIG_RTC_DRV_GENERIC)	+= rtc-generic.o
>  obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
>  obj-$(CONFIG_RTC_DRV_HYM8563)	+= rtc-hym8563.o
> diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c
> new file mode 100644
> index 0000000..5b36450
> --- /dev/null
> +++ b/drivers/rtc/rtc-gemini.c
> @@ -0,0 +1,190 @@
> +/*
> + *  Gemini OnChip RTC
> + *
> + *  Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * Original code for older kernel 2.6.15 are from Stormlinksemi
> + * first update from Janos Laube for > 2.6.29 kernels
> + *
> + * checkpatch fixes and usage of rtc-lib code
> + * Hans Ulli Kroll <ulli.kroll@googlemail.com>
> + */
> +
> +#include <linux/rtc.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#define DRV_NAME        "rtc-gemini"
> +#define DRV_VERSION     "0.2"
> +
> +MODULE_AUTHOR("Hans Ulli Kroll <ulli.kroll@googlemail.com>");
> +MODULE_DESCRIPTION("RTC driver for Gemini SoC");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:" DRV_NAME);
> +
> +struct gemini_rtc {
> +	struct rtc_device	*rtc_dev;
> +	void __iomem		*rtc_base;
> +	int			rtc_irq;
> +};
> +
> +enum gemini_rtc_offsets {
> +	GEMINI_RTC_SECOND	= 0x00,
> +	GEMINI_RTC_MINUTE	= 0x04,
> +	GEMINI_RTC_HOUR		= 0x08,
> +	GEMINI_RTC_DAYS		= 0x0C,
> +	GEMINI_RTC_ALARM_SECOND	= 0x10,
> +	GEMINI_RTC_ALARM_MINUTE	= 0x14,
> +	GEMINI_RTC_ALARM_HOUR	= 0x18,
> +	GEMINI_RTC_RECORD	= 0x1C,
> +	GEMINI_RTC_CR		= 0x20
> +};
> +
> +static irqreturn_t gemini_rtc_interrupt(int irq, void *dev)
> +{
> +	return IRQ_HANDLED;
> +}
> +
> +/*
> + * Looks like the RTC in the Gemini SoC is (totaly) broken
> + * We can't read/write directly the time from RTC registers.
> + * We must do some "offset" calculation to get the real time
> + *
> + * This FIX works pretty fine and Stormlinksemi aka Cortina-Networks does
> + * the same thing, without the rtc-lib.c calls.
> + */
> +
> +static int gemini_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct gemini_rtc *rtc = dev_get_drvdata(dev);
> +
> +	unsigned int  days, hour, min, sec;
> +	unsigned long offset, time;
> +
> +	sec  = readl(rtc->rtc_base + GEMINI_RTC_SECOND);
> +	min  = readl(rtc->rtc_base + GEMINI_RTC_MINUTE);
> +	hour = readl(rtc->rtc_base + GEMINI_RTC_HOUR);
> +	days = readl(rtc->rtc_base + GEMINI_RTC_DAYS);
> +	offset = readl(rtc->rtc_base + GEMINI_RTC_RECORD);
> +
> +	time = offset + days * 86400 + hour * 3600 + min * 60 + sec;
> +
> +	rtc_time_to_tm(time, tm);
> +
> +	return 0;
> +}
> +
> +static int gemini_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct gemini_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned int sec, min, hour, day;
> +	unsigned long offset, time;
> +
> +	if (tm->tm_year >= 2148)	/* EPOCH Year + 179 */
> +		return -EINVAL;
> +
> +	rtc_tm_to_time(tm, &time);
> +
> +	sec = readl(rtc->rtc_base + GEMINI_RTC_SECOND);
> +	min = readl(rtc->rtc_base + GEMINI_RTC_MINUTE);
> +	hour = readl(rtc->rtc_base + GEMINI_RTC_HOUR);
> +	day = readl(rtc->rtc_base + GEMINI_RTC_DAYS);
> +
> +	offset = time - (day * 86400 + hour * 3600 + min * 60 + sec);
> +
> +	writel(offset, rtc->rtc_base + GEMINI_RTC_RECORD);
> +	writel(0x01, rtc->rtc_base + GEMINI_RTC_CR);
> +
> +	return 0;
> +}
> +
> +static struct rtc_class_ops gemini_rtc_ops = {
> +	.read_time     = gemini_rtc_read_time,
> +	.set_time      = gemini_rtc_set_time,
> +};
> +
> +static int gemini_rtc_probe(struct platform_device *pdev)
> +{
> +	struct gemini_rtc *rtc;
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	int ret;
> +
> +	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
> +	if (unlikely(!rtc))
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, rtc);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +	if (!res) {
> +		ret = -ENODEV;
> +		goto err_mem;
> +	}
> +	rtc->rtc_irq = res->start;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		ret = -ENODEV;
> +		goto err_mem;
> +	}
> +	rtc->rtc_base =	devm_ioremap(&pdev->dev, res->start,
> +				    res->end - res->start + 1);
> +
> +	ret = request_irq(rtc->rtc_irq, gemini_rtc_interrupt,
> +			 IRQF_SHARED, pdev->name, dev);
> +	if (unlikely(ret))
> +		goto err_mem;
> +
> +	rtc->rtc_dev =	rtc_device_register(pdev->name, dev,
> +					   &gemini_rtc_ops, THIS_MODULE);
> +	if (likely(IS_ERR(rtc->rtc_dev))) {
> +		ret = PTR_ERR(rtc->rtc_dev);
> +		goto err_irq;
> +	}
> +	return 0;
> +
> +err_irq:
> +	free_irq(rtc->rtc_irq, dev);
> +
> +err_mem:
> +	kfree(rtc);
> +	return ret;
> +}
> +
> +static int gemini_rtc_remove(struct platform_device *pdev)
> +{
> +	struct gemini_rtc *rtc = platform_get_drvdata(pdev);
> +	struct device *dev = &pdev->dev;
> +
> +	free_irq(rtc->rtc_irq, dev);
> +	rtc_device_unregister(rtc->rtc_dev);
> +	platform_set_drvdata(pdev, NULL);
> +	kfree(rtc);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver gemini_rtc_driver = {
> +	.driver		= {
> +		.name	= DRV_NAME,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= gemini_rtc_probe,
> +	.remove		= gemini_rtc_remove,
> +};
> +
> +module_platform_driver_probe(gemini_rtc_driver, gemini_rtc_probe);
> +
> -- 
> 2.4.0
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

      reply	other threads:[~2015-05-30 21:47 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-20 15:49 [PATCHv6] RTC:driver for Cortina's SOC Hans Ulli Kroll
2015-05-20 15:49 ` [PATCHv 1/1] " Hans Ulli Kroll
2015-05-30 21:47   ` Alexandre Belloni [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150530214741.GK2185@piout.net \
    --to=alexandre.belloni@free-electrons.com \
    --cc=arnd@arndb.de \
    --cc=geert@linux-m68k.org \
    --cc=joe@perches.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pebolle@tiscali.nl \
    --cc=ulli.kroll@googlemail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.