@@ -57,6 +57,7 @@
#include <plat/keypad.h>
#include <linux/platform_data/mmc-s3cmci.h>
#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/samsung-time.h>
#include <plat/sdhci.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
#include <linux/platform_data/usb-s3c2410_udc.h>
@@ -1184,6 +1185,12 @@ struct platform_device samsung_device_pwm = {
.resource = samsung_pwm_resource,
};
+void samsung_timer_init(void)
+{
+ samsung_pwm_register(&samsung_device_pwm);
+ samsung_time_init();
+}
+
/* RTC */
#ifdef CONFIG_PLAT_S3C24XX
@@ -13,6 +13,10 @@
#ifndef __ASM_PLAT_SAMSUNG_TIME_H
#define __ASM_PLAT_SAMSUNG_TIME_H __FILE__
+#include <linux/platform_data/samsung-pwm.h>
+
+#include <plat/devs.h>
+
/* SAMSUNG HR-Timer Clock mode */
enum samsung_timer_mode {
SAMSUNG_PWM0,
@@ -39,8 +43,17 @@ struct samsung_timer_source {
#define TSIZE 32
#endif
-extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
- enum samsung_timer_mode source);
+static inline void samsung_set_timer_source(enum samsung_timer_mode event,
+ enum samsung_timer_mode source)
+{
+ struct samsung_pwm_variant *variant;
+
+ variant = samsung_device_pwm.dev.platform_data;
+ BUG_ON(!variant);
+
+ variant->output_mask = (1 << 5) - 1;
+ variant->output_mask &= ~((1 << event) | (1 << source));
+}
extern void __init samsung_timer_init(void);
@@ -14,19 +14,14 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/clockchips.h>
+#include <linux/mfd/samsung-pwm.h>
#include <linux/platform_device.h>
-#include <asm/smp_twd.h>
-#include <asm/mach/time.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
#include <asm/sched_clock.h>
-#include <mach/map.h>
#include <plat/devs.h>
#include <plat/samsung-time.h>
-
-#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x))
+#define S3C_TIMERREG(x) (pwm->base + (x))
#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c))
#define S3C2410_TCON S3C_TIMERREG(0x08)
@@ -61,6 +56,7 @@
#define S3C2410_TCON_T0MANUALUPD (1<<1)
#define S3C2410_TCON_T0START (1<<0)
+static struct samsung_pwm *pwm;
static struct clk *tin_event;
static struct clk *tin_source;
static struct clk *tdiv_event;
@@ -256,16 +252,9 @@ static void samsung_timer_resume(void)
samsung_time_start(timer_source.source_id, true);
}
-void __init samsung_set_timer_source(enum samsung_timer_mode event,
- enum samsung_timer_mode source)
-{
s3c_device_timer[event].dev.bus = &platform_bus_type;
s3c_device_timer[source].dev.bus = &platform_bus_type;
- timer_source.event_id = event;
- timer_source.source_id = source;
-}
-
static struct clock_event_device time_event_device = {
.name = "samsung_event_timer",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
@@ -311,7 +300,7 @@ static void __init samsung_clockevent_init(void)
time_event_device.cpumask = cpumask_of(0);
clockevents_config_and_register(&time_event_device, clock_rate, 1, -1);
- irq_number = timer_source.event_id + IRQ_TIMER0;
+ irq_number = pwm->irq[timer_source.event_id];
setup_irq(irq_number, &samsung_clock_event_irq);
}
@@ -420,8 +409,31 @@ static void __init samsung_timer_resources(void)
clk_enable(tin_source);
}
-void __init samsung_timer_init(void)
+void __init samsung_time_init(void)
{
+ u8 mask;
+ int channel;
+
+ pwm = samsung_pwm_get(NULL);
+ if (IS_ERR(pwm))
+ panic("failed to get PWM device");
+
+ mask = ~pwm->variant.output_mask & ((1 << SAMSUNG_PWM_NUM) - 1);
+ channel = fls(mask) - 1;
+ if (channel < 0)
+ panic("failed to find PWM channel for clocksource");
+ timer_source.source_id = channel;
+
+ samsung_pwm_request(pwm, channel);
+
+ mask &= ~(1 << channel);
+ channel = fls(mask) - 1;
+ if (channel < 0)
+ panic("failed to find PWM channel for clock event");
+ timer_source.event_id = channel;
+
+ samsung_pwm_request(pwm, channel);
+
samsung_timer_resources();
samsung_clockevent_init();
samsung_clocksource_init();
@@ -24,5 +24,6 @@ struct samsung_pwm_variant {
};
extern int samsung_pwm_register(struct platform_device *pdev);
+extern void samsung_time_init(void);
#endif