aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-sa1100
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:41:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:41:24 -0400
commit34800598b2eebe061445216473b1e4c2ff5cba99 (patch)
treea6d0eb6fe45d9480888d7ddb34840e172ed80e56 /arch/arm/mach-sa1100
parent46b407ca4a6149c8d27fcec1881d4f184bec7c77 (diff)
parent511f1cb6d426938fabf9c6d69ce4861b66ffd919 (diff)
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull "ARM: driver specific updates" from Arnd Bergmann: "These are all specific to some driver. They are typically the platform side of a change in the drivers directory, such as adding a new driver or extending the interface to the platform. In cases where there is no maintainer for the driver, or the maintainer prefers to have the platform changes in the same branch as the driver changes, the patches to the drivers are included as well. A much smaller set of driver updates that depend on other branches getting merged first will be sent later. The new export of tegra_chip_uid conflicts with other changes in fuse.c. In rtc-sa1100.c, the global removal of IRQF_DISABLED conflicts with the cleanup of the interrupt handling of that driver. Signed-off-by: Arnd Bergmann <arnd@arndb.de>" Fixed up aforementioned trivial conflicts. * tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (94 commits) ARM: SAMSUNG: change the name from s3c-sdhci to exynos4-sdhci mmc: sdhci-s3c: add platform data for the second capability ARM: SAMSUNG: support the second capability for samsung-soc ARM: EXYNOS: add support DMA for EXYNOS4X12 SoC ARM: EXYNOS: Add apb_pclk clkdev entry for mdma1 ARM: EXYNOS: Enable MDMA driver regulator: Remove bq24022 regulator driver rtc: sa1100: add OF support pxa: magician/hx4700: Convert to gpio-regulator from bq24022 ARM: OMAP3+: SmartReflex: fix error handling ARM: OMAP3+: SmartReflex: fix the use of debugfs_create_* API ARM: OMAP3+: SmartReflex: micro-optimization for sanity check ARM: OMAP3+: SmartReflex: misc cleanups ARM: OMAP3+: SmartReflex: move late_initcall() closer to its argument ARM: OMAP3+: SmartReflex: add missing platform_set_drvdata() ARM: OMAP3+: hwmod: add SmartReflex IRQs ARM: OMAP3+: SmartReflex: clear ERRCONFIG_VPBOUNDINTST only on a need ARM: OMAP3+: SmartReflex: Fix status masking in ERRCONFIG register ARM: OMAP3+: SmartReflex: Add a shutdown hook ARM: OMAP3+: SmartReflex Class3: disable errorgen before disable VP ... Conflicts: arch/arm/mach-tegra/Makefile arch/arm/mach-tegra/fuse.c drivers/rtc/rtc-sa1100.c
Diffstat (limited to 'arch/arm/mach-sa1100')
-rw-r--r--arch/arm/mach-sa1100/clock.c82
-rw-r--r--arch/arm/mach-sa1100/generic.c8
2 files changed, 55 insertions, 35 deletions
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index dab3c6347a8f..172ebd0ee0a2 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -11,17 +11,29 @@
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/mutex.h> 13#include <linux/mutex.h>
14#include <linux/io.h>
15#include <linux/clkdev.h>
14 16
15#include <mach/hardware.h> 17#include <mach/hardware.h>
16 18
17/* 19struct clkops {
18 * Very simple clock implementation - we only have one clock to deal with. 20 void (*enable)(struct clk *);
19 */ 21 void (*disable)(struct clk *);
22};
23
20struct clk { 24struct clk {
25 const struct clkops *ops;
21 unsigned int enabled; 26 unsigned int enabled;
22}; 27};
23 28
24static void clk_gpio27_enable(void) 29#define DEFINE_CLK(_name, _ops) \
30struct clk clk_##_name = { \
31 .ops = _ops, \
32 }
33
34static DEFINE_SPINLOCK(clocks_lock);
35
36static void clk_gpio27_enable(struct clk *clk)
25{ 37{
26 /* 38 /*
27 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: 39 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
@@ -32,38 +44,24 @@ static void clk_gpio27_enable(void)
32 TUCR = TUCR_3_6864MHz; 44 TUCR = TUCR_3_6864MHz;
33} 45}
34 46
35static void clk_gpio27_disable(void) 47static void clk_gpio27_disable(struct clk *clk)
36{ 48{
37 TUCR = 0; 49 TUCR = 0;
38 GPDR &= ~GPIO_32_768kHz; 50 GPDR &= ~GPIO_32_768kHz;
39 GAFR &= ~GPIO_32_768kHz; 51 GAFR &= ~GPIO_32_768kHz;
40} 52}
41 53
42static struct clk clk_gpio27;
43
44static DEFINE_SPINLOCK(clocks_lock);
45
46struct clk *clk_get(struct device *dev, const char *id)
47{
48 const char *devname = dev_name(dev);
49
50 return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
51}
52EXPORT_SYMBOL(clk_get);
53
54void clk_put(struct clk *clk)
55{
56}
57EXPORT_SYMBOL(clk_put);
58
59int clk_enable(struct clk *clk) 54int clk_enable(struct clk *clk)
60{ 55{
61 unsigned long flags; 56 unsigned long flags;
62 57
63 spin_lock_irqsave(&clocks_lock, flags); 58 if (clk) {
64 if (clk->enabled++ == 0) 59 spin_lock_irqsave(&clocks_lock, flags);
65 clk_gpio27_enable(); 60 if (clk->enabled++ == 0)
66 spin_unlock_irqrestore(&clocks_lock, flags); 61 clk->ops->enable(clk);
62 spin_unlock_irqrestore(&clocks_lock, flags);
63 }
64
67 return 0; 65 return 0;
68} 66}
69EXPORT_SYMBOL(clk_enable); 67EXPORT_SYMBOL(clk_enable);
@@ -72,17 +70,31 @@ void clk_disable(struct clk *clk)
72{ 70{
73 unsigned long flags; 71 unsigned long flags;
74 72
75 WARN_ON(clk->enabled == 0); 73 if (clk) {
76 74 WARN_ON(clk->enabled == 0);
77 spin_lock_irqsave(&clocks_lock, flags); 75 spin_lock_irqsave(&clocks_lock, flags);
78 if (--clk->enabled == 0) 76 if (--clk->enabled == 0)
79 clk_gpio27_disable(); 77 clk->ops->disable(clk);
80 spin_unlock_irqrestore(&clocks_lock, flags); 78 spin_unlock_irqrestore(&clocks_lock, flags);
79 }
81} 80}
82EXPORT_SYMBOL(clk_disable); 81EXPORT_SYMBOL(clk_disable);
83 82
84unsigned long clk_get_rate(struct clk *clk) 83const struct clkops clk_gpio27_ops = {
84 .enable = clk_gpio27_enable,
85 .disable = clk_gpio27_disable,
86};
87
88static DEFINE_CLK(gpio27, &clk_gpio27_ops);
89
90static struct clk_lookup sa11xx_clkregs[] = {
91 CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
92 CLKDEV_INIT("sa1100-rtc", NULL, NULL),
93};
94
95static int __init sa11xx_clk_init(void)
85{ 96{
86 return 3686400; 97 clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
98 return 0;
87} 99}
88EXPORT_SYMBOL(clk_get_rate); 100core_initcall(sa11xx_clk_init);
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index bb10ee2cb89f..7c1ebf4a7920 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -345,9 +345,17 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
345 sa11x0_register_device(&sa11x0ir_device, irda); 345 sa11x0_register_device(&sa11x0ir_device, irda);
346} 346}
347 347
348static struct resource sa1100_rtc_resources[] = {
349 DEFINE_RES_MEM(0x90010000, 0x9001003f),
350 DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
351 DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
352};
353
348static struct platform_device sa11x0rtc_device = { 354static struct platform_device sa11x0rtc_device = {
349 .name = "sa1100-rtc", 355 .name = "sa1100-rtc",
350 .id = -1, 356 .id = -1,
357 .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
358 .resource = sa1100_rtc_resources,
351}; 359};
352 360
353static struct platform_device *sa11x0_devices[] __initdata = { 361static struct platform_device *sa11x0_devices[] __initdata = {