ADM8211 WIRELESS DRIVER
-W: http://linuxwireless.org/
+W: http://wireless.kernel.org/
S: Orphan
F: drivers/net/wireless/adm8211.*
F: net/appletalk/
ARASAN COMPACT FLASH PATA CONTROLLER
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
S: Maintained
F: include/linux/pata_arasan_cf_data.h
S: Maintained
+ARM/Marvell Armada 370 and Armada XP SOC support
+S: Maintained
+F: arch/arm/mach-mvebu/
+
ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support
F: arch/arm/mach-shmobile/
F: drivers/sh/
+ARM/SOCFPGA ARCHITECTURE
+S: Maintained
+F: arch/arm/mach-socfpga/
+
+ARM/SOCFPGA CLOCK FRAMEWORK SUPPORT
+S: Maintained
+F: drivers/clk/socfpga/
+
ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
-W: http://linuxwireless.org/en/users/Drivers/b43
+W: http://wireless.kernel.org/en/users/Drivers/b43
S: Maintained
F: drivers/net/wireless/b43/
-W: http://linuxwireless.org/en/users/Drivers/b43
+W: http://wireless.kernel.org/en/users/Drivers/b43
S: Maintained
F: drivers/net/wireless/b43legacy/
S: Supported
F: drivers/net/wireless/brcm80211/
F: drivers/gpio/gpio-bt8xx.c
BTRFS FILE SYSTEM
-M: Chris Mason <chris.mason@oracle.com>
+M: Chris Mason <chris.mason@fusionio.com>
W: http://btrfs.wiki.kernel.org/
Q: http://patchwork.kernel.org/project/linux-btrfs/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git
S: Maintained
F: Documentation/filesystems/btrfs.txt
F: fs/btrfs/
CFG80211 and NL80211
+W: http://wireless.kernel.org/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
S: Maintained
F: include/linux/nl80211.h
F: include/net/cfg80211.h
F: drivers/idle/i7300_idle.c
IEEE 802.15.4 SUBSYSTEM
W: http://apps.sourceforge.net/trac/linux-zigbee
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git
S: Maintained
F: net/ieee802154/
+F: net/mac802154/
F: drivers/ieee802154/
IIO SUBSYSTEM AND DRIVERS
S: Supported
F: drivers/net/wireless/iwlwifi/
-INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi)
-S: Supported
-W: http://wireless.kernel.org/en/users/Drivers/iwmc3200wifi
-F: drivers/net/wireless/iwmc3200wifi/
-
INTEL MANAGEMENT ENGINE (mei)
F: arch/ia64/kvm/
KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
W: http://www.ibm.com/developerworks/linux/linux390/
MAC80211
-W: http://linuxwireless.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
+W: http://wireless.kernel.org/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
S: Maintained
F: Documentation/networking/mac80211-injection.txt
F: include/net/mac80211.h
-W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
+W: http://wireless.kernel.org/en/developers/Documentation/mac80211/RateControl/PID
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
S: Maintained
F: net/mac80211/rc80211_pid*
F: drivers/usb/musb/
MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
W: http://www.myri.com/scs/download-Myri10GE.html
NETERION 10GbE DRIVERS (s2io/vxge)
-W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
-W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
S: Supported
F: Documentation/networking/s2io.txt
F: Documentation/networking/vxge.txt
W: http://www.netfilter.org/
W: http://www.iptables.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git
+T: git git://1984.lsi.us.es/nf
+T: git git://1984.lsi.us.es/nf-next
S: Supported
F: include/linux/netfilter*
F: include/linux/netfilter/
S: Maintained
F: arch/arm/*omap*/*pm*
+F: drivers/cpufreq/omap-cpufreq.c
OMAP POWERDOMAIN/CLOCKDOMAIN SOC ADAPTATION LAYER SUPPORT
ORINOCO DRIVER
-W: http://linuxwireless.org/en/users/Drivers/orinoco
+W: http://wireless.kernel.org/en/users/Drivers/orinoco
W: http://www.nongnu.org/orinoco/
S: Orphan
F: drivers/net/wireless/orinoco/
Q: http://patchwork.ozlabs.org/project/linux-pci/list/
- T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/linux.git
+ T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
S: Supported
F: Documentation/PCI/
F: drivers/pci/
F: drivers/pinctrl/
PIN CONTROLLER - ST SPEAR
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
W: http://www.st.com/spear
F: drivers/net/ethernet/qlogic/qla3xxx.*
QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
-M: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
+M: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
F: drivers/net/ethernet/qlogic/qlcnic/
QLOGIC QLGE 10Gb ETHERNET DRIVER
RFKILL
+W: http://wireless.kernel.org/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
S: Maintained
F: Documentation/rfkill.txt
F: net/rfkill/
RTL8180 WIRELESS DRIVER
-W: http://linuxwireless.org/
+W: http://wireless.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
F: drivers/net/wireless/rtl818x/rtl8180/
-W: http://linuxwireless.org/
+W: http://wireless.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
F: drivers/net/wireless/rtl818x/rtl8187/
-W: http://linuxwireless.org/
+W: http://wireless.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
F: drivers/net/wireless/rtlwifi/
F: drivers/tty/serial
SYNOPSYS DESIGNWARE DMAC DRIVER
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
S: Maintained
F: include/linux/dw_dmac.h
F: drivers/dma/dw_dmac_regs.h
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched/core
S: Maintained
-F: kernel/sched*
+F: kernel/sched/
F: include/linux/sched.h
SCORE ARCHITECTURE
F: drivers/mmc/host/sdhci-s3c.c
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
S: Maintained
F: include/linux/srcu*
F: kernel/srcu*
+SMACK SECURITY MODULE
+W: http://schaufler-ca.com
+T: git git://git.gitorious.org/smack-next/kernel.git
+S: Maintained
+F: Documentation/security/Smack.txt
+F: security/smack/
+
SMC91x ETHERNET DRIVER
S: Odd Fixes
F: drivers/hwmon/smm665.c
SMSC EMC2103 HARDWARE MONITOR DRIVER
-M: Steve Glendinning <steve.glendinning@smsc.com>
+M: Steve Glendinning <steve.glendinning@shawell.net>
-S: Supported
+S: Maintained
F: Documentation/hwmon/emc2103
F: drivers/hwmon/emc2103.c
F: drivers/hwmon/smsc47b397.c
SMSC911x ETHERNET DRIVER
-M: Steve Glendinning <steve.glendinning@smsc.com>
+M: Steve Glendinning <steve.glendinning@shawell.net>
-S: Supported
+S: Maintained
F: include/linux/smsc911x.h
F: drivers/net/ethernet/smsc/smsc911x.*
SMSC9420 PCI ETHERNET DRIVER
-M: Steve Glendinning <steve.glendinning@smsc.com>
+M: Steve Glendinning <steve.glendinning@shawell.net>
-S: Supported
+S: Maintained
F: drivers/net/ethernet/smsc/smsc9420.*
SMSC UFX6000 and UFX7000 USB to VGA DRIVER
-M: Steve Glendinning <steve.glendinning@smsc.com>
+M: Steve Glendinning <steve.glendinning@shawell.net>
-S: Supported
+S: Maintained
F: drivers/video/smscufx.c
SN-IA64 (Itanium) SUB-PLATFORM
F: include/linux/compiler.h
SPEAR PLATFORM SUPPORT
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
F: arch/arm/plat-spear/
SPEAR13XX MACHINE SUPPORT
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
F: arch/arm/mach-spear13xx/
SPEAR3XX MACHINE SUPPORT
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
SPEAR6XX MACHINE SUPPORT
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
W: http://www.st.com/spear
F: arch/arm/mach-spear6xx/
SPEAR CLOCK FRAMEWORK SUPPORT
-M: Viresh Kumar <viresh.kumar@st.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
W: http://www.st.com/spear
TI LM49xxx FAMILY ASoC CODEC DRIVERS
S: Maintained
F: sound/soc/codecs/lm49453*
+F: sound/soc/codecs/isabelle*
TI TWL4030 SERIES SOC CODEC DRIVER
F: mm/shmem.c
TPM DEVICE DRIVER
-M: Debora Velarde <debora@linux.vnet.ibm.com>
+M: Kent Yoder <key@linux.vnet.ibm.com>
W: http://tpmdd.sourceforge.net
W: http://www.sirrix.com
S: Maintained
F: Documentation/filesystems/ufs.txt
F: fs/ufs/
+UHID USERSPACE HID IO DRIVER:
+S: Maintained
+F: drivers/hid/uhid.c
+F: include/linux/uhid.h
+
ULTRA-WIDEBAND (UWB) SUBSYSTEM:
S: Orphan
F: drivers/usb/serial/whiteheat*
USB SMSC95XX ETHERNET DRIVER
-M: Steve Glendinning <steve.glendinning@smsc.com>
+M: Steve Glendinning <steve.glendinning@shawell.net>
-S: Supported
+S: Maintained
F: drivers/net/usb/smsc95xx.*
USB SN9C1xx DRIVER
VME SUBSYSTEM
-M: Manohar Vanga <manohar.vanga@cern.ch>
+M: Manohar Vanga <manohar.vanga@gmail.com>
S: Maintained
/* No special bus mastering setup handling */
}
- char __devinit *pcibios_setup(char *str)
- {
- return str;
- }
-
/*
* Reads the interrupt pin to determine if interrupt is use by card.
* If the interrupt is used, then gets the interrupt line from the
} else {
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.specifier[1],
- oirq.controller ? oirq.controller->full_name :
- "<default>");
+ of_node_full_name(oirq.controller));
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
struct pci_bus *bus;
struct device_node *node = hose->dn;
- pr_debug("PCI: Scanning PHB %s\n",
- node ? node->full_name : "<NO NAME>");
+ pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
pcibios_setup_phb_resources(hose, &resources);
pci_free_resource_list(&resources);
return;
}
- bus->secondary = hose->first_busno;
+ bus->busn_res.start = hose->first_busno;
hose->bus = bus;
- hose->last_busno = bus->subordinate;
+ hose->last_busno = bus->busn_res.end;
}
static int __init pcibios_init(void)
return device_create_file(&pdev->dev, &dev_attr_devspec);
}
- char __devinit *pcibios_setup(char *str)
- {
- return str;
- }
-
/*
* Reads the interrupt pin to determine if interrupt is use by card.
* If the interrupt is used, then gets the interrupt line from the
} else {
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.specifier[1],
- oirq.controller ? oirq.controller->full_name :
- "<default>");
+ of_node_full_name(oirq.controller));
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
struct device_node *node = hose->dn;
int mode;
- pr_debug("PCI: Scanning PHB %s\n",
- node ? node->full_name : "<NO NAME>");
+ pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
/* Get some IO space for the new PHB */
pcibios_setup_phb_io_space(hose);
/* Wire up PHB bus resources */
pcibios_setup_phb_resources(hose, &resources);
+ hose->busn.start = hose->first_busno;
+ hose->busn.end = hose->last_busno;
+ hose->busn.flags = IORESOURCE_BUS;
+ pci_add_resource(&resources, &hose->busn);
+
/* Create an empty bus for the toplevel */
bus = pci_create_root_bus(hose->parent, hose->first_busno,
hose->ops, hose, &resources);
if (node && ppc_md.pci_probe_mode)
mode = ppc_md.pci_probe_mode(bus);
pr_debug(" probe mode: %d\n", mode);
- if (mode == PCI_PROBE_DEVTREE) {
- bus->subordinate = hose->last_busno;
+ if (mode == PCI_PROBE_DEVTREE)
of_scan_bus(node, bus);
- }
- if (mode == PCI_PROBE_NORMAL)
- hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+ if (mode == PCI_PROBE_NORMAL) {
+ pci_bus_update_busn_res_end(bus, 255);
+ hose->last_busno = pci_scan_child_bus(bus);
+ pci_bus_update_busn_res_end(bus, hose->last_busno);
+ }
/* Platform gets a chance to do some global fixups before
* we proceed to resource allocation
/**
* of_scan_pci_bridge - Set up a PCI bridge and scan for child nodes
- * @node: device tree node of bridge
* @dev: pci_dev structure for the bridge
*
* of_scan_bus() calls this routine for each PCI bridge that it finds, and
}
bus->primary = dev->bus->number;
- bus->subordinate = busrange[1];
+ pci_bus_insert_busn_res(bus, busrange[0], busrange[1]);
bus->bridge_ctl = 0;
/* parse ranges property */
#undef DEBUG
#ifdef DEBUG
-#define DBG(x...) printk(x)
+#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
-#define DBG(x...)
+#define DBG(fmt, ...) \
+do { \
+ if (0) \
+ printk(fmt, ##__VA_ARGS__); \
+} while (0)
#endif
#define PCI_PROBE_BIOS 0x0001
extern const struct pci_raw_ops *raw_pci_ops;
extern const struct pci_raw_ops *raw_pci_ext_ops;
+ extern const struct pci_raw_ops pci_mmcfg;
extern const struct pci_raw_ops pci_direct_conf1;
extern bool port_cf9_safe;
extern int __init pci_mmcfg_arch_init(void);
extern void __init pci_mmcfg_arch_free(void);
+ extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
+ extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
+ extern int __devinit pci_mmconfig_insert(struct device *dev,
+ u16 seg, u8 start,
+ u8 end, phys_addr_t addr);
+ extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
extern struct list_head pci_mmcfg_list;
#include <linux/prefetch.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
+#if IS_ENABLED(CONFIG_HWMON)
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#endif
#include <net/checksum.h>
#include <net/ip.h>
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
tg3_ape_write32(tp, gnt + 4 * locknum, bit);
}
-static void tg3_ape_send_event(struct tg3 *tp, u32 event)
+static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us)
{
- int i;
u32 apedata;
- /* NCSI does not support APE events */
- if (tg3_flag(tp, APE_HAS_NCSI))
- return;
+ while (timeout_us) {
+ if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM))
+ return -EBUSY;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);
+ if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
+ break;
+
+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+
+ udelay(10);
+ timeout_us -= (timeout_us > 10) ? 10 : timeout_us;
+ }
+
+ return timeout_us ? 0 : -EBUSY;
+}
+
+static int tg3_ape_wait_for_event(struct tg3 *tp, u32 timeout_us)
+{
+ u32 i, apedata;
+
+ for (i = 0; i < timeout_us / 10; i++) {
+ apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);
+
+ if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
+ break;
+
+ udelay(10);
+ }
+
+ return i == timeout_us / 10;
+}
+
+int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off, u32 len)
+{
+ int err;
+ u32 i, bufoff, msgoff, maxlen, apedata;
+
+ if (!tg3_flag(tp, APE_HAS_NCSI))
+ return 0;
apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
if (apedata != APE_SEG_SIG_MAGIC)
- return;
+ return -ENODEV;
apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
if (!(apedata & APE_FW_STATUS_READY))
- return;
+ return -EAGAIN;
- /* Wait for up to 1 millisecond for APE to service previous event. */
- for (i = 0; i < 10; i++) {
- if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM))
- return;
+ bufoff = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_OFF) +
+ TG3_APE_SHMEM_BASE;
+ msgoff = bufoff + 2 * sizeof(u32);
+ maxlen = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_LEN);
- apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);
+ while (len) {
+ u32 length;
- if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
- tg3_ape_write32(tp, TG3_APE_EVENT_STATUS,
- event | APE_EVENT_STATUS_EVENT_PENDING);
+ /* Cap xfer sizes to scratchpad limits. */
+ length = (len > maxlen) ? maxlen : len;
+ len -= length;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+ if (!(apedata & APE_FW_STATUS_READY))
+ return -EAGAIN;
+
+ /* Wait for up to 1 msec for APE to service previous event. */
+ err = tg3_ape_event_lock(tp, 1000);
+ if (err)
+ return err;
+
+ apedata = APE_EVENT_STATUS_DRIVER_EVNT |
+ APE_EVENT_STATUS_SCRTCHPD_READ |
+ APE_EVENT_STATUS_EVENT_PENDING;
+ tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, apedata);
+
+ tg3_ape_write32(tp, bufoff, base_off);
+ tg3_ape_write32(tp, bufoff + sizeof(u32), length);
tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+ tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
- if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
- break;
+ base_off += length;
- udelay(100);
+ if (tg3_ape_wait_for_event(tp, 30000))
+ return -EAGAIN;
+
+ for (i = 0; length; i += 4, length -= 4) {
+ u32 val = tg3_ape_read32(tp, msgoff + i);
+ memcpy(data, &val, sizeof(u32));
+ data++;
+ }
}
- if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
- tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
+ return 0;
+}
+
+static int tg3_ape_send_event(struct tg3 *tp, u32 event)
+{
+ int err;
+ u32 apedata;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
+ if (apedata != APE_SEG_SIG_MAGIC)
+ return -EAGAIN;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+ if (!(apedata & APE_FW_STATUS_READY))
+ return -EAGAIN;
+
+ /* Wait for up to 1 millisecond for APE to service previous event. */
+ err = tg3_ape_event_lock(tp, 1000);
+ if (err)
+ return err;
+
+ tg3_ape_write32(tp, TG3_APE_EVENT_STATUS,
+ event | APE_EVENT_STATUS_EVENT_PENDING);
+
+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+ tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
+
+ return 0;
}
static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
return tg3_reset_hw(tp, reset_phy);
}
+#if IS_ENABLED(CONFIG_HWMON)
+static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
+{
+ int i;
+
+ for (i = 0; i < TG3_SD_NUM_RECS; i++, ocir++) {
+ u32 off = i * TG3_OCIR_LEN, len = TG3_OCIR_LEN;
+
+ tg3_ape_scratchpad_read(tp, (u32 *) ocir, off, len);
+ off += len;
+
+ if (ocir->signature != TG3_OCIR_SIG_MAGIC ||
+ !(ocir->version_flags & TG3_OCIR_FLAG_ACTIVE))
+ memset(ocir, 0, TG3_OCIR_LEN);
+ }
+}
+
+/* sysfs attributes for hwmon */
+static ssize_t tg3_show_temp(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct tg3 *tp = netdev_priv(netdev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ u32 temperature;
+
+ spin_lock_bh(&tp->lock);
+ tg3_ape_scratchpad_read(tp, &temperature, attr->index,
+ sizeof(temperature));
+ spin_unlock_bh(&tp->lock);
+ return sprintf(buf, "%u\n", temperature);
+}
+
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tg3_show_temp, NULL,
+ TG3_TEMP_SENSOR_OFFSET);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, tg3_show_temp, NULL,
+ TG3_TEMP_CAUTION_OFFSET);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL,
+ TG3_TEMP_MAX_OFFSET);
+
+static struct attribute *tg3_attributes[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_crit.dev_attr.attr,
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group tg3_group = {
+ .attrs = tg3_attributes,
+};
+
+#endif
+
+static void tg3_hwmon_close(struct tg3 *tp)
+{
+#if IS_ENABLED(CONFIG_HWMON)
+ if (tp->hwmon_dev) {
+ hwmon_device_unregister(tp->hwmon_dev);
+ tp->hwmon_dev = NULL;
+ sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
+ }
+#endif
+}
+
+static void tg3_hwmon_open(struct tg3 *tp)
+{
+#if IS_ENABLED(CONFIG_HWMON)
+ int i, err;
+ u32 size = 0;
+ struct pci_dev *pdev = tp->pdev;
+ struct tg3_ocir ocirs[TG3_SD_NUM_RECS];
+
+ tg3_sd_scan_scratchpad(tp, ocirs);
+
+ for (i = 0; i < TG3_SD_NUM_RECS; i++) {
+ if (!ocirs[i].src_data_length)
+ continue;
+
+ size += ocirs[i].src_hdr_length;
+ size += ocirs[i].src_data_length;
+ }
+
+ if (!size)
+ return;
+
+ /* Register hwmon sysfs hooks */
+ err = sysfs_create_group(&pdev->dev.kobj, &tg3_group);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n");
+ return;
+ }
+
+ tp->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(tp->hwmon_dev)) {
+ tp->hwmon_dev = NULL;
+ dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n");
+ sysfs_remove_group(&pdev->dev.kobj, &tg3_group);
+ }
+#endif
+}
+
+
#define TG3_STAT_ADD32(PSTAT, REG) \
do { u32 __val = tr32(REG); \
(PSTAT)->low += __val; \
int i, rc;
struct msix_entry msix_ent[tp->irq_max];
- tp->irq_cnt = num_online_cpus();
+ tp->irq_cnt = netif_get_num_default_rss_queues();
if (tp->irq_cnt > 1) {
/* We want as many rx rings enabled as there are cpus.
* In multiqueue MSI-X mode, the first MSI-X vector
tg3_phy_start(tp);
+ tg3_hwmon_open(tp);
+
tg3_full_lock(tp, 0);
tg3_timer_start(tp);
tg3_timer_stop(tp);
+ tg3_hwmon_close(tp);
+
tg3_phy_stop(tp);
tg3_full_lock(tp, 1);
}
}
-static void __devinit tg3_read_dash_ver(struct tg3 *tp)
+static void __devinit tg3_probe_ncsi(struct tg3 *tp)
{
- int vlen;
u32 apedata;
- char *fwtype;
-
- if (!tg3_flag(tp, ENABLE_APE) || !tg3_flag(tp, ENABLE_ASF))
- return;
apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
if (apedata != APE_SEG_SIG_MAGIC)
if (!(apedata & APE_FW_STATUS_READY))
return;
+ if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI)
+ tg3_flag_set(tp, APE_HAS_NCSI);
+}
+
+static void __devinit tg3_read_dash_ver(struct tg3 *tp)
+{
+ int vlen;
+ u32 apedata;
+ char *fwtype;
+
apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
- if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) {
- tg3_flag_set(tp, APE_HAS_NCSI);
+ if (tg3_flag(tp, APE_HAS_NCSI))
fwtype = "NCSI";
- } else {
+ else
fwtype = "DASH";
- }
vlen = strlen(tp->fw_ver);
tg3_read_sb_ver(tp, val);
else if ((val & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
tg3_read_hwsb_ver(tp);
- else
- return;
-
- if (vpd_vers)
- goto done;
- if (tg3_flag(tp, ENABLE_APE)) {
- if (tg3_flag(tp, ENABLE_ASF))
- tg3_read_dash_ver(tp);
- } else if (tg3_flag(tp, ENABLE_ASF)) {
- tg3_read_mgmtfw_ver(tp);
+ if (tg3_flag(tp, ENABLE_ASF)) {
+ if (tg3_flag(tp, ENABLE_APE)) {
+ tg3_probe_ncsi(tp);
+ if (!vpd_vers)
+ tg3_read_dash_ver(tp);
+ } else if (!vpd_vers) {
+ tg3_read_mgmtfw_ver(tp);
+ }
}
-done:
tp->fw_ver[TG3_VER_SIZE - 1] = 0;
}
if (bridge->subordinate &&
(bridge->subordinate->number <=
tp->pdev->bus->number) &&
- (bridge->subordinate->subordinate >=
+ (bridge->subordinate->busn_res.end >=
tp->pdev->bus->number)) {
tg3_flag_set(tp, 5701_DMA_BUG);
pci_dev_put(bridge);
if (bridge && bridge->subordinate &&
(bridge->subordinate->number <=
tp->pdev->bus->number) &&
- (bridge->subordinate->subordinate >=
+ (bridge->subordinate->busn_res.end >=
tp->pdev->bus->number)) {
tg3_flag_set(tp, 40BIT_DMA_BUG);
pci_dev_put(bridge);
}
}
- if (tg3_flag(tp, 5755_PLUS))
+ if (tg3_flag(tp, 5755_PLUS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tg3_flag_set(tp, SHORT_DMA_BUG);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
#endif
#include <asm/ropes.h>
-#include "./iosapic_private.h"
+#include "iosapic_private.h"
#define MODULE_NAME "iosapic"
intr_slot = PCI_SLOT(pcidev->devfn);
}
DBG_IRT("iosapic_xlate_pin: bus %d slot %d pin %d\n",
- pcidev->bus->secondary, intr_slot, intr_pin);
+ pcidev->bus->busn_res.start, intr_slot, intr_pin);
return irt_find_irqline(isi, intr_slot, intr_pin);
}
for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
(l != 0x0000) && (l != 0xffff)) {
- debug("%s - Inside bus_struture_fixup()\n",
+ debug("%s - Inside bus_structure_fixup()\n",
__func__);
pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
break;
static int ibm_configure_device(struct pci_func *func)
{
- unsigned char bus;
struct pci_bus *child;
int num;
int flag = 0; /* this is to make sure we don't double scan the bus,
}
}
if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
- pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
- child = pci_add_new_bus(func->dev->bus, func->dev, bus);
- pci_do_scan_bus(child);
+ pci_hp_add_bridge(func->dev);
+ child = func->dev->subordinate;
+ if (child)
+ pci_bus_add_devices(child);
}
return 0;
return 0;
}
+ #endif
+
+ #ifdef CONFIG_PM_SLEEP
+
static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
{
- pci_restore_standard_config(pci_dev);
+ pci_power_up(pci_dev);
+ pci_restore_state(pci_dev);
pci_fixup_device(pci_fixup_resume_early, pci_dev);
}
- #endif
-
- #ifdef CONFIG_PM_SLEEP
-
/*
* Default "suspend" method for devices that have no driver provided suspend,
* or not even a driver at all (second part).
pci_pm_set_unknown_state(pci_dev);
+ /*
+ * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's
+ * PCI COMMAND register isn't 0, the BIOS assumes that the controller
+ * hasn't been quiesced and tries to turn it off. If the controller
+ * is already in D3, this can hang or cause memory corruption.
+ *
+ * Since the value of the COMMAND register doesn't matter once the
+ * device has been suspended, we can safely set it to 0 here.
+ */
+ if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
+ pci_write_config_word(pci_dev, PCI_COMMAND, 0);
+
return 0;
}
if (!pm || !pm->runtime_suspend)
return -ENOSYS;
+ pci_dev->no_d3cold = false;
error = pm->runtime_suspend(dev);
suspend_report_result(pm->runtime_suspend, error);
if (error)
return error;
+ if (!pci_dev->d3cold_allowed)
+ pci_dev->no_d3cold = true;
pci_fixup_device(pci_fixup_suspend, pci_dev);
static int pci_pm_runtime_resume(struct device *dev)
{
+ int rc;
struct pci_dev *pci_dev = to_pci_dev(dev);
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
if (!pm || !pm->runtime_resume)
return -ENOSYS;
- pci_pm_default_resume_early(pci_dev);
+ pci_restore_standard_config(pci_dev);
+ pci_fixup_device(pci_fixup_resume_early, pci_dev);
__pci_enable_wake(pci_dev, PCI_D0, true, false);
pci_fixup_device(pci_fixup_resume, pci_dev);
- return pm->runtime_resume(dev);
+ rc = pm->runtime_resume(dev);
+
+ pci_dev->runtime_d3cold = false;
+
+ return rc;
}
static int pci_pm_runtime_idle(struct device *dev)
* workaround applied too
* [Info kindly provided by ALi]
*/
- static void __init quirk_alimagik(struct pci_dev *dev)
+ static void __devinit quirk_alimagik(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) {
dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic);
- static void __init quirk_ioapic_rmw(struct pci_dev *dev)
+ static void __devinit quirk_ioapic_rmw(struct pci_dev *dev)
{
if (dev->devfn == 0 && dev->bus->number == 0)
sis_apic_bug = 1;
* Some settings of MMRBC can lead to data corruption so block changes.
* See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide
*/
- static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev)
+ static void __devinit quirk_amd_8131_mmrbc(struct pci_dev *dev)
{
if (dev->subordinate && dev->revision <= 0x12) {
dev_info(&dev->dev, "AMD8131 rev %x detected; "
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
- static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
+ static void quirk_amd_ide_mode(struct pci_dev *pdev)
{
/* set SBX00/Hudson-2 SATA in IDE mode to AHCI mode */
u8 tmp;
/*
* Intel 82801CAM ICH3-M datasheet says IDE modes must be the same
*/
- static void __init quirk_ide_samemode(struct pci_dev *pdev)
+ static void __devinit quirk_ide_samemode(struct pci_dev *pdev)
{
u8 prog;
/* This was originally an Alpha specific thing, but it really fits here.
* The i82375 PCI/EISA bridge appears as non-classified. Fix that.
*/
- static void __init quirk_eisa_bridge(struct pci_dev *dev)
+ static void __devinit quirk_eisa_bridge(struct pci_dev *dev)
{
dev->class = PCI_CLASS_BRIDGE_EISA << 8;
}
*/
static int asus_hides_smbus;
- static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
+ static void __devinit asus_hides_smbus_hostbridge(struct pci_dev *dev)
{
if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB)
#endif
#ifdef CONFIG_X86_IO_APIC
- static void __init quirk_alder_ioapic(struct pci_dev *pdev)
+ static void __devinit quirk_alder_ioapic(struct pci_dev *pdev)
{
int i;
* but the PIO transfers won't work if BAR0 falls at the odd 8 bytes.
* Re-allocate the region if needed...
*/
- static void __init quirk_tc86c001_ide(struct pci_dev *dev)
+ static void __devinit quirk_tc86c001_ide(struct pci_dev *dev)
{
struct resource *r = &dev->resource[0];
static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
{
u16 en1k;
- u8 io_base_lo, io_limit_lo;
- unsigned long base, limit;
- struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
pci_read_config_word(dev, 0x40, &en1k);
if (en1k & 0x200) {
dev_info(&dev->dev, "Enable I/O Space to 1KB granularity\n");
-
- pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
- pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
- base = (io_base_lo & (PCI_IO_RANGE_MASK | 0x0c)) << 8;
- limit = (io_limit_lo & (PCI_IO_RANGE_MASK | 0x0c)) << 8;
-
- if (base <= limit) {
- res->start = base;
- res->end = limit + 0x3ff;
- }
+ dev->io_window_1k = 1;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io);
- /* Fix the IOBL_ADR for 1k I/O space granularity on the Intel P64H2
- * The IOBL_ADR gets re-written to 4k boundaries in pci_setup_bridge()
- * in drivers/pci/setup-bus.c
- */
- static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev)
- {
- u16 en1k, iobl_adr, iobl_adr_1k;
- struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
-
- pci_read_config_word(dev, 0x40, &en1k);
-
- if (en1k & 0x200) {
- pci_read_config_word(dev, PCI_IO_BASE, &iobl_adr);
-
- iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00);
-
- if (iobl_adr != iobl_adr_1k) {
- dev_info(&dev->dev, "Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1KB granularity\n",
- iobl_adr,iobl_adr_1k);
- pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k);
- }
- }
- }
- DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io_fix_iobl);
-
/* Under some circumstances, AER is not linked with extended capabilities.
* Force it to be linked by setting the corresponding control bit in the
* config space.
PCI_DEVICE_ID_NX2_5709S,
quirk_brcm_570x_limit_vpd);
- static void __devinit quirk_brcm_5719_limit_mrrs(struct pci_dev *dev)
+ static void quirk_brcm_5719_limit_mrrs(struct pci_dev *dev)
{
u32 rev;
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
quirk_unhide_mch_dev6);
-#ifdef CONFIG_TILE
+#ifdef CONFIG_TILEPRO
/*
- * The Tilera TILEmpower platform needs to set the link speed
+ * The Tilera TILEmpower tilepro platform needs to set the link speed
* to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed
* setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe
* capability register of the PEX8624 PCIe switch. The switch
}
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
-#endif /* CONFIG_TILE */
+#endif /* CONFIG_TILEPRO */
#ifdef CONFIG_PCI_MSI
/* Some chipsets do not support MSI. We cannot easily rely on setting
* aware of it. Instead of setting the flag on all busses in the
* machine, simply disable MSI globally.
*/
- static void __init quirk_disable_all_msi(struct pci_dev *dev)
+ static void __devinit quirk_disable_all_msi(struct pci_dev *dev)
{
pci_no_msi();
dev_warn(&dev->dev, "MSI quirk detected; MSI disabled\n");
/* Go through the list of Hypertransport capabilities and
* return 1 if a HT MSI capability is found and enabled */
- static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
+ static int msi_ht_cap_enabled(struct pci_dev *dev)
{
int pos, ttl = 48;
}
/* Check the hypertransport MSI mapping to know whether MSI is enabled or not */
- static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
+ static void quirk_msi_ht_cap(struct pci_dev *dev)
{
if (dev->subordinate && !msi_ht_cap_enabled(dev)) {
dev_warn(&dev->dev, "MSI quirk detected; "
/* The nVidia CK804 chipset may have 2 HT MSI mappings.
* MSI are supported if the MSI capability set in any of these mappings.
*/
- static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+ static void quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
{
struct pci_dev *pdev;
quirk_nvidia_ck804_msi_ht_cap);
/* Force enable MSI mapping capability on HT bridges */
- static void __devinit ht_enable_msi_mapping(struct pci_dev *dev)
+ static void ht_enable_msi_mapping(struct pci_dev *dev)
{
int pos, ttl = 48;
PCI_DEVICE_ID_NVIDIA_MCP55_BRIDGE_V4,
nvbridge_check_legacy_irq_routing);
- static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
+ static int ht_check_msi_mapping(struct pci_dev *dev)
{
int pos, ttl = 48;
int found = 0;
return found;
}
- static int __devinit host_bridge_with_leaf(struct pci_dev *host_bridge)
+ static int host_bridge_with_leaf(struct pci_dev *host_bridge)
{
struct pci_dev *dev;
int pos;
#define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */
#define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */
- static int __devinit is_end_of_ht_chain(struct pci_dev *dev)
+ static int is_end_of_ht_chain(struct pci_dev *dev)
{
int pos, ctrl_off;
int end = 0;
return end;
}
- static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
+ static void nv_ht_enable_msi_mapping(struct pci_dev *dev)
{
struct pci_dev *host_bridge;
int pos;
pci_dev_put(host_bridge);
}
- static void __devinit ht_disable_msi_mapping(struct pci_dev *dev)
+ static void ht_disable_msi_mapping(struct pci_dev *dev)
{
int pos, ttl = 48;
}
}
- static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
+ static void __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
{
struct pci_dev *host_bridge;
int pos;
else
nv_ht_enable_msi_mapping(dev);
}
- return;
+ goto out;
}
/* HT MSI is not enabled */
if (found == 1)
- return;
+ goto out;
/* Host bridge is not to HT, disable HT MSI mapping on this device */
ht_disable_msi_mapping(dev);
+
+ out:
+ pci_dev_put(host_bridge);
}
- static void __devinit nv_msi_ht_cap_quirk_all(struct pci_dev *dev)
+ static void nv_msi_ht_cap_quirk_all(struct pci_dev *dev)
{
return __nv_msi_ht_cap_quirk(dev, 1);
}
- static void __devinit nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev)
+ static void nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev)
{
return __nv_msi_ht_cap_quirk(dev, 0);
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
- static void do_one_fixup_debug(void (*fn)(struct pci_dev *dev), struct pci_dev *dev)
+ static ktime_t fixup_debug_start(struct pci_dev *dev,
+ void (*fn)(struct pci_dev *dev))
+ {
+ ktime_t calltime = ktime_set(0, 0);
+
+ dev_dbg(&dev->dev, "calling %pF\n", fn);
+ if (initcall_debug) {
+ pr_debug("calling %pF @ %i for %s\n",
+ fn, task_pid_nr(current), dev_name(&dev->dev));
+ calltime = ktime_get();
+ }
+
+ return calltime;
+ }
+
+ static void fixup_debug_report(struct pci_dev *dev, ktime_t calltime,
+ void (*fn)(struct pci_dev *dev))
{
- ktime_t calltime, delta, rettime;
+ ktime_t delta, rettime;
unsigned long long duration;
- printk(KERN_DEBUG "calling %pF @ %i for %s\n",
- fn, task_pid_nr(current), dev_name(&dev->dev));
- calltime = ktime_get();
- fn(dev);
- rettime = ktime_get();
- delta = ktime_sub(rettime, calltime);
- duration = (unsigned long long) ktime_to_ns(delta) >> 10;
- printk(KERN_DEBUG "pci fixup %pF returned after %lld usecs for %s\n",
- fn, duration, dev_name(&dev->dev));
+ if (initcall_debug) {
+ rettime = ktime_get();
+ delta = ktime_sub(rettime, calltime);
+ duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+ pr_debug("pci fixup %pF returned after %lld usecs for %s\n",
+ fn, duration, dev_name(&dev->dev));
+ }
}
/*
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
+ /*
+ * Some devices may pass our check in pci_intx_mask_supported if
+ * PCI_COMMAND_INTX_DISABLE works though they actually do not properly
+ * support this feature.
+ */
+ static void __devinit quirk_broken_intx_masking(struct pci_dev *dev)
+ {
+ dev->broken_intx_masking = 1;
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, 0x0030,
+ quirk_broken_intx_masking);
+ DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
+ quirk_broken_intx_masking);
+
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
struct pci_fixup *end)
{
+ ktime_t calltime;
+
for (; f < end; f++)
if ((f->class == (u32) (dev->class >> f->class_shift) ||
f->class == (u32) PCI_ANY_ID) &&
f->vendor == (u16) PCI_ANY_ID) &&
(f->device == dev->device ||
f->device == (u16) PCI_ANY_ID)) {
- dev_dbg(&dev->dev, "calling %pF\n", f->hook);
- if (initcall_debug)
- do_one_fixup_debug(f->hook, dev);
- else
- f->hook(dev);
+ calltime = fixup_debug_start(dev, f->hook);
+ f->hook(dev);
+ fixup_debug_report(dev, calltime, f->hook);
}
}
extern struct pci_fixup __start_pci_fixups_suspend[];
extern struct pci_fixup __end_pci_fixups_suspend[];
+ static bool pci_apply_fixup_final_quirks;
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
{
break;
case pci_fixup_final:
+ if (!pci_apply_fixup_final_quirks)
+ return;
start = __start_pci_fixups_final;
end = __end_pci_fixups_final;
break;
}
EXPORT_SYMBOL(pci_fixup_device);
+
static int __init pci_apply_final_quirks(void)
{
struct pci_dev *dev = NULL;
printk(KERN_DEBUG "PCI: CLS %u bytes\n",
pci_cache_line_size << 2);
+ pci_apply_fixup_final_quirks = true;
for_each_pci_dev(dev) {
pci_fixup_device(pci_fixup_final, dev);
/*
pci_cache_line_size = pci_dfl_cache_line_size;
}
}
+
if (!pci_cache_line_size) {
printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n",
cls << 2, pci_dfl_cache_line_size << 2);
return -ENOTTY;
}
+
+ static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev)
+ {
+ if (!PCI_FUNC(dev->devfn))
+ return pci_dev_get(dev);
+
+ return pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+ }
+
+ static const struct pci_dev_dma_source {
+ u16 vendor;
+ u16 device;
+ struct pci_dev *(*dma_source)(struct pci_dev *dev);
+ } pci_dev_dma_source[] = {
+ /*
+ * https://bugzilla.redhat.com/show_bug.cgi?id=605888
+ *
+ * Some Ricoh devices use the function 0 source ID for DMA on
+ * other functions of a multifunction device. The DMA devices
+ * is therefore function 0, which will have implications of the
+ * iommu grouping of these devices.
+ */
+ { PCI_VENDOR_ID_RICOH, 0xe822, pci_func_0_dma_source },
+ { PCI_VENDOR_ID_RICOH, 0xe230, pci_func_0_dma_source },
+ { PCI_VENDOR_ID_RICOH, 0xe832, pci_func_0_dma_source },
+ { PCI_VENDOR_ID_RICOH, 0xe476, pci_func_0_dma_source },
+ { 0 }
+ };
+
+ /*
+ * IOMMUs with isolation capabilities need to be programmed with the
+ * correct source ID of a device. In most cases, the source ID matches
+ * the device doing the DMA, but sometimes hardware is broken and will
+ * tag the DMA as being sourced from a different device. This function
+ * allows that translation. Note that the reference count of the
+ * returned device is incremented on all paths.
+ */
+ struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
+ {
+ const struct pci_dev_dma_source *i;
+
+ for (i = pci_dev_dma_source; i->dma_source; i++) {
+ if ((i->vendor == dev->vendor ||
+ i->vendor == (u16)PCI_ANY_ID) &&
+ (i->device == dev->device ||
+ i->device == (u16)PCI_ANY_ID))
+ return i->dma_source(dev);
+ }
+
+ return pci_dev_get(dev);
+ }
+
+ static const struct pci_dev_acs_enabled {
+ u16 vendor;
+ u16 device;
+ int (*acs_enabled)(struct pci_dev *dev, u16 acs_flags);
+ } pci_dev_acs_enabled[] = {
+ { 0 }
+ };
+
+ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags)
+ {
+ const struct pci_dev_acs_enabled *i;
+ int ret;
+
+ /*
+ * Allow devices that do not expose standard PCIe ACS capabilities
+ * or control to indicate their support here. Multi-function express
+ * devices which do not allow internal peer-to-peer between functions,
+ * but do not implement PCIe ACS may wish to return true here.
+ */
+ for (i = pci_dev_acs_enabled; i->acs_enabled; i++) {
+ if ((i->vendor == dev->vendor ||
+ i->vendor == (u16)PCI_ANY_ID) &&
+ (i->device == dev->device ||
+ i->device == (u16)PCI_ANY_ID)) {
+ ret = i->acs_enabled(dev, acs_flags);
+ if (ret >= 0)
+ return ret;
+ }
+ }
+
+ return -ENOTTY;
+ }
* assign_requested_resources_sorted() - satisfy resource requests
*
* @head : head of the list tracking requests for resources
- * @failed_list : head of the list tracking requests that could
+ * @fail_head : head of the list tracking requests that could
* not be allocated
*
* Satisfy resource requests of each element in the list. Add
* Should not assign requested resources at first.
* they could be adjacent, so later reassign can not reallocate
* them one by one in parent resource window.
- * Try to assign requested + add_size at begining
+ * Try to assign requested + add_size at beginning
* if could do that, could get out early.
* if could not do that, we still try to assign requested at first,
* then try to reassign add_size for some resources.
struct resource *res;
struct pci_bus_region region;
- dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
- bus->secondary, bus->subordinate);
+ dev_info(&bridge->dev, "CardBus bridge to %pR\n",
+ &bus->busn_res);
res = bus->resource[0];
pcibios_resource_to_bus(bridge, ®ion, res);
struct pci_dev *bridge = bus->self;
struct resource *res;
struct pci_bus_region region;
+ unsigned long io_mask;
+ u8 io_base_lo, io_limit_lo;
u32 l, io_upper16;
+ io_mask = PCI_IO_RANGE_MASK;
+ if (bridge->io_window_1k)
+ io_mask = PCI_IO_1K_RANGE_MASK;
+
/* Set up the top and bottom of the PCI I/O segment for this bus. */
res = bus->resource[0];
pcibios_resource_to_bus(bridge, ®ion, res);
if (res->flags & IORESOURCE_IO) {
pci_read_config_dword(bridge, PCI_IO_BASE, &l);
l &= 0xffff0000;
- l |= (region.start >> 8) & 0x00f0;
- l |= region.end & 0xf000;
+ io_base_lo = (region.start >> 8) & io_mask;
+ io_limit_lo = (region.end >> 8) & io_mask;
+ l |= ((u32) io_limit_lo << 8) | io_base_lo;
/* Set up upper 16 bits of I/O base/limit. */
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
dev_info(&bridge->dev, " bridge window %pR\n", res);
{
struct pci_dev *bridge = bus->self;
- dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
- bus->secondary, bus->subordinate);
+ dev_info(&bridge->dev, "PCI bridge to %pR\n",
+ &bus->busn_res);
if (type & IORESOURCE_IO)
pci_setup_bridge_io(bus);
* @realloc_head : track the additional io window on this list
*
* Sizing the IO windows of the PCI-PCI bridge is trivial,
- * since these windows have 4K granularity and the IO ranges
+ * since these windows have 1K or 4K granularity and the IO ranges
* of non-bridge PCI devices are limited to 256 bytes.
* We must be careful with the ISA aliasing though.
*/
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
unsigned long size = 0, size0 = 0, size1 = 0;
resource_size_t children_add_size = 0;
+ resource_size_t min_align = 4096, align;
if (!b_res)
return;
+ /*
+ * Per spec, I/O windows are 4K-aligned, but some bridges have an
+ * extension to support 1K alignment.
+ */
+ if (bus->self->io_window_1k)
+ min_align = 1024;
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
else
size1 += r_size;
+ align = pci_resource_alignment(dev, r);
+ if (align > min_align)
+ min_align = align;
+
if (realloc_head)
children_add_size += get_res_add_size(realloc_head, r);
}
}
+
+ if (min_align > 4096)
+ min_align = 4096;
+
size0 = calculate_iosize(size, min_size, size1,
- resource_size(b_res), 4096);
+ resource_size(b_res), min_align);
if (children_add_size > add_size)
add_size = children_add_size;
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
calculate_iosize(size, min_size, add_size + size1,
- resource_size(b_res), 4096);
+ resource_size(b_res), min_align);
if (!size0 && !size1) {
if (b_res->start || b_res->end)
dev_info(&bus->self->dev, "disabling bridge window "
- "%pR to [bus %02x-%02x] (unused)\n", b_res,
- bus->secondary, bus->subordinate);
+ "%pR to %pR (unused)\n", b_res,
+ &bus->busn_res);
b_res->flags = 0;
return;
}
- /* Alignment of the IO window is always 4K */
- b_res->start = 4096;
+
+ b_res->start = min_align;
b_res->end = b_res->start + size0 - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
if (size1 > size0 && realloc_head) {
- add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
+ add_to_list(realloc_head, bus->self, b_res, size1-size0,
+ min_align);
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
- "%pR to [bus %02x-%02x] add_size %lx\n", b_res,
- bus->secondary, bus->subordinate, size1-size0);
+ "%pR to %pR add_size %lx\n", b_res,
+ &bus->busn_res, size1-size0);
}
}
if (!size0 && !size1) {
if (b_res->start || b_res->end)
dev_info(&bus->self->dev, "disabling bridge window "
- "%pR to [bus %02x-%02x] (unused)\n", b_res,
- bus->secondary, bus->subordinate);
+ "%pR to %pR (unused)\n", b_res,
+ &bus->busn_res);
b_res->flags = 0;
return 1;
}
if (size1 > size0 && realloc_head) {
add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
- "%pR to [bus %02x-%02x] add_size %llx\n", b_res,
- bus->secondary, bus->subordinate, (unsigned long long)size1-size0);
+ "%pR to %pR add_size %llx\n", b_res,
+ &bus->busn_res, (unsigned long long)size1-size0);
}
return 1;
}
typedef int (*acpi_op_add) (struct acpi_device * device);
typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
typedef int (*acpi_op_start) (struct acpi_device * device);
-typedef int (*acpi_op_suspend) (struct acpi_device * device,
- pm_message_t state);
-typedef int (*acpi_op_resume) (struct acpi_device * device);
typedef int (*acpi_op_bind) (struct acpi_device * device);
typedef int (*acpi_op_unbind) (struct acpi_device * device);
typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
acpi_op_add add;
acpi_op_remove remove;
acpi_op_start start;
- acpi_op_suspend suspend;
- acpi_op_resume resume;
acpi_op_bind bind;
acpi_op_unbind unbind;
acpi_op_notify notify;
u32 osc_support_set; /* _OSC state of support bits */
u32 osc_control_set; /* _OSC state of control bits */
+ phys_addr_t mcfg_addr;
};
/* helper */
int acpi_disable_wakeup_device_power(struct acpi_device *dev);
#ifdef CONFIG_PM
- int acpi_pm_device_sleep_state(struct device *, int *);
+ int acpi_pm_device_sleep_state(struct device *, int *, int);
#else
- static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
+ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
{
if (p)
*p = ACPI_STATE_D0;
- return ACPI_STATE_D3;
+ return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0;
}
#endif