Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cs5535-mfgpt.c
Go to the documentation of this file.
1 /*
2  * Driver for the CS5535/CS5536 Multi-Function General Purpose Timers (MFGPT)
3  *
4  * Copyright (C) 2006, Advanced Micro Devices, Inc.
5  * Copyright (C) 2007 Andres Salomon <[email protected]>
6  * Copyright (C) 2009 Andres Salomon <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of version 2 of the GNU General Public License
10  * as published by the Free Software Foundation.
11  *
12  * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book.
13  */
14 
15 #include <linux/kernel.h>
16 #include <linux/spinlock.h>
17 #include <linux/interrupt.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/cs5535.h>
21 #include <linux/slab.h>
22 
23 #define DRV_NAME "cs5535-mfgpt"
24 
25 static int mfgpt_reset_timers;
26 module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644);
27 MODULE_PARM_DESC(mfgptfix, "Reset the MFGPT timers during init; "
28  "required by some broken BIOSes (ie, TinyBIOS < 0.99).");
29 
31  struct cs5535_mfgpt_chip *chip;
32  int nr;
33 };
34 
35 static struct cs5535_mfgpt_chip {
38 
39  struct platform_device *pdev;
41  int initialized;
42 } cs5535_mfgpt_chip;
43 
45  int event, int enable)
46 {
47  uint32_t msr, mask, value, dummy;
48  int shift = (cmp == MFGPT_CMP1) ? 0 : 8;
49 
50  if (!timer) {
51  WARN_ON(1);
52  return -EIO;
53  }
54 
55  /*
56  * The register maps for these are described in sections 6.17.1.x of
57  * the AMD Geode CS5536 Companion Device Data Book.
58  */
59  switch (event) {
60  case MFGPT_EVENT_RESET:
61  /*
62  * XXX: According to the docs, we cannot reset timers above
63  * 6; that is, resets for 7 and 8 will be ignored. Is this
64  * a problem? -dilinger
65  */
66  msr = MSR_MFGPT_NR;
67  mask = 1 << (timer->nr + 24);
68  break;
69 
70  case MFGPT_EVENT_NMI:
71  msr = MSR_MFGPT_NR;
72  mask = 1 << (timer->nr + shift);
73  break;
74 
75  case MFGPT_EVENT_IRQ:
76  msr = MSR_MFGPT_IRQ;
77  mask = 1 << (timer->nr + shift);
78  break;
79 
80  default:
81  return -EIO;
82  }
83 
84  rdmsr(msr, value, dummy);
85 
86  if (enable)
87  value |= mask;
88  else
89  value &= ~mask;
90 
91  wrmsr(msr, value, dummy);
92  return 0;
93 }
95 
96 int cs5535_mfgpt_set_irq(struct cs5535_mfgpt_timer *timer, int cmp, int *irq,
97  int enable)
98 {
99  uint32_t zsel, lpc, dummy;
100  int shift;
101 
102  if (!timer) {
103  WARN_ON(1);
104  return -EIO;
105  }
106 
107  /*
108  * Unfortunately, MFGPTs come in pairs sharing their IRQ lines. If VSA
109  * is using the same CMP of the timer's Siamese twin, the IRQ is set to
110  * 2, and we mustn't use nor change it.
111  * XXX: Likewise, 2 Linux drivers might clash if the 2nd overwrites the
112  * IRQ of the 1st. This can only happen if forcing an IRQ, calling this
113  * with *irq==0 is safe. Currently there _are_ no 2 drivers.
114  */
115  rdmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
116  shift = ((cmp == MFGPT_CMP1 ? 0 : 4) + timer->nr % 4) * 4;
117  if (((zsel >> shift) & 0xF) == 2)
118  return -EIO;
119 
120  /* Choose IRQ: if none supplied, keep IRQ already set or use default */
121  if (!*irq)
122  *irq = (zsel >> shift) & 0xF;
123  if (!*irq)
124  *irq = CONFIG_CS5535_MFGPT_DEFAULT_IRQ;
125 
126  /* Can't use IRQ if it's 0 (=disabled), 2, or routed to LPC */
127  if (*irq < 1 || *irq == 2 || *irq > 15)
128  return -EIO;
129  rdmsr(MSR_PIC_IRQM_LPC, lpc, dummy);
130  if (lpc & (1 << *irq))
131  return -EIO;
132 
133  /* All chosen and checked - go for it */
134  if (cs5535_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable))
135  return -EIO;
136  if (enable) {
137  zsel = (zsel & ~(0xF << shift)) | (*irq << shift);
138  wrmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
139  }
140 
141  return 0;
142 }
144 
145 struct cs5535_mfgpt_timer *cs5535_mfgpt_alloc_timer(int timer_nr, int domain)
146 {
147  struct cs5535_mfgpt_chip *mfgpt = &cs5535_mfgpt_chip;
148  struct cs5535_mfgpt_timer *timer = NULL;
149  unsigned long flags;
150  int max;
151 
152  if (!mfgpt->initialized)
153  goto done;
154 
155  /* only allocate timers from the working domain if requested */
156  if (domain == MFGPT_DOMAIN_WORKING)
157  max = 6;
158  else
159  max = MFGPT_MAX_TIMERS;
160 
161  if (timer_nr >= max) {
162  /* programmer error. silly programmers! */
163  WARN_ON(1);
164  goto done;
165  }
166 
167  spin_lock_irqsave(&mfgpt->lock, flags);
168  if (timer_nr < 0) {
169  unsigned long t;
170 
171  /* try to find any available timer */
172  t = find_first_bit(mfgpt->avail, max);
173  /* set timer_nr to -1 if no timers available */
174  timer_nr = t < max ? (int) t : -1;
175  } else {
176  /* check if the requested timer's available */
177  if (!test_bit(timer_nr, mfgpt->avail))
178  timer_nr = -1;
179  }
180 
181  if (timer_nr >= 0)
182  /* if timer_nr is not -1, it's an available timer */
183  __clear_bit(timer_nr, mfgpt->avail);
184  spin_unlock_irqrestore(&mfgpt->lock, flags);
185 
186  if (timer_nr < 0)
187  goto done;
188 
189  timer = kmalloc(sizeof(*timer), GFP_KERNEL);
190  if (!timer) {
191  /* aw hell */
192  spin_lock_irqsave(&mfgpt->lock, flags);
193  __set_bit(timer_nr, mfgpt->avail);
194  spin_unlock_irqrestore(&mfgpt->lock, flags);
195  goto done;
196  }
197  timer->chip = mfgpt;
198  timer->nr = timer_nr;
199  dev_info(&mfgpt->pdev->dev, "registered timer %d\n", timer_nr);
200 
201 done:
202  return timer;
203 }
205 
206 /*
207  * XXX: This frees the timer memory, but never resets the actual hardware
208  * timer. The old geode_mfgpt code did this; it would be good to figure
209  * out a way to actually release the hardware timer. See comments below.
210  */
212 {
213  unsigned long flags;
214  uint16_t val;
215 
216  /* timer can be made available again only if never set up */
217  val = cs5535_mfgpt_read(timer, MFGPT_REG_SETUP);
218  if (!(val & MFGPT_SETUP_SETUP)) {
219  spin_lock_irqsave(&timer->chip->lock, flags);
220  __set_bit(timer->nr, timer->chip->avail);
221  spin_unlock_irqrestore(&timer->chip->lock, flags);
222  }
223 
224  kfree(timer);
225 }
227 
229 {
230  return inw(timer->chip->base + reg + (timer->nr * 8));
231 }
233 
235  uint16_t value)
236 {
237  outw(value, timer->chip->base + reg + (timer->nr * 8));
238 }
240 
241 /*
242  * This is a sledgehammer that resets all MFGPT timers. This is required by
243  * some broken BIOSes which leave the system in an unstable state
244  * (TinyBIOS 0.98, for example; fixed in 0.99). It's uncertain as to
245  * whether or not this secret MSR can be used to release individual timers.
246  * Jordan tells me that he and Mitch once played w/ it, but it's unclear
247  * what the results of that were (and they experienced some instability).
248  */
249 static void __devinit reset_all_timers(void)
250 {
251  uint32_t val, dummy;
252 
253  /* The following undocumented bit resets the MFGPT timers */
254  val = 0xFF; dummy = 0;
255  wrmsr(MSR_MFGPT_SETUP, val, dummy);
256 }
257 
258 /*
259  * Check whether any MFGPTs are available for the kernel to use. In most
260  * cases, firmware that uses AMD's VSA code will claim all timers during
261  * bootup; we certainly don't want to take them if they're already in use.
262  * In other cases (such as with VSAless OpenFirmware), the system firmware
263  * leaves timers available for us to use.
264  */
265 static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt)
266 {
267  struct cs5535_mfgpt_timer timer = { .chip = mfgpt };
268  unsigned long flags;
269  int timers = 0;
270  uint16_t val;
271  int i;
272 
273  /* bios workaround */
274  if (mfgpt_reset_timers)
275  reset_all_timers();
276 
277  /* just to be safe, protect this section w/ lock */
278  spin_lock_irqsave(&mfgpt->lock, flags);
279  for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
280  timer.nr = i;
281  val = cs5535_mfgpt_read(&timer, MFGPT_REG_SETUP);
282  if (!(val & MFGPT_SETUP_SETUP)) {
283  __set_bit(i, mfgpt->avail);
284  timers++;
285  }
286  }
287  spin_unlock_irqrestore(&mfgpt->lock, flags);
288 
289  return timers;
290 }
291 
292 static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev)
293 {
294  struct resource *res;
295  int err = -EIO, t;
296 
297  /* There are two ways to get the MFGPT base address; one is by
298  * fetching it from MSR_LBAR_MFGPT, the other is by reading the
299  * PCI BAR info. The latter method is easier (especially across
300  * different architectures), so we'll stick with that for now. If
301  * it turns out to be unreliable in the face of crappy BIOSes, we
302  * can always go back to using MSRs.. */
303 
304  res = platform_get_resource(pdev, IORESOURCE_IO, 0);
305  if (!res) {
306  dev_err(&pdev->dev, "can't fetch device resource info\n");
307  goto done;
308  }
309 
310  if (!request_region(res->start, resource_size(res), pdev->name)) {
311  dev_err(&pdev->dev, "can't request region\n");
312  goto done;
313  }
314 
315  /* set up the driver-specific struct */
316  cs5535_mfgpt_chip.base = res->start;
317  cs5535_mfgpt_chip.pdev = pdev;
318  spin_lock_init(&cs5535_mfgpt_chip.lock);
319 
320  dev_info(&pdev->dev, "reserved resource region %pR\n", res);
321 
322  /* detect the available timers */
323  t = scan_timers(&cs5535_mfgpt_chip);
324  dev_info(&pdev->dev, "%d MFGPT timers available\n", t);
325  cs5535_mfgpt_chip.initialized = 1;
326  return 0;
327 
328 done:
329  return err;
330 }
331 
332 static struct platform_driver cs5535_mfgpt_driver = {
333  .driver = {
334  .name = DRV_NAME,
335  .owner = THIS_MODULE,
336  },
337  .probe = cs5535_mfgpt_probe,
338 };
339 
340 
341 static int __init cs5535_mfgpt_init(void)
342 {
343  return platform_driver_register(&cs5535_mfgpt_driver);
344 }
345 
346 module_init(cs5535_mfgpt_init);
347 
348 MODULE_AUTHOR("Andres Salomon <[email protected]>");
349 MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver");
350 MODULE_LICENSE("GPL");
351 MODULE_ALIAS("platform:" DRV_NAME);