in sh_cmt.c [861:921]
static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
unsigned int hwidx, bool clockevent,
bool clocksource, struct sh_cmt_device *cmt)
{
u32 value;
int ret;
/* Skip unused channels. */
if (!clockevent && !clocksource)
return 0;
ch->cmt = cmt;
ch->index = index;
ch->hwidx = hwidx;
ch->timer_bit = hwidx;
/*
* Compute the address of the channel control register block. For the
* timers with a per-channel start/stop register, compute its address
* as well.
*/
switch (cmt->info->model) {
case SH_CMT_16BIT:
ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
break;
case SH_CMT_32BIT:
case SH_CMT_48BIT:
ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
break;
case SH_CMT0_RCAR_GEN2:
case SH_CMT1_RCAR_GEN2:
ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
ch->ioctrl = ch->iostart + 0x10;
ch->timer_bit = 0;
/* Enable the clock supply to the channel */
value = ioread32(cmt->mapbase + CMCLKE);
value |= BIT(hwidx);
iowrite32(value, cmt->mapbase + CMCLKE);
break;
}
if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
ch->max_match_value = ~0;
else
ch->max_match_value = (1 << cmt->info->width) - 1;
ch->match_value = ch->max_match_value;
raw_spin_lock_init(&ch->lock);
ret = sh_cmt_register(ch, dev_name(&cmt->pdev->dev),
clockevent, clocksource);
if (ret) {
dev_err(&cmt->pdev->dev, "ch%u: registration failed\n",
ch->index);
return ret;
}
ch->cs_enabled = false;
return 0;
}