/* * Linux driver model AC97 bus interface * * Author: Nicolas Pitre * Created: Jan 14, 2005 * Copyright: (C) MontaVista Software Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include /* * snd_ac97_check_id() - Reads and checks the vendor ID of the device * @ac97: The AC97 device to check * @id: The ID to compare to * @id_mask: Mask that is applied to the device ID before comparing to @id * * If @id is 0 this function returns true if the read device vendor ID is * a valid ID. If @id is non 0 this functions returns true if @id * matches the read vendor ID. Otherwise the function returns false. */ static bool snd_ac97_check_id(struct snd_ac97 *ac97, unsigned int id, unsigned int id_mask) { ac97->id = ac97->bus->ops->read(ac97, AC97_VENDOR_ID1) << 16; ac97->id |= ac97->bus->ops->read(ac97, AC97_VENDOR_ID2); if (ac97->id == 0x0 || ac97->id == 0xffffffff) return false; if (id != 0 && id != (ac97->id & id_mask)) return false; return true; } /** * snd_ac97_reset() - Reset AC'97 device * @ac97: The AC'97 device to reset * @try_warm: Try a warm reset first * @id: Expected device vendor ID * @id_mask: Mask that is applied to the device ID before comparing to @id * * This function resets the AC'97 device. If @try_warm is true the function * first performs a warm reset. If the warm reset is successful the function * returns 1. Otherwise or if @try_warm is false the function issues cold reset * followed by a warm reset. If this is successful the function returns 0, * otherwise a negative error code. If @id is 0 any valid device ID will be * accepted, otherwise only the ID that matches @id and @id_mask is accepted. */ int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id, unsigned int id_mask) { struct snd_ac97_bus_ops *ops = ac97->bus->ops; if (try_warm && ops->warm_reset) { ops->warm_reset(ac97); if (snd_ac97_check_id(ac97, id, id_mask)) return 1; } if (ops->reset) ops->reset(ac97); if (ops->warm_reset) ops->warm_reset(ac97); if (snd_ac97_check_id(ac97, id, id_mask)) return 0; return -ENODEV; } EXPORT_SYMBOL_GPL(snd_ac97_reset); /* * Let drivers decide whether they want to support given codec from their * probe method. Drivers have direct access to the struct snd_ac97 * structure and may decide based on the id field amongst other things. */ static int ac97_bus_match(struct device *dev, struct device_driver *drv) { return 1; } struct bus_type ac97_bus_type = { .name = "ac97", .match = ac97_bus_match, }; static int __init ac97_bus_init(void) { return bus_register(&ac97_bus_type); } subsys_initcall(ac97_bus_init); static void __exit ac97_bus_exit(void) { bus_unregister(&ac97_bus_type); } module_exit(ac97_bus_exit); EXPORT_SYMBOL(ac97_bus_type); MODULE_LICENSE("GPL"); nput type='hidden' name='h' value='nds-private-remove'/>
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2017-01-17 16:00:48 +0000
committerThomas Gleixner <tglx@linutronix.de>2017-01-30 15:18:56 +0100
commit08d85f3ea99f1eeafc4e8507936190e86a16ee8c (patch)
tree410bb1acd0cd7dcfaad37ae7b63ff243b7fa4bee /drivers
parent566cf877a1fcb6d6dc0126b076aad062054c2637 (diff)
irqdomain: Avoid activating interrupts more than once
Since commit f3b0946d629c ("genirq/msi: Make sure PCI MSIs are activated early"), we can end-up activating a PCI/MSI twice (once at allocation time, and once at startup time). This is normally of no consequences, except that there is some HW out there that may misbehave if activate is used more than once (the GICv3 ITS, for example, uses the activate callback to issue the MAPVI command, and the architecture spec says that "If there is an existing mapping for the EventID-DeviceID combination, behavior is UNPREDICTABLE"). While this could be worked around in each individual driver, it may make more sense to tackle the issue at the core level. In order to avoid getting in that situation, let's have a per-interrupt flag to remember if we have already activated that interrupt or not. Fixes: f3b0946d629c ("genirq/msi: Make sure PCI MSIs are activated early") Reported-and-tested-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1484668848-24361-1-git-send-email-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers')