Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
timer.c
Go to the documentation of this file.
1 
23 #include <linux/clk.h>
24 #include <linux/io.h>
25 #include <linux/err.h>
26 #include <linux/slab.h>
27 #include <linux/platform_device.h>
28 
29 #include <mach/irqs.h>
30 
31 #include <plat/dmtimer.h>
32 
33 #define OMAP1610_GPTIMER1_BASE 0xfffb1400
34 #define OMAP1610_GPTIMER2_BASE 0xfffb1c00
35 #define OMAP1610_GPTIMER3_BASE 0xfffb2400
36 #define OMAP1610_GPTIMER4_BASE 0xfffb2c00
37 #define OMAP1610_GPTIMER5_BASE 0xfffb3400
38 #define OMAP1610_GPTIMER6_BASE 0xfffb3c00
39 #define OMAP1610_GPTIMER7_BASE 0xfffb7400
40 #define OMAP1610_GPTIMER8_BASE 0xfffbd400
41 
42 #define OMAP1_DM_TIMER_COUNT 8
43 
44 static int omap1_dm_timer_set_src(struct platform_device *pdev,
45  int source)
46 {
47  int n = (pdev->id - 1) << 1;
48  u32 l;
49 
50  l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
51  l |= source << n;
53 
54  return 0;
55 }
56 
57 static int __init omap1_dm_timer_init(void)
58 {
59  int i;
60  int ret;
62  struct platform_device *pdev;
63 
64  if (!cpu_is_omap16xx())
65  return 0;
66 
67  for (i = 1; i <= OMAP1_DM_TIMER_COUNT; i++) {
68  struct resource res[2];
69  u32 base, irq;
70 
71  switch (i) {
72  case 1:
74  irq = INT_1610_GPTIMER1;
75  break;
76  case 2:
78  irq = INT_1610_GPTIMER2;
79  break;
80  case 3:
82  irq = INT_1610_GPTIMER3;
83  break;
84  case 4:
86  irq = INT_1610_GPTIMER4;
87  break;
88  case 5:
90  irq = INT_1610_GPTIMER5;
91  break;
92  case 6:
94  irq = INT_1610_GPTIMER6;
95  break;
96  case 7:
98  irq = INT_1610_GPTIMER7;
99  break;
100  case 8:
101  base = OMAP1610_GPTIMER8_BASE;
102  irq = INT_1610_GPTIMER8;
103  break;
104  default:
105  /*
106  * not supposed to reach here.
107  * this is to remove warning.
108  */
109  return -EINVAL;
110  }
111 
112  pdev = platform_device_alloc("omap_timer", i);
113  if (!pdev) {
114  pr_err("%s: Failed to device alloc for dmtimer%d\n",
115  __func__, i);
116  return -ENOMEM;
117  }
118 
119  memset(res, 0, 2 * sizeof(struct resource));
120  res[0].start = base;
121  res[0].end = base + 0x46;
122  res[0].flags = IORESOURCE_MEM;
123  res[1].start = irq;
124  res[1].end = irq;
125  res[1].flags = IORESOURCE_IRQ;
127  ARRAY_SIZE(res));
128  if (ret) {
129  dev_err(&pdev->dev, "%s: Failed to add resources.\n",
130  __func__);
131  goto err_free_pdev;
132  }
133 
134  pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
135  if (!pdata) {
136  dev_err(&pdev->dev, "%s: Failed to allocate pdata.\n",
137  __func__);
138  ret = -ENOMEM;
139  goto err_free_pdata;
140  }
141 
142  pdata->set_timer_src = omap1_dm_timer_set_src;
145 
146  ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
147  if (ret) {
148  dev_err(&pdev->dev, "%s: Failed to add platform data.\n",
149  __func__);
150  goto err_free_pdata;
151  }
152 
153  ret = platform_device_add(pdev);
154  if (ret) {
155  dev_err(&pdev->dev, "%s: Failed to add platform device.\n",
156  __func__);
157  goto err_free_pdata;
158  }
159 
160  dev_dbg(&pdev->dev, " Registered.\n");
161  }
162 
163  return 0;
164 
165 err_free_pdata:
166  kfree(pdata);
167 
168 err_free_pdev:
170 
171  return ret;
172 }
173 arch_initcall(omap1_dm_timer_init);