diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/core.c | 4 | ||||
-rw-r--r-- | drivers/base/cpu.c | 30 | ||||
-rw-r--r-- | drivers/base/dd.c | 12 | ||||
-rw-r--r-- | drivers/base/driver.c | 5 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 3 | ||||
-rw-r--r-- | drivers/base/memory.c | 2 | ||||
-rw-r--r-- | drivers/base/platform.c | 2 | ||||
-rw-r--r-- | drivers/base/power/shutdown.c | 9 |
8 files changed, 57 insertions, 10 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index fd8059920dbf..6b355bd7816d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -161,8 +161,8 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, return count; } -/** - * device_subsys - structure to be registered with kobject core. +/* + * devices_subsys - structure to be registered with kobject core. */ decl_subsys(devices, &ktype_device, &device_uevent_ops); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 281d26784d25..07a7f97e1de9 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -83,6 +83,31 @@ static inline void register_cpu_control(struct cpu *cpu) } #endif /* CONFIG_HOTPLUG_CPU */ +#ifdef CONFIG_KEXEC +#include <linux/kexec.h> + +static ssize_t show_crash_notes(struct sys_device *dev, char *buf) +{ + struct cpu *cpu = container_of(dev, struct cpu, sysdev); + ssize_t rc; + unsigned long long addr; + int cpunum; + + cpunum = cpu->sysdev.id; + + /* + * Might be reading other cpu's data based on which cpu read thread + * has been scheduled. But cpu data (memory) is allocated once during + * boot up and this data does not change there after. Hence this + * operation should be safe. No locking required. + */ + addr = __pa(per_cpu_ptr(crash_notes, cpunum)); + rc = sprintf(buf, "%Lx\n", addr); + return rc; +} +static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); +#endif + /* * register_cpu - Setup a driverfs device for a CPU. * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to @@ -108,6 +133,11 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root) register_cpu_control(cpu); if (!error) cpu_sys_devices[num] = &cpu->sysdev; + +#ifdef CONFIG_KEXEC + if (!error) + error = sysdev_create_file(&cpu->sysdev, &attr_crash_notes); +#endif return error; } diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 2b905016664d..730a9ce0a14a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -78,7 +78,13 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) pr_debug("%s: Matched Device %s with Driver %s\n", drv->bus->name, dev->bus_id, drv->name); dev->driver = drv; - if (drv->probe) { + if (dev->bus->probe) { + ret = dev->bus->probe(dev); + if (ret) { + dev->driver = NULL; + goto ProbeFailed; + } + } else if (drv->probe) { ret = drv->probe(dev); if (ret) { dev->driver = NULL; @@ -203,7 +209,9 @@ static void __device_release_driver(struct device * dev) sysfs_remove_link(&dev->kobj, "driver"); klist_remove(&dev->knode_driver); - if (drv->remove) + if (dev->bus->remove) + dev->bus->remove(dev); + else if (drv->remove) drv->remove(dev); dev->driver = NULL; put_driver(drv); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 161f3a390d90..b400314e1c62 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -171,6 +171,11 @@ static void klist_devices_put(struct klist_node *n) */ int driver_register(struct device_driver * drv) { + if ((drv->bus->probe && drv->probe) || + (drv->bus->remove && drv->remove) || + (drv->bus->shutdown && drv->shutdown)) { + printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); + } klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put); init_completion(&drv->unloaded); return bus_add_driver(drv); diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 5b3d5e9ddcb6..e97e911ebf7a 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -7,6 +7,7 @@ * */ +#include <linux/capability.h> #include <linux/device.h> #include <linux/module.h> #include <linux/init.h> @@ -47,7 +48,7 @@ struct firmware_priv { struct timer_list timeout; }; -static inline void +static void fw_load_abort(struct firmware_priv *fw_priv) { set_bit(FW_STATUS_ABORT, &fw_priv->status); diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 58801d718cc2..d1a05224627e 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -13,8 +13,8 @@ #include <linux/sysdev.h> #include <linux/module.h> #include <linux/init.h> -#include <linux/sched.h> /* capable() */ #include <linux/topology.h> +#include <linux/capability.h> #include <linux/device.h> #include <linux/memory.h> #include <linux/kobject.h> diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 0f81731bdfa8..461554a02517 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -327,7 +327,7 @@ EXPORT_SYMBOL_GPL(platform_device_register); * @pdev: platform device we're unregistering * * Unregistration is done in 2 steps. Fisrt we release all resources - * and remove it from the sybsystem, then we drop reference count by + * and remove it from the subsystem, then we drop reference count by * calling platform_device_put(). */ void platform_device_unregister(struct platform_device * pdev) diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index f50a08be424b..c2475f3134ea 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c @@ -35,12 +35,15 @@ extern int sysdev_shutdown(void); */ void device_shutdown(void) { - struct device * dev; + struct device * dev, *devn; down_write(&devices_subsys.rwsem); - list_for_each_entry_reverse(dev, &devices_subsys.kset.list, + list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.kset.list, kobj.entry) { - if (dev->driver && dev->driver->shutdown) { + if (dev->bus && dev->bus->shutdown) { + dev_dbg(dev, "shutdown\n"); + dev->bus->shutdown(dev); + } else if (dev->driver && dev->driver->shutdown) { dev_dbg(dev, "shutdown\n"); dev->driver->shutdown(dev); } |