Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd1364a7 authored by Daniel Lezcano's avatar Daniel Lezcano
Browse files

clocksource/drivers/nios2: Convert init function to return error



The init functions do not return any error. They behave as the following:

  - panic, thus leading to a kernel crash while another timer may work and
       make the system boot up correctly

  or

  - print an error and let the caller unaware if the state of the system

Change that by converting the init functions to return an error conforming
to the CLOCKSOURCE_OF_RET prototype.

Proper error handling (rollback, errno value) will be changed later case
by case, thus this change just return back an error or success in the init
function.

Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
parent 2712616f
Loading
Loading
Loading
Loading
+45 −20
Original line number Diff line number Diff line
@@ -206,15 +206,21 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static void __init nios2_timer_get_base_and_freq(struct device_node *np,
static int __init nios2_timer_get_base_and_freq(struct device_node *np,
				void __iomem **base, u32 *freq)
{
	*base = of_iomap(np, 0);
	if (!*base)
		panic("Unable to map reg for %s\n", np->name);
	if (!*base) {
		pr_crit("Unable to map reg for %s\n", np->name);
		return -ENXIO;
	}

	if (of_property_read_u32(np, "clock-frequency", freq)) {
		pr_crit("Unable to get %s clock frequency\n", np->name);
		return -EINVAL;
	}

	if (of_property_read_u32(np, "clock-frequency", freq))
		panic("Unable to get %s clock frequency\n", np->name);
	return 0;
}

static struct nios2_clockevent_dev nios2_ce = {
@@ -231,17 +237,21 @@ static struct nios2_clockevent_dev nios2_ce = {
	},
};

static __init void nios2_clockevent_init(struct device_node *timer)
static __init int nios2_clockevent_init(struct device_node *timer)
{
	void __iomem *iobase;
	u32 freq;
	int irq;
	int irq, ret;

	nios2_timer_get_base_and_freq(timer, &iobase, &freq);
	ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq);
	if (ret)
		return ret;

	irq = irq_of_parse_and_map(timer, 0);
	if (!irq)
		panic("Unable to parse timer irq\n");
	if (!irq) {
		pr_crit("Unable to parse timer irq\n");
		return -EINVAL;
	}

	nios2_ce.timer.base = iobase;
	nios2_ce.timer.freq = freq;
@@ -253,25 +263,35 @@ static __init void nios2_clockevent_init(struct device_node *timer)
	/* clear pending interrupt */
	timer_writew(&nios2_ce.timer, 0, ALTERA_TIMER_STATUS_REG);

	if (request_irq(irq, timer_interrupt, IRQF_TIMER, timer->name,
		&nios2_ce.ced))
		panic("Unable to setup timer irq\n");
	ret = request_irq(irq, timer_interrupt, IRQF_TIMER, timer->name,
			  &nios2_ce.ced);
	if (ret) {
		pr_crit("Unable to setup timer irq\n");
		return ret;
	}

	clockevents_config_and_register(&nios2_ce.ced, freq, 1, ULONG_MAX);

	return 0;
}

static __init void nios2_clocksource_init(struct device_node *timer)
static __init int nios2_clocksource_init(struct device_node *timer)
{
	unsigned int ctrl;
	void __iomem *iobase;
	u32 freq;
	int ret;

	nios2_timer_get_base_and_freq(timer, &iobase, &freq);
	ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq);
	if (ret)
		return ret;

	nios2_cs.timer.base = iobase;
	nios2_cs.timer.freq = freq;

	clocksource_register_hz(&nios2_cs.cs, freq);
	ret = clocksource_register_hz(&nios2_cs.cs, freq);
	if (ret)
		return ret;

	timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODL_REG);
	timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODH_REG);
@@ -282,6 +302,8 @@ static __init void nios2_clocksource_init(struct device_node *timer)

	/* Calibrate the delay loop directly */
	lpj_fine = freq / HZ;

	return 0;
}

/*
@@ -289,22 +311,25 @@ static __init void nios2_clocksource_init(struct device_node *timer)
 * more instances, the second one gets used as clocksource and all
 * others are unused.
*/
static void __init nios2_time_init(struct device_node *timer)
static int __init nios2_time_init(struct device_node *timer)
{
	static int num_called;
	int ret;

	switch (num_called) {
	case 0:
		nios2_clockevent_init(timer);
		ret = nios2_clockevent_init(timer);
		break;
	case 1:
		nios2_clocksource_init(timer);
		ret = nios2_clocksource_init(timer);
		break;
	default:
		break;
	}

	num_called++;

	return ret;
}

void read_persistent_clock(struct timespec *ts)
@@ -327,4 +352,4 @@ void __init time_init(void)
	clocksource_probe();
}

CLOCKSOURCE_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);
CLOCKSOURCE_OF_DECLARE_RET(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);