diff options
author | Thierry Reding <thierry.reding@avionic-design.de> | 2012-09-14 04:14:25 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@avionic-design.de> | 2012-10-05 14:56:39 -0400 |
commit | d1b6886502160eb771aefe21c1f891597138ddfe (patch) | |
tree | eee4f1aade9c3b34878ba849301a196532a9fdd0 | |
parent | 60ce70285b4d3b933eea15e494a9b35fe85b19b7 (diff) |
unicore32: pwm: Properly remap memory-mapped registers
Instead of writing to the timer controller registers by dereferencing a
pointer to the memory location, properly remap the memory region with a
call to ioremap_nocache() and access the registers using writel().
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Tested-by: Qin Rui <qinrui@mprc.pku.edu.cn>
-rw-r--r-- | arch/unicore32/include/mach/regs-ost.h | 18 | ||||
-rw-r--r-- | arch/unicore32/kernel/pwm.c | 21 |
2 files changed, 26 insertions, 13 deletions
diff --git a/arch/unicore32/include/mach/regs-ost.h b/arch/unicore32/include/mach/regs-ost.h index 7b91fe698eed..4a85fb463848 100644 --- a/arch/unicore32/include/mach/regs-ost.h +++ b/arch/unicore32/include/mach/regs-ost.h | |||
@@ -33,18 +33,16 @@ | |||
33 | * Interrupt Enable Reg OST_OIER | 33 | * Interrupt Enable Reg OST_OIER |
34 | */ | 34 | */ |
35 | #define OST_OIER (PKUNITY_OST_BASE + 0x001C) | 35 | #define OST_OIER (PKUNITY_OST_BASE + 0x001C) |
36 | |||
36 | /* | 37 | /* |
37 | * PWM Pulse Width Control Reg OST_PWMPWCR | 38 | * PWM Registers: IO base address: PKUNITY_OST_BASE + 0x80 |
38 | */ | 39 | * PWCR: Pulse Width Control Reg |
39 | #define OST_PWMPWCR (PKUNITY_OST_BASE + 0x0080) | 40 | * DCCR: Duty Cycle Control Reg |
40 | /* | 41 | * PCR: Period Control Reg |
41 | * PWM Duty Cycle Control Reg OST_PWMDCCR | ||
42 | */ | ||
43 | #define OST_PWMDCCR (PKUNITY_OST_BASE + 0x0084) | ||
44 | /* | ||
45 | * PWM Period Control Reg OST_PWMPCR | ||
46 | */ | 42 | */ |
47 | #define OST_PWMPCR (PKUNITY_OST_BASE + 0x0088) | 43 | #define OST_PWM_PWCR (0x00) |
44 | #define OST_PWM_DCCR (0x04) | ||
45 | #define OST_PWM_PCR (0x08) | ||
48 | 46 | ||
49 | /* | 47 | /* |
50 | * Match detected 0 OST_OSSR_M0 | 48 | * Match detected 0 OST_OSSR_M0 |
diff --git a/arch/unicore32/kernel/pwm.c b/arch/unicore32/kernel/pwm.c index 4615d51e3ba6..885bbcdc253d 100644 --- a/arch/unicore32/kernel/pwm.c +++ b/arch/unicore32/kernel/pwm.c | |||
@@ -27,6 +27,8 @@ struct pwm_device { | |||
27 | struct list_head node; | 27 | struct list_head node; |
28 | struct platform_device *pdev; | 28 | struct platform_device *pdev; |
29 | 29 | ||
30 | void __iomem *base; | ||
31 | |||
30 | const char *label; | 32 | const char *label; |
31 | struct clk *clk; | 33 | struct clk *clk; |
32 | int clk_enabled; | 34 | int clk_enabled; |
@@ -69,9 +71,11 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | |||
69 | * before writing to the registers | 71 | * before writing to the registers |
70 | */ | 72 | */ |
71 | clk_enable(pwm->clk); | 73 | clk_enable(pwm->clk); |
72 | OST_PWMPWCR = prescale; | 74 | |
73 | OST_PWMDCCR = pv - dc; | 75 | writel(prescale, pwm->base + OST_PWM_PWCR); |
74 | OST_PWMPCR = pv; | 76 | writel(pv - dc, pwm->base + OST_PWM_DCCR); |
77 | writel(pv, pwm->base + OST_PWM_PCR); | ||
78 | |||
75 | clk_disable(pwm->clk); | 79 | clk_disable(pwm->clk); |
76 | 80 | ||
77 | return 0; | 81 | return 0; |
@@ -190,10 +194,19 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev, | |||
190 | goto err_free_clk; | 194 | goto err_free_clk; |
191 | } | 195 | } |
192 | 196 | ||
197 | pwm->base = ioremap_nocache(r->start, resource_size(r)); | ||
198 | if (pwm->base == NULL) { | ||
199 | dev_err(&pdev->dev, "failed to remap memory resource\n"); | ||
200 | ret = -EADDRNOTAVAIL; | ||
201 | goto err_release_mem; | ||
202 | } | ||
203 | |||
193 | __add_pwm(pwm); | 204 | __add_pwm(pwm); |
194 | platform_set_drvdata(pdev, pwm); | 205 | platform_set_drvdata(pdev, pwm); |
195 | return pwm; | 206 | return pwm; |
196 | 207 | ||
208 | err_release_mem: | ||
209 | release_mem_region(r->start, resource_size(r)); | ||
197 | err_free_clk: | 210 | err_free_clk: |
198 | clk_put(pwm->clk); | 211 | clk_put(pwm->clk); |
199 | err_free: | 212 | err_free: |
@@ -224,6 +237,8 @@ static int __devexit pwm_remove(struct platform_device *pdev) | |||
224 | list_del(&pwm->node); | 237 | list_del(&pwm->node); |
225 | mutex_unlock(&pwm_lock); | 238 | mutex_unlock(&pwm_lock); |
226 | 239 | ||
240 | iounmap(pwm->base); | ||
241 | |||
227 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 242 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
228 | release_mem_region(r->start, resource_size(r)); | 243 | release_mem_region(r->start, resource_size(r)); |
229 | 244 | ||