1833c95456a70826d1384883b73fd23aff24d366fJohannes Berg/*
2833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * This file is provided under the GPLv2 license.
3833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
4833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * GPL LICENSE SUMMARY
5833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
6833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * Copyright(c) 2014 Intel Mobile Communications GmbH
7833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
8833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * This program is free software; you can redistribute it and/or modify
9833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * it under the terms of version 2 of the GNU General Public License as
10833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * published by the Free Software Foundation.
11833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
12833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * This program is distributed in the hope that it will be useful, but
13833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * WITHOUT ANY WARRANTY; without even the implied warranty of
14833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * General Public License for more details.
16833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
17833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * The full GNU General Public License is included in this distribution
18833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * in the file called COPYING.
19833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
20833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * Contact Information:
21833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *  Intel Linux Wireless <ilw@linux.intel.com>
22833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
23833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
24833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * Author: Johannes Berg <johannes@sipsolutions.net>
25833c95456a70826d1384883b73fd23aff24d366fJohannes Berg */
26833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#include <linux/module.h>
27833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#include <linux/device.h>
28833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#include <linux/devcoredump.h>
29833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#include <linux/list.h>
30833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#include <linux/slab.h>
31833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#include <linux/fs.h>
32833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#include <linux/workqueue.h>
33833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
34833c95456a70826d1384883b73fd23aff24d366fJohannes Berg/* if data isn't read by userspace after 5 minutes then delete it */
35833c95456a70826d1384883b73fd23aff24d366fJohannes Berg#define DEVCD_TIMEOUT	(HZ * 60 * 5)
36833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
37833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstruct devcd_entry {
38833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct device devcd_dev;
39833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	const void *data;
40833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	size_t datalen;
41833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct module *owner;
42833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	ssize_t (*read)(char *buffer, loff_t offset, size_t count,
43833c95456a70826d1384883b73fd23aff24d366fJohannes Berg			const void *data, size_t datalen);
44833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	void (*free)(const void *data);
45833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct delayed_work del_wk;
46833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct device *failing_dev;
47833c95456a70826d1384883b73fd23aff24d366fJohannes Berg};
48833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
49833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic struct devcd_entry *dev_to_devcd(struct device *dev)
50833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
51833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return container_of(dev, struct devcd_entry, devcd_dev);
52833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
53833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
54833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic void devcd_dev_release(struct device *dev)
55833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
56833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct devcd_entry *devcd = dev_to_devcd(dev);
57833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
58833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->free(devcd->data);
59833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	module_put(devcd->owner);
60833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
61833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	/*
62833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	 * this seems racy, but I don't see a notifier or such on
63833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	 * a struct device to know when it goes away?
64833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	 */
65833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (devcd->failing_dev->kobj.sd)
66833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		sysfs_delete_link(&devcd->failing_dev->kobj, &dev->kobj,
67833c95456a70826d1384883b73fd23aff24d366fJohannes Berg				  "devcoredump");
68833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
69833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	put_device(devcd->failing_dev);
70833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	kfree(devcd);
71833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
72833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
73833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic void devcd_del(struct work_struct *wk)
74833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
75833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct devcd_entry *devcd;
76833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
77833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd = container_of(wk, struct devcd_entry, del_wk.work);
78833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
79833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	device_del(&devcd->devcd_dev);
80833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	put_device(&devcd->devcd_dev);
81833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
82833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
83833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic ssize_t devcd_data_read(struct file *filp, struct kobject *kobj,
84833c95456a70826d1384883b73fd23aff24d366fJohannes Berg			       struct bin_attribute *bin_attr,
85833c95456a70826d1384883b73fd23aff24d366fJohannes Berg			       char *buffer, loff_t offset, size_t count)
86833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
87833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct device *dev = kobj_to_dev(kobj);
88833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct devcd_entry *devcd = dev_to_devcd(dev);
89833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
90833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return devcd->read(buffer, offset, count, devcd->data, devcd->datalen);
91833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
92833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
93833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic ssize_t devcd_data_write(struct file *filp, struct kobject *kobj,
94833c95456a70826d1384883b73fd23aff24d366fJohannes Berg				struct bin_attribute *bin_attr,
95833c95456a70826d1384883b73fd23aff24d366fJohannes Berg				char *buffer, loff_t offset, size_t count)
96833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
97833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct device *dev = kobj_to_dev(kobj);
98833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct devcd_entry *devcd = dev_to_devcd(dev);
99833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
100833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	mod_delayed_work(system_wq, &devcd->del_wk, 0);
101833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
102833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return count;
103833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
104833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
105833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic struct bin_attribute devcd_attr_data = {
106833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.attr = { .name = "data", .mode = S_IRUSR | S_IWUSR, },
107833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.size = 0,
108833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.read = devcd_data_read,
109833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.write = devcd_data_write,
110833c95456a70826d1384883b73fd23aff24d366fJohannes Berg};
111833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
112833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic struct bin_attribute *devcd_dev_bin_attrs[] = {
113833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	&devcd_attr_data, NULL,
114833c95456a70826d1384883b73fd23aff24d366fJohannes Berg};
115833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
116833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic const struct attribute_group devcd_dev_group = {
117833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.bin_attrs = devcd_dev_bin_attrs,
118833c95456a70826d1384883b73fd23aff24d366fJohannes Berg};
119833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
120833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic const struct attribute_group *devcd_dev_groups[] = {
121833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	&devcd_dev_group, NULL,
122833c95456a70826d1384883b73fd23aff24d366fJohannes Berg};
123833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
124833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic struct class devcd_class = {
125833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.name		= "devcoredump",
126833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.owner		= THIS_MODULE,
127833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.dev_release	= devcd_dev_release,
128833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	.dev_groups	= devcd_dev_groups,
129833c95456a70826d1384883b73fd23aff24d366fJohannes Berg};
130833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
131833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic ssize_t devcd_readv(char *buffer, loff_t offset, size_t count,
132833c95456a70826d1384883b73fd23aff24d366fJohannes Berg			   const void *data, size_t datalen)
133833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
134833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (offset > datalen)
135833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		return -EINVAL;
136833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
137833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (offset + count > datalen)
138833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		count = datalen - offset;
139833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
140833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (count)
141833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		memcpy(buffer, ((u8 *)data) + offset, count);
142833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
143833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return count;
144833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
145833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
146833c95456a70826d1384883b73fd23aff24d366fJohannes Berg/**
147833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * dev_coredumpv - create device coredump with vmalloc data
148833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @dev: the struct device for the crashed device
149833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @data: vmalloc data containing the device coredump
150833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @datalen: length of the data
151833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @gfp: allocation flags
152833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
153833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * This function takes ownership of the vmalloc'ed data and will free
154833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * it when it is no longer used. See dev_coredumpm() for more information.
155833c95456a70826d1384883b73fd23aff24d366fJohannes Berg */
156833c95456a70826d1384883b73fd23aff24d366fJohannes Bergvoid dev_coredumpv(struct device *dev, const void *data, size_t datalen,
157833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		   gfp_t gfp)
158833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
159833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	dev_coredumpm(dev, NULL, data, datalen, gfp, devcd_readv, vfree);
160833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
161833c95456a70826d1384883b73fd23aff24d366fJohannes BergEXPORT_SYMBOL_GPL(dev_coredumpv);
162833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
163833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic int devcd_match_failing(struct device *dev, const void *failing)
164833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
165833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct devcd_entry *devcd = dev_to_devcd(dev);
166833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
167833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return devcd->failing_dev == failing;
168833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
169833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
170833c95456a70826d1384883b73fd23aff24d366fJohannes Berg/**
171833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * dev_coredumpm - create device coredump with read/free methods
172833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @dev: the struct device for the crashed device
173833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @owner: the module that contains the read/free functions, use %THIS_MODULE
174833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @data: data cookie for the @read/@free functions
175833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @datalen: length of the data
176833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @gfp: allocation flags
177833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @read: function to read from the given buffer
178833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * @free: function to free the given buffer
179833c95456a70826d1384883b73fd23aff24d366fJohannes Berg *
180833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * Creates a new device coredump for the given device. If a previous one hasn't
181833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * been read yet, the new coredump is discarded. The data lifetime is determined
182833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * by the device coredump framework and when it is no longer needed the @free
183833c95456a70826d1384883b73fd23aff24d366fJohannes Berg * function will be called to free the data.
184833c95456a70826d1384883b73fd23aff24d366fJohannes Berg */
185833c95456a70826d1384883b73fd23aff24d366fJohannes Bergvoid dev_coredumpm(struct device *dev, struct module *owner,
186833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		   const void *data, size_t datalen, gfp_t gfp,
187833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		   ssize_t (*read)(char *buffer, loff_t offset, size_t count,
188833c95456a70826d1384883b73fd23aff24d366fJohannes Berg				   const void *data, size_t datalen),
189833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		   void (*free)(const void *data))
190833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
191833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	static atomic_t devcd_count = ATOMIC_INIT(0);
192833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct devcd_entry *devcd;
193833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct device *existing;
194833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
195833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	existing = class_find_device(&devcd_class, NULL, dev,
196833c95456a70826d1384883b73fd23aff24d366fJohannes Berg				     devcd_match_failing);
197833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (existing) {
198833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		put_device(existing);
199833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		goto free;
200833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	}
201833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
202833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (!try_module_get(owner))
203833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		goto free;
204833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
205833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd = kzalloc(sizeof(*devcd), gfp);
206833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (!devcd)
207833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		goto put_module;
208833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
209833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->owner = owner;
210833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->data = data;
211833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->datalen = datalen;
212833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->read = read;
213833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->free = free;
214833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->failing_dev = get_device(dev);
215833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
216833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	device_initialize(&devcd->devcd_dev);
217833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
218833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	dev_set_name(&devcd->devcd_dev, "devcd%d",
219833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		     atomic_inc_return(&devcd_count));
220833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	devcd->devcd_dev.class = &devcd_class;
221833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
222833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (device_add(&devcd->devcd_dev))
223833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		goto put_device;
224833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
225833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (sysfs_create_link(&devcd->devcd_dev.kobj, &dev->kobj,
226833c95456a70826d1384883b73fd23aff24d366fJohannes Berg			      "failing_device"))
227833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		/* nothing - symlink will be missing */;
228833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
229833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	if (sysfs_create_link(&dev->kobj, &devcd->devcd_dev.kobj,
230833c95456a70826d1384883b73fd23aff24d366fJohannes Berg			      "devcoredump"))
231833c95456a70826d1384883b73fd23aff24d366fJohannes Berg		/* nothing - symlink will be missing */;
232833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
233833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	INIT_DELAYED_WORK(&devcd->del_wk, devcd_del);
234833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT);
235833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
236833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return;
237833c95456a70826d1384883b73fd23aff24d366fJohannes Berg put_device:
238833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	put_device(&devcd->devcd_dev);
239833c95456a70826d1384883b73fd23aff24d366fJohannes Berg put_module:
240833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	module_put(owner);
241833c95456a70826d1384883b73fd23aff24d366fJohannes Berg free:
242833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	free(data);
243833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
244833c95456a70826d1384883b73fd23aff24d366fJohannes BergEXPORT_SYMBOL_GPL(dev_coredumpm);
245833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
246833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic int __init devcoredump_init(void)
247833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
248833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return class_register(&devcd_class);
249833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
250833c95456a70826d1384883b73fd23aff24d366fJohannes Berg__initcall(devcoredump_init);
251833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
252833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic int devcd_free(struct device *dev, void *data)
253833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
254833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	struct devcd_entry *devcd = dev_to_devcd(dev);
255833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
256833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	flush_delayed_work(&devcd->del_wk);
257833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	return 0;
258833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
259833c95456a70826d1384883b73fd23aff24d366fJohannes Berg
260833c95456a70826d1384883b73fd23aff24d366fJohannes Bergstatic void __exit devcoredump_exit(void)
261833c95456a70826d1384883b73fd23aff24d366fJohannes Berg{
262833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	class_for_each_device(&devcd_class, NULL, NULL, devcd_free);
263833c95456a70826d1384883b73fd23aff24d366fJohannes Berg	class_unregister(&devcd_class);
264833c95456a70826d1384883b73fd23aff24d366fJohannes Berg}
265833c95456a70826d1384883b73fd23aff24d366fJohannes Berg__exitcall(devcoredump_exit);
266