diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-02-17 10:49:05 -0500 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-07-02 10:01:48 -0400 |
commit | de599c8843ebbdfc29a119c94af481b1de76700e (patch) | |
tree | f3c1aa973374bc1c9a29ebdc80e5ef28fbe19c91 /drivers/clocksource/sh_cmt.c | |
parent | 31e912f598371bcfdffc990289029e1110f8b3f9 (diff) |
clocksource: sh_cmt: Replace global spinlock with a per-device spinlock
The global spinlock is used to protect the shared start/stop register.
Now that all CMT channels are handled by a single device instance, use a
per-device spinlock.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/clocksource/sh_cmt.c')
-rw-r--r-- | drivers/clocksource/sh_cmt.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index fcd38db9ce5c..190c655d8352 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -118,6 +118,8 @@ struct sh_cmt_device { | |||
118 | void __iomem *mapbase; | 118 | void __iomem *mapbase; |
119 | struct clk *clk; | 119 | struct clk *clk; |
120 | 120 | ||
121 | raw_spinlock_t lock; /* Protect the shared start/stop register */ | ||
122 | |||
121 | struct sh_cmt_channel *channels; | 123 | struct sh_cmt_channel *channels; |
122 | unsigned int num_channels; | 124 | unsigned int num_channels; |
123 | 125 | ||
@@ -299,14 +301,12 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch, | |||
299 | return v2; | 301 | return v2; |
300 | } | 302 | } |
301 | 303 | ||
302 | static DEFINE_RAW_SPINLOCK(sh_cmt_lock); | ||
303 | |||
304 | static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start) | 304 | static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start) |
305 | { | 305 | { |
306 | unsigned long flags, value; | 306 | unsigned long flags, value; |
307 | 307 | ||
308 | /* start stop register shared by multiple timer channels */ | 308 | /* start stop register shared by multiple timer channels */ |
309 | raw_spin_lock_irqsave(&sh_cmt_lock, flags); | 309 | raw_spin_lock_irqsave(&ch->cmt->lock, flags); |
310 | value = sh_cmt_read_cmstr(ch); | 310 | value = sh_cmt_read_cmstr(ch); |
311 | 311 | ||
312 | if (start) | 312 | if (start) |
@@ -315,7 +315,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start) | |||
315 | value &= ~(1 << ch->timer_bit); | 315 | value &= ~(1 << ch->timer_bit); |
316 | 316 | ||
317 | sh_cmt_write_cmstr(ch, value); | 317 | sh_cmt_write_cmstr(ch, value); |
318 | raw_spin_unlock_irqrestore(&sh_cmt_lock, flags); | 318 | raw_spin_unlock_irqrestore(&ch->cmt->lock, flags); |
319 | } | 319 | } |
320 | 320 | ||
321 | static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate) | 321 | static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate) |
@@ -934,6 +934,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) | |||
934 | 934 | ||
935 | memset(cmt, 0, sizeof(*cmt)); | 935 | memset(cmt, 0, sizeof(*cmt)); |
936 | cmt->pdev = pdev; | 936 | cmt->pdev = pdev; |
937 | raw_spin_lock_init(&cmt->lock); | ||
937 | 938 | ||
938 | if (!cfg) { | 939 | if (!cfg) { |
939 | dev_err(&cmt->pdev->dev, "missing platform data\n"); | 940 | dev_err(&cmt->pdev->dev, "missing platform data\n"); |