Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
heartbeat.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2009 Michal Simek <[email protected]>
3  * Copyright (C) 2007-2009 PetaLogix
4  * Copyright (C) 2006 Atmark Techno, Inc.
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License. See the file "COPYING" in the main directory of this archive
8  * for more details.
9  */
10 
11 #include <linux/sched.h>
12 #include <linux/io.h>
13 
14 #include <asm/setup.h>
15 #include <asm/page.h>
16 #include <asm/prom.h>
17 
18 static unsigned int base_addr;
19 
20 void heartbeat(void)
21 {
22  static unsigned int cnt, period, dist;
23 
24  if (base_addr) {
25  if (cnt == 0 || cnt == dist)
26  out_be32(base_addr, 1);
27  else if (cnt == 7 || cnt == dist + 7)
28  out_be32(base_addr, 0);
29 
30  if (++cnt > period) {
31  cnt = 0;
32  /*
33  * The hyperbolic function below modifies the heartbeat
34  * period length in dependency of the current (5min)
35  * load. It goes through the points f(0)=126, f(1)=86,
36  * f(5)=51, f(inf)->30.
37  */
38  period = ((672 << FSHIFT) / (5 * avenrun[0] +
39  (7 << FSHIFT))) + 30;
40  dist = period / 4;
41  }
42  }
43 }
44 
45 void setup_heartbeat(void)
46 {
47  struct device_node *gpio = NULL;
48  int *prop;
49  int j;
50  const char * const gpio_list[] = {
51  "xlnx,xps-gpio-1.00.a",
52  NULL
53  };
54 
55  for (j = 0; gpio_list[j] != NULL; j++) {
56  gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
57  if (gpio)
58  break;
59  }
60 
61  if (gpio) {
62  base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
63  base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
64  printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
65 
66  /* GPIO is configured as output */
67  prop = (int *) of_get_property(gpio, "xlnx,is-bidir", NULL);
68  if (prop)
69  out_be32(base_addr + 4, 0);
70  }
71 }