// SPDX-License-Identifier: GPL-2.0-only /* * Driver for the CS5535/CS5536 Multi-Function General Purpose Timers (MFGPT) * * Copyright (C) 2006, Advanced Micro Devices, Inc. * Copyright (C) 2007 Andres Salomon <[email protected]> * Copyright (C) 2009 Andres Salomon <[email protected]> * * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book. */ #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/cs5535.h> #include <linux/slab.h> #define DRV_NAME … static int mfgpt_reset_timers; module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); MODULE_PARM_DESC(…) …; struct cs5535_mfgpt_timer { … }; static struct cs5535_mfgpt_chip { … } cs5535_mfgpt_chip; int cs5535_mfgpt_toggle_event(struct cs5535_mfgpt_timer *timer, int cmp, int event, int enable) { … } EXPORT_SYMBOL_GPL(…); int cs5535_mfgpt_set_irq(struct cs5535_mfgpt_timer *timer, int cmp, int *irq, int enable) { … } EXPORT_SYMBOL_GPL(…); struct cs5535_mfgpt_timer *cs5535_mfgpt_alloc_timer(int timer_nr, int domain) { … } EXPORT_SYMBOL_GPL(…); /* * XXX: This frees the timer memory, but never resets the actual hardware * timer. The old geode_mfgpt code did this; it would be good to figure * out a way to actually release the hardware timer. See comments below. */ void cs5535_mfgpt_free_timer(struct cs5535_mfgpt_timer *timer) { … } EXPORT_SYMBOL_GPL(…); uint16_t cs5535_mfgpt_read(struct cs5535_mfgpt_timer *timer, uint16_t reg) { … } EXPORT_SYMBOL_GPL(…); void cs5535_mfgpt_write(struct cs5535_mfgpt_timer *timer, uint16_t reg, uint16_t value) { … } EXPORT_SYMBOL_GPL(…); /* * This is a sledgehammer that resets all MFGPT timers. This is required by * some broken BIOSes which leave the system in an unstable state * (TinyBIOS 0.98, for example; fixed in 0.99). It's uncertain as to * whether or not this secret MSR can be used to release individual timers. * Jordan tells me that he and Mitch once played w/ it, but it's unclear * what the results of that were (and they experienced some instability). */ static void reset_all_timers(void) { … } /* * This is another sledgehammer to reset all MFGPT timers. * Instead of using the undocumented bit method it clears * IRQ, NMI and RESET settings. */ static void soft_reset(void) { … } /* * Check whether any MFGPTs are available for the kernel to use. In most * cases, firmware that uses AMD's VSA code will claim all timers during * bootup; we certainly don't want to take them if they're already in use. * In other cases (such as with VSAless OpenFirmware), the system firmware * leaves timers available for us to use. */ static int scan_timers(struct cs5535_mfgpt_chip *mfgpt) { … } static int cs5535_mfgpt_probe(struct platform_device *pdev) { … } static struct platform_driver cs5535_mfgpt_driver = …; static int __init cs5535_mfgpt_init(void) { … } module_init(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; MODULE_ALIAS(…) …;