source: rtems/bsps/arm/raspberrypi/clock/clockdrv.c

Last change on this file was 7ee59313, checked in by Sebastian Huber <sebastian.huber@…>, on 06/01/18 at 05:11:12

Remove Clock_driver_support_shutdown_hardware()

The aim of this clock driver hook was to stop clock tick interrupts at
some late point in the exit() procedure.

The use of atexit() pulls in malloc() which pulls in errno. It is
incompatible with the intention of the
CONFIGURE_DISABLE_NEWLIB_REENTRANCY configuration option.

The exit() function must be called from thread context, so accompanied
clock tick interrupts should cause no harm. On the contrary, someone
may assume a normal operating system operation, e.g. working timeouts.

Remove the Clock_driver_support_shutdown_hardware() clock driver hook.

Close #3436.

  • Property mode set to 100644
File size: 2.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_clock
5 *
6 * @brief Raspberry Pi clock support.
7 */
8
9/*
10 * BCM2835 Clock driver
11 *
12 * Copyright (c) 2013 Alan Cudmore
13 * Copyright (c) 2016 Pavel Pisa
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *
18 *  http://www.rtems.org/license/LICENSE
19 *
20*/
21
22#include <rtems.h>
23#include <bsp.h>
24#include <bsp/irq.h>
25#include <bsp/irq-generic.h>
26#include <bsp/raspberrypi.h>
27#include <rtems/timecounter.h>
28
29/* This is defined in ../../../shared/dev/clock/clockimpl.h */
30void Clock_isr(rtems_irq_hdl_param arg);
31
32static struct timecounter raspberrypi_tc;
33
34static uint32_t raspberrypi_clock_get_timecount(struct timecounter *tc)
35{
36  return BCM2835_REG(BCM2835_GPU_TIMER_CLO);
37}
38
39static void raspberrypi_clock_at_tick(void)
40{
41  uint32_t act_val;
42  uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_C3);
43  next_cmp += rtems_configuration_get_microseconds_per_tick();
44  BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
45  act_val = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
46
47  /*
48   * Clear interrupt only if there is time left to the next tick.
49   * If time of the next tick has already passed then interrupt
50   * request stays active and fires immediately after current tick
51   * processing is finished.
52   */
53  if ((int32_t)(next_cmp - act_val) > 0)
54    BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
55}
56
57static void raspberrypi_clock_handler_install_isr(
58  rtems_isr_entry clock_isr
59)
60{
61  rtems_status_code sc = RTEMS_SUCCESSFUL;
62
63  if (clock_isr != NULL) {
64    sc = rtems_interrupt_handler_install(
65      BCM2835_IRQ_ID_GPU_TIMER_M3,
66      "Clock",
67      RTEMS_INTERRUPT_UNIQUE,
68      (rtems_interrupt_handler) clock_isr,
69      NULL
70    );
71  } else {
72    /* Remove interrupt handler */
73    sc = rtems_interrupt_handler_remove(
74      BCM2835_IRQ_ID_GPU_TIMER_M3,
75      (rtems_interrupt_handler) Clock_isr,
76      NULL
77    );
78  }
79  if ( sc != RTEMS_SUCCESSFUL ) {
80    rtems_fatal_error_occurred(0xdeadbeef);
81  }
82}
83
84static void raspberrypi_clock_initialize_hardware(void)
85{
86  uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
87  next_cmp += rtems_configuration_get_microseconds_per_tick();
88  BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
89  BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
90
91  raspberrypi_tc.tc_get_timecount = raspberrypi_clock_get_timecount;
92  raspberrypi_tc.tc_counter_mask = 0xffffffff;
93  raspberrypi_tc.tc_frequency = 1000000; /* 1 MHz */
94  raspberrypi_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
95  rtems_timecounter_install(&raspberrypi_tc);
96}
97
98#define Clock_driver_support_at_tick() raspberrypi_clock_at_tick()
99
100#define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize_hardware()
101
102#define Clock_driver_support_install_isr(clock_isr) \
103  raspberrypi_clock_handler_install_isr(clock_isr)
104
105#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1
106
107#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.