提交 fc76a258 编写于 作者: L Linus Torvalds

Merge tag 'driver-core-3.11-rc1' of...

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
  ...
...@@ -64,7 +64,6 @@ Description: ...@@ -64,7 +64,6 @@ Description:
Writing a non-zero value to this attribute will Writing a non-zero value to this attribute will
force a rescan of all PCI buses in the system, and force a rescan of all PCI buses in the system, and
re-discover previously removed devices. re-discover previously removed devices.
Depends on CONFIG_HOTPLUG.
What: /sys/bus/pci/devices/.../msi_irqs/ What: /sys/bus/pci/devices/.../msi_irqs/
Date: September, 2011 Date: September, 2011
...@@ -90,7 +89,6 @@ Contact: Linux PCI developers <linux-pci@vger.kernel.org> ...@@ -90,7 +89,6 @@ Contact: Linux PCI developers <linux-pci@vger.kernel.org>
Description: Description:
Writing a non-zero value to this attribute will Writing a non-zero value to this attribute will
hot-remove the PCI device and any of its children. hot-remove the PCI device and any of its children.
Depends on CONFIG_HOTPLUG.
What: /sys/bus/pci/devices/.../pci_bus/.../rescan What: /sys/bus/pci/devices/.../pci_bus/.../rescan
Date: May 2011 Date: May 2011
...@@ -99,7 +97,7 @@ Description: ...@@ -99,7 +97,7 @@ Description:
Writing a non-zero value to this attribute will Writing a non-zero value to this attribute will
force a rescan of the bus and all child buses, force a rescan of the bus and all child buses,
and re-discover devices removed earlier from this 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 What: /sys/bus/pci/devices/.../rescan
Date: January 2009 Date: January 2009
...@@ -109,7 +107,6 @@ Description: ...@@ -109,7 +107,6 @@ Description:
force a rescan of the device's parent bus and all force a rescan of the device's parent bus and all
child buses, and re-discover devices removed earlier child buses, and re-discover devices removed earlier
from this part of the device tree. from this part of the device tree.
Depends on CONFIG_HOTPLUG.
What: /sys/bus/pci/devices/.../reset What: /sys/bus/pci/devices/.../reset
Date: July 2009 Date: July 2009
......
...@@ -112,7 +112,7 @@ required reading: ...@@ -112,7 +112,7 @@ required reading:
Other excellent descriptions of how to create patches properly are: Other excellent descriptions of how to create patches properly are:
"The Perfect Patch" "The Perfect Patch"
http://userweb.kernel.org/~akpm/stuff/tpp.txt http://kerneltrap.org/node/3737
"Linux kernel patch submission format" "Linux kernel patch submission format"
http://linux.yyz.us/patch-format.html http://linux.yyz.us/patch-format.html
......
...@@ -105,5 +105,5 @@ kernel patches. ...@@ -105,5 +105,5 @@ kernel patches.
same time, just various/random combinations of them]: same time, just various/random combinations of them]:
CONFIG_SMP, CONFIG_SYSFS, CONFIG_PROC_FS, CONFIG_INPUT, CONFIG_PCI, 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) CONFIG_NET, CONFIG_INET=n (but latter with CONFIG_NET=y)
...@@ -128,7 +128,7 @@ A: When doing make defconfig, Enable CPU hotplug support ...@@ -128,7 +128,7 @@ A: When doing make defconfig, Enable CPU hotplug support
"Processor type and Features" -> Support for Hotpluggable CPUs "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 You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support
as well. as well.
......
...@@ -27,8 +27,7 @@ increase the chances of your change being accepted. ...@@ -27,8 +27,7 @@ increase the chances of your change being accepted.
explicitly below the patch header. explicitly below the patch header.
* If your patch (or the driver) is affected by configuration options such as * 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 CONFIG_SMP, make sure it compiles for all configuration variants.
variants.
2. Adding functionality to existing drivers 2. Adding functionality to existing drivers
......
...@@ -165,7 +165,7 @@ Searching in menuconfig: ...@@ -165,7 +165,7 @@ Searching in menuconfig:
Example: Example:
/hotplug /hotplug
This lists all config symbols that contain "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 For search help, enter / followed TAB-TAB-TAB (to highlight
<Help>) and Enter. This will tell you that you can also use <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. ...@@ -33,9 +33,9 @@ you get the best hotplugging when you configure a highly modular system.
KERNEL HOTPLUG HELPER (/sbin/hotplug) KERNEL HOTPLUG HELPER (/sbin/hotplug)
When you compile with CONFIG_HOTPLUG, you get a new kernel parameter: There is a kernel parameter: /proc/sys/kernel/hotplug, which normally
/proc/sys/kernel/hotplug, which normally holds the pathname "/sbin/hotplug". holds the pathname "/sbin/hotplug". That parameter names a program
That parameter names a program which the kernel may invoke at various times. which the kernel may invoke at various times.
The /sbin/hotplug program can be invoked by any subsystem as part of its 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. reaction to a configuration change, from a thread in that subsystem.
......
...@@ -1552,7 +1552,7 @@ config NR_CPUS ...@@ -1552,7 +1552,7 @@ config NR_CPUS
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs" bool "Support for hot-pluggable CPUs"
depends on SMP && HOTPLUG depends on SMP
help help
Say Y here to experiment with turning CPUs off and on. CPUs Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu. can be controlled through /sys/devices/system/cpu.
......
...@@ -288,24 +288,16 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, ...@@ -288,24 +288,16 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
if (strcmp(".ARM.exidx.init.text", secname) == 0) if (strcmp(".ARM.exidx.init.text", secname) == 0)
maps[ARM_SEC_INIT].unw_sec = s; 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) else if (strcmp(".ARM.exidx", secname) == 0)
maps[ARM_SEC_CORE].unw_sec = s; maps[ARM_SEC_CORE].unw_sec = s;
else if (strcmp(".ARM.exidx.exit.text", secname) == 0) else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
maps[ARM_SEC_EXIT].unw_sec = s; 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) else if (strcmp(".init.text", secname) == 0)
maps[ARM_SEC_INIT].txt_sec = s; 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) else if (strcmp(".text", secname) == 0)
maps[ARM_SEC_CORE].txt_sec = s; maps[ARM_SEC_CORE].txt_sec = s;
else if (strcmp(".exit.text", secname) == 0) else if (strcmp(".exit.text", secname) == 0)
maps[ARM_SEC_EXIT].txt_sec = s; 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++) for (i = 0; i < ARM_SEC_MAX; i++)
......
...@@ -70,10 +70,6 @@ SECTIONS ...@@ -70,10 +70,6 @@ SECTIONS
ARM_EXIT_DISCARD(EXIT_TEXT) ARM_EXIT_DISCARD(EXIT_TEXT)
ARM_EXIT_DISCARD(EXIT_DATA) ARM_EXIT_DISCARD(EXIT_DATA)
EXIT_CALL EXIT_CALL
#ifndef CONFIG_HOTPLUG
*(.ARM.exidx.devexit.text)
*(.ARM.extab.devexit.text)
#endif
#ifndef CONFIG_MMU #ifndef CONFIG_MMU
*(.fixup) *(.fixup)
*(__ex_table) *(__ex_table)
......
...@@ -235,7 +235,6 @@ config IXP4XX_QMGR ...@@ -235,7 +235,6 @@ config IXP4XX_QMGR
config IXP4XX_NPE config IXP4XX_NPE
tristate "IXP4xx Network Processor Engine support" tristate "IXP4xx Network Processor Engine support"
select FW_LOADER select FW_LOADER
select HOTPLUG
help help
This driver supports IXP4xx built-in network coprocessors This driver supports IXP4xx built-in network coprocessors
and is automatically selected by Ethernet and HSS drivers. and is automatically selected by Ethernet and HSS drivers.
......
...@@ -253,7 +253,7 @@ config NR_CPUS ...@@ -253,7 +253,7 @@ config NR_CPUS
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs" bool "Support for hot-pluggable CPUs"
depends on SMP && HOTPLUG depends on SMP
default y default y
config BF_REV_MIN config BF_REV_MIN
......
...@@ -617,7 +617,6 @@ config ETRAX_PV_CHANGEABLE_BITS ...@@ -617,7 +617,6 @@ config ETRAX_PV_CHANGEABLE_BITS
config ETRAX_CARDBUS config ETRAX_CARDBUS
bool "Cardbus support" bool "Cardbus support"
depends on ETRAX_ARCH_V32 depends on ETRAX_ARCH_V32
select HOTPLUG
help help
Enabled the ETRAX Cardbus driver. Enabled the ETRAX Cardbus driver.
......
...@@ -376,7 +376,6 @@ config NR_CPUS ...@@ -376,7 +376,6 @@ config NR_CPUS
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs" bool "Support for hot-pluggable CPUs"
depends on SMP depends on SMP
select HOTPLUG
default n default n
---help--- ---help---
Say Y here to experiment with turning CPUs off and on. CPUs Say Y here to experiment with turning CPUs off and on. CPUs
......
...@@ -962,7 +962,7 @@ config SYS_HAS_EARLY_PRINTK ...@@ -962,7 +962,7 @@ config SYS_HAS_EARLY_PRINTK
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs" bool "Support for hot-pluggable CPUs"
depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU depends on SMP && SYS_SUPPORTS_HOTPLUG_CPU
help help
Say Y here to allow turning CPUs off and on. CPUs can be Say Y here to allow turning CPUs off and on. CPUs can be
controlled through /sys/devices/system/cpu. controlled through /sys/devices/system/cpu.
......
...@@ -254,7 +254,6 @@ config IRQSTACKS ...@@ -254,7 +254,6 @@ config IRQSTACKS
config HOTPLUG_CPU config HOTPLUG_CPU
bool bool
default y if SMP default y if SMP
select HOTPLUG
config ARCH_SELECT_MEMORY_MODEL config ARCH_SELECT_MEMORY_MODEL
def_bool y def_bool y
......
...@@ -341,7 +341,7 @@ config SWIOTLB ...@@ -341,7 +341,7 @@ config SWIOTLB
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs" 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)) PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
---help--- ---help---
Say Y here to be able to disable and re-enable individual Say Y here to be able to disable and re-enable individual
......
...@@ -183,8 +183,8 @@ void tlb_flush(struct mmu_gather *tlb) ...@@ -183,8 +183,8 @@ void tlb_flush(struct mmu_gather *tlb)
* since 64K pages may overlap with other bridges when using 64K pages * since 64K pages may overlap with other bridges when using 64K pages
* with 4K HW pages on IO space. * with 4K HW pages on IO space.
* *
* Because of that usage pattern, it's only available with CONFIG_HOTPLUG * Because of that usage pattern, it is implemented for small size rather
* and is implemented for small size rather than speed. * than speed.
*/ */
void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
unsigned long end) unsigned long end)
......
...@@ -301,7 +301,6 @@ config HOTPLUG_CPU ...@@ -301,7 +301,6 @@ config HOTPLUG_CPU
def_bool y def_bool y
prompt "Support for hot-pluggable CPUs" prompt "Support for hot-pluggable CPUs"
depends on SMP depends on SMP
select HOTPLUG
help help
Say Y here to be able to turn CPUs off and on. CPUs Say Y here to be able to turn CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu/cpu#. can be controlled through /sys/devices/system/cpu/cpu#.
......
...@@ -748,7 +748,7 @@ config NR_CPUS ...@@ -748,7 +748,7 @@ config NR_CPUS
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
depends on SMP && HOTPLUG depends on SMP
help help
Say Y here to experiment with turning CPUs off and on. CPUs Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu. can be controlled through /sys/devices/system/cpu.
......
...@@ -243,7 +243,6 @@ config SECCOMP ...@@ -243,7 +243,6 @@ config SECCOMP
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs" bool "Support for hot-pluggable CPUs"
depends on SPARC64 && SMP depends on SPARC64 && SMP
select HOTPLUG
help help
Say Y here to experiment with turning CPUs off and on. CPUs Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu/cpu#. can be controlled through /sys/devices/system/cpu/cpu#.
......
...@@ -1725,7 +1725,7 @@ config PHYSICAL_ALIGN ...@@ -1725,7 +1725,7 @@ config PHYSICAL_ALIGN
config HOTPLUG_CPU config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs" bool "Support for hot-pluggable CPUs"
depends on SMP && HOTPLUG depends on SMP
---help--- ---help---
Say Y here to allow turning CPUs off and on. CPUs can be Say Y here to allow turning CPUs off and on. CPUs can be
controlled through /sys/devices/system/cpu. controlled through /sys/devices/system/cpu.
......
...@@ -2,7 +2,6 @@ menu "Generic Driver Options" ...@@ -2,7 +2,6 @@ menu "Generic Driver Options"
config UEVENT_HELPER_PATH config UEVENT_HELPER_PATH
string "path to uevent helper" string "path to uevent helper"
depends on HOTPLUG
default "" default ""
help help
Path to uevent helper program forked by the kernel for Path to uevent helper program forked by the kernel for
...@@ -23,7 +22,6 @@ config UEVENT_HELPER_PATH ...@@ -23,7 +22,6 @@ config UEVENT_HELPER_PATH
config DEVTMPFS config DEVTMPFS
bool "Maintain a devtmpfs filesystem to mount at /dev" bool "Maintain a devtmpfs filesystem to mount at /dev"
depends on HOTPLUG
help help
This creates a tmpfs/ramfs filesystem instance early at bootup. This creates a tmpfs/ramfs filesystem instance early at bootup.
In this filesystem, the kernel driver core maintains device In this filesystem, the kernel driver core maintains device
......
...@@ -1334,8 +1334,8 @@ const char *device_get_devnode(struct device *dev, ...@@ -1334,8 +1334,8 @@ const char *device_get_devnode(struct device *dev,
/** /**
* device_for_each_child - device child iterator. * device_for_each_child - device child iterator.
* @parent: parent struct device. * @parent: parent struct device.
* @data: data for the callback.
* @fn: function to be called for each device. * @fn: function to be called for each device.
* @data: data for the callback.
* *
* Iterate over @parent's child devices, and call @fn for each, * Iterate over @parent's child devices, and call @fn for each,
* passing it @data. * passing it @data.
...@@ -1363,8 +1363,8 @@ int device_for_each_child(struct device *parent, void *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. * device_find_child - device iterator for locating a particular device.
* @parent: parent struct device * @parent: parent struct device
* @data: Data to pass to match function
* @match: Callback function to check device * @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 * 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 * 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, ...@@ -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 * 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 * current device can be obtained, this function will return to the caller
* and not iterate over any more devices. * 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, struct device *device_find_child(struct device *parent, void *data,
int (*match)(struct device *dev, void *data)) int (*match)(struct device *dev, void *data))
......
...@@ -85,18 +85,21 @@ static ssize_t __ref store_online(struct device *dev, ...@@ -85,18 +85,21 @@ static ssize_t __ref store_online(struct device *dev,
} }
static DEVICE_ATTR(online, 0644, show_online, store_online); static DEVICE_ATTR(online, 0644, show_online, store_online);
static void __cpuinit register_cpu_control(struct cpu *cpu) static struct attribute *hotplug_cpu_attrs[] = {
{ &dev_attr_online.attr,
device_create_file(&cpu->dev, &dev_attr_online); NULL
} };
static struct attribute_group hotplug_cpu_attr_group = {
.attrs = hotplug_cpu_attrs,
};
void unregister_cpu(struct cpu *cpu) void unregister_cpu(struct cpu *cpu)
{ {
int logical_cpu = cpu->dev.id; int logical_cpu = cpu->dev.id;
unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu)); unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
device_remove_file(&cpu->dev, &dev_attr_online);
device_unregister(&cpu->dev); device_unregister(&cpu->dev);
per_cpu(cpu_sys_devices, logical_cpu) = NULL; per_cpu(cpu_sys_devices, logical_cpu) = NULL;
return; return;
...@@ -122,11 +125,6 @@ static ssize_t cpu_release_store(struct device *dev, ...@@ -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(probe, S_IWUSR, NULL, cpu_probe_store);
static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store); static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
#else /* ... !CONFIG_HOTPLUG_CPU */
static inline void register_cpu_control(struct cpu *cpu)
{
}
#endif /* CONFIG_HOTPLUG_CPU */ #endif /* CONFIG_HOTPLUG_CPU */
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC
...@@ -164,8 +162,35 @@ static ssize_t show_crash_notes_size(struct device *dev, ...@@ -164,8 +162,35 @@ static ssize_t show_crash_notes_size(struct device *dev,
return rc; return rc;
} }
static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL); 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 #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 * Print cpu online, possible, present, and system maps
*/ */
...@@ -280,21 +305,15 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) ...@@ -280,21 +305,15 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
cpu->dev.bus->uevent = arch_cpu_uevent; cpu->dev.bus->uevent = arch_cpu_uevent;
#endif #endif
cpu->dev.groups = common_cpu_attr_groups;
if (cpu->hotpluggable)
cpu->dev.groups = hotplugable_cpu_attr_groups;
error = device_register(&cpu->dev); error = device_register(&cpu->dev);
if (!error && cpu->hotpluggable)
register_cpu_control(cpu);
if (!error) if (!error)
per_cpu(cpu_sys_devices, num) = &cpu->dev; per_cpu(cpu_sys_devices, num) = &cpu->dev;
if (!error) if (!error)
register_cpu_under_node(num, cpu_to_node(num)); 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; return error;
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <linux/reboot.h>
#include <generated/utsrelease.h> #include <generated/utsrelease.h>
...@@ -127,9 +128,11 @@ struct firmware_buf { ...@@ -127,9 +128,11 @@ struct firmware_buf {
size_t size; size_t size;
#ifdef CONFIG_FW_LOADER_USER_HELPER #ifdef CONFIG_FW_LOADER_USER_HELPER
bool is_paged_buf; bool is_paged_buf;
bool need_uevent;
struct page **pages; struct page **pages;
int nr_pages; int nr_pages;
int page_array_size; int page_array_size;
struct list_head pending_list;
#endif #endif
char fw_id[]; char fw_id[];
}; };
...@@ -171,6 +174,9 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name, ...@@ -171,6 +174,9 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name,
strcpy(buf->fw_id, fw_name); strcpy(buf->fw_id, fw_name);
buf->fwc = fwc; buf->fwc = fwc;
init_completion(&buf->completion); 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); 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, ...@@ -212,18 +218,6 @@ static int fw_lookup_and_allocate_buf(const char *fw_name,
return tmp ? 0 : -ENOMEM; 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) static void __fw_free_buf(struct kref *ref)
{ {
struct firmware_buf *buf = to_fwbuf(ref); struct firmware_buf *buf = to_fwbuf(ref);
...@@ -446,10 +440,8 @@ static struct firmware_priv *to_firmware_priv(struct device *dev) ...@@ -446,10 +440,8 @@ static struct firmware_priv *to_firmware_priv(struct device *dev)
return container_of(dev, struct firmware_priv, 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' * There is a small window in which user can write to 'loading'
* between loading done and disappearance of 'loading' * between loading done and disappearance of 'loading'
...@@ -457,8 +449,16 @@ static void fw_load_abort(struct firmware_priv *fw_priv) ...@@ -457,8 +449,16 @@ static void fw_load_abort(struct firmware_priv *fw_priv)
if (test_bit(FW_STATUS_DONE, &buf->status)) if (test_bit(FW_STATUS_DONE, &buf->status))
return; return;
list_del_init(&buf->pending_list);
set_bit(FW_STATUS_ABORT, &buf->status); set_bit(FW_STATUS_ABORT, &buf->status);
complete_all(&buf->completion); 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 */ /* avoid user action after loading abort */
fw_priv->buf = NULL; fw_priv->buf = NULL;
...@@ -467,6 +467,25 @@ static void fw_load_abort(struct firmware_priv *fw_priv) ...@@ -467,6 +467,25 @@ static void fw_load_abort(struct firmware_priv *fw_priv)
#define is_fw_load_aborted(buf) \ #define is_fw_load_aborted(buf) \
test_bit(FW_STATUS_ABORT, &(buf)->status) 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, static ssize_t firmware_timeout_show(struct class *class,
struct class_attribute *attr, struct class_attribute *attr,
char *buf) char *buf)
...@@ -509,8 +528,6 @@ static void fw_dev_release(struct device *dev) ...@@ -509,8 +528,6 @@ static void fw_dev_release(struct device *dev)
struct firmware_priv *fw_priv = to_firmware_priv(dev); struct firmware_priv *fw_priv = to_firmware_priv(dev);
kfree(fw_priv); kfree(fw_priv);
module_put(THIS_MODULE);
} }
static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) 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, ...@@ -619,6 +636,7 @@ static ssize_t firmware_loading_store(struct device *dev,
* is completed. * is completed.
* */ * */
fw_map_pages_buf(fw_buf); fw_map_pages_buf(fw_buf);
list_del_init(&fw_buf->pending_list);
complete_all(&fw_buf->completion); complete_all(&fw_buf->completion);
break; break;
} }
...@@ -838,9 +856,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, ...@@ -838,9 +856,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
dev_set_uevent_suppress(f_dev, true); 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); retval = device_add(f_dev);
if (retval) { if (retval) {
dev_err(f_dev, "%s: device_register failed\n", __func__); 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, ...@@ -860,6 +875,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
} }
if (uevent) { if (uevent) {
buf->need_uevent = true;
dev_set_uevent_suppress(f_dev, false); dev_set_uevent_suppress(f_dev, false);
dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id);
if (timeout != MAX_SCHEDULE_TIMEOUT) if (timeout != MAX_SCHEDULE_TIMEOUT)
...@@ -868,6 +884,10 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, ...@@ -868,6 +884,10 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); 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); wait_for_completion(&buf->completion);
cancel_delayed_work_sync(&fw_priv->timeout_work); cancel_delayed_work_sync(&fw_priv->timeout_work);
...@@ -895,6 +915,23 @@ static int fw_load_from_user_helper(struct firmware *firmware, ...@@ -895,6 +915,23 @@ static int fw_load_from_user_helper(struct firmware *firmware,
fw_priv->buf = firmware->priv; fw_priv->buf = firmware->priv;
return _request_firmware_load(fw_priv, uevent, timeout); 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 */ #else /* CONFIG_FW_LOADER_USER_HELPER */
static inline int static inline int
fw_load_from_user_helper(struct firmware *firmware, const char *name, 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, ...@@ -907,6 +944,10 @@ fw_load_from_user_helper(struct firmware *firmware, const char *name,
/* No abort during direct loading */ /* No abort during direct loading */
#define is_fw_load_aborted(buf) false #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 */ #endif /* CONFIG_FW_LOADER_USER_HELPER */
...@@ -974,7 +1015,8 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, ...@@ -974,7 +1015,8 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
return 1; /* need to load */ 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; struct firmware_buf *buf = fw->priv;
...@@ -991,7 +1033,7 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device) ...@@ -991,7 +1033,7 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device)
* device may has been deleted already, but the problem * device may has been deleted already, but the problem
* should be fixed in devres or driver core. * should be fixed in devres or driver core.
*/ */
if (device) if (device && !skip_cache)
fw_add_devm_name(device, buf->fw_id); fw_add_devm_name(device, buf->fw_id);
/* /*
...@@ -1047,8 +1089,10 @@ _request_firmware(const struct firmware **firmware_p, const char *name, ...@@ -1047,8 +1089,10 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
if (!fw_get_filesystem_firmware(device, fw->priv)) if (!fw_get_filesystem_firmware(device, fw->priv))
ret = fw_load_from_user_helper(fw, name, device, ret = fw_load_from_user_helper(fw, name, device,
uevent, nowait, timeout); uevent, nowait, timeout);
/* don't cache firmware handled without uevent */
if (!ret) if (!ret)
ret = assign_firmware_buf(fw, device); ret = assign_firmware_buf(fw, device, !uevent);
usermodehelper_read_unlock(); usermodehelper_read_unlock();
...@@ -1086,8 +1130,15 @@ int ...@@ -1086,8 +1130,15 @@ int
request_firmware(const struct firmware **firmware_p, const char *name, request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device) 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 * release_firmware: - release the resource associated with a firmware image
...@@ -1101,6 +1152,7 @@ void release_firmware(const struct firmware *fw) ...@@ -1101,6 +1152,7 @@ void release_firmware(const struct firmware *fw)
kfree(fw); kfree(fw);
} }
} }
EXPORT_SYMBOL(release_firmware);
/* Async support */ /* Async support */
struct firmware_work { struct firmware_work {
...@@ -1181,6 +1233,10 @@ request_firmware_nowait( ...@@ -1181,6 +1233,10 @@ request_firmware_nowait(
schedule_work(&fw_work->work); schedule_work(&fw_work->work);
return 0; 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 * cache_firmware - cache one firmware image in kernel memory space
...@@ -1196,7 +1252,7 @@ request_firmware_nowait( ...@@ -1196,7 +1252,7 @@ request_firmware_nowait(
* Return !0 otherwise * Return !0 otherwise
* *
*/ */
int cache_firmware(const char *fw_name) static int cache_firmware(const char *fw_name)
{ {
int ret; int ret;
const struct firmware *fw; const struct firmware *fw;
...@@ -1212,6 +1268,18 @@ int cache_firmware(const char *fw_name) ...@@ -1212,6 +1268,18 @@ int cache_firmware(const char *fw_name)
return ret; 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 * uncache_firmware - remove one cached firmware image
* @fw_name: the firmware image name * @fw_name: the firmware image name
...@@ -1223,7 +1291,7 @@ int cache_firmware(const char *fw_name) ...@@ -1223,7 +1291,7 @@ int cache_firmware(const char *fw_name)
* Return !0 otherwise * Return !0 otherwise
* *
*/ */
int uncache_firmware(const char *fw_name) static int uncache_firmware(const char *fw_name)
{ {
struct firmware_buf *buf; struct firmware_buf *buf;
struct firmware fw; struct firmware fw;
...@@ -1242,9 +1310,6 @@ int uncache_firmware(const char *fw_name) ...@@ -1242,9 +1310,6 @@ int uncache_firmware(const char *fw_name)
return -EINVAL; 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) static struct fw_cache_entry *alloc_fw_cache_entry(const char *name)
{ {
struct fw_cache_entry *fce; struct fw_cache_entry *fce;
...@@ -1464,6 +1529,7 @@ static int fw_pm_notify(struct notifier_block *notify_block, ...@@ -1464,6 +1529,7 @@ static int fw_pm_notify(struct notifier_block *notify_block,
switch (mode) { switch (mode) {
case PM_HIBERNATION_PREPARE: case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE: case PM_SUSPEND_PREPARE:
kill_requests_without_uevent();
device_cache_fw_images(); device_cache_fw_images();
break; break;
...@@ -1526,6 +1592,7 @@ static int __init firmware_class_init(void) ...@@ -1526,6 +1592,7 @@ static int __init firmware_class_init(void)
{ {
fw_cache_init(); fw_cache_init();
#ifdef CONFIG_FW_LOADER_USER_HELPER #ifdef CONFIG_FW_LOADER_USER_HELPER
register_reboot_notifier(&fw_shutdown_nb);
return class_register(&firmware_class); return class_register(&firmware_class);
#else #else
return 0; return 0;
...@@ -1539,15 +1606,10 @@ static void __exit firmware_class_exit(void) ...@@ -1539,15 +1606,10 @@ static void __exit firmware_class_exit(void)
unregister_pm_notifier(&fw_cache.pm_notify); unregister_pm_notifier(&fw_cache.pm_notify);
#endif #endif
#ifdef CONFIG_FW_LOADER_USER_HELPER #ifdef CONFIG_FW_LOADER_USER_HELPER
unregister_reboot_notifier(&fw_shutdown_nb);
class_unregister(&firmware_class); class_unregister(&firmware_class);
#endif #endif
} }
fs_initcall(firmware_class_init); fs_initcall(firmware_class_init);
module_exit(firmware_class_exit); 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) ...@@ -77,22 +77,6 @@ static void memory_block_release(struct device *dev)
kfree(mem); 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) unsigned long __weak memory_block_size_bytes(void)
{ {
return MIN_MEMORY_BLOCK_SIZE; return MIN_MEMORY_BLOCK_SIZE;
...@@ -371,11 +355,6 @@ static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state); ...@@ -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(phys_device, 0444, show_phys_device, NULL);
static DEVICE_ATTR(removable, 0444, show_mem_removable, 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 * Block size attribute stuff
*/ */
...@@ -388,12 +367,6 @@ print_block_size(struct device *dev, struct device_attribute *attr, ...@@ -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 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 * Some architectures will have custom drivers to do this, and
* will not need to do it from userspace. The fake hot-add code * 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, ...@@ -429,17 +402,8 @@ memory_probe_store(struct device *dev, struct device_attribute *attr,
out: out:
return ret; return ret;
} }
static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
static int memory_probe_init(void) static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
{
return device_create_file(memory_subsys.dev_root, &dev_attr_probe);
}
#else
static inline int memory_probe_init(void)
{
return 0;
}
#endif #endif
#ifdef CONFIG_MEMORY_FAILURE #ifdef CONFIG_MEMORY_FAILURE
...@@ -485,23 +449,6 @@ store_hard_offline_page(struct device *dev, ...@@ -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(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page);
static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_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 #endif
/* /*
...@@ -546,6 +493,41 @@ struct memory_block *find_memory_block(struct mem_section *section) ...@@ -546,6 +493,41 @@ struct memory_block *find_memory_block(struct mem_section *section)
return find_memory_block_hinted(section, NULL); 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, static int init_memory_block(struct memory_block **memory,
struct mem_section *section, unsigned long state) struct mem_section *section, unsigned long state)
{ {
...@@ -569,16 +551,6 @@ static int init_memory_block(struct memory_block **memory, ...@@ -569,16 +551,6 @@ static int init_memory_block(struct memory_block **memory,
mem->phys_device = arch_get_memory_phys_device(start_pfn); mem->phys_device = arch_get_memory_phys_device(start_pfn);
ret = register_memory(mem); 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; *memory = mem;
return ret; return ret;
...@@ -656,14 +628,9 @@ static int remove_memory_block(unsigned long node_id, ...@@ -656,14 +628,9 @@ static int remove_memory_block(unsigned long node_id,
unregister_mem_sect_under_nodes(mem, __section_nr(section)); unregister_mem_sect_under_nodes(mem, __section_nr(section));
mem->section_count--; mem->section_count--;
if (mem->section_count == 0) { 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);
unregister_memory(mem); unregister_memory(mem);
} else else
kobject_put(&mem->dev.kobj); kobject_put(&mem->dev.kobj);
mutex_unlock(&mem_sysfs_mutex); mutex_unlock(&mem_sysfs_mutex);
...@@ -700,6 +667,29 @@ bool is_memblock_offlined(struct memory_block *mem) ...@@ -700,6 +667,29 @@ bool is_memblock_offlined(struct memory_block *mem)
return mem->state == MEM_OFFLINE; 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... * Initialize the sysfs support for memory devices...
*/ */
...@@ -711,7 +701,7 @@ int __init memory_dev_init(void) ...@@ -711,7 +701,7 @@ int __init memory_dev_init(void)
unsigned long block_sz; unsigned long block_sz;
struct memory_block *mem = NULL; struct memory_block *mem = NULL;
ret = subsys_system_register(&memory_subsys, NULL); ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);
if (ret) if (ret)
goto out; goto out;
...@@ -734,15 +724,6 @@ int __init memory_dev_init(void) ...@@ -734,15 +724,6 @@ int __init memory_dev_init(void)
ret = err; 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: out:
if (ret) if (ret)
printk(KERN_ERR "%s() failed: %d\n", __func__, ret); printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
......
...@@ -523,11 +523,13 @@ static void platform_drv_shutdown(struct device *_dev) ...@@ -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 * @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; drv->driver.bus = &platform_bus_type;
if (drv->probe) if (drv->probe)
drv->driver.probe = platform_drv_probe; drv->driver.probe = platform_drv_probe;
...@@ -538,7 +540,7 @@ int platform_driver_register(struct platform_driver *drv) ...@@ -538,7 +540,7 @@ int platform_driver_register(struct platform_driver *drv)
return driver_register(&drv->driver); 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 * platform_driver_unregister - unregister a driver for platform-level devices
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
menu "PCMCIA character devices" menu "PCMCIA character devices"
depends on HOTPLUG && PCMCIA!=n depends on PCMCIA!=n
config SYNCLINK_CS config SYNCLINK_CS
tristate "SyncLink PC Card support" tristate "SyncLink PC Card support"
......
...@@ -145,7 +145,7 @@ config EDAC_E7XXX ...@@ -145,7 +145,7 @@ config EDAC_E7XXX
config EDAC_E752X config EDAC_E752X
tristate "Intel e752x (e7520, e7525, e7320) and 3100" tristate "Intel e752x (e7520, e7525, e7320) and 3100"
depends on EDAC_MM_EDAC && PCI && X86 && HOTPLUG depends on EDAC_MM_EDAC && PCI && X86
help help
Support for error detection and correction on the Intel Support for error detection and correction on the Intel
E7520, E7525, E7320 server chipsets. E7520, E7525, E7320 server chipsets.
......
...@@ -64,6 +64,7 @@ config DELL_RBU ...@@ -64,6 +64,7 @@ config DELL_RBU
tristate "BIOS update support for DELL systems via sysfs" tristate "BIOS update support for DELL systems via sysfs"
depends on X86 depends on X86
select FW_LOADER select FW_LOADER
select FW_LOADER_USER_HELPER
help help
Say m if you want to have the option of updating the BIOS for your 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) DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
......
...@@ -135,7 +135,7 @@ config PHANTOM ...@@ -135,7 +135,7 @@ config PHANTOM
config INTEL_MID_PTI config INTEL_MID_PTI
tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" 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 default n
help help
The PTI (Parallel Trace Interface) driver directs The PTI (Parallel Trace Interface) driver directs
......
...@@ -55,7 +55,6 @@ config PCI_STUB ...@@ -55,7 +55,6 @@ config PCI_STUB
config XEN_PCIDEV_FRONTEND config XEN_PCIDEV_FRONTEND
tristate "Xen PCI Frontend" tristate "Xen PCI Frontend"
depends on PCI && X86 && XEN depends on PCI && X86 && XEN
select HOTPLUG
select PCI_XEN select PCI_XEN
select XEN_XENBUS_FRONTEND select XEN_XENBUS_FRONTEND
default y default y
...@@ -113,7 +112,6 @@ config PCI_IOAPIC ...@@ -113,7 +112,6 @@ config PCI_IOAPIC
tristate "PCI IO-APIC hotplug support" if X86 tristate "PCI IO-APIC hotplug support" if X86
depends on PCI depends on PCI
depends on ACPI depends on ACPI
depends on HOTPLUG
default !X86 default !X86
config PCI_LABEL config PCI_LABEL
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
menuconfig HOTPLUG_PCI menuconfig HOTPLUG_PCI
tristate "Support for PCI Hotplug" tristate "Support for PCI Hotplug"
depends on PCI && HOTPLUG && SYSFS depends on PCI && SYSFS
---help--- ---help---
Say Y here if you have a motherboard with a PCI Hotplug controller. 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 This allows you to add and remove PCI cards while the machine is
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
menuconfig PCCARD menuconfig PCCARD
tristate "PCCard (PCMCIA/CardBus) support" tristate "PCCard (PCMCIA/CardBus) support"
depends on HOTPLUG
---help--- ---help---
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux 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, computer. These are credit-card size devices such as network cards,
......
...@@ -72,6 +72,7 @@ config DP83640_PHY ...@@ -72,6 +72,7 @@ config DP83640_PHY
config PTP_1588_CLOCK_PCH config PTP_1588_CLOCK_PCH
tristate "Intel PCH EG20T as PTP clock" tristate "Intel PCH EG20T as PTP clock"
depends on X86 || COMPILE_TEST
select PTP_1588_CLOCK select PTP_1588_CLOCK
help help
This driver adds support for using the PCH EG20T as a PTP 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, ...@@ -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 for custom-built kernels, the following options need to be enabled in the
kernel as built-in or modules: kernel as built-in or modules:
CONFIG_HOTPLUG - Support for hot-pluggable devices
CONFIG_MODULES - Enable loadable module support CONFIG_MODULES - Enable loadable module support
CONFIG_KMOD - Automatic kernel module loading CONFIG_KMOD - Automatic kernel module loading
CONFIG_FW_LOADER - Hotplug firmware loading support CONFIG_FW_LOADER - Hotplug firmware loading support
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
config FB_GEODE config FB_GEODE
bool "AMD Geode family framebuffer support" bool "AMD Geode family framebuffer support"
depends on FB && PCI && X86 depends on FB && PCI && (X86_32 || (X86 && COMPILE_TEST))
---help--- ---help---
Say 'Y' here to allow you to select framebuffer drivers for Say 'Y' here to allow you to select framebuffer drivers for
the AMD Geode family of processors. the AMD Geode family of processors.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/atomic.h>
static ssize_t default_read_file(struct file *file, char __user *buf, static ssize_t default_read_file(struct file *file, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -403,6 +404,47 @@ struct dentry *debugfs_create_size_t(const char *name, umode_t mode, ...@@ -403,6 +404,47 @@ struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
} }
EXPORT_SYMBOL_GPL(debugfs_create_size_t); 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, static ssize_t read_file_bool(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -431,6 +473,7 @@ static ssize_t write_file_bool(struct file *file, const char __user *user_buf, ...@@ -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)) if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT; return -EFAULT;
buf[buf_size] = '\0';
if (strtobool(buf, &bv) == 0) if (strtobool(buf, &bv) == 0)
*val = bv; *val = bv;
......
...@@ -20,13 +20,12 @@ config GFS2_FS ...@@ -20,13 +20,12 @@ config GFS2_FS
be found here: http://sources.redhat.com/cluster be found here: http://sources.redhat.com/cluster
The "nolock" lock module is now built in to GFS2 by default. If 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 you want to use the DLM, be sure to enable IPv4/6 networking.
networking.
config GFS2_FS_LOCKING_DLM config GFS2_FS_LOCKING_DLM
bool "GFS2 DLM locking" bool "GFS2 DLM locking"
depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \ 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 help
Multiple node locking module for GFS2 Multiple node locking module for GFS2
......
...@@ -74,7 +74,7 @@ static int sysfs_sd_compare(const struct sysfs_dirent *left, ...@@ -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 * @sd: sysfs_dirent of interest
* *
* Link @sd into its sibling rbtree which starts from * Link @sd into its sibling rbtree which starts from
......
...@@ -449,11 +449,13 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd) ...@@ -449,11 +449,13 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd)
spin_lock_irqsave(&sysfs_open_dirent_lock, flags); spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) {
od = sd->s_attr.open; od = sd->s_attr.open;
if (od) { if (od) {
atomic_inc(&od->event); atomic_inc(&od->event);
wake_up_interruptible(&od->poll); wake_up_interruptible(&od->poll);
} }
}
spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
} }
......
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#include <linux/security.h> #include <linux/security.h>
#include "sysfs.h" #include "sysfs.h"
extern struct super_block * sysfs_sb;
static const struct address_space_operations sysfs_aops = { static const struct address_space_operations sysfs_aops = {
.readpage = simple_readpage, .readpage = simple_readpage,
.write_begin = simple_write_begin, .write_begin = simple_write_begin,
......
...@@ -68,14 +68,6 @@ ...@@ -68,14 +68,6 @@
* are handled as text/data or they can be discarded (which * are handled as text/data or they can be discarded (which
* often happens at runtime) * 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 #ifdef CONFIG_HOTPLUG_CPU
#define CPU_KEEP(sec) *(.cpu##sec) #define CPU_KEEP(sec) *(.cpu##sec)
#define CPU_DISCARD(sec) #define CPU_DISCARD(sec)
...@@ -182,8 +174,6 @@ ...@@ -182,8 +174,6 @@
*(.data) \ *(.data) \
*(.ref.data) \ *(.ref.data) \
*(.data..shared_aligned) /* percpu related */ \ *(.data..shared_aligned) /* percpu related */ \
DEV_KEEP(init.data) \
DEV_KEEP(exit.data) \
CPU_KEEP(init.data) \ CPU_KEEP(init.data) \
CPU_KEEP(exit.data) \ CPU_KEEP(exit.data) \
MEM_KEEP(init.data) \ MEM_KEEP(init.data) \
...@@ -372,8 +362,6 @@ ...@@ -372,8 +362,6 @@
/* __*init sections */ \ /* __*init sections */ \
__init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \ __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \
*(.ref.rodata) \ *(.ref.rodata) \
DEV_KEEP(init.rodata) \
DEV_KEEP(exit.rodata) \
CPU_KEEP(init.rodata) \ CPU_KEEP(init.rodata) \
CPU_KEEP(exit.rodata) \ CPU_KEEP(exit.rodata) \
MEM_KEEP(init.rodata) \ MEM_KEEP(init.rodata) \
...@@ -416,8 +404,6 @@ ...@@ -416,8 +404,6 @@
*(.text.hot) \ *(.text.hot) \
*(.text) \ *(.text) \
*(.ref.text) \ *(.ref.text) \
DEV_KEEP(init.text) \
DEV_KEEP(exit.text) \
CPU_KEEP(init.text) \ CPU_KEEP(init.text) \
CPU_KEEP(exit.text) \ CPU_KEEP(exit.text) \
MEM_KEEP(init.text) \ MEM_KEEP(init.text) \
...@@ -503,7 +489,6 @@ ...@@ -503,7 +489,6 @@
/* init and exit section handling */ /* init and exit section handling */
#define INIT_DATA \ #define INIT_DATA \
*(.init.data) \ *(.init.data) \
DEV_DISCARD(init.data) \
CPU_DISCARD(init.data) \ CPU_DISCARD(init.data) \
MEM_DISCARD(init.data) \ MEM_DISCARD(init.data) \
KERNEL_CTORS() \ KERNEL_CTORS() \
...@@ -511,7 +496,6 @@ ...@@ -511,7 +496,6 @@
*(.init.rodata) \ *(.init.rodata) \
FTRACE_EVENTS() \ FTRACE_EVENTS() \
TRACE_SYSCALLS() \ TRACE_SYSCALLS() \
DEV_DISCARD(init.rodata) \
CPU_DISCARD(init.rodata) \ CPU_DISCARD(init.rodata) \
MEM_DISCARD(init.rodata) \ MEM_DISCARD(init.rodata) \
CLK_OF_TABLES() \ CLK_OF_TABLES() \
...@@ -521,14 +505,11 @@ ...@@ -521,14 +505,11 @@
#define INIT_TEXT \ #define INIT_TEXT \
*(.init.text) \ *(.init.text) \
DEV_DISCARD(init.text) \
CPU_DISCARD(init.text) \ CPU_DISCARD(init.text) \
MEM_DISCARD(init.text) MEM_DISCARD(init.text)
#define EXIT_DATA \ #define EXIT_DATA \
*(.exit.data) \ *(.exit.data) \
DEV_DISCARD(exit.data) \
DEV_DISCARD(exit.rodata) \
CPU_DISCARD(exit.data) \ CPU_DISCARD(exit.data) \
CPU_DISCARD(exit.rodata) \ CPU_DISCARD(exit.rodata) \
MEM_DISCARD(exit.data) \ MEM_DISCARD(exit.data) \
...@@ -536,7 +517,6 @@ ...@@ -536,7 +517,6 @@
#define EXIT_TEXT \ #define EXIT_TEXT \
*(.exit.text) \ *(.exit.text) \
DEV_DISCARD(exit.text) \
CPU_DISCARD(exit.text) \ CPU_DISCARD(exit.text) \
MEM_DISCARD(exit.text) MEM_DISCARD(exit.text)
......
...@@ -79,6 +79,8 @@ struct dentry *debugfs_create_x64(const char *name, umode_t mode, ...@@ -79,6 +79,8 @@ struct dentry *debugfs_create_x64(const char *name, umode_t mode,
struct dentry *parent, u64 *value); struct dentry *parent, u64 *value);
struct dentry *debugfs_create_size_t(const char *name, umode_t mode, struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
struct dentry *parent, size_t *value); 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 *debugfs_create_bool(const char *name, umode_t mode,
struct dentry *parent, u32 *value); struct dentry *parent, u32 *value);
......
...@@ -80,6 +80,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); ...@@ -80,6 +80,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
* bus-specific setup * bus-specific setup
* @p: The private data of the driver core, only the driver core can * @p: The private data of the driver core, only the driver core can
* touch this. * 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 * 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 * purposes of the device model, all devices are connected via a bus, even if
...@@ -635,6 +636,7 @@ struct acpi_dev_node { ...@@ -635,6 +636,7 @@ struct acpi_dev_node {
* segment limitations. * segment limitations.
* @dma_pools: Dma pools (if dma'ble device). * @dma_pools: Dma pools (if dma'ble device).
* @dma_mem: Internal for coherent mem override. * @dma_mem: Internal for coherent mem override.
* @cma_area: Contiguous memory area for dma allocations
* @archdata: For arch-specific additions. * @archdata: For arch-specific additions.
* @of_node: Associated device tree node. * @of_node: Associated device tree node.
* @acpi_node: Associated ACPI device node. * @acpi_node: Associated ACPI device node.
...@@ -648,6 +650,7 @@ struct acpi_dev_node { ...@@ -648,6 +650,7 @@ struct acpi_dev_node {
* @release: Callback to free the device after all references have * @release: Callback to free the device after all references have
* gone away. This should be set by the allocator of the * gone away. This should be set by the allocator of the
* device (i.e. the bus driver that discovered the device). * 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 * At the lowest level, every device in a Linux system is represented by an
* instance of struct device. The device structure contains the information * instance of struct device. The device structure contains the information
......
...@@ -47,8 +47,6 @@ int request_firmware_nowait( ...@@ -47,8 +47,6 @@ int request_firmware_nowait(
void (*cont)(const struct firmware *fw, void *context)); void (*cont)(const struct firmware *fw, void *context));
void release_firmware(const struct firmware *fw); void release_firmware(const struct firmware *fw);
int cache_firmware(const char *name);
int uncache_firmware(const char *name);
#else #else
static inline int request_firmware(const struct firmware **fw, static inline int request_firmware(const struct firmware **fw,
const char *name, const char *name,
...@@ -68,15 +66,6 @@ static inline void release_firmware(const struct firmware *fw) ...@@ -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
#endif #endif
...@@ -180,7 +180,13 @@ struct platform_driver { ...@@ -180,7 +180,13 @@ struct platform_driver {
const struct platform_device_id *id_table; 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 *); extern void platform_driver_unregister(struct platform_driver *);
/* non-hotpluggable platform devices may use this so that probe() and /* non-hotpluggable platform devices may use this so that probe() and
......
...@@ -53,6 +53,20 @@ config CROSS_COMPILE ...@@ -53,6 +53,20 @@ config CROSS_COMPILE
need to set this unless you want the configured kernel build need to set this unless you want the configured kernel build
directory to select the cross-compiler automatically. 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 config LOCALVERSION
string "Local version - append to kernel release" string "Local version - append to kernel release"
help help
...@@ -1245,9 +1259,6 @@ config SYSCTL_ARCH_UNALIGN_ALLOW ...@@ -1245,9 +1259,6 @@ config SYSCTL_ARCH_UNALIGN_ALLOW
the unaligned access emulation. the unaligned access emulation.
see arch/parisc/kernel/unaligned.c for reference see arch/parisc/kernel/unaligned.c for reference
config HOTPLUG
def_bool y
config HAVE_PCSPKR_PLATFORM config HAVE_PCSPKR_PLATFORM
bool bool
......
...@@ -100,7 +100,6 @@ config PM_SLEEP_SMP ...@@ -100,7 +100,6 @@ config PM_SLEEP_SMP
depends on SMP depends on SMP
depends on ARCH_SUSPEND_POSSIBLE || ARCH_HIBERNATION_POSSIBLE depends on ARCH_SUSPEND_POSSIBLE || ARCH_HIBERNATION_POSSIBLE
depends on PM_SLEEP depends on PM_SLEEP
select HOTPLUG
select HOTPLUG_CPU select HOTPLUG_CPU
config PM_AUTOSLEEP config PM_AUTOSLEEP
......
...@@ -182,27 +182,6 @@ static struct dentry *debugfs_create_stacktrace_depth( ...@@ -182,27 +182,6 @@ static struct dentry *debugfs_create_stacktrace_depth(
#endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ #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 *fault_create_debugfs_attr(const char *name,
struct dentry *parent, struct fault_attr *attr) struct dentry *parent, struct fault_attr *attr)
{ {
......
...@@ -805,7 +805,7 @@ static struct kset *kset_create(const char *name, ...@@ -805,7 +805,7 @@ static struct kset *kset_create(const char *name,
kset = kzalloc(sizeof(*kset), GFP_KERNEL); kset = kzalloc(sizeof(*kset), GFP_KERNEL);
if (!kset) if (!kset)
return NULL; return NULL;
retval = kobject_set_name(&kset->kobj, name); retval = kobject_set_name(&kset->kobj, "%s", name);
if (retval) { if (retval) {
kfree(kset); kfree(kset);
return NULL; return NULL;
......
...@@ -173,7 +173,7 @@ config HAVE_BOOTMEM_INFO_NODE ...@@ -173,7 +173,7 @@ config HAVE_BOOTMEM_INFO_NODE
config MEMORY_HOTPLUG config MEMORY_HOTPLUG
bool "Allow for memory hot-add" bool "Allow for memory hot-add"
depends on SPARSEMEM || X86_64_ACPI_NUMA 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) depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390)
config MEMORY_HOTPLUG_SPARSE config MEMORY_HOTPLUG_SPARSE
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册