diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-03-04 08:23:00 -0500 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-04-16 06:03:30 -0400 |
commit | c54ccb431ce6ce813bb850e8659991fc4c5bc6bc (patch) | |
tree | e39e93c1cc81e79e85920aa92761c641d95a4d14 | |
parent | 810c651369b343618d949826e0acd0df1b8b06eb (diff) |
clocksource: sh_mtu2: Allocate channels dynamically
This prepares the driver for multi-channel support.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Wolfram Sang <wsa@sang-engineering.com>
-rw-r--r-- | drivers/clocksource/sh_mtu2.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 94a53428a556..45e1e85fcbeb 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c | |||
@@ -52,7 +52,8 @@ struct sh_mtu2_device { | |||
52 | void __iomem *mapbase; | 52 | void __iomem *mapbase; |
53 | struct clk *clk; | 53 | struct clk *clk; |
54 | 54 | ||
55 | struct sh_mtu2_channel channel; | 55 | struct sh_mtu2_channel *channels; |
56 | unsigned int num_channels; | ||
56 | }; | 57 | }; |
57 | 58 | ||
58 | static DEFINE_RAW_SPINLOCK(sh_mtu2_lock); | 59 | static DEFINE_RAW_SPINLOCK(sh_mtu2_lock); |
@@ -296,6 +297,7 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu, | |||
296 | { | 297 | { |
297 | struct sh_timer_config *cfg = pdev->dev.platform_data; | 298 | struct sh_timer_config *cfg = pdev->dev.platform_data; |
298 | struct resource *res; | 299 | struct resource *res; |
300 | void __iomem *base; | ||
299 | int ret; | 301 | int ret; |
300 | ret = -ENXIO; | 302 | ret = -ENXIO; |
301 | 303 | ||
@@ -315,16 +317,16 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu, | |||
315 | } | 317 | } |
316 | 318 | ||
317 | /* | 319 | /* |
318 | * Map memory, let channel.base point to our channel and mapbase to the | 320 | * Map memory, let base point to our channel and mapbase to the |
319 | * start/stop shared register. | 321 | * start/stop shared register. |
320 | */ | 322 | */ |
321 | mtu->channel.base = ioremap_nocache(res->start, resource_size(res)); | 323 | base = ioremap_nocache(res->start, resource_size(res)); |
322 | if (mtu->channel.base == NULL) { | 324 | if (base == NULL) { |
323 | dev_err(&mtu->pdev->dev, "failed to remap I/O memory\n"); | 325 | dev_err(&mtu->pdev->dev, "failed to remap I/O memory\n"); |
324 | goto err0; | 326 | goto err0; |
325 | } | 327 | } |
326 | 328 | ||
327 | mtu->mapbase = mtu->channel.base + cfg->channel_offset; | 329 | mtu->mapbase = base + cfg->channel_offset; |
328 | 330 | ||
329 | /* get hold of clock */ | 331 | /* get hold of clock */ |
330 | mtu->clk = clk_get(&mtu->pdev->dev, "mtu2_fck"); | 332 | mtu->clk = clk_get(&mtu->pdev->dev, "mtu2_fck"); |
@@ -338,17 +340,28 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu, | |||
338 | if (ret < 0) | 340 | if (ret < 0) |
339 | goto err2; | 341 | goto err2; |
340 | 342 | ||
341 | ret = sh_mtu2_setup_channel(&mtu->channel, mtu); | 343 | mtu->channels = kzalloc(sizeof(*mtu->channels), GFP_KERNEL); |
344 | if (mtu->channels == NULL) { | ||
345 | ret = -ENOMEM; | ||
346 | goto err3; | ||
347 | } | ||
348 | |||
349 | mtu->num_channels = 1; | ||
350 | |||
351 | mtu->channels[0].base = base; | ||
352 | |||
353 | ret = sh_mtu2_setup_channel(&mtu->channels[0], mtu); | ||
342 | if (ret < 0) | 354 | if (ret < 0) |
343 | goto err3; | 355 | goto err3; |
344 | 356 | ||
345 | return 0; | 357 | return 0; |
346 | err3: | 358 | err3: |
359 | kfree(mtu->channels); | ||
347 | clk_unprepare(mtu->clk); | 360 | clk_unprepare(mtu->clk); |
348 | err2: | 361 | err2: |
349 | clk_put(mtu->clk); | 362 | clk_put(mtu->clk); |
350 | err1: | 363 | err1: |
351 | iounmap(mtu->channel.base); | 364 | iounmap(base); |
352 | err0: | 365 | err0: |
353 | return ret; | 366 | return ret; |
354 | } | 367 | } |