Driver core patches for 3.11-rc1
Here's the big driver core merge for 3.11-rc1 Lots of little things, and larger firmware subsystem updates, all described in the shortlog. Nice thing here is that we finally get rid of CONFIG_HOTPLUG, after 10+ years, thanks to Stephen Rohtwell (it had been always on for a number of kernel releases, now it's just removed.) Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlHRsGMACgkQMUfUDdst+ylIIACfW8lLxOPVK+iYG699TWEBAkp0 LFEAnjlpAMJ1JnoZCuWDZObNCev93zGB =020+ -----END PGP SIGNATURE----- Merge tag 'driver-core-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core updates from Greg KH: "Here's the big driver core merge for 3.11-rc1 Lots of little things, and larger firmware subsystem updates, all described in the shortlog. Nice thing here is that we finally get rid of CONFIG_HOTPLUG, after 10+ years, thanks to Stephen Rohtwell (it had been always on for a number of kernel releases, now it's just removed)" * tag 'driver-core-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (27 commits) driver core: device.h: fix doc compilation warnings firmware loader: fix another compile warning with PM_SLEEP unset build some drivers only when compile-testing firmware loader: fix compile warning with PM_SLEEP set kobject: sanitize argument for format string sysfs_notify is only possible on file attributes firmware loader: simplify holding module for request_firmware firmware loader: don't export cache_firmware and uncache_firmware drivers/base: Use attribute groups to create sysfs memory files firmware loader: fix compile warning firmware loader: fix build failure with !CONFIG_FW_LOADER_USER_HELPER Documentation: Updated broken link in HOWTO Finally eradicate CONFIG_HOTPLUG driver core: firmware loader: kill FW_ACTION_NOHOTPLUG requests before suspend driver core: firmware loader: don't cache FW_ACTION_NOHOTPLUG firmware Documentation: Tidy up some drivers/base/core.c kerneldoc content. platform_device: use a macro instead of platform_driver_register firmware: move EXPORT_SYMBOL annotations firmware: Avoid deadlock of usermodehelper lock at shutdown dell_rbu: Select CONFIG_FW_LOADER_USER_HELPER explicitly ...
This commit is contained in:
commit
fc76a258d4
53 changed files with 316 additions and 265 deletions
|
@ -64,7 +64,6 @@ Description:
|
|||
Writing a non-zero value to this attribute will
|
||||
force a rescan of all PCI buses in the system, and
|
||||
re-discover previously removed devices.
|
||||
Depends on CONFIG_HOTPLUG.
|
||||
|
||||
What: /sys/bus/pci/devices/.../msi_irqs/
|
||||
Date: September, 2011
|
||||
|
@ -90,7 +89,6 @@ Contact: Linux PCI developers <linux-pci@vger.kernel.org>
|
|||
Description:
|
||||
Writing a non-zero value to this attribute will
|
||||
hot-remove the PCI device and any of its children.
|
||||
Depends on CONFIG_HOTPLUG.
|
||||
|
||||
What: /sys/bus/pci/devices/.../pci_bus/.../rescan
|
||||
Date: May 2011
|
||||
|
@ -99,7 +97,7 @@ Description:
|
|||
Writing a non-zero value to this attribute will
|
||||
force a rescan of the bus and all child buses,
|
||||
and re-discover devices removed earlier from this
|
||||
part of the device tree. Depends on CONFIG_HOTPLUG.
|
||||
part of the device tree.
|
||||
|
||||
What: /sys/bus/pci/devices/.../rescan
|
||||
Date: January 2009
|
||||
|
@ -109,7 +107,6 @@ Description:
|
|||
force a rescan of the device's parent bus and all
|
||||
child buses, and re-discover devices removed earlier
|
||||
from this part of the device tree.
|
||||
Depends on CONFIG_HOTPLUG.
|
||||
|
||||
What: /sys/bus/pci/devices/.../reset
|
||||
Date: July 2009
|
||||
|
|
|
@ -112,7 +112,7 @@ required reading:
|
|||
|
||||
Other excellent descriptions of how to create patches properly are:
|
||||
"The Perfect Patch"
|
||||
http://userweb.kernel.org/~akpm/stuff/tpp.txt
|
||||
http://kerneltrap.org/node/3737
|
||||
"Linux kernel patch submission format"
|
||||
http://linux.yyz.us/patch-format.html
|
||||
|
||||
|
|
|
@ -105,5 +105,5 @@ kernel patches.
|
|||
same time, just various/random combinations of them]:
|
||||
|
||||
CONFIG_SMP, CONFIG_SYSFS, CONFIG_PROC_FS, CONFIG_INPUT, CONFIG_PCI,
|
||||
CONFIG_BLOCK, CONFIG_PM, CONFIG_HOTPLUG, CONFIG_MAGIC_SYSRQ,
|
||||
CONFIG_BLOCK, CONFIG_PM, CONFIG_MAGIC_SYSRQ,
|
||||
CONFIG_NET, CONFIG_INET=n (but latter with CONFIG_NET=y)
|
||||
|
|
|
@ -128,7 +128,7 @@ A: When doing make defconfig, Enable CPU hotplug support
|
|||
|
||||
"Processor type and Features" -> Support for Hotpluggable CPUs
|
||||
|
||||
Make sure that you have CONFIG_HOTPLUG, and CONFIG_SMP turned on as well.
|
||||
Make sure that you have CONFIG_SMP turned on as well.
|
||||
|
||||
You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support
|
||||
as well.
|
||||
|
|
|
@ -27,8 +27,7 @@ increase the chances of your change being accepted.
|
|||
explicitly below the patch header.
|
||||
|
||||
* If your patch (or the driver) is affected by configuration options such as
|
||||
CONFIG_SMP or CONFIG_HOTPLUG, make sure it compiles for all configuration
|
||||
variants.
|
||||
CONFIG_SMP, make sure it compiles for all configuration variants.
|
||||
|
||||
|
||||
2. Adding functionality to existing drivers
|
||||
|
|
|
@ -165,7 +165,7 @@ Searching in menuconfig:
|
|||
Example:
|
||||
/hotplug
|
||||
This lists all config symbols that contain "hotplug",
|
||||
e.g., HOTPLUG, HOTPLUG_CPU, MEMORY_HOTPLUG.
|
||||
e.g., HOTPLUG_CPU, MEMORY_HOTPLUG.
|
||||
|
||||
For search help, enter / followed TAB-TAB-TAB (to highlight
|
||||
<Help>) and Enter. This will tell you that you can also use
|
||||
|
|
|
@ -33,9 +33,9 @@ you get the best hotplugging when you configure a highly modular system.
|
|||
|
||||
KERNEL HOTPLUG HELPER (/sbin/hotplug)
|
||||
|
||||
When you compile with CONFIG_HOTPLUG, you get a new kernel parameter:
|
||||
/proc/sys/kernel/hotplug, which normally holds the pathname "/sbin/hotplug".
|
||||
That parameter names a program which the kernel may invoke at various times.
|
||||
There is a kernel parameter: /proc/sys/kernel/hotplug, which normally
|
||||
holds the pathname "/sbin/hotplug". That parameter names a program
|
||||
which the kernel may invoke at various times.
|
||||
|
||||
The /sbin/hotplug program can be invoked by any subsystem as part of its
|
||||
reaction to a configuration change, from a thread in that subsystem.
|
||||
|
|
|
@ -1552,7 +1552,7 @@ config NR_CPUS
|
|||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SMP && HOTPLUG
|
||||
depends on SMP
|
||||
help
|
||||
Say Y here to experiment with turning CPUs off and on. CPUs
|
||||
can be controlled through /sys/devices/system/cpu.
|
||||
|
|
|
@ -288,24 +288,16 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
|
|||
|
||||
if (strcmp(".ARM.exidx.init.text", secname) == 0)
|
||||
maps[ARM_SEC_INIT].unw_sec = s;
|
||||
else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
|
||||
maps[ARM_SEC_DEVINIT].unw_sec = s;
|
||||
else if (strcmp(".ARM.exidx", secname) == 0)
|
||||
maps[ARM_SEC_CORE].unw_sec = s;
|
||||
else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
|
||||
maps[ARM_SEC_EXIT].unw_sec = s;
|
||||
else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
|
||||
maps[ARM_SEC_DEVEXIT].unw_sec = s;
|
||||
else if (strcmp(".init.text", secname) == 0)
|
||||
maps[ARM_SEC_INIT].txt_sec = s;
|
||||
else if (strcmp(".devinit.text", secname) == 0)
|
||||
maps[ARM_SEC_DEVINIT].txt_sec = s;
|
||||
else if (strcmp(".text", secname) == 0)
|
||||
maps[ARM_SEC_CORE].txt_sec = s;
|
||||
else if (strcmp(".exit.text", secname) == 0)
|
||||
maps[ARM_SEC_EXIT].txt_sec = s;
|
||||
else if (strcmp(".devexit.text", secname) == 0)
|
||||
maps[ARM_SEC_DEVEXIT].txt_sec = s;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARM_SEC_MAX; i++)
|
||||
|
|
|
@ -70,10 +70,6 @@ SECTIONS
|
|||
ARM_EXIT_DISCARD(EXIT_TEXT)
|
||||
ARM_EXIT_DISCARD(EXIT_DATA)
|
||||
EXIT_CALL
|
||||
#ifndef CONFIG_HOTPLUG
|
||||
*(.ARM.exidx.devexit.text)
|
||||
*(.ARM.extab.devexit.text)
|
||||
#endif
|
||||
#ifndef CONFIG_MMU
|
||||
*(.fixup)
|
||||
*(__ex_table)
|
||||
|
|
|
@ -235,7 +235,6 @@ config IXP4XX_QMGR
|
|||
config IXP4XX_NPE
|
||||
tristate "IXP4xx Network Processor Engine support"
|
||||
select FW_LOADER
|
||||
select HOTPLUG
|
||||
help
|
||||
This driver supports IXP4xx built-in network coprocessors
|
||||
and is automatically selected by Ethernet and HSS drivers.
|
||||
|
|
|
@ -253,7 +253,7 @@ config NR_CPUS
|
|||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SMP && HOTPLUG
|
||||
depends on SMP
|
||||
default y
|
||||
|
||||
config BF_REV_MIN
|
||||
|
|
|
@ -617,7 +617,6 @@ config ETRAX_PV_CHANGEABLE_BITS
|
|||
config ETRAX_CARDBUS
|
||||
bool "Cardbus support"
|
||||
depends on ETRAX_ARCH_V32
|
||||
select HOTPLUG
|
||||
help
|
||||
Enabled the ETRAX Cardbus driver.
|
||||
|
||||
|
|
|
@ -376,7 +376,6 @@ config NR_CPUS
|
|||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SMP
|
||||
select HOTPLUG
|
||||
default n
|
||||
---help---
|
||||
Say Y here to experiment with turning CPUs off and on. CPUs
|
||||
|
|
|
@ -962,7 +962,7 @@ config SYS_HAS_EARLY_PRINTK
|
|||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU
|
||||
depends on SMP && SYS_SUPPORTS_HOTPLUG_CPU
|
||||
help
|
||||
Say Y here to allow turning CPUs off and on. CPUs can be
|
||||
controlled through /sys/devices/system/cpu.
|
||||
|
|
|
@ -254,7 +254,6 @@ config IRQSTACKS
|
|||
config HOTPLUG_CPU
|
||||
bool
|
||||
default y if SMP
|
||||
select HOTPLUG
|
||||
|
||||
config ARCH_SELECT_MEMORY_MODEL
|
||||
def_bool y
|
||||
|
|
|
@ -341,7 +341,7 @@ config SWIOTLB
|
|||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for enabling/disabling CPUs"
|
||||
depends on SMP && HOTPLUG && (PPC_PSERIES || \
|
||||
depends on SMP && (PPC_PSERIES || \
|
||||
PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
|
||||
---help---
|
||||
Say Y here to be able to disable and re-enable individual
|
||||
|
|
|
@ -183,8 +183,8 @@ void tlb_flush(struct mmu_gather *tlb)
|
|||
* since 64K pages may overlap with other bridges when using 64K pages
|
||||
* with 4K HW pages on IO space.
|
||||
*
|
||||
* Because of that usage pattern, it's only available with CONFIG_HOTPLUG
|
||||
* and is implemented for small size rather than speed.
|
||||
* Because of that usage pattern, it is implemented for small size rather
|
||||
* than speed.
|
||||
*/
|
||||
void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
|
||||
unsigned long end)
|
||||
|
|
|
@ -301,7 +301,6 @@ config HOTPLUG_CPU
|
|||
def_bool y
|
||||
prompt "Support for hot-pluggable CPUs"
|
||||
depends on SMP
|
||||
select HOTPLUG
|
||||
help
|
||||
Say Y here to be able to turn CPUs off and on. CPUs
|
||||
can be controlled through /sys/devices/system/cpu/cpu#.
|
||||
|
|
|
@ -748,7 +748,7 @@ config NR_CPUS
|
|||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
|
||||
depends on SMP && HOTPLUG
|
||||
depends on SMP
|
||||
help
|
||||
Say Y here to experiment with turning CPUs off and on. CPUs
|
||||
can be controlled through /sys/devices/system/cpu.
|
||||
|
|
|
@ -243,7 +243,6 @@ config SECCOMP
|
|||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SPARC64 && SMP
|
||||
select HOTPLUG
|
||||
help
|
||||
Say Y here to experiment with turning CPUs off and on. CPUs
|
||||
can be controlled through /sys/devices/system/cpu/cpu#.
|
||||
|
|
|
@ -1725,7 +1725,7 @@ config PHYSICAL_ALIGN
|
|||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SMP && HOTPLUG
|
||||
depends on SMP
|
||||
---help---
|
||||
Say Y here to allow turning CPUs off and on. CPUs can be
|
||||
controlled through /sys/devices/system/cpu.
|
||||
|
|
|
@ -2,7 +2,6 @@ menu "Generic Driver Options"
|
|||
|
||||
config UEVENT_HELPER_PATH
|
||||
string "path to uevent helper"
|
||||
depends on HOTPLUG
|
||||
default ""
|
||||
help
|
||||
Path to uevent helper program forked by the kernel for
|
||||
|
@ -23,7 +22,6 @@ config UEVENT_HELPER_PATH
|
|||
|
||||
config DEVTMPFS
|
||||
bool "Maintain a devtmpfs filesystem to mount at /dev"
|
||||
depends on HOTPLUG
|
||||
help
|
||||
This creates a tmpfs/ramfs filesystem instance early at bootup.
|
||||
In this filesystem, the kernel driver core maintains device
|
||||
|
|
|
@ -193,12 +193,12 @@ ssize_t device_show_bool(struct device *dev, struct device_attribute *attr,
|
|||
EXPORT_SYMBOL_GPL(device_show_bool);
|
||||
|
||||
/**
|
||||
* device_release - free device structure.
|
||||
* @kobj: device's kobject.
|
||||
* device_release - free device structure.
|
||||
* @kobj: device's kobject.
|
||||
*
|
||||
* This is called once the reference count for the object
|
||||
* reaches 0. We forward the call to the device's release
|
||||
* method, which should handle actually freeing the structure.
|
||||
* This is called once the reference count for the object
|
||||
* reaches 0. We forward the call to the device's release
|
||||
* method, which should handle actually freeing the structure.
|
||||
*/
|
||||
static void device_release(struct kobject *kobj)
|
||||
{
|
||||
|
@ -1334,8 +1334,8 @@ const char *device_get_devnode(struct device *dev,
|
|||
/**
|
||||
* device_for_each_child - device child iterator.
|
||||
* @parent: parent struct device.
|
||||
* @data: data for the callback.
|
||||
* @fn: function to be called for each device.
|
||||
* @data: data for the callback.
|
||||
*
|
||||
* Iterate over @parent's child devices, and call @fn for each,
|
||||
* passing it @data.
|
||||
|
@ -1363,8 +1363,8 @@ int device_for_each_child(struct device *parent, void *data,
|
|||
/**
|
||||
* device_find_child - device iterator for locating a particular device.
|
||||
* @parent: parent struct device
|
||||
* @data: Data to pass to match function
|
||||
* @match: Callback function to check device
|
||||
* @data: Data to pass to match function
|
||||
*
|
||||
* This is similar to the device_for_each_child() function above, but it
|
||||
* returns a reference to a device that is 'found' for later use, as
|
||||
|
@ -1374,6 +1374,8 @@ int device_for_each_child(struct device *parent, void *data,
|
|||
* if it does. If the callback returns non-zero and a reference to the
|
||||
* current device can be obtained, this function will return to the caller
|
||||
* and not iterate over any more devices.
|
||||
*
|
||||
* NOTE: you will need to drop the reference with put_device() after use.
|
||||
*/
|
||||
struct device *device_find_child(struct device *parent, void *data,
|
||||
int (*match)(struct device *dev, void *data))
|
||||
|
|
|
@ -85,18 +85,21 @@ static ssize_t __ref store_online(struct device *dev,
|
|||
}
|
||||
static DEVICE_ATTR(online, 0644, show_online, store_online);
|
||||
|
||||
static void __cpuinit register_cpu_control(struct cpu *cpu)
|
||||
{
|
||||
device_create_file(&cpu->dev, &dev_attr_online);
|
||||
}
|
||||
static struct attribute *hotplug_cpu_attrs[] = {
|
||||
&dev_attr_online.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group hotplug_cpu_attr_group = {
|
||||
.attrs = hotplug_cpu_attrs,
|
||||
};
|
||||
|
||||
void unregister_cpu(struct cpu *cpu)
|
||||
{
|
||||
int logical_cpu = cpu->dev.id;
|
||||
|
||||
unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
|
||||
|
||||
device_remove_file(&cpu->dev, &dev_attr_online);
|
||||
|
||||
device_unregister(&cpu->dev);
|
||||
per_cpu(cpu_sys_devices, logical_cpu) = NULL;
|
||||
return;
|
||||
|
@ -122,11 +125,6 @@ static ssize_t cpu_release_store(struct device *dev,
|
|||
static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
|
||||
static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
|
||||
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
|
||||
|
||||
#else /* ... !CONFIG_HOTPLUG_CPU */
|
||||
static inline void register_cpu_control(struct cpu *cpu)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
|
@ -164,8 +162,35 @@ static ssize_t show_crash_notes_size(struct device *dev,
|
|||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL);
|
||||
|
||||
static struct attribute *crash_note_cpu_attrs[] = {
|
||||
&dev_attr_crash_notes.attr,
|
||||
&dev_attr_crash_notes_size.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group crash_note_cpu_attr_group = {
|
||||
.attrs = crash_note_cpu_attrs,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct attribute_group *common_cpu_attr_groups[] = {
|
||||
#ifdef CONFIG_KEXEC
|
||||
&crash_note_cpu_attr_group,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
|
||||
#ifdef CONFIG_KEXEC
|
||||
&crash_note_cpu_attr_group,
|
||||
#endif
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
&hotplug_cpu_attr_group,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Print cpu online, possible, present, and system maps
|
||||
*/
|
||||
|
@ -280,21 +305,15 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
|
|||
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
cpu->dev.bus->uevent = arch_cpu_uevent;
|
||||
#endif
|
||||
cpu->dev.groups = common_cpu_attr_groups;
|
||||
if (cpu->hotpluggable)
|
||||
cpu->dev.groups = hotplugable_cpu_attr_groups;
|
||||
error = device_register(&cpu->dev);
|
||||
if (!error && cpu->hotpluggable)
|
||||
register_cpu_control(cpu);
|
||||
if (!error)
|
||||
per_cpu(cpu_sys_devices, num) = &cpu->dev;
|
||||
if (!error)
|
||||
register_cpu_under_node(num, cpu_to_node(num));
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
if (!error)
|
||||
error = device_create_file(&cpu->dev, &dev_attr_crash_notes);
|
||||
if (!error)
|
||||
error = device_create_file(&cpu->dev,
|
||||
&dev_attr_crash_notes_size);
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/pm.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include <generated/utsrelease.h>
|
||||
|
||||
|
@ -127,9 +128,11 @@ struct firmware_buf {
|
|||
size_t size;
|
||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||
bool is_paged_buf;
|
||||
bool need_uevent;
|
||||
struct page **pages;
|
||||
int nr_pages;
|
||||
int page_array_size;
|
||||
struct list_head pending_list;
|
||||
#endif
|
||||
char fw_id[];
|
||||
};
|
||||
|
@ -171,6 +174,9 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name,
|
|||
strcpy(buf->fw_id, fw_name);
|
||||
buf->fwc = fwc;
|
||||
init_completion(&buf->completion);
|
||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||
INIT_LIST_HEAD(&buf->pending_list);
|
||||
#endif
|
||||
|
||||
pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf);
|
||||
|
||||
|
@ -212,18 +218,6 @@ static int fw_lookup_and_allocate_buf(const char *fw_name,
|
|||
return tmp ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static struct firmware_buf *fw_lookup_buf(const char *fw_name)
|
||||
{
|
||||
struct firmware_buf *tmp;
|
||||
struct firmware_cache *fwc = &fw_cache;
|
||||
|
||||
spin_lock(&fwc->lock);
|
||||
tmp = __fw_lookup_buf(fw_name);
|
||||
spin_unlock(&fwc->lock);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void __fw_free_buf(struct kref *ref)
|
||||
{
|
||||
struct firmware_buf *buf = to_fwbuf(ref);
|
||||
|
@ -446,10 +440,8 @@ static struct firmware_priv *to_firmware_priv(struct device *dev)
|
|||
return container_of(dev, struct firmware_priv, dev);
|
||||
}
|
||||
|
||||
static void fw_load_abort(struct firmware_priv *fw_priv)
|
||||
static void __fw_load_abort(struct firmware_buf *buf)
|
||||
{
|
||||
struct firmware_buf *buf = fw_priv->buf;
|
||||
|
||||
/*
|
||||
* There is a small window in which user can write to 'loading'
|
||||
* between loading done and disappearance of 'loading'
|
||||
|
@ -457,8 +449,16 @@ static void fw_load_abort(struct firmware_priv *fw_priv)
|
|||
if (test_bit(FW_STATUS_DONE, &buf->status))
|
||||
return;
|
||||
|
||||
list_del_init(&buf->pending_list);
|
||||
set_bit(FW_STATUS_ABORT, &buf->status);
|
||||
complete_all(&buf->completion);
|
||||
}
|
||||
|
||||
static void fw_load_abort(struct firmware_priv *fw_priv)
|
||||
{
|
||||
struct firmware_buf *buf = fw_priv->buf;
|
||||
|
||||
__fw_load_abort(buf);
|
||||
|
||||
/* avoid user action after loading abort */
|
||||
fw_priv->buf = NULL;
|
||||
|
@ -467,6 +467,25 @@ static void fw_load_abort(struct firmware_priv *fw_priv)
|
|||
#define is_fw_load_aborted(buf) \
|
||||
test_bit(FW_STATUS_ABORT, &(buf)->status)
|
||||
|
||||
static LIST_HEAD(pending_fw_head);
|
||||
|
||||
/* reboot notifier for avoid deadlock with usermode_lock */
|
||||
static int fw_shutdown_notify(struct notifier_block *unused1,
|
||||
unsigned long unused2, void *unused3)
|
||||
{
|
||||
mutex_lock(&fw_lock);
|
||||
while (!list_empty(&pending_fw_head))
|
||||
__fw_load_abort(list_first_entry(&pending_fw_head,
|
||||
struct firmware_buf,
|
||||
pending_list));
|
||||
mutex_unlock(&fw_lock);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block fw_shutdown_nb = {
|
||||
.notifier_call = fw_shutdown_notify,
|
||||
};
|
||||
|
||||
static ssize_t firmware_timeout_show(struct class *class,
|
||||
struct class_attribute *attr,
|
||||
char *buf)
|
||||
|
@ -509,8 +528,6 @@ static void fw_dev_release(struct device *dev)
|
|||
struct firmware_priv *fw_priv = to_firmware_priv(dev);
|
||||
|
||||
kfree(fw_priv);
|
||||
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
|
@ -619,6 +636,7 @@ static ssize_t firmware_loading_store(struct device *dev,
|
|||
* is completed.
|
||||
* */
|
||||
fw_map_pages_buf(fw_buf);
|
||||
list_del_init(&fw_buf->pending_list);
|
||||
complete_all(&fw_buf->completion);
|
||||
break;
|
||||
}
|
||||
|
@ -838,9 +856,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
|
|||
|
||||
dev_set_uevent_suppress(f_dev, true);
|
||||
|
||||
/* Need to pin this module until class device is destroyed */
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
retval = device_add(f_dev);
|
||||
if (retval) {
|
||||
dev_err(f_dev, "%s: device_register failed\n", __func__);
|
||||
|
@ -860,6 +875,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
|
|||
}
|
||||
|
||||
if (uevent) {
|
||||
buf->need_uevent = true;
|
||||
dev_set_uevent_suppress(f_dev, false);
|
||||
dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id);
|
||||
if (timeout != MAX_SCHEDULE_TIMEOUT)
|
||||
|
@ -868,6 +884,10 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
|
|||
kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
|
||||
}
|
||||
|
||||
mutex_lock(&fw_lock);
|
||||
list_add(&buf->pending_list, &pending_fw_head);
|
||||
mutex_unlock(&fw_lock);
|
||||
|
||||
wait_for_completion(&buf->completion);
|
||||
|
||||
cancel_delayed_work_sync(&fw_priv->timeout_work);
|
||||
|
@ -895,6 +915,23 @@ static int fw_load_from_user_helper(struct firmware *firmware,
|
|||
fw_priv->buf = firmware->priv;
|
||||
return _request_firmware_load(fw_priv, uevent, timeout);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/* kill pending requests without uevent to avoid blocking suspend */
|
||||
static void kill_requests_without_uevent(void)
|
||||
{
|
||||
struct firmware_buf *buf;
|
||||
struct firmware_buf *next;
|
||||
|
||||
mutex_lock(&fw_lock);
|
||||
list_for_each_entry_safe(buf, next, &pending_fw_head, pending_list) {
|
||||
if (!buf->need_uevent)
|
||||
__fw_load_abort(buf);
|
||||
}
|
||||
mutex_unlock(&fw_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_FW_LOADER_USER_HELPER */
|
||||
static inline int
|
||||
fw_load_from_user_helper(struct firmware *firmware, const char *name,
|
||||
|
@ -907,6 +944,10 @@ fw_load_from_user_helper(struct firmware *firmware, const char *name,
|
|||
/* No abort during direct loading */
|
||||
#define is_fw_load_aborted(buf) false
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static inline void kill_requests_without_uevent(void) { }
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_FW_LOADER_USER_HELPER */
|
||||
|
||||
|
||||
|
@ -974,7 +1015,8 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
|
|||
return 1; /* need to load */
|
||||
}
|
||||
|
||||
static int assign_firmware_buf(struct firmware *fw, struct device *device)
|
||||
static int assign_firmware_buf(struct firmware *fw, struct device *device,
|
||||
bool skip_cache)
|
||||
{
|
||||
struct firmware_buf *buf = fw->priv;
|
||||
|
||||
|
@ -991,7 +1033,7 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device)
|
|||
* device may has been deleted already, but the problem
|
||||
* should be fixed in devres or driver core.
|
||||
*/
|
||||
if (device)
|
||||
if (device && !skip_cache)
|
||||
fw_add_devm_name(device, buf->fw_id);
|
||||
|
||||
/*
|
||||
|
@ -1047,8 +1089,10 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||
if (!fw_get_filesystem_firmware(device, fw->priv))
|
||||
ret = fw_load_from_user_helper(fw, name, device,
|
||||
uevent, nowait, timeout);
|
||||
|
||||
/* don't cache firmware handled without uevent */
|
||||
if (!ret)
|
||||
ret = assign_firmware_buf(fw, device);
|
||||
ret = assign_firmware_buf(fw, device, !uevent);
|
||||
|
||||
usermodehelper_read_unlock();
|
||||
|
||||
|
@ -1086,8 +1130,15 @@ int
|
|||
request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
struct device *device)
|
||||
{
|
||||
return _request_firmware(firmware_p, name, device, true, false);
|
||||
int ret;
|
||||
|
||||
/* Need to pin this module until return */
|
||||
__module_get(THIS_MODULE);
|
||||
ret = _request_firmware(firmware_p, name, device, true, false);
|
||||
module_put(THIS_MODULE);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(request_firmware);
|
||||
|
||||
/**
|
||||
* release_firmware: - release the resource associated with a firmware image
|
||||
|
@ -1101,6 +1152,7 @@ void release_firmware(const struct firmware *fw)
|
|||
kfree(fw);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(release_firmware);
|
||||
|
||||
/* Async support */
|
||||
struct firmware_work {
|
||||
|
@ -1181,6 +1233,10 @@ request_firmware_nowait(
|
|||
schedule_work(&fw_work->work);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(request_firmware_nowait);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
|
||||
|
||||
/**
|
||||
* cache_firmware - cache one firmware image in kernel memory space
|
||||
|
@ -1196,7 +1252,7 @@ request_firmware_nowait(
|
|||
* Return !0 otherwise
|
||||
*
|
||||
*/
|
||||
int cache_firmware(const char *fw_name)
|
||||
static int cache_firmware(const char *fw_name)
|
||||
{
|
||||
int ret;
|
||||
const struct firmware *fw;
|
||||
|
@ -1212,6 +1268,18 @@ int cache_firmware(const char *fw_name)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct firmware_buf *fw_lookup_buf(const char *fw_name)
|
||||
{
|
||||
struct firmware_buf *tmp;
|
||||
struct firmware_cache *fwc = &fw_cache;
|
||||
|
||||
spin_lock(&fwc->lock);
|
||||
tmp = __fw_lookup_buf(fw_name);
|
||||
spin_unlock(&fwc->lock);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* uncache_firmware - remove one cached firmware image
|
||||
* @fw_name: the firmware image name
|
||||
|
@ -1223,7 +1291,7 @@ int cache_firmware(const char *fw_name)
|
|||
* Return !0 otherwise
|
||||
*
|
||||
*/
|
||||
int uncache_firmware(const char *fw_name)
|
||||
static int uncache_firmware(const char *fw_name)
|
||||
{
|
||||
struct firmware_buf *buf;
|
||||
struct firmware fw;
|
||||
|
@ -1242,9 +1310,6 @@ int uncache_firmware(const char *fw_name)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
|
||||
|
||||
static struct fw_cache_entry *alloc_fw_cache_entry(const char *name)
|
||||
{
|
||||
struct fw_cache_entry *fce;
|
||||
|
@ -1464,6 +1529,7 @@ static int fw_pm_notify(struct notifier_block *notify_block,
|
|||
switch (mode) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_SUSPEND_PREPARE:
|
||||
kill_requests_without_uevent();
|
||||
device_cache_fw_images();
|
||||
break;
|
||||
|
||||
|
@ -1526,6 +1592,7 @@ static int __init firmware_class_init(void)
|
|||
{
|
||||
fw_cache_init();
|
||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||
register_reboot_notifier(&fw_shutdown_nb);
|
||||
return class_register(&firmware_class);
|
||||
#else
|
||||
return 0;
|
||||
|
@ -1539,15 +1606,10 @@ static void __exit firmware_class_exit(void)
|
|||
unregister_pm_notifier(&fw_cache.pm_notify);
|
||||
#endif
|
||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||
unregister_reboot_notifier(&fw_shutdown_nb);
|
||||
class_unregister(&firmware_class);
|
||||
#endif
|
||||
}
|
||||
|
||||
fs_initcall(firmware_class_init);
|
||||
module_exit(firmware_class_exit);
|
||||
|
||||
EXPORT_SYMBOL(release_firmware);
|
||||
EXPORT_SYMBOL(request_firmware);
|
||||
EXPORT_SYMBOL(request_firmware_nowait);
|
||||
EXPORT_SYMBOL_GPL(cache_firmware);
|
||||
EXPORT_SYMBOL_GPL(uncache_firmware);
|
||||
|
|
|
@ -77,22 +77,6 @@ static void memory_block_release(struct device *dev)
|
|||
kfree(mem);
|
||||
}
|
||||
|
||||
/*
|
||||
* register_memory - Setup a sysfs device for a memory block
|
||||
*/
|
||||
static
|
||||
int register_memory(struct memory_block *memory)
|
||||
{
|
||||
int error;
|
||||
|
||||
memory->dev.bus = &memory_subsys;
|
||||
memory->dev.id = memory->start_section_nr / sections_per_block;
|
||||
memory->dev.release = memory_block_release;
|
||||
|
||||
error = device_register(&memory->dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
unsigned long __weak memory_block_size_bytes(void)
|
||||
{
|
||||
return MIN_MEMORY_BLOCK_SIZE;
|
||||
|
@ -371,11 +355,6 @@ static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state);
|
|||
static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL);
|
||||
static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL);
|
||||
|
||||
#define mem_create_simple_file(mem, attr_name) \
|
||||
device_create_file(&mem->dev, &dev_attr_##attr_name)
|
||||
#define mem_remove_simple_file(mem, attr_name) \
|
||||
device_remove_file(&mem->dev, &dev_attr_##attr_name)
|
||||
|
||||
/*
|
||||
* Block size attribute stuff
|
||||
*/
|
||||
|
@ -388,12 +367,6 @@ print_block_size(struct device *dev, struct device_attribute *attr,
|
|||
|
||||
static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL);
|
||||
|
||||
static int block_size_init(void)
|
||||
{
|
||||
return device_create_file(memory_subsys.dev_root,
|
||||
&dev_attr_block_size_bytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some architectures will have custom drivers to do this, and
|
||||
* will not need to do it from userspace. The fake hot-add code
|
||||
|
@ -429,17 +402,8 @@ memory_probe_store(struct device *dev, struct device_attribute *attr,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
|
||||
|
||||
static int memory_probe_init(void)
|
||||
{
|
||||
return device_create_file(memory_subsys.dev_root, &dev_attr_probe);
|
||||
}
|
||||
#else
|
||||
static inline int memory_probe_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MEMORY_FAILURE
|
||||
|
@ -485,23 +449,6 @@ store_hard_offline_page(struct device *dev,
|
|||
|
||||
static DEVICE_ATTR(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page);
|
||||
static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_offline_page);
|
||||
|
||||
static __init int memory_fail_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = device_create_file(memory_subsys.dev_root,
|
||||
&dev_attr_soft_offline_page);
|
||||
if (!err)
|
||||
err = device_create_file(memory_subsys.dev_root,
|
||||
&dev_attr_hard_offline_page);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
static inline int memory_fail_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -546,6 +493,41 @@ struct memory_block *find_memory_block(struct mem_section *section)
|
|||
return find_memory_block_hinted(section, NULL);
|
||||
}
|
||||
|
||||
static struct attribute *memory_memblk_attrs[] = {
|
||||
&dev_attr_phys_index.attr,
|
||||
&dev_attr_end_phys_index.attr,
|
||||
&dev_attr_state.attr,
|
||||
&dev_attr_phys_device.attr,
|
||||
&dev_attr_removable.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group memory_memblk_attr_group = {
|
||||
.attrs = memory_memblk_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *memory_memblk_attr_groups[] = {
|
||||
&memory_memblk_attr_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* register_memory - Setup a sysfs device for a memory block
|
||||
*/
|
||||
static
|
||||
int register_memory(struct memory_block *memory)
|
||||
{
|
||||
int error;
|
||||
|
||||
memory->dev.bus = &memory_subsys;
|
||||
memory->dev.id = memory->start_section_nr / sections_per_block;
|
||||
memory->dev.release = memory_block_release;
|
||||
memory->dev.groups = memory_memblk_attr_groups;
|
||||
|
||||
error = device_register(&memory->dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int init_memory_block(struct memory_block **memory,
|
||||
struct mem_section *section, unsigned long state)
|
||||
{
|
||||
|
@ -569,16 +551,6 @@ static int init_memory_block(struct memory_block **memory,
|
|||
mem->phys_device = arch_get_memory_phys_device(start_pfn);
|
||||
|
||||
ret = register_memory(mem);
|
||||
if (!ret)
|
||||
ret = mem_create_simple_file(mem, phys_index);
|
||||
if (!ret)
|
||||
ret = mem_create_simple_file(mem, end_phys_index);
|
||||
if (!ret)
|
||||
ret = mem_create_simple_file(mem, state);
|
||||
if (!ret)
|
||||
ret = mem_create_simple_file(mem, phys_device);
|
||||
if (!ret)
|
||||
ret = mem_create_simple_file(mem, removable);
|
||||
|
||||
*memory = mem;
|
||||
return ret;
|
||||
|
@ -656,14 +628,9 @@ static int remove_memory_block(unsigned long node_id,
|
|||
unregister_mem_sect_under_nodes(mem, __section_nr(section));
|
||||
|
||||
mem->section_count--;
|
||||
if (mem->section_count == 0) {
|
||||
mem_remove_simple_file(mem, phys_index);
|
||||
mem_remove_simple_file(mem, end_phys_index);
|
||||
mem_remove_simple_file(mem, state);
|
||||
mem_remove_simple_file(mem, phys_device);
|
||||
mem_remove_simple_file(mem, removable);
|
||||
if (mem->section_count == 0)
|
||||
unregister_memory(mem);
|
||||
} else
|
||||
else
|
||||
kobject_put(&mem->dev.kobj);
|
||||
|
||||
mutex_unlock(&mem_sysfs_mutex);
|
||||
|
@ -700,6 +667,29 @@ bool is_memblock_offlined(struct memory_block *mem)
|
|||
return mem->state == MEM_OFFLINE;
|
||||
}
|
||||
|
||||
static struct attribute *memory_root_attrs[] = {
|
||||
#ifdef CONFIG_ARCH_MEMORY_PROBE
|
||||
&dev_attr_probe.attr,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MEMORY_FAILURE
|
||||
&dev_attr_soft_offline_page.attr,
|
||||
&dev_attr_hard_offline_page.attr,
|
||||
#endif
|
||||
|
||||
&dev_attr_block_size_bytes.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group memory_root_attr_group = {
|
||||
.attrs = memory_root_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *memory_root_attr_groups[] = {
|
||||
&memory_root_attr_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the sysfs support for memory devices...
|
||||
*/
|
||||
|
@ -711,7 +701,7 @@ int __init memory_dev_init(void)
|
|||
unsigned long block_sz;
|
||||
struct memory_block *mem = NULL;
|
||||
|
||||
ret = subsys_system_register(&memory_subsys, NULL);
|
||||
ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -734,15 +724,6 @@ int __init memory_dev_init(void)
|
|||
ret = err;
|
||||
}
|
||||
|
||||
err = memory_probe_init();
|
||||
if (!ret)
|
||||
ret = err;
|
||||
err = memory_fail_init();
|
||||
if (!ret)
|
||||
ret = err;
|
||||
err = block_size_init();
|
||||
if (!ret)
|
||||
ret = err;
|
||||
out:
|
||||
if (ret)
|
||||
printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
|
||||
|
|
|
@ -523,11 +523,13 @@ static void platform_drv_shutdown(struct device *_dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* platform_driver_register - register a driver for platform-level devices
|
||||
* __platform_driver_register - register a driver for platform-level devices
|
||||
* @drv: platform driver structure
|
||||
*/
|
||||
int platform_driver_register(struct platform_driver *drv)
|
||||
int __platform_driver_register(struct platform_driver *drv,
|
||||
struct module *owner)
|
||||
{
|
||||
drv->driver.owner = owner;
|
||||
drv->driver.bus = &platform_bus_type;
|
||||
if (drv->probe)
|
||||
drv->driver.probe = platform_drv_probe;
|
||||
|
@ -538,7 +540,7 @@ int platform_driver_register(struct platform_driver *drv)
|
|||
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_driver_register);
|
||||
EXPORT_SYMBOL_GPL(__platform_driver_register);
|
||||
|
||||
/**
|
||||
* platform_driver_unregister - unregister a driver for platform-level devices
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
menu "PCMCIA character devices"
|
||||
depends on HOTPLUG && PCMCIA!=n
|
||||
depends on PCMCIA!=n
|
||||
|
||||
config SYNCLINK_CS
|
||||
tristate "SyncLink PC Card support"
|
||||
|
|
|
@ -145,7 +145,7 @@ config EDAC_E7XXX
|
|||
|
||||
config EDAC_E752X
|
||||
tristate "Intel e752x (e7520, e7525, e7320) and 3100"
|
||||
depends on EDAC_MM_EDAC && PCI && X86 && HOTPLUG
|
||||
depends on EDAC_MM_EDAC && PCI && X86
|
||||
help
|
||||
Support for error detection and correction on the Intel
|
||||
E7520, E7525, E7320 server chipsets.
|
||||
|
|
|
@ -64,6 +64,7 @@ config DELL_RBU
|
|||
tristate "BIOS update support for DELL systems via sysfs"
|
||||
depends on X86
|
||||
select FW_LOADER
|
||||
select FW_LOADER_USER_HELPER
|
||||
help
|
||||
Say m if you want to have the option of updating the BIOS for your
|
||||
DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
|
||||
|
|
|
@ -135,7 +135,7 @@ config PHANTOM
|
|||
|
||||
config INTEL_MID_PTI
|
||||
tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
|
||||
depends on PCI && TTY
|
||||
depends on PCI && TTY && (X86_INTEL_MID || COMPILE_TEST)
|
||||
default n
|
||||
help
|
||||
The PTI (Parallel Trace Interface) driver directs
|
||||
|
|
|
@ -55,7 +55,6 @@ config PCI_STUB
|
|||
config XEN_PCIDEV_FRONTEND
|
||||
tristate "Xen PCI Frontend"
|
||||
depends on PCI && X86 && XEN
|
||||
select HOTPLUG
|
||||
select PCI_XEN
|
||||
select XEN_XENBUS_FRONTEND
|
||||
default y
|
||||
|
@ -113,7 +112,6 @@ config PCI_IOAPIC
|
|||
tristate "PCI IO-APIC hotplug support" if X86
|
||||
depends on PCI
|
||||
depends on ACPI
|
||||
depends on HOTPLUG
|
||||
default !X86
|
||||
|
||||
config PCI_LABEL
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
menuconfig HOTPLUG_PCI
|
||||
tristate "Support for PCI Hotplug"
|
||||
depends on PCI && HOTPLUG && SYSFS
|
||||
depends on PCI && SYSFS
|
||||
---help---
|
||||
Say Y here if you have a motherboard with a PCI Hotplug controller.
|
||||
This allows you to add and remove PCI cards while the machine is
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
menuconfig PCCARD
|
||||
tristate "PCCard (PCMCIA/CardBus) support"
|
||||
depends on HOTPLUG
|
||||
---help---
|
||||
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
|
||||
computer. These are credit-card size devices such as network cards,
|
||||
|
|
|
@ -72,6 +72,7 @@ config DP83640_PHY
|
|||
|
||||
config PTP_1588_CLOCK_PCH
|
||||
tristate "Intel PCH EG20T as PTP clock"
|
||||
depends on X86 || COMPILE_TEST
|
||||
select PTP_1588_CLOCK
|
||||
help
|
||||
This driver adds support for using the PCH EG20T as a PTP
|
||||
|
|
|
@ -78,7 +78,6 @@ All vendor-built kernels should already be configured properly. However,
|
|||
for custom-built kernels, the following options need to be enabled in the
|
||||
kernel as built-in or modules:
|
||||
|
||||
CONFIG_HOTPLUG - Support for hot-pluggable devices
|
||||
CONFIG_MODULES - Enable loadable module support
|
||||
CONFIG_KMOD - Automatic kernel module loading
|
||||
CONFIG_FW_LOADER - Hotplug firmware loading support
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
config FB_GEODE
|
||||
bool "AMD Geode family framebuffer support"
|
||||
depends on FB && PCI && X86
|
||||
depends on FB && PCI && (X86_32 || (X86 && COMPILE_TEST))
|
||||
---help---
|
||||
Say 'Y' here to allow you to select framebuffer drivers for
|
||||
the AMD Geode family of processors.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/debugfs.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
static ssize_t default_read_file(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
|
@ -403,6 +404,47 @@ struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(debugfs_create_size_t);
|
||||
|
||||
static int debugfs_atomic_t_set(void *data, u64 val)
|
||||
{
|
||||
atomic_set((atomic_t *)data, val);
|
||||
return 0;
|
||||
}
|
||||
static int debugfs_atomic_t_get(void *data, u64 *val)
|
||||
{
|
||||
*val = atomic_read((atomic_t *)data);
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
|
||||
debugfs_atomic_t_set, "%lld\n");
|
||||
DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, "%lld\n");
|
||||
DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%lld\n");
|
||||
|
||||
/**
|
||||
* debugfs_create_atomic_t - create a debugfs file that is used to read and
|
||||
* write an atomic_t value
|
||||
* @name: a pointer to a string containing the name of the file to create.
|
||||
* @mode: the permission that the file should have
|
||||
* @parent: a pointer to the parent dentry for this file. This should be a
|
||||
* directory dentry if set. If this parameter is %NULL, then the
|
||||
* file will be created in the root of the debugfs filesystem.
|
||||
* @value: a pointer to the variable that the file should read to and write
|
||||
* from.
|
||||
*/
|
||||
struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
|
||||
struct dentry *parent, atomic_t *value)
|
||||
{
|
||||
/* if there are no write bits set, make read only */
|
||||
if (!(mode & S_IWUGO))
|
||||
return debugfs_create_file(name, mode, parent, value,
|
||||
&fops_atomic_t_ro);
|
||||
/* if there are no read bits set, make write only */
|
||||
if (!(mode & S_IRUGO))
|
||||
return debugfs_create_file(name, mode, parent, value,
|
||||
&fops_atomic_t_wo);
|
||||
|
||||
return debugfs_create_file(name, mode, parent, value, &fops_atomic_t);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(debugfs_create_atomic_t);
|
||||
|
||||
static ssize_t read_file_bool(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
|
@ -431,6 +473,7 @@ static ssize_t write_file_bool(struct file *file, const char __user *user_buf,
|
|||
if (copy_from_user(buf, user_buf, buf_size))
|
||||
return -EFAULT;
|
||||
|
||||
buf[buf_size] = '\0';
|
||||
if (strtobool(buf, &bv) == 0)
|
||||
*val = bv;
|
||||
|
||||
|
|
|
@ -20,13 +20,12 @@ config GFS2_FS
|
|||
be found here: http://sources.redhat.com/cluster
|
||||
|
||||
The "nolock" lock module is now built in to GFS2 by default. If
|
||||
you want to use the DLM, be sure to enable HOTPLUG and IPv4/6
|
||||
networking.
|
||||
you want to use the DLM, be sure to enable IPv4/6 networking.
|
||||
|
||||
config GFS2_FS_LOCKING_DLM
|
||||
bool "GFS2 DLM locking"
|
||||
depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \
|
||||
HOTPLUG && CONFIGFS_FS && SYSFS && (DLM=y || DLM=GFS2_FS)
|
||||
CONFIGFS_FS && SYSFS && (DLM=y || DLM=GFS2_FS)
|
||||
help
|
||||
Multiple node locking module for GFS2
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ static int sysfs_sd_compare(const struct sysfs_dirent *left,
|
|||
}
|
||||
|
||||
/**
|
||||
* sysfs_link_subling - link sysfs_dirent into sibling rbtree
|
||||
* sysfs_link_sibling - link sysfs_dirent into sibling rbtree
|
||||
* @sd: sysfs_dirent of interest
|
||||
*
|
||||
* Link @sd into its sibling rbtree which starts from
|
||||
|
|
|
@ -449,10 +449,12 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd)
|
|||
|
||||
spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
|
||||
|
||||
od = sd->s_attr.open;
|
||||
if (od) {
|
||||
atomic_inc(&od->event);
|
||||
wake_up_interruptible(&od->poll);
|
||||
if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) {
|
||||
od = sd->s_attr.open;
|
||||
if (od) {
|
||||
atomic_inc(&od->event);
|
||||
wake_up_interruptible(&od->poll);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include <linux/security.h>
|
||||
#include "sysfs.h"
|
||||
|
||||
extern struct super_block * sysfs_sb;
|
||||
|
||||
static const struct address_space_operations sysfs_aops = {
|
||||
.readpage = simple_readpage,
|
||||
.write_begin = simple_write_begin,
|
||||
|
|
|
@ -68,14 +68,6 @@
|
|||
* are handled as text/data or they can be discarded (which
|
||||
* often happens at runtime)
|
||||
*/
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
#define DEV_KEEP(sec) *(.dev##sec)
|
||||
#define DEV_DISCARD(sec)
|
||||
#else
|
||||
#define DEV_KEEP(sec)
|
||||
#define DEV_DISCARD(sec) *(.dev##sec)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
#define CPU_KEEP(sec) *(.cpu##sec)
|
||||
#define CPU_DISCARD(sec)
|
||||
|
@ -182,8 +174,6 @@
|
|||
*(.data) \
|
||||
*(.ref.data) \
|
||||
*(.data..shared_aligned) /* percpu related */ \
|
||||
DEV_KEEP(init.data) \
|
||||
DEV_KEEP(exit.data) \
|
||||
CPU_KEEP(init.data) \
|
||||
CPU_KEEP(exit.data) \
|
||||
MEM_KEEP(init.data) \
|
||||
|
@ -372,8 +362,6 @@
|
|||
/* __*init sections */ \
|
||||
__init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \
|
||||
*(.ref.rodata) \
|
||||
DEV_KEEP(init.rodata) \
|
||||
DEV_KEEP(exit.rodata) \
|
||||
CPU_KEEP(init.rodata) \
|
||||
CPU_KEEP(exit.rodata) \
|
||||
MEM_KEEP(init.rodata) \
|
||||
|
@ -416,8 +404,6 @@
|
|||
*(.text.hot) \
|
||||
*(.text) \
|
||||
*(.ref.text) \
|
||||
DEV_KEEP(init.text) \
|
||||
DEV_KEEP(exit.text) \
|
||||
CPU_KEEP(init.text) \
|
||||
CPU_KEEP(exit.text) \
|
||||
MEM_KEEP(init.text) \
|
||||
|
@ -503,7 +489,6 @@
|
|||
/* init and exit section handling */
|
||||
#define INIT_DATA \
|
||||
*(.init.data) \
|
||||
DEV_DISCARD(init.data) \
|
||||
CPU_DISCARD(init.data) \
|
||||
MEM_DISCARD(init.data) \
|
||||
KERNEL_CTORS() \
|
||||
|
@ -511,7 +496,6 @@
|
|||
*(.init.rodata) \
|
||||
FTRACE_EVENTS() \
|
||||
TRACE_SYSCALLS() \
|
||||
DEV_DISCARD(init.rodata) \
|
||||
CPU_DISCARD(init.rodata) \
|
||||
MEM_DISCARD(init.rodata) \
|
||||
CLK_OF_TABLES() \
|
||||
|
@ -521,14 +505,11 @@
|
|||
|
||||
#define INIT_TEXT \
|
||||
*(.init.text) \
|
||||
DEV_DISCARD(init.text) \
|
||||
CPU_DISCARD(init.text) \
|
||||
MEM_DISCARD(init.text)
|
||||
|
||||
#define EXIT_DATA \
|
||||
*(.exit.data) \
|
||||
DEV_DISCARD(exit.data) \
|
||||
DEV_DISCARD(exit.rodata) \
|
||||
CPU_DISCARD(exit.data) \
|
||||
CPU_DISCARD(exit.rodata) \
|
||||
MEM_DISCARD(exit.data) \
|
||||
|
@ -536,7 +517,6 @@
|
|||
|
||||
#define EXIT_TEXT \
|
||||
*(.exit.text) \
|
||||
DEV_DISCARD(exit.text) \
|
||||
CPU_DISCARD(exit.text) \
|
||||
MEM_DISCARD(exit.text)
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@ struct dentry *debugfs_create_x64(const char *name, umode_t mode,
|
|||
struct dentry *parent, u64 *value);
|
||||
struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
|
||||
struct dentry *parent, size_t *value);
|
||||
struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
|
||||
struct dentry *parent, atomic_t *value);
|
||||
struct dentry *debugfs_create_bool(const char *name, umode_t mode,
|
||||
struct dentry *parent, u32 *value);
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
|
|||
* bus-specific setup
|
||||
* @p: The private data of the driver core, only the driver core can
|
||||
* touch this.
|
||||
* @lock_key: Lock class key for use by the lock validator
|
||||
*
|
||||
* A bus is a channel between the processor and one or more devices. For the
|
||||
* purposes of the device model, all devices are connected via a bus, even if
|
||||
|
@ -635,6 +636,7 @@ struct acpi_dev_node {
|
|||
* segment limitations.
|
||||
* @dma_pools: Dma pools (if dma'ble device).
|
||||
* @dma_mem: Internal for coherent mem override.
|
||||
* @cma_area: Contiguous memory area for dma allocations
|
||||
* @archdata: For arch-specific additions.
|
||||
* @of_node: Associated device tree node.
|
||||
* @acpi_node: Associated ACPI device node.
|
||||
|
@ -648,6 +650,7 @@ struct acpi_dev_node {
|
|||
* @release: Callback to free the device after all references have
|
||||
* gone away. This should be set by the allocator of the
|
||||
* device (i.e. the bus driver that discovered the device).
|
||||
* @iommu_group: IOMMU group the device belongs to.
|
||||
*
|
||||
* At the lowest level, every device in a Linux system is represented by an
|
||||
* instance of struct device. The device structure contains the information
|
||||
|
|
|
@ -47,8 +47,6 @@ int request_firmware_nowait(
|
|||
void (*cont)(const struct firmware *fw, void *context));
|
||||
|
||||
void release_firmware(const struct firmware *fw);
|
||||
int cache_firmware(const char *name);
|
||||
int uncache_firmware(const char *name);
|
||||
#else
|
||||
static inline int request_firmware(const struct firmware **fw,
|
||||
const char *name,
|
||||
|
@ -68,15 +66,6 @@ static inline void release_firmware(const struct firmware *fw)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int cache_firmware(const char *name)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static inline int uncache_firmware(const char *name)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -180,7 +180,13 @@ struct platform_driver {
|
|||
const struct platform_device_id *id_table;
|
||||
};
|
||||
|
||||
extern int platform_driver_register(struct platform_driver *);
|
||||
/*
|
||||
* use a macro to avoid include chaining to get THIS_MODULE
|
||||
*/
|
||||
#define platform_driver_register(drv) \
|
||||
__platform_driver_register(drv, THIS_MODULE)
|
||||
extern int __platform_driver_register(struct platform_driver *,
|
||||
struct module *);
|
||||
extern void platform_driver_unregister(struct platform_driver *);
|
||||
|
||||
/* non-hotpluggable platform devices may use this so that probe() and
|
||||
|
|
17
init/Kconfig
17
init/Kconfig
|
@ -53,6 +53,20 @@ config CROSS_COMPILE
|
|||
need to set this unless you want the configured kernel build
|
||||
directory to select the cross-compiler automatically.
|
||||
|
||||
config COMPILE_TEST
|
||||
bool "Compile also drivers which will not load"
|
||||
default n
|
||||
help
|
||||
Some drivers can be compiled on a different platform than they are
|
||||
intended to be run on. Despite they cannot be loaded there (or even
|
||||
when they load they cannot be used due to missing HW support),
|
||||
developers still, opposing to distributors, might want to build such
|
||||
drivers to compile-test them.
|
||||
|
||||
If you are a developer and want to build everything available, say Y
|
||||
here. If you are a user/distributor, say N here to exclude useless
|
||||
drivers to be distributed.
|
||||
|
||||
config LOCALVERSION
|
||||
string "Local version - append to kernel release"
|
||||
help
|
||||
|
@ -1245,9 +1259,6 @@ config SYSCTL_ARCH_UNALIGN_ALLOW
|
|||
the unaligned access emulation.
|
||||
see arch/parisc/kernel/unaligned.c for reference
|
||||
|
||||
config HOTPLUG
|
||||
def_bool y
|
||||
|
||||
config HAVE_PCSPKR_PLATFORM
|
||||
bool
|
||||
|
||||
|
|
|
@ -100,7 +100,6 @@ config PM_SLEEP_SMP
|
|||
depends on SMP
|
||||
depends on ARCH_SUSPEND_POSSIBLE || ARCH_HIBERNATION_POSSIBLE
|
||||
depends on PM_SLEEP
|
||||
select HOTPLUG
|
||||
select HOTPLUG_CPU
|
||||
|
||||
config PM_AUTOSLEEP
|
||||
|
|
|
@ -182,27 +182,6 @@ static struct dentry *debugfs_create_stacktrace_depth(
|
|||
|
||||
#endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */
|
||||
|
||||
static int debugfs_atomic_t_set(void *data, u64 val)
|
||||
{
|
||||
atomic_set((atomic_t *)data, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int debugfs_atomic_t_get(void *data, u64 *val)
|
||||
{
|
||||
*val = atomic_read((atomic_t *)data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
|
||||
debugfs_atomic_t_set, "%lld\n");
|
||||
|
||||
static struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
|
||||
struct dentry *parent, atomic_t *value)
|
||||
{
|
||||
return debugfs_create_file(name, mode, parent, value, &fops_atomic_t);
|
||||
}
|
||||
|
||||
struct dentry *fault_create_debugfs_attr(const char *name,
|
||||
struct dentry *parent, struct fault_attr *attr)
|
||||
{
|
||||
|
|
|
@ -805,7 +805,7 @@ static struct kset *kset_create(const char *name,
|
|||
kset = kzalloc(sizeof(*kset), GFP_KERNEL);
|
||||
if (!kset)
|
||||
return NULL;
|
||||
retval = kobject_set_name(&kset->kobj, name);
|
||||
retval = kobject_set_name(&kset->kobj, "%s", name);
|
||||
if (retval) {
|
||||
kfree(kset);
|
||||
return NULL;
|
||||
|
|
|
@ -173,7 +173,7 @@ config HAVE_BOOTMEM_INFO_NODE
|
|||
config MEMORY_HOTPLUG
|
||||
bool "Allow for memory hot-add"
|
||||
depends on SPARSEMEM || X86_64_ACPI_NUMA
|
||||
depends on HOTPLUG && ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
depends on ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390)
|
||||
|
||||
config MEMORY_HOTPLUG_SPARSE
|
||||
|
|
Loading…
Reference in a new issue