diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/base.h | 4 | ||||
-rw-r--r-- | drivers/base/power/resume.c | 3 | ||||
-rw-r--r-- | drivers/base/power/shutdown.c | 2 | ||||
-rw-r--r-- | drivers/base/power/suspend.c | 3 | ||||
-rw-r--r-- | drivers/base/power/sysfs.c | 24 | ||||
-rw-r--r-- | drivers/base/sys.c | 3 | ||||
-rw-r--r-- | drivers/char/drm/drmP.h | 10 | ||||
-rw-r--r-- | drivers/char/drm/drm_stub.c | 2 | ||||
-rw-r--r-- | drivers/char/drm/drm_sysfs.c | 131 | ||||
-rw-r--r-- | drivers/infiniband/core/ucm.c | 13 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/spi/spi_butterfly.c | 36 |
12 files changed, 79 insertions, 162 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h index e3b548d46cff..5735b38582d0 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -19,6 +19,10 @@ extern void bus_remove_driver(struct device_driver *); | |||
19 | extern void driver_detach(struct device_driver * drv); | 19 | extern void driver_detach(struct device_driver * drv); |
20 | extern int driver_probe_device(struct device_driver *, struct device *); | 20 | extern int driver_probe_device(struct device_driver *, struct device *); |
21 | 21 | ||
22 | extern void sysdev_shutdown(void); | ||
23 | extern int sysdev_suspend(pm_message_t state); | ||
24 | extern int sysdev_resume(void); | ||
25 | |||
22 | static inline struct class_device *to_class_dev(struct kobject *obj) | 26 | static inline struct class_device *to_class_dev(struct kobject *obj) |
23 | { | 27 | { |
24 | return container_of(obj, struct class_device, kobj); | 28 | return container_of(obj, struct class_device, kobj); |
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 0a7aa07b9a2a..317edbf0feca 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c | |||
@@ -9,10 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include "../base.h" | ||
12 | #include "power.h" | 13 | #include "power.h" |
13 | 14 | ||
14 | extern int sysdev_resume(void); | ||
15 | |||
16 | 15 | ||
17 | /** | 16 | /** |
18 | * resume_device - Restore state for one device. | 17 | * resume_device - Restore state for one device. |
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index c2475f3134ea..8826a5b6673e 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <asm/semaphore.h> | 13 | #include <asm/semaphore.h> |
14 | 14 | ||
15 | #include "../base.h" | ||
15 | #include "power.h" | 16 | #include "power.h" |
16 | 17 | ||
17 | #define to_dev(node) container_of(node, struct device, kobj.entry) | 18 | #define to_dev(node) container_of(node, struct device, kobj.entry) |
@@ -28,7 +29,6 @@ extern struct subsystem devices_subsys; | |||
28 | * they only get one called once when interrupts are disabled. | 29 | * they only get one called once when interrupts are disabled. |
29 | */ | 30 | */ |
30 | 31 | ||
31 | extern int sysdev_shutdown(void); | ||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * device_shutdown - call ->shutdown() on each device to shutdown. | 34 | * device_shutdown - call ->shutdown() on each device to shutdown. |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 50501764d050..8660779fb288 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -9,10 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include "../base.h" | ||
12 | #include "power.h" | 13 | #include "power.h" |
13 | 14 | ||
14 | extern int sysdev_suspend(pm_message_t state); | ||
15 | |||
16 | /* | 15 | /* |
17 | * The entries in the dpm_active list are in a depth first order, simply | 16 | * The entries in the dpm_active list are in a depth first order, simply |
18 | * because children are guaranteed to be discovered after parents, and | 17 | * because children are guaranteed to be discovered after parents, and |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index f3a0c562bcb5..40d7242a07c1 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
@@ -27,22 +27,30 @@ | |||
27 | 27 | ||
28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) | 28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) |
29 | { | 29 | { |
30 | return sprintf(buf, "%u\n", dev->power.power_state.event); | 30 | if (dev->power.power_state.event) |
31 | return sprintf(buf, "2\n"); | ||
32 | else | ||
33 | return sprintf(buf, "0\n"); | ||
31 | } | 34 | } |
32 | 35 | ||
33 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) | 36 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) |
34 | { | 37 | { |
35 | pm_message_t state; | 38 | pm_message_t state; |
36 | char * rest; | 39 | int error = -EINVAL; |
37 | int error = 0; | ||
38 | 40 | ||
39 | state.event = simple_strtoul(buf, &rest, 10); | 41 | state.event = PM_EVENT_SUSPEND; |
40 | if (*rest) | 42 | /* Older apps expected to write "3" here - confused with PCI D3 */ |
41 | return -EINVAL; | 43 | if ((n == 1) && !strcmp(buf, "3")) |
42 | if (state.event) | ||
43 | error = dpm_runtime_suspend(dev, state); | 44 | error = dpm_runtime_suspend(dev, state); |
44 | else | 45 | |
46 | if ((n == 1) && !strcmp(buf, "2")) | ||
47 | error = dpm_runtime_suspend(dev, state); | ||
48 | |||
49 | if ((n == 1) && !strcmp(buf, "0")) { | ||
45 | dpm_runtime_resume(dev); | 50 | dpm_runtime_resume(dev); |
51 | error = 0; | ||
52 | } | ||
53 | |||
46 | return error ? error : n; | 54 | return error ? error : n; |
47 | } | 55 | } |
48 | 56 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 66ed8f2fece5..6fc23ab127bd 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -21,8 +21,11 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/device.h> | ||
24 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
25 | 26 | ||
27 | #include "base.h" | ||
28 | |||
26 | extern struct subsystem devices_subsys; | 29 | extern struct subsystem devices_subsys; |
27 | 30 | ||
28 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | 31 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 71b8b32b075f..107df9fdba4e 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -980,7 +980,7 @@ extern int drm_put_head(drm_head_t * head); | |||
980 | extern unsigned int drm_debug; | 980 | extern unsigned int drm_debug; |
981 | extern unsigned int drm_cards_limit; | 981 | extern unsigned int drm_cards_limit; |
982 | extern drm_head_t **drm_heads; | 982 | extern drm_head_t **drm_heads; |
983 | extern struct drm_sysfs_class *drm_class; | 983 | extern struct class *drm_class; |
984 | extern struct proc_dir_entry *drm_proc_root; | 984 | extern struct proc_dir_entry *drm_proc_root; |
985 | 985 | ||
986 | /* Proc support (drm_proc.h) */ | 986 | /* Proc support (drm_proc.h) */ |
@@ -1011,11 +1011,9 @@ extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | |||
1011 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | 1011 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); |
1012 | 1012 | ||
1013 | /* sysfs support (drm_sysfs.c) */ | 1013 | /* sysfs support (drm_sysfs.c) */ |
1014 | struct drm_sysfs_class; | 1014 | extern struct class *drm_sysfs_create(struct module *owner, char *name); |
1015 | extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, | 1015 | extern void drm_sysfs_destroy(struct class *cs); |
1016 | char *name); | 1016 | extern struct class_device *drm_sysfs_device_add(struct class *cs, |
1017 | extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); | ||
1018 | extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | ||
1019 | drm_head_t *head); | 1017 | drm_head_t *head); |
1020 | extern void drm_sysfs_device_remove(struct class_device *class_dev); | 1018 | extern void drm_sysfs_device_remove(struct class_device *class_dev); |
1021 | 1019 | ||
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 7a9263ff3007..68073e14fdec 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444); | |||
50 | module_param_named(debug, drm_debug, int, 0600); | 50 | module_param_named(debug, drm_debug, int, 0600); |
51 | 51 | ||
52 | drm_head_t **drm_heads; | 52 | drm_head_t **drm_heads; |
53 | struct drm_sysfs_class *drm_class; | 53 | struct class *drm_class; |
54 | struct proc_dir_entry *drm_proc_root; | 54 | struct proc_dir_entry *drm_proc_root; |
55 | 55 | ||
56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | 56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 68e43ddc16ae..0b9f98a7eb10 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support | 3 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support |
3 | * extra sysfs attribute from DRM. Normal drm_sysfs_class | 4 | * extra sysfs attribute from DRM. Normal drm_sysfs_class |
@@ -19,36 +20,6 @@ | |||
19 | #include "drm_core.h" | 20 | #include "drm_core.h" |
20 | #include "drmP.h" | 21 | #include "drmP.h" |
21 | 22 | ||
22 | struct drm_sysfs_class { | ||
23 | struct class_device_attribute attr; | ||
24 | struct class class; | ||
25 | }; | ||
26 | #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) | ||
27 | |||
28 | struct simple_dev { | ||
29 | dev_t dev; | ||
30 | struct class_device class_dev; | ||
31 | }; | ||
32 | #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) | ||
33 | |||
34 | static void release_simple_dev(struct class_device *class_dev) | ||
35 | { | ||
36 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
37 | kfree(s_dev); | ||
38 | } | ||
39 | |||
40 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | ||
41 | { | ||
42 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
43 | return print_dev_t(buf, s_dev->dev); | ||
44 | } | ||
45 | |||
46 | static void drm_sysfs_class_release(struct class *class) | ||
47 | { | ||
48 | struct drm_sysfs_class *cs = to_drm_sysfs_class(class); | ||
49 | kfree(cs); | ||
50 | } | ||
51 | |||
52 | /* Display the version of drm_core. This doesn't work right in current design */ | 23 | /* Display the version of drm_core. This doesn't work right in current design */ |
53 | static ssize_t version_show(struct class *dev, char *buf) | 24 | static ssize_t version_show(struct class *dev, char *buf) |
54 | { | 25 | { |
@@ -69,38 +40,16 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); | |||
69 | * Note, the pointer created here is to be destroyed when finished by making a | 40 | * Note, the pointer created here is to be destroyed when finished by making a |
70 | * call to drm_sysfs_destroy(). | 41 | * call to drm_sysfs_destroy(). |
71 | */ | 42 | */ |
72 | struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | 43 | struct class *drm_sysfs_create(struct module *owner, char *name) |
73 | { | 44 | { |
74 | struct drm_sysfs_class *cs; | 45 | struct class *class; |
75 | int retval; | 46 | |
76 | 47 | class = class_create(owner, name); | |
77 | cs = kmalloc(sizeof(*cs), GFP_KERNEL); | 48 | if (!class) |
78 | if (!cs) { | 49 | return class; |
79 | retval = -ENOMEM; | 50 | |
80 | goto error; | 51 | class_create_file(class, &class_attr_version); |
81 | } | 52 | return class; |
82 | memset(cs, 0x00, sizeof(*cs)); | ||
83 | |||
84 | cs->class.name = name; | ||
85 | cs->class.class_release = drm_sysfs_class_release; | ||
86 | cs->class.release = release_simple_dev; | ||
87 | |||
88 | cs->attr.attr.name = "dev"; | ||
89 | cs->attr.attr.mode = S_IRUGO; | ||
90 | cs->attr.attr.owner = owner; | ||
91 | cs->attr.show = show_dev; | ||
92 | cs->attr.store = NULL; | ||
93 | |||
94 | retval = class_register(&cs->class); | ||
95 | if (retval) | ||
96 | goto error; | ||
97 | class_create_file(&cs->class, &class_attr_version); | ||
98 | |||
99 | return cs; | ||
100 | |||
101 | error: | ||
102 | kfree(cs); | ||
103 | return ERR_PTR(retval); | ||
104 | } | 53 | } |
105 | 54 | ||
106 | /** | 55 | /** |
@@ -110,12 +59,13 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | |||
110 | * Note, the pointer to be destroyed must have been created with a call to | 59 | * Note, the pointer to be destroyed must have been created with a call to |
111 | * drm_sysfs_create(). | 60 | * drm_sysfs_create(). |
112 | */ | 61 | */ |
113 | void drm_sysfs_destroy(struct drm_sysfs_class *cs) | 62 | void drm_sysfs_destroy(struct class *class) |
114 | { | 63 | { |
115 | if ((cs == NULL) || (IS_ERR(cs))) | 64 | if ((class == NULL) || (IS_ERR(class))) |
116 | return; | 65 | return; |
117 | 66 | ||
118 | class_unregister(&cs->class); | 67 | class_remove_file(class, &class_attr_version); |
68 | class_destroy(class); | ||
119 | } | 69 | } |
120 | 70 | ||
121 | static ssize_t show_dri(struct class_device *class_device, char *buf) | 71 | static ssize_t show_dri(struct class_device *class_device, char *buf) |
@@ -132,7 +82,7 @@ static struct class_device_attribute class_device_attrs[] = { | |||
132 | 82 | ||
133 | /** | 83 | /** |
134 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver | 84 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver |
135 | * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. | 85 | * @cs: pointer to the struct class that this device should be registered to. |
136 | * @dev: the dev_t for the device to be added. | 86 | * @dev: the dev_t for the device to be added. |
137 | * @device: a pointer to a struct device that is assiociated with this class device. | 87 | * @device: a pointer to a struct device that is assiociated with this class device. |
138 | * @fmt: string for the class device's name | 88 | * @fmt: string for the class device's name |
@@ -141,46 +91,26 @@ static struct class_device_attribute class_device_attrs[] = { | |||
141 | * class. A "dev" file will be created, showing the dev_t for the device. The | 91 | * class. A "dev" file will be created, showing the dev_t for the device. The |
142 | * pointer to the struct class_device will be returned from the call. Any further | 92 | * pointer to the struct class_device will be returned from the call. Any further |
143 | * sysfs files that might be required can be created using this pointer. | 93 | * sysfs files that might be required can be created using this pointer. |
144 | * Note: the struct drm_sysfs_class passed to this function must have previously been | 94 | * Note: the struct class passed to this function must have previously been |
145 | * created with a call to drm_sysfs_create(). | 95 | * created with a call to drm_sysfs_create(). |
146 | */ | 96 | */ |
147 | struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | 97 | struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) |
148 | drm_head_t *head) | ||
149 | { | 98 | { |
150 | struct simple_dev *s_dev = NULL; | 99 | struct class_device *class_dev; |
151 | int i, retval; | 100 | int i; |
152 | |||
153 | if ((cs == NULL) || (IS_ERR(cs))) { | ||
154 | retval = -ENODEV; | ||
155 | goto error; | ||
156 | } | ||
157 | |||
158 | s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL); | ||
159 | if (!s_dev) { | ||
160 | retval = -ENOMEM; | ||
161 | goto error; | ||
162 | } | ||
163 | memset(s_dev, 0x00, sizeof(*s_dev)); | ||
164 | |||
165 | s_dev->dev = MKDEV(DRM_MAJOR, head->minor); | ||
166 | s_dev->class_dev.dev = &(head->dev->pdev)->dev; | ||
167 | s_dev->class_dev.class = &cs->class; | ||
168 | 101 | ||
169 | snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); | 102 | class_dev = class_device_create(cs, NULL, |
170 | retval = class_device_register(&s_dev->class_dev); | 103 | MKDEV(DRM_MAJOR, head->minor), |
171 | if (retval) | 104 | &(head->dev->pdev)->dev, |
172 | goto error; | 105 | "card%d", head->minor); |
106 | if (!class_dev) | ||
107 | return NULL; | ||
173 | 108 | ||
174 | class_device_create_file(&s_dev->class_dev, &cs->attr); | 109 | class_set_devdata(class_dev, head); |
175 | class_set_devdata(&s_dev->class_dev, head); | ||
176 | 110 | ||
177 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 111 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
178 | class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); | 112 | class_device_create_file(class_dev, &class_device_attrs[i]); |
179 | return &s_dev->class_dev; | 113 | return class_dev; |
180 | |||
181 | error: | ||
182 | kfree(s_dev); | ||
183 | return ERR_PTR(retval); | ||
184 | } | 114 | } |
185 | 115 | ||
186 | /** | 116 | /** |
@@ -192,10 +122,9 @@ error: | |||
192 | */ | 122 | */ |
193 | void drm_sysfs_device_remove(struct class_device *class_dev) | 123 | void drm_sysfs_device_remove(struct class_device *class_dev) |
194 | { | 124 | { |
195 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
196 | int i; | 125 | int i; |
197 | 126 | ||
198 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 127 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
199 | class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); | 128 | class_device_remove_file(class_dev, &class_device_attrs[i]); |
200 | class_device_unregister(&s_dev->class_dev); | 129 | class_device_unregister(class_dev); |
201 | } | 130 | } |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index e95c4293a496..f6a05965a4e8 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -1319,15 +1319,6 @@ static struct class ucm_class = { | |||
1319 | .release = ib_ucm_release_class_dev | 1319 | .release = ib_ucm_release_class_dev |
1320 | }; | 1320 | }; |
1321 | 1321 | ||
1322 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | ||
1323 | { | ||
1324 | struct ib_ucm_device *dev; | ||
1325 | |||
1326 | dev = container_of(class_dev, struct ib_ucm_device, class_dev); | ||
1327 | return print_dev_t(buf, dev->dev.dev); | ||
1328 | } | ||
1329 | static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); | ||
1330 | |||
1331 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) | 1322 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) |
1332 | { | 1323 | { |
1333 | struct ib_ucm_device *dev; | 1324 | struct ib_ucm_device *dev; |
@@ -1364,15 +1355,13 @@ static void ib_ucm_add_one(struct ib_device *device) | |||
1364 | 1355 | ||
1365 | ucm_dev->class_dev.class = &ucm_class; | 1356 | ucm_dev->class_dev.class = &ucm_class; |
1366 | ucm_dev->class_dev.dev = device->dma_device; | 1357 | ucm_dev->class_dev.dev = device->dma_device; |
1358 | ucm_dev->class_dev.devt = ucm_dev->dev.dev; | ||
1367 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", | 1359 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", |
1368 | ucm_dev->devnum); | 1360 | ucm_dev->devnum); |
1369 | if (class_device_register(&ucm_dev->class_dev)) | 1361 | if (class_device_register(&ucm_dev->class_dev)) |
1370 | goto err_cdev; | 1362 | goto err_cdev; |
1371 | 1363 | ||
1372 | if (class_device_create_file(&ucm_dev->class_dev, | 1364 | if (class_device_create_file(&ucm_dev->class_dev, |
1373 | &class_device_attr_dev)) | ||
1374 | goto err_class; | ||
1375 | if (class_device_create_file(&ucm_dev->class_dev, | ||
1376 | &class_device_attr_ibdev)) | 1365 | &class_device_attr_ibdev)) |
1377 | goto err_class; | 1366 | goto err_class; |
1378 | 1367 | ||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b77dbd63e596..7a75faeb0526 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -75,16 +75,6 @@ config SPI_BUTTERFLY | |||
75 | inexpensive battery powered microcontroller evaluation board. | 75 | inexpensive battery powered microcontroller evaluation board. |
76 | This same cable can be used to flash new firmware. | 76 | This same cable can be used to flash new firmware. |
77 | 77 | ||
78 | config SPI_BUTTERFLY | ||
79 | tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" | ||
80 | depends on SPI_MASTER && PARPORT && EXPERIMENTAL | ||
81 | select SPI_BITBANG | ||
82 | help | ||
83 | This uses a custom parallel port cable to connect to an AVR | ||
84 | Butterfly <http://www.atmel.com/products/avr/butterfly>, an | ||
85 | inexpensive battery powered microcontroller evaluation board. | ||
86 | This same cable can be used to flash new firmware. | ||
87 | |||
88 | # | 78 | # |
89 | # Add new SPI master controllers in alphabetical order above this line | 79 | # Add new SPI master controllers in alphabetical order above this line |
90 | # | 80 | # |
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index 79a3c59615ab..ff9e5faa4dc9 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c | |||
@@ -163,21 +163,20 @@ static void butterfly_chipselect(struct spi_device *spi, int value) | |||
163 | struct butterfly *pp = spidev_to_pp(spi); | 163 | struct butterfly *pp = spidev_to_pp(spi); |
164 | 164 | ||
165 | /* set default clock polarity */ | 165 | /* set default clock polarity */ |
166 | if (value) | 166 | if (value != BITBANG_CS_INACTIVE) |
167 | setsck(spi, spi->mode & SPI_CPOL); | 167 | setsck(spi, spi->mode & SPI_CPOL); |
168 | 168 | ||
169 | /* no chipselect on this USI link config */ | 169 | /* no chipselect on this USI link config */ |
170 | if (is_usidev(spi)) | 170 | if (is_usidev(spi)) |
171 | return; | 171 | return; |
172 | 172 | ||
173 | /* here, value == "activate or not" */ | 173 | /* here, value == "activate or not"; |
174 | 174 | * most PARPORT_CONTROL_* bits are negated, so we must | |
175 | /* most PARPORT_CONTROL_* bits are negated */ | 175 | * morph it to value == "bit value to write in control register" |
176 | */ | ||
176 | if (spi_cs_bit == PARPORT_CONTROL_INIT) | 177 | if (spi_cs_bit == PARPORT_CONTROL_INIT) |
177 | value = !value; | 178 | value = !value; |
178 | 179 | ||
179 | /* here, value == "bit value to write in control register" */ | ||
180 | |||
181 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); | 180 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); |
182 | } | 181 | } |
183 | 182 | ||
@@ -202,7 +201,9 @@ butterfly_txrx_word_mode0(struct spi_device *spi, | |||
202 | 201 | ||
203 | /* override default partitioning with cmdlinepart */ | 202 | /* override default partitioning with cmdlinepart */ |
204 | static struct mtd_partition partitions[] = { { | 203 | static struct mtd_partition partitions[] = { { |
205 | /* JFFS2 wants partitions of 4*N blocks for this device ... */ | 204 | /* JFFS2 wants partitions of 4*N blocks for this device, |
205 | * so sectors 0 and 1 can't be partitions by themselves. | ||
206 | */ | ||
206 | 207 | ||
207 | /* sector 0 = 8 pages * 264 bytes/page (1 block) | 208 | /* sector 0 = 8 pages * 264 bytes/page (1 block) |
208 | * sector 1 = 248 pages * 264 bytes/page | 209 | * sector 1 = 248 pages * 264 bytes/page |
@@ -316,8 +317,9 @@ static void butterfly_attach(struct parport *p) | |||
316 | if (status < 0) | 317 | if (status < 0) |
317 | goto clean2; | 318 | goto clean2; |
318 | 319 | ||
319 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR) | 320 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR |
320 | * or AVR (firmware resets at45, acts as spi slave) | 321 | * (firmware resets at45, acts as spi slave) or neither (we ignore |
322 | * both, AVR uses AT45). Here we expect firmware for the first option. | ||
321 | */ | 323 | */ |
322 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; | 324 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; |
323 | strcpy(pp->info[0].modalias, "mtd_dataflash"); | 325 | strcpy(pp->info[0].modalias, "mtd_dataflash"); |
@@ -330,7 +332,9 @@ static void butterfly_attach(struct parport *p) | |||
330 | pp->dataflash->dev.bus_id); | 332 | pp->dataflash->dev.bus_id); |
331 | 333 | ||
332 | #ifdef HAVE_USI | 334 | #ifdef HAVE_USI |
333 | /* even more custom AVR firmware */ | 335 | /* Bus 2 is only for talking to the AVR, and it can work no |
336 | * matter who masters bus 1; needs appropriate AVR firmware. | ||
337 | */ | ||
334 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; | 338 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; |
335 | strcpy(pp->info[1].modalias, "butterfly"); | 339 | strcpy(pp->info[1].modalias, "butterfly"); |
336 | // pp->info[1].platform_data = ... TBD ... ; | 340 | // pp->info[1].platform_data = ... TBD ... ; |
@@ -378,13 +382,8 @@ static void butterfly_detach(struct parport *p) | |||
378 | pp = butterfly; | 382 | pp = butterfly; |
379 | butterfly = NULL; | 383 | butterfly = NULL; |
380 | 384 | ||
381 | #ifdef HAVE_USI | 385 | /* stop() unregisters child devices too */ |
382 | spi_unregister_device(pp->butterfly); | 386 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); |
383 | pp->butterfly = NULL; | ||
384 | #endif | ||
385 | spi_unregister_device(pp->dataflash); | ||
386 | pp->dataflash = NULL; | ||
387 | |||
388 | status = spi_bitbang_stop(&pp->bitbang); | 387 | status = spi_bitbang_stop(&pp->bitbang); |
389 | 388 | ||
390 | /* turn off VCC */ | 389 | /* turn off VCC */ |
@@ -394,8 +393,6 @@ static void butterfly_detach(struct parport *p) | |||
394 | parport_release(pp->pd); | 393 | parport_release(pp->pd); |
395 | parport_unregister_device(pp->pd); | 394 | parport_unregister_device(pp->pd); |
396 | 395 | ||
397 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); | ||
398 | |||
399 | (void) spi_master_put(pp->bitbang.master); | 396 | (void) spi_master_put(pp->bitbang.master); |
400 | 397 | ||
401 | platform_device_unregister(pdev); | 398 | platform_device_unregister(pdev); |
@@ -420,4 +417,5 @@ static void __exit butterfly_exit(void) | |||
420 | } | 417 | } |
421 | module_exit(butterfly_exit); | 418 | module_exit(butterfly_exit); |
422 | 419 | ||
420 | MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly"); | ||
423 | MODULE_LICENSE("GPL"); | 421 | MODULE_LICENSE("GPL"); |