Skip to content

Commit

Permalink
Merge branch 'rtc-sa1100' of git://github.com/hzhuang1/linux into nex…
Browse files Browse the repository at this point in the history
…t/drivers

* 'rtc-sa1100' of git://github.com/hzhuang1/linux:
  ARM: mmp: enable rtc in pxa910
  rtc: sa1100: enable clk support
  ARM: pxa: add rtc dummy clock
  ARM: sa1100: clean up clock support
  rtc: sa1100: declare irq in resource
  rtc: sa1100: remove verification code of alarm
  rtc: sa1100: remove periodic code
  • Loading branch information
Arnd Bergmann committed Feb 28, 2012
2 parents e135e45 + 4128e27 commit 7169ff4
Show file tree
Hide file tree
Showing 15 changed files with 234 additions and 145 deletions.
2 changes: 1 addition & 1 deletion arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ config ARCH_SA1100
select ARCH_HAS_CPUFREQ
select CPU_FREQ
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select CLKDEV_LOOKUP
select HAVE_SCHED_CLOCK
select TICK_ONESHOT
select ARCH_REQUIRE_GPIOLIB
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-mmp/include/mach/pxa910.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern struct pxa_device_desc pxa910_device_pwm4;
extern struct pxa_device_desc pxa910_device_nand;

extern struct platform_device pxa910_device_gpio;
extern struct platform_device pxa910_device_rtc;

static inline int pxa910_add_uart(int id)
{
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-mmp/include/mach/regs-apbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#define APBC_PXA910_SSP1 APBC_REG(0x01c)
#define APBC_PXA910_SSP2 APBC_REG(0x020)
#define APBC_PXA910_IPC APBC_REG(0x024)
#define APBC_PXA910_RTC APBC_REG(0x028)
#define APBC_PXA910_TWSI0 APBC_REG(0x02c)
#define APBC_PXA910_KPC APBC_REG(0x030)
#define APBC_PXA910_TIMERS APBC_REG(0x034)
Expand Down
23 changes: 23 additions & 0 deletions arch/arm/mach-mmp/include/mach/regs-rtc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef __ASM_MACH_REGS_RTC_H
#define __ASM_MACH_REGS_RTC_H

#include <mach/addr-map.h>

#define RTC_VIRT_BASE (APB_VIRT_BASE + 0x10000)
#define RTC_REG(x) (*((volatile u32 __iomem *)(RTC_VIRT_BASE + (x))))

/*
* Real Time Clock
*/

#define RCNR RTC_REG(0x00) /* RTC Count Register */
#define RTAR RTC_REG(0x04) /* RTC Alarm Register */
#define RTSR RTC_REG(0x08) /* RTC Status Register */
#define RTTR RTC_REG(0x0C) /* RTC Timer Trim Register */

#define RTSR_HZE (1 << 3) /* HZ interrupt enable */
#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */
#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */
#define RTSR_AL (1 << 0) /* RTC alarm detected */

#endif /* __ASM_MACH_REGS_RTC_H */
27 changes: 27 additions & 0 deletions arch/arm/mach-mmp/pxa910.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
static APBC_CLK(gpio, PXA910_GPIO, 0, 13000000);
static APBC_CLK(rtc, PXA910_RTC, 8, 32768);

static APMU_CLK(nand, NAND, 0x19b, 156000000);
static APMU_CLK(u2o, USB, 0x1b, 480000000);
Expand All @@ -109,6 +110,7 @@ static struct clk_lookup pxa910_clkregs[] = {
INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"),
INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
};

static int __init pxa910_init(void)
Expand Down Expand Up @@ -183,3 +185,28 @@ struct platform_device pxa910_device_gpio = {
.num_resources = ARRAY_SIZE(pxa910_resource_gpio),
.resource = pxa910_resource_gpio,
};

static struct resource pxa910_resource_rtc[] = {
{
.start = 0xd4010000,
.end = 0xd401003f,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_PXA910_RTC_INT,
.end = IRQ_PXA910_RTC_INT,
.name = "rtc 1Hz",
.flags = IORESOURCE_IRQ,
}, {
.start = IRQ_PXA910_RTC_ALARM,
.end = IRQ_PXA910_RTC_ALARM,
.name = "rtc alarm",
.flags = IORESOURCE_IRQ,
},
};

struct platform_device pxa910_device_rtc = {
.name = "sa1100-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(pxa910_resource_rtc),
.resource = pxa910_resource_rtc,
};
1 change: 1 addition & 0 deletions arch/arm/mach-mmp/ttc_dkb.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ static struct platform_device ttc_dkb_device_onenand = {

static struct platform_device *ttc_dkb_devices[] = {
&pxa910_device_gpio,
&pxa910_device_rtc,
&ttc_dkb_device_onenand,
};

Expand Down
28 changes: 23 additions & 5 deletions arch/arm/mach-pxa/devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,27 +406,45 @@ static struct resource pxa_rtc_resources[] = {
[1] = {
.start = IRQ_RTC1Hz,
.end = IRQ_RTC1Hz,
.name = "rtc 1Hz",
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_RTCAlrm,
.end = IRQ_RTCAlrm,
.name = "rtc alarm",
.flags = IORESOURCE_IRQ,
},
};

struct platform_device sa1100_device_rtc = {
.name = "sa1100-rtc",
.id = -1,
};

struct platform_device pxa_device_rtc = {
.name = "pxa-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(pxa_rtc_resources),
.resource = pxa_rtc_resources,
};

static struct resource sa1100_rtc_resources[] = {
{
.start = IRQ_RTC1Hz,
.end = IRQ_RTC1Hz,
.name = "rtc 1Hz",
.flags = IORESOURCE_IRQ,
}, {
.start = IRQ_RTCAlrm,
.end = IRQ_RTCAlrm,
.name = "rtc alarm",
.flags = IORESOURCE_IRQ,
},
};

struct platform_device sa1100_device_rtc = {
.name = "sa1100-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(sa1100_rtc_resources),
.resource = sa1100_rtc_resources,
};

static struct resource pxa_ac97_resources[] = {
[0] = {
.start = 0x40500000,
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-pxa/pxa25x.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ static struct clk_lookup pxa25x_clkregs[] = {
INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};

static struct clk_lookup pxa25x_hwuart_clkreg =
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-pxa/pxa27x.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ static struct clk_lookup pxa27x_clkregs[] = {
INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};

#ifdef CONFIG_PM
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-pxa/pxa3xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
INIT_CLKREG(&clk_pxa3xx_gpio, "pxa-gpio", NULL),
INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};

#ifdef CONFIG_PM
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-pxa/pxa95x.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ static struct clk_lookup pxa95x_clkregs[] = {
INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL),
INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL),
INIT_CLKREG(&clk_pxa95x_gpio, "pxa-gpio", NULL),
INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};

void __init pxa95x_init_irq(void)
Expand Down
82 changes: 47 additions & 35 deletions arch/arm/mach-sa1100/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,29 @@
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/io.h>
#include <linux/clkdev.h>

#include <mach/hardware.h>

/*
* Very simple clock implementation - we only have one clock to deal with.
*/
struct clkops {
void (*enable)(struct clk *);
void (*disable)(struct clk *);
};

struct clk {
const struct clkops *ops;
unsigned int enabled;
};

static void clk_gpio27_enable(void)
#define DEFINE_CLK(_name, _ops) \
struct clk clk_##_name = { \
.ops = _ops, \
}

static DEFINE_SPINLOCK(clocks_lock);

static void clk_gpio27_enable(struct clk *clk)
{
/*
* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
Expand All @@ -32,38 +44,24 @@ static void clk_gpio27_enable(void)
TUCR = TUCR_3_6864MHz;
}

static void clk_gpio27_disable(void)
static void clk_gpio27_disable(struct clk *clk)
{
TUCR = 0;
GPDR &= ~GPIO_32_768kHz;
GAFR &= ~GPIO_32_768kHz;
}

static struct clk clk_gpio27;

static DEFINE_SPINLOCK(clocks_lock);

struct clk *clk_get(struct device *dev, const char *id)
{
const char *devname = dev_name(dev);

return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
}
EXPORT_SYMBOL(clk_get);

void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);

int clk_enable(struct clk *clk)
{
unsigned long flags;

spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
clk_gpio27_enable();
spin_unlock_irqrestore(&clocks_lock, flags);
if (clk) {
spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
clk->ops->enable(clk);
spin_unlock_irqrestore(&clocks_lock, flags);
}

return 0;
}
EXPORT_SYMBOL(clk_enable);
Expand All @@ -72,17 +70,31 @@ void clk_disable(struct clk *clk)
{
unsigned long flags;

WARN_ON(clk->enabled == 0);

spin_lock_irqsave(&clocks_lock, flags);
if (--clk->enabled == 0)
clk_gpio27_disable();
spin_unlock_irqrestore(&clocks_lock, flags);
if (clk) {
WARN_ON(clk->enabled == 0);
spin_lock_irqsave(&clocks_lock, flags);
if (--clk->enabled == 0)
clk->ops->disable(clk);
spin_unlock_irqrestore(&clocks_lock, flags);
}
}
EXPORT_SYMBOL(clk_disable);

unsigned long clk_get_rate(struct clk *clk)
const struct clkops clk_gpio27_ops = {
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
};

static DEFINE_CLK(gpio27, &clk_gpio27_ops);

static struct clk_lookup sa11xx_clkregs[] = {
CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
CLKDEV_INIT("sa1100-rtc", NULL, NULL),
};

static int __init sa11xx_clk_init(void)
{
return 3686400;
clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
return 0;
}
EXPORT_SYMBOL(clk_get_rate);
core_initcall(sa11xx_clk_init);
8 changes: 8 additions & 0 deletions arch/arm/mach-sa1100/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,17 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
sa11x0_register_device(&sa11x0ir_device, irda);
}

static struct resource sa1100_rtc_resources[] = {
DEFINE_RES_MEM(0x90010000, 0x9001003f),
DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
};

static struct platform_device sa11x0rtc_device = {
.name = "sa1100-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(sa1100_rtc_resources),
.resource = sa1100_rtc_resources,
};

static struct platform_device *sa11x0_devices[] __initdata = {
Expand Down
4 changes: 2 additions & 2 deletions drivers/rtc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -773,8 +773,8 @@ config RTC_DRV_EP93XX
will be called rtc-ep93xx.

config RTC_DRV_SA1100
tristate "SA11x0/PXA2xx"
depends on ARCH_SA1100 || ARCH_PXA
tristate "SA11x0/PXA2xx/PXA910"
depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP
help
If you say Y here you will get access to the real time clock
built into your SA11x0 or PXA2xx CPU.
Expand Down
Loading

0 comments on commit 7169ff4

Please sign in to comment.