Skip to content

Commit

Permalink
Merge branch 'timers/core' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/tip/tip

Pull timer code update from Thomas Gleixner:
 - armada SoC clocksource overhaul with a trivial merge conflict
 - Minor improvements to various SoC clocksource drivers

* 'timers/core' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  clocksource: armada-370-xp: Add detailed clock requirements in devicetree binding
  clocksource: armada-370-xp: Get reference fixed-clock by name
  clocksource: armada-370-xp: Replace WARN_ON with BUG_ON
  clocksource: armada-370-xp: Fix device-tree binding
  clocksource: armada-370-xp: Introduce new compatibles
  clocksource: armada-370-xp: Use CLOCKSOURCE_OF_DECLARE
  clocksource: armada-370-xp: Simplify TIMER_CTRL register access
  clocksource: armada-370-xp: Use BIT()
  ARM: timer-sp: Set dynamic irq affinity
  ARM: nomadik: add dynamic irq flag to the timer
  clocksource: sh_cmt: 32-bit control register support
  clocksource: em_sti: Convert to devm_* managed helpers
  • Loading branch information
torvalds committed Sep 16, 2013
2 parents 3369d11 + 63ce2cc commit a4ae54f
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,40 @@ Marvell Armada 370 and Armada XP Timers
---------------------------------------

Required properties:
- compatible: Should be "marvell,armada-370-xp-timer"
- compatible: Should be either "marvell,armada-370-timer" or
"marvell,armada-xp-timer" as appropriate.
- interrupts: Should contain the list of Global Timer interrupts and
then local timer interrupts
- reg: Should contain location and length for timers register. First
pair for the Global Timer registers, second pair for the
local/private timers.
- clocks: clock driving the timer hardware

Optional properties:
- marvell,timer-25Mhz: Tells whether the Global timer supports the 25
Mhz fixed mode (available on Armada XP and not on Armada 370)
Clocks required for compatible = "marvell,armada-370-timer":
- clocks : Must contain a single entry describing the clock input

Clocks required for compatible = "marvell,armada-xp-timer":
- clocks : Must contain an entry for each entry in clock-names.
- clock-names : Must include the following entries:
"nbclk" (L2/coherency fabric clock),
"fixed" (Reference 25 MHz fixed-clock).

Examples:

- Armada 370:

timer {
compatible = "marvell,armada-370-timer";
reg = <0x20300 0x30>, <0x21040 0x30>;
interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
clocks = <&coreclk 2>;
};

- Armada XP:

timer {
compatible = "marvell,armada-xp-timer";
reg = <0x20300 0x30>, <0x21040 0x30>;
interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
clocks = <&coreclk 2>, <&refclk>;
clock-names = "nbclk", "fixed";
};
3 changes: 2 additions & 1 deletion arch/arm/common/timer-sp.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ static int sp804_set_next_event(unsigned long next,
}

static struct clock_event_device sp804_clockevent = {
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_DYNIRQ,
.set_mode = sp804_set_mode,
.set_next_event = sp804_set_next_event,
.rating = 300,
Expand Down
4 changes: 2 additions & 2 deletions arch/arm/mach-mvebu/armada-370-xp.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/time-armada-370-xp.h>
#include <linux/clocksource.h>
#include <linux/dma-mapping.h>
#include <linux/mbus.h>
#include <asm/hardware/cache-l2x0.h>
Expand All @@ -37,7 +37,7 @@ static void __init armada_370_xp_map_io(void)
static void __init armada_370_xp_timer_and_clk_init(void)
{
of_clk_init(NULL);
armada_370_xp_timer_init();
clocksource_of_init();
coherency_init();
BUG_ON(mvebu_mbus_dt_init());
#ifdef CONFIG_CACHE_L2X0
Expand Down
49 changes: 14 additions & 35 deletions drivers/clocksource/em_sti.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,68 +315,47 @@ static int em_sti_probe(struct platform_device *pdev)
{
struct em_sti_priv *p;
struct resource *res;
int irq, ret;
int irq;

p = kzalloc(sizeof(*p), GFP_KERNEL);
p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
if (p == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
ret = -ENOMEM;
goto err0;
return -ENOMEM;
}

p->pdev = pdev;
platform_set_drvdata(pdev, p);

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get I/O memory\n");
ret = -EINVAL;
goto err0;
}

irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get irq\n");
ret = -EINVAL;
goto err0;
return -EINVAL;
}

/* map memory, let base point to the STI instance */
p->base = ioremap_nocache(res->start, resource_size(res));
if (p->base == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
ret = -ENXIO;
goto err0;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
p->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(p->base))
return PTR_ERR(p->base);

/* get hold of clock */
p->clk = clk_get(&pdev->dev, "sclk");
p->clk = devm_clk_get(&pdev->dev, "sclk");
if (IS_ERR(p->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
ret = PTR_ERR(p->clk);
goto err1;
return PTR_ERR(p->clk);
}

if (request_irq(irq, em_sti_interrupt,
IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
dev_name(&pdev->dev), p)) {
if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
dev_name(&pdev->dev), p)) {
dev_err(&pdev->dev, "failed to request low IRQ\n");
ret = -ENOENT;
goto err2;
return -ENOENT;
}

raw_spin_lock_init(&p->lock);
em_sti_register_clockevent(p);
em_sti_register_clocksource(p);
return 0;

err2:
clk_put(p->clk);
err1:
iounmap(p->base);
err0:
kfree(p);
return ret;
}

static int em_sti_remove(struct platform_device *pdev)
Expand Down
3 changes: 2 additions & 1 deletion drivers/clocksource/nomadik-mtu.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ static void nmdk_clkevt_resume(struct clock_event_device *cedev)

static struct clock_event_device nmdk_clkevt = {
.name = "mtu_1",
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_DYNIRQ,
.rating = 200,
.set_mode = nmdk_clkevt_mode,
.set_next_event = nmdk_clkevt_next,
Expand Down
50 changes: 36 additions & 14 deletions drivers/clocksource/sh_cmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

struct sh_cmt_priv {
void __iomem *mapbase;
void __iomem *mapbase_str;
struct clk *clk;
unsigned long width; /* 16 or 32 bit version of hardware block */
unsigned long overflow_bit;
Expand Down Expand Up @@ -79,6 +80,12 @@ struct sh_cmt_priv {
* CMCSR 0xffca0060 16-bit
* CMCNT 0xffca0064 32-bit
* CMCOR 0xffca0068 32-bit
*
* "32-bit counter and 32-bit control" as found on r8a73a4 and r8a7790:
* CMSTR 0xffca0500 32-bit
* CMCSR 0xffca0510 32-bit
* CMCNT 0xffca0514 32-bit
* CMCOR 0xffca0518 32-bit
*/

static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
Expand Down Expand Up @@ -109,9 +116,7 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,

static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
{
struct sh_timer_config *cfg = p->pdev->dev.platform_data;

return p->read_control(p->mapbase - cfg->channel_offset, 0);
return p->read_control(p->mapbase_str, 0);
}

static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
Expand All @@ -127,9 +132,7 @@ static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
unsigned long value)
{
struct sh_timer_config *cfg = p->pdev->dev.platform_data;

p->write_control(p->mapbase - cfg->channel_offset, 0, value);
p->write_control(p->mapbase_str, 0, value);
}

static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
Expand Down Expand Up @@ -676,7 +679,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
{
struct sh_timer_config *cfg = pdev->dev.platform_data;
struct resource *res;
struct resource *res, *res2;
int irq, ret;
ret = -ENXIO;

Expand All @@ -694,6 +697,9 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
goto err0;
}

/* optional resource for the shared timer start/stop register */
res2 = platform_get_resource(p->pdev, IORESOURCE_MEM, 1);

irq = platform_get_irq(p->pdev, 0);
if (irq < 0) {
dev_err(&p->pdev->dev, "failed to get irq\n");
Expand All @@ -707,6 +713,15 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
goto err0;
}

/* map second resource for CMSTR */
p->mapbase_str = ioremap_nocache(res2 ? res2->start :
res->start - cfg->channel_offset,
res2 ? resource_size(res2) : 2);
if (p->mapbase_str == NULL) {
dev_err(&p->pdev->dev, "failed to remap I/O second memory\n");
goto err1;
}

/* request irq using setup_irq() (too early for request_irq()) */
p->irqaction.name = dev_name(&p->pdev->dev);
p->irqaction.handler = sh_cmt_interrupt;
Expand All @@ -719,11 +734,17 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
if (IS_ERR(p->clk)) {
dev_err(&p->pdev->dev, "cannot get clock\n");
ret = PTR_ERR(p->clk);
goto err1;
goto err2;
}

p->read_control = sh_cmt_read16;
p->write_control = sh_cmt_write16;
if (res2 && (resource_size(res2) == 4)) {
/* assume both CMSTR and CMCSR to be 32-bit */
p->read_control = sh_cmt_read32;
p->write_control = sh_cmt_write32;
} else {
p->read_control = sh_cmt_read16;
p->write_control = sh_cmt_write16;
}

if (resource_size(res) == 6) {
p->width = 16;
Expand Down Expand Up @@ -752,22 +773,23 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
cfg->clocksource_rating);
if (ret) {
dev_err(&p->pdev->dev, "registration failed\n");
goto err2;
goto err3;
}
p->cs_enabled = false;

ret = setup_irq(irq, &p->irqaction);
if (ret) {
dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
goto err2;
goto err3;
}

platform_set_drvdata(pdev, p);

return 0;
err2:
err3:
clk_put(p->clk);

err2:
iounmap(p->mapbase_str);
err1:
iounmap(p->mapbase);
err0:
Expand Down
Loading

0 comments on commit a4ae54f

Please sign in to comment.