aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-02-07 19:29:55 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-07 19:29:55 -0500
commit92118c739df879497b8cc5a2eb3a9dc255f01b20 (patch)
treeda556ca2f8afa1b43ca0626c9426f6634c64d32d /drivers
parentb4669d66fb1488fd9cebe0b8da447cfeb86109ba (diff)
parent276e0c75f1e9a8b34b7b19e8fe188be958d420dd (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/base.h4
-rw-r--r--drivers/base/power/resume.c3
-rw-r--r--drivers/base/power/shutdown.c2
-rw-r--r--drivers/base/power/suspend.c3
-rw-r--r--drivers/base/power/sysfs.c24
-rw-r--r--drivers/base/sys.c3
-rw-r--r--drivers/char/drm/drmP.h10
-rw-r--r--drivers/char/drm/drm_stub.c2
-rw-r--r--drivers/char/drm/drm_sysfs.c131
-rw-r--r--drivers/infiniband/core/ucm.c13
-rw-r--r--drivers/spi/Kconfig10
-rw-r--r--drivers/spi/spi_butterfly.c36
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 *);
19extern void driver_detach(struct device_driver * drv); 19extern void driver_detach(struct device_driver * drv);
20extern int driver_probe_device(struct device_driver *, struct device *); 20extern int driver_probe_device(struct device_driver *, struct device *);
21 21
22extern void sysdev_shutdown(void);
23extern int sysdev_suspend(pm_message_t state);
24extern int sysdev_resume(void);
25
22static inline struct class_device *to_class_dev(struct kobject *obj) 26static 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
14extern 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
31extern 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
14extern 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
28static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) 28static 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
33static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) 36static 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
26extern struct subsystem devices_subsys; 29extern 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);
980extern unsigned int drm_debug; 980extern unsigned int drm_debug;
981extern unsigned int drm_cards_limit; 981extern unsigned int drm_cards_limit;
982extern drm_head_t **drm_heads; 982extern drm_head_t **drm_heads;
983extern struct drm_sysfs_class *drm_class; 983extern struct class *drm_class;
984extern struct proc_dir_entry *drm_proc_root; 984extern 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);
1011extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); 1011extern 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) */
1014struct drm_sysfs_class; 1014extern struct class *drm_sysfs_create(struct module *owner, char *name);
1015extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, 1015extern void drm_sysfs_destroy(struct class *cs);
1016 char *name); 1016extern struct class_device *drm_sysfs_device_add(struct class *cs,
1017extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
1018extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
1019 drm_head_t *head); 1017 drm_head_t *head);
1020extern void drm_sysfs_device_remove(struct class_device *class_dev); 1018extern 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);
50module_param_named(debug, drm_debug, int, 0600); 50module_param_named(debug, drm_debug, int, 0600);
51 51
52drm_head_t **drm_heads; 52drm_head_t **drm_heads;
53struct drm_sysfs_class *drm_class; 53struct class *drm_class;
54struct proc_dir_entry *drm_proc_root; 54struct proc_dir_entry *drm_proc_root;
55 55
56static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, 56static 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
22struct 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
28struct 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
34static 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
40static 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
46static 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 */
53static ssize_t version_show(struct class *dev, char *buf) 24static 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 */
72struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) 43struct 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 */
113void drm_sysfs_destroy(struct drm_sysfs_class *cs) 62void 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
121static ssize_t show_dri(struct class_device *class_device, char *buf) 71static 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 */
147struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, 97struct 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
181error:
182 kfree(s_dev);
183 return ERR_PTR(retval);
184} 114}
185 115
186/** 116/**
@@ -192,10 +122,9 @@ error:
192 */ 122 */
193void drm_sysfs_device_remove(struct class_device *class_dev) 123void 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
1322static 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}
1329static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
1330
1331static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 1322static 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
78config 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 */
204static struct mtd_partition partitions[] = { { 203static 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}
421module_exit(butterfly_exit); 418module_exit(butterfly_exit);
422 419
420MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly");
423MODULE_LICENSE("GPL"); 421MODULE_LICENSE("GPL");