diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 14:17:05 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 14:17:05 -0500 |
commit | 70c07e02625ec46d0ffbfce1acef42d660803528 (patch) | |
tree | f500f1a4f93e72747fb08b0eefabb167dcdc5db9 /drivers | |
parent | 5d1769ac3d0ea5ff3a286b097c21faaf6a9e6859 (diff) | |
parent | 2746b8623abce815aaae7afc946b1b39f8436f5a (diff) |
Merge branch 'viro'
Diffstat (limited to 'drivers')
108 files changed, 2891 insertions, 700 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/bus.c b/drivers/base/bus.c index 29f6af554e71..c3141565d59d 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -133,6 +133,8 @@ static struct kobj_type ktype_bus = { | |||
133 | decl_subsys(bus, &ktype_bus, NULL); | 133 | decl_subsys(bus, &ktype_bus, NULL); |
134 | 134 | ||
135 | 135 | ||
136 | #ifdef CONFIG_HOTPLUG | ||
137 | |||
136 | /* Manually detach a device from its associated driver. */ | 138 | /* Manually detach a device from its associated driver. */ |
137 | static int driver_helper(struct device *dev, void *data) | 139 | static int driver_helper(struct device *dev, void *data) |
138 | { | 140 | { |
@@ -193,6 +195,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
193 | } | 195 | } |
194 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 196 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); |
195 | 197 | ||
198 | #endif | ||
196 | 199 | ||
197 | static struct device * next_device(struct klist_iter * i) | 200 | static struct device * next_device(struct klist_iter * i) |
198 | { | 201 | { |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index d1a05224627e..105a0d61eb1f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -303,7 +303,7 @@ static int block_size_init(void) | |||
303 | */ | 303 | */ |
304 | #ifdef CONFIG_ARCH_MEMORY_PROBE | 304 | #ifdef CONFIG_ARCH_MEMORY_PROBE |
305 | static ssize_t | 305 | static ssize_t |
306 | memory_probe_store(struct class *class, const char __user *buf, size_t count) | 306 | memory_probe_store(struct class *class, const char *buf, size_t count) |
307 | { | 307 | { |
308 | u64 phys_addr; | 308 | u64 phys_addr; |
309 | int ret; | 309 | int ret; |
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/cdrom/viocd.c b/drivers/cdrom/viocd.c index 193446e6a08a..e27617259552 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -42,8 +42,6 @@ | |||
42 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
44 | 44 | ||
45 | #include <asm/bug.h> | ||
46 | |||
47 | #include <asm/vio.h> | 45 | #include <asm/vio.h> |
48 | #include <asm/scatterlist.h> | 46 | #include <asm/scatterlist.h> |
49 | #include <asm/iseries/hv_types.h> | 47 | #include <asm/iseries/hv_types.h> |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4c67727d75b1..05ba410682a3 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -222,7 +222,7 @@ config SYNCLINKMP | |||
222 | 222 | ||
223 | config SYNCLINK_GT | 223 | config SYNCLINK_GT |
224 | tristate "SyncLink GT/AC support" | 224 | tristate "SyncLink GT/AC support" |
225 | depends on SERIAL_NONSTANDARD | 225 | depends on SERIAL_NONSTANDARD && PCI |
226 | help | 226 | help |
227 | Support for SyncLink GT and SyncLink AC families of | 227 | Support for SyncLink GT and SyncLink AC families of |
228 | synchronous and asynchronous serial adapters | 228 | synchronous and asynchronous serial adapters |
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/char/ser_a2232.c b/drivers/char/ser_a2232.c index 80a5b840e22f..fee68cc895f8 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -103,6 +103,7 @@ | |||
103 | 103 | ||
104 | #include <linux/serial.h> | 104 | #include <linux/serial.h> |
105 | #include <linux/generic_serial.h> | 105 | #include <linux/generic_serial.h> |
106 | #include <linux/tty_flip.h> | ||
106 | 107 | ||
107 | #include "ser_a2232.h" | 108 | #include "ser_a2232.h" |
108 | #include "ser_a2232fw.h" | 109 | #include "ser_a2232fw.h" |
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c index 7a4dfb95d087..837b1ec3ffe3 100644 --- a/drivers/char/watchdog/sbc_epx_c3.c +++ b/drivers/char/watchdog/sbc_epx_c3.c | |||
@@ -92,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static ssize_t epx_c3_write(struct file *file, const char *data, | 95 | static ssize_t epx_c3_write(struct file *file, const char __user *data, |
96 | size_t len, loff_t *ppos) | 96 | size_t len, loff_t *ppos) |
97 | { | 97 | { |
98 | /* Refresh the timer. */ | 98 | /* Refresh the timer. */ |
@@ -105,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
105 | unsigned int cmd, unsigned long arg) | 105 | unsigned int cmd, unsigned long arg) |
106 | { | 106 | { |
107 | int options, retval = -EINVAL; | 107 | int options, retval = -EINVAL; |
108 | int __user *argp = (void __user *)arg; | ||
108 | static struct watchdog_info ident = { | 109 | static struct watchdog_info ident = { |
109 | .options = WDIOF_KEEPALIVEPING | | 110 | .options = WDIOF_KEEPALIVEPING | |
110 | WDIOF_MAGICCLOSE, | 111 | WDIOF_MAGICCLOSE, |
@@ -114,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
114 | 115 | ||
115 | switch (cmd) { | 116 | switch (cmd) { |
116 | case WDIOC_GETSUPPORT: | 117 | case WDIOC_GETSUPPORT: |
117 | if (copy_to_user((struct watchdog_info *)arg, | 118 | if (copy_to_user(argp, &ident, sizeof(ident))) |
118 | &ident, sizeof(ident))) | ||
119 | return -EFAULT; | 119 | return -EFAULT; |
120 | return 0; | 120 | return 0; |
121 | case WDIOC_GETSTATUS: | 121 | case WDIOC_GETSTATUS: |
122 | case WDIOC_GETBOOTSTATUS: | 122 | case WDIOC_GETBOOTSTATUS: |
123 | return put_user(0,(int *)arg); | 123 | return put_user(0, argp); |
124 | case WDIOC_KEEPALIVE: | 124 | case WDIOC_KEEPALIVE: |
125 | epx_c3_pet(); | 125 | epx_c3_pet(); |
126 | return 0; | 126 | return 0; |
127 | case WDIOC_GETTIMEOUT: | 127 | case WDIOC_GETTIMEOUT: |
128 | return put_user(WATCHDOG_TIMEOUT,(int *)arg); | 128 | return put_user(WATCHDOG_TIMEOUT, argp); |
129 | case WDIOC_SETOPTIONS: { | 129 | case WDIOC_SETOPTIONS: |
130 | if (get_user(options, (int *)arg)) | 130 | if (get_user(options, argp)) |
131 | return -EFAULT; | 131 | return -EFAULT; |
132 | 132 | ||
133 | if (options & WDIOS_DISABLECARD) { | 133 | if (options & WDIOS_DISABLECARD) { |
@@ -141,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
141 | } | 141 | } |
142 | 142 | ||
143 | return retval; | 143 | return retval; |
144 | } | ||
145 | default: | 144 | default: |
146 | return -ENOIOCTLCMD; | 145 | return -ENOIOCTLCMD; |
147 | } | 146 | } |
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 009c08fe5d69..1991f94af753 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c | |||
@@ -159,7 +159,7 @@ enum i82875p_chips { | |||
159 | 159 | ||
160 | struct i82875p_pvt { | 160 | struct i82875p_pvt { |
161 | struct pci_dev *ovrfl_pdev; | 161 | struct pci_dev *ovrfl_pdev; |
162 | void *ovrfl_window; | 162 | void __iomem *ovrfl_window; |
163 | }; | 163 | }; |
164 | 164 | ||
165 | 165 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c58295914365..7230d4e08196 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -113,6 +113,16 @@ config SENSORS_DS1621 | |||
113 | This driver can also be built as a module. If so, the module | 113 | This driver can also be built as a module. If so, the module |
114 | will be called ds1621. | 114 | will be called ds1621. |
115 | 115 | ||
116 | config SENSORS_F71805F | ||
117 | tristate "Fintek F71805F/FG" | ||
118 | depends on HWMON && EXPERIMENTAL | ||
119 | help | ||
120 | If you say yes here you get support for hardware monitoring | ||
121 | features of the Fintek F71805F/FG chips. | ||
122 | |||
123 | This driver can also be built as a module. If so, the module | ||
124 | will be called f71805f. | ||
125 | |||
116 | config SENSORS_FSCHER | 126 | config SENSORS_FSCHER |
117 | tristate "FSC Hermes" | 127 | tristate "FSC Hermes" |
118 | depends on HWMON && I2C && EXPERIMENTAL | 128 | depends on HWMON && I2C && EXPERIMENTAL |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 06d4a1d14105..fbdb8d911a72 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | |||
18 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 18 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
19 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 19 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
20 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 20 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
21 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | ||
21 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | 22 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o |
22 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | 23 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o |
23 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 24 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c new file mode 100644 index 000000000000..e029e0a94ecc --- /dev/null +++ b/drivers/hwmon/f71805f.c | |||
@@ -0,0 +1,908 @@ | |||
1 | /* | ||
2 | * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated | ||
3 | * hardware monitoring features | ||
4 | * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | ||
5 | * | ||
6 | * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates | ||
7 | * complete hardware monitoring features: voltage, fan and temperature | ||
8 | * sensors, and manual and automatic fan speed control. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/hwmon.h> | ||
31 | #include <linux/hwmon-sysfs.h> | ||
32 | #include <linux/err.h> | ||
33 | #include <asm/io.h> | ||
34 | |||
35 | static struct platform_device *pdev; | ||
36 | |||
37 | #define DRVNAME "f71805f" | ||
38 | |||
39 | /* | ||
40 | * Super-I/O constants and functions | ||
41 | */ | ||
42 | |||
43 | #define F71805F_LD_HWM 0x04 | ||
44 | |||
45 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
46 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | ||
47 | #define SIO_REG_DEVREV 0x22 /* Device revision */ | ||
48 | #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ | ||
49 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
50 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | ||
51 | |||
52 | #define SIO_FINTEK_ID 0x1934 | ||
53 | #define SIO_F71805F_ID 0x0406 | ||
54 | |||
55 | static inline int | ||
56 | superio_inb(int base, int reg) | ||
57 | { | ||
58 | outb(reg, base); | ||
59 | return inb(base + 1); | ||
60 | } | ||
61 | |||
62 | static int | ||
63 | superio_inw(int base, int reg) | ||
64 | { | ||
65 | int val; | ||
66 | outb(reg++, base); | ||
67 | val = inb(base + 1) << 8; | ||
68 | outb(reg, base); | ||
69 | val |= inb(base + 1); | ||
70 | return val; | ||
71 | } | ||
72 | |||
73 | static inline void | ||
74 | superio_select(int base, int ld) | ||
75 | { | ||
76 | outb(SIO_REG_LDSEL, base); | ||
77 | outb(ld, base + 1); | ||
78 | } | ||
79 | |||
80 | static inline void | ||
81 | superio_enter(int base) | ||
82 | { | ||
83 | outb(0x87, base); | ||
84 | outb(0x87, base); | ||
85 | } | ||
86 | |||
87 | static inline void | ||
88 | superio_exit(int base) | ||
89 | { | ||
90 | outb(0xaa, base); | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * ISA constants | ||
95 | */ | ||
96 | |||
97 | #define REGION_LENGTH 2 | ||
98 | #define ADDR_REG_OFFSET 0 | ||
99 | #define DATA_REG_OFFSET 1 | ||
100 | |||
101 | static struct resource f71805f_resource __initdata = { | ||
102 | .flags = IORESOURCE_IO, | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * Registers | ||
107 | */ | ||
108 | |||
109 | /* in nr from 0 to 8 (8-bit values) */ | ||
110 | #define F71805F_REG_IN(nr) (0x10 + (nr)) | ||
111 | #define F71805F_REG_IN_HIGH(nr) (0x40 + 2 * (nr)) | ||
112 | #define F71805F_REG_IN_LOW(nr) (0x41 + 2 * (nr)) | ||
113 | /* fan nr from 0 to 2 (12-bit values, two registers) */ | ||
114 | #define F71805F_REG_FAN(nr) (0x20 + 2 * (nr)) | ||
115 | #define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr)) | ||
116 | #define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr)) | ||
117 | /* temp nr from 0 to 2 (8-bit values) */ | ||
118 | #define F71805F_REG_TEMP(nr) (0x1B + (nr)) | ||
119 | #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) | ||
120 | #define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) | ||
121 | #define F71805F_REG_TEMP_MODE 0x01 | ||
122 | |||
123 | #define F71805F_REG_START 0x00 | ||
124 | /* status nr from 0 to 2 */ | ||
125 | #define F71805F_REG_STATUS(nr) (0x36 + (nr)) | ||
126 | |||
127 | /* | ||
128 | * Data structures and manipulation thereof | ||
129 | */ | ||
130 | |||
131 | struct f71805f_data { | ||
132 | unsigned short addr; | ||
133 | const char *name; | ||
134 | struct semaphore lock; | ||
135 | struct class_device *class_dev; | ||
136 | |||
137 | struct semaphore update_lock; | ||
138 | char valid; /* !=0 if following fields are valid */ | ||
139 | unsigned long last_updated; /* In jiffies */ | ||
140 | unsigned long last_limits; /* In jiffies */ | ||
141 | |||
142 | /* Register values */ | ||
143 | u8 in[9]; | ||
144 | u8 in_high[9]; | ||
145 | u8 in_low[9]; | ||
146 | u16 fan[3]; | ||
147 | u16 fan_low[3]; | ||
148 | u8 fan_enabled; /* Read once at init time */ | ||
149 | u8 temp[3]; | ||
150 | u8 temp_high[3]; | ||
151 | u8 temp_hyst[3]; | ||
152 | u8 temp_mode; | ||
153 | u8 alarms[3]; | ||
154 | }; | ||
155 | |||
156 | static inline long in_from_reg(u8 reg) | ||
157 | { | ||
158 | return (reg * 8); | ||
159 | } | ||
160 | |||
161 | /* The 2 least significant bits are not used */ | ||
162 | static inline u8 in_to_reg(long val) | ||
163 | { | ||
164 | if (val <= 0) | ||
165 | return 0; | ||
166 | if (val >= 2016) | ||
167 | return 0xfc; | ||
168 | return (((val + 16) / 32) << 2); | ||
169 | } | ||
170 | |||
171 | /* in0 is downscaled by a factor 2 internally */ | ||
172 | static inline long in0_from_reg(u8 reg) | ||
173 | { | ||
174 | return (reg * 16); | ||
175 | } | ||
176 | |||
177 | static inline u8 in0_to_reg(long val) | ||
178 | { | ||
179 | if (val <= 0) | ||
180 | return 0; | ||
181 | if (val >= 4032) | ||
182 | return 0xfc; | ||
183 | return (((val + 32) / 64) << 2); | ||
184 | } | ||
185 | |||
186 | /* The 4 most significant bits are not used */ | ||
187 | static inline long fan_from_reg(u16 reg) | ||
188 | { | ||
189 | reg &= 0xfff; | ||
190 | if (!reg || reg == 0xfff) | ||
191 | return 0; | ||
192 | return (1500000 / reg); | ||
193 | } | ||
194 | |||
195 | static inline u16 fan_to_reg(long rpm) | ||
196 | { | ||
197 | /* If the low limit is set below what the chip can measure, | ||
198 | store the largest possible 12-bit value in the registers, | ||
199 | so that no alarm will ever trigger. */ | ||
200 | if (rpm < 367) | ||
201 | return 0xfff; | ||
202 | return (1500000 / rpm); | ||
203 | } | ||
204 | |||
205 | static inline long temp_from_reg(u8 reg) | ||
206 | { | ||
207 | return (reg * 1000); | ||
208 | } | ||
209 | |||
210 | static inline u8 temp_to_reg(long val) | ||
211 | { | ||
212 | if (val < 0) | ||
213 | val = 0; | ||
214 | else if (val > 1000 * 0xff) | ||
215 | val = 0xff; | ||
216 | return ((val + 500) / 1000); | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Device I/O access | ||
221 | */ | ||
222 | |||
223 | static u8 f71805f_read8(struct f71805f_data *data, u8 reg) | ||
224 | { | ||
225 | u8 val; | ||
226 | |||
227 | down(&data->lock); | ||
228 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
229 | val = inb(data->addr + DATA_REG_OFFSET); | ||
230 | up(&data->lock); | ||
231 | |||
232 | return val; | ||
233 | } | ||
234 | |||
235 | static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) | ||
236 | { | ||
237 | down(&data->lock); | ||
238 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
239 | outb(val, data->addr + DATA_REG_OFFSET); | ||
240 | up(&data->lock); | ||
241 | } | ||
242 | |||
243 | /* It is important to read the MSB first, because doing so latches the | ||
244 | value of the LSB, so we are sure both bytes belong to the same value. */ | ||
245 | static u16 f71805f_read16(struct f71805f_data *data, u8 reg) | ||
246 | { | ||
247 | u16 val; | ||
248 | |||
249 | down(&data->lock); | ||
250 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
251 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | ||
252 | outb(++reg, data->addr + ADDR_REG_OFFSET); | ||
253 | val |= inb(data->addr + DATA_REG_OFFSET); | ||
254 | up(&data->lock); | ||
255 | |||
256 | return val; | ||
257 | } | ||
258 | |||
259 | static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) | ||
260 | { | ||
261 | down(&data->lock); | ||
262 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
263 | outb(val >> 8, data->addr + DATA_REG_OFFSET); | ||
264 | outb(++reg, data->addr + ADDR_REG_OFFSET); | ||
265 | outb(val & 0xff, data->addr + DATA_REG_OFFSET); | ||
266 | up(&data->lock); | ||
267 | } | ||
268 | |||
269 | static struct f71805f_data *f71805f_update_device(struct device *dev) | ||
270 | { | ||
271 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
272 | int nr; | ||
273 | |||
274 | down(&data->update_lock); | ||
275 | |||
276 | /* Limit registers cache is refreshed after 60 seconds */ | ||
277 | if (time_after(jiffies, data->last_updated + 60 * HZ) | ||
278 | || !data->valid) { | ||
279 | for (nr = 0; nr < 9; nr++) { | ||
280 | data->in_high[nr] = f71805f_read8(data, | ||
281 | F71805F_REG_IN_HIGH(nr)); | ||
282 | data->in_low[nr] = f71805f_read8(data, | ||
283 | F71805F_REG_IN_LOW(nr)); | ||
284 | } | ||
285 | for (nr = 0; nr < 3; nr++) { | ||
286 | if (data->fan_enabled & (1 << nr)) | ||
287 | data->fan_low[nr] = f71805f_read16(data, | ||
288 | F71805F_REG_FAN_LOW(nr)); | ||
289 | } | ||
290 | for (nr = 0; nr < 3; nr++) { | ||
291 | data->temp_high[nr] = f71805f_read8(data, | ||
292 | F71805F_REG_TEMP_HIGH(nr)); | ||
293 | data->temp_hyst[nr] = f71805f_read8(data, | ||
294 | F71805F_REG_TEMP_HYST(nr)); | ||
295 | } | ||
296 | data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); | ||
297 | |||
298 | data->last_limits = jiffies; | ||
299 | } | ||
300 | |||
301 | /* Measurement registers cache is refreshed after 1 second */ | ||
302 | if (time_after(jiffies, data->last_updated + HZ) | ||
303 | || !data->valid) { | ||
304 | for (nr = 0; nr < 9; nr++) { | ||
305 | data->in[nr] = f71805f_read8(data, | ||
306 | F71805F_REG_IN(nr)); | ||
307 | } | ||
308 | for (nr = 0; nr < 3; nr++) { | ||
309 | if (data->fan_enabled & (1 << nr)) | ||
310 | data->fan[nr] = f71805f_read16(data, | ||
311 | F71805F_REG_FAN(nr)); | ||
312 | } | ||
313 | for (nr = 0; nr < 3; nr++) { | ||
314 | data->temp[nr] = f71805f_read8(data, | ||
315 | F71805F_REG_TEMP(nr)); | ||
316 | } | ||
317 | for (nr = 0; nr < 3; nr++) { | ||
318 | data->alarms[nr] = f71805f_read8(data, | ||
319 | F71805F_REG_STATUS(nr)); | ||
320 | } | ||
321 | |||
322 | data->last_updated = jiffies; | ||
323 | data->valid = 1; | ||
324 | } | ||
325 | |||
326 | up(&data->update_lock); | ||
327 | |||
328 | return data; | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * Sysfs interface | ||
333 | */ | ||
334 | |||
335 | static ssize_t show_in0(struct device *dev, struct device_attribute *devattr, | ||
336 | char *buf) | ||
337 | { | ||
338 | struct f71805f_data *data = f71805f_update_device(dev); | ||
339 | |||
340 | return sprintf(buf, "%ld\n", in0_from_reg(data->in[0])); | ||
341 | } | ||
342 | |||
343 | static ssize_t show_in0_max(struct device *dev, struct device_attribute | ||
344 | *devattr, char *buf) | ||
345 | { | ||
346 | struct f71805f_data *data = f71805f_update_device(dev); | ||
347 | |||
348 | return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0])); | ||
349 | } | ||
350 | |||
351 | static ssize_t show_in0_min(struct device *dev, struct device_attribute | ||
352 | *devattr, char *buf) | ||
353 | { | ||
354 | struct f71805f_data *data = f71805f_update_device(dev); | ||
355 | |||
356 | return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0])); | ||
357 | } | ||
358 | |||
359 | static ssize_t set_in0_max(struct device *dev, struct device_attribute | ||
360 | *devattr, const char *buf, size_t count) | ||
361 | { | ||
362 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
363 | long val = simple_strtol(buf, NULL, 10); | ||
364 | |||
365 | down(&data->update_lock); | ||
366 | data->in_high[0] = in0_to_reg(val); | ||
367 | f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]); | ||
368 | up(&data->update_lock); | ||
369 | |||
370 | return count; | ||
371 | } | ||
372 | |||
373 | static ssize_t set_in0_min(struct device *dev, struct device_attribute | ||
374 | *devattr, const char *buf, size_t count) | ||
375 | { | ||
376 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
377 | long val = simple_strtol(buf, NULL, 10); | ||
378 | |||
379 | down(&data->update_lock); | ||
380 | data->in_low[0] = in0_to_reg(val); | ||
381 | f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]); | ||
382 | up(&data->update_lock); | ||
383 | |||
384 | return count; | ||
385 | } | ||
386 | |||
387 | static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL); | ||
388 | static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max); | ||
389 | static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min); | ||
390 | |||
391 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | ||
392 | char *buf) | ||
393 | { | ||
394 | struct f71805f_data *data = f71805f_update_device(dev); | ||
395 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
396 | int nr = attr->index; | ||
397 | |||
398 | return sprintf(buf, "%ld\n", in_from_reg(data->in[nr])); | ||
399 | } | ||
400 | |||
401 | static ssize_t show_in_max(struct device *dev, struct device_attribute | ||
402 | *devattr, char *buf) | ||
403 | { | ||
404 | struct f71805f_data *data = f71805f_update_device(dev); | ||
405 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
406 | int nr = attr->index; | ||
407 | |||
408 | return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr])); | ||
409 | } | ||
410 | |||
411 | static ssize_t show_in_min(struct device *dev, struct device_attribute | ||
412 | *devattr, char *buf) | ||
413 | { | ||
414 | struct f71805f_data *data = f71805f_update_device(dev); | ||
415 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
416 | int nr = attr->index; | ||
417 | |||
418 | return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr])); | ||
419 | } | ||
420 | |||
421 | static ssize_t set_in_max(struct device *dev, struct device_attribute | ||
422 | *devattr, const char *buf, size_t count) | ||
423 | { | ||
424 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
425 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
426 | int nr = attr->index; | ||
427 | long val = simple_strtol(buf, NULL, 10); | ||
428 | |||
429 | down(&data->update_lock); | ||
430 | data->in_high[nr] = in_to_reg(val); | ||
431 | f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); | ||
432 | up(&data->update_lock); | ||
433 | |||
434 | return count; | ||
435 | } | ||
436 | |||
437 | static ssize_t set_in_min(struct device *dev, struct device_attribute | ||
438 | *devattr, const char *buf, size_t count) | ||
439 | { | ||
440 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
442 | int nr = attr->index; | ||
443 | long val = simple_strtol(buf, NULL, 10); | ||
444 | |||
445 | down(&data->update_lock); | ||
446 | data->in_low[nr] = in_to_reg(val); | ||
447 | f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); | ||
448 | up(&data->update_lock); | ||
449 | |||
450 | return count; | ||
451 | } | ||
452 | |||
453 | #define sysfs_in(offset) \ | ||
454 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | ||
455 | show_in, NULL, offset); \ | ||
456 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
457 | show_in_max, set_in_max, offset); \ | ||
458 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
459 | show_in_min, set_in_min, offset) | ||
460 | |||
461 | sysfs_in(1); | ||
462 | sysfs_in(2); | ||
463 | sysfs_in(3); | ||
464 | sysfs_in(4); | ||
465 | sysfs_in(5); | ||
466 | sysfs_in(6); | ||
467 | sysfs_in(7); | ||
468 | sysfs_in(8); | ||
469 | |||
470 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
471 | char *buf) | ||
472 | { | ||
473 | struct f71805f_data *data = f71805f_update_device(dev); | ||
474 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
475 | int nr = attr->index; | ||
476 | |||
477 | return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr])); | ||
478 | } | ||
479 | |||
480 | static ssize_t show_fan_min(struct device *dev, struct device_attribute | ||
481 | *devattr, char *buf) | ||
482 | { | ||
483 | struct f71805f_data *data = f71805f_update_device(dev); | ||
484 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
485 | int nr = attr->index; | ||
486 | |||
487 | return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr])); | ||
488 | } | ||
489 | |||
490 | static ssize_t set_fan_min(struct device *dev, struct device_attribute | ||
491 | *devattr, const char *buf, size_t count) | ||
492 | { | ||
493 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
494 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
495 | int nr = attr->index; | ||
496 | long val = simple_strtol(buf, NULL, 10); | ||
497 | |||
498 | down(&data->update_lock); | ||
499 | data->fan_low[nr] = fan_to_reg(val); | ||
500 | f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); | ||
501 | up(&data->update_lock); | ||
502 | |||
503 | return count; | ||
504 | } | ||
505 | |||
506 | #define sysfs_fan(offset) \ | ||
507 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
508 | show_fan, NULL, offset - 1); \ | ||
509 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
510 | show_fan_min, set_fan_min, offset - 1) | ||
511 | |||
512 | sysfs_fan(1); | ||
513 | sysfs_fan(2); | ||
514 | sysfs_fan(3); | ||
515 | |||
516 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
517 | char *buf) | ||
518 | { | ||
519 | struct f71805f_data *data = f71805f_update_device(dev); | ||
520 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
521 | int nr = attr->index; | ||
522 | |||
523 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr])); | ||
524 | } | ||
525 | |||
526 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
527 | *devattr, char *buf) | ||
528 | { | ||
529 | struct f71805f_data *data = f71805f_update_device(dev); | ||
530 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
531 | int nr = attr->index; | ||
532 | |||
533 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr])); | ||
534 | } | ||
535 | |||
536 | static ssize_t show_temp_hyst(struct device *dev, struct device_attribute | ||
537 | *devattr, char *buf) | ||
538 | { | ||
539 | struct f71805f_data *data = f71805f_update_device(dev); | ||
540 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
541 | int nr = attr->index; | ||
542 | |||
543 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr])); | ||
544 | } | ||
545 | |||
546 | static ssize_t show_temp_type(struct device *dev, struct device_attribute | ||
547 | *devattr, char *buf) | ||
548 | { | ||
549 | struct f71805f_data *data = f71805f_update_device(dev); | ||
550 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
551 | int nr = attr->index; | ||
552 | |||
553 | /* 3 is diode, 4 is thermistor */ | ||
554 | return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4); | ||
555 | } | ||
556 | |||
557 | static ssize_t set_temp_max(struct device *dev, struct device_attribute | ||
558 | *devattr, const char *buf, size_t count) | ||
559 | { | ||
560 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
561 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
562 | int nr = attr->index; | ||
563 | long val = simple_strtol(buf, NULL, 10); | ||
564 | |||
565 | down(&data->update_lock); | ||
566 | data->temp_high[nr] = temp_to_reg(val); | ||
567 | f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]); | ||
568 | up(&data->update_lock); | ||
569 | |||
570 | return count; | ||
571 | } | ||
572 | |||
573 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute | ||
574 | *devattr, const char *buf, size_t count) | ||
575 | { | ||
576 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
577 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
578 | int nr = attr->index; | ||
579 | long val = simple_strtol(buf, NULL, 10); | ||
580 | |||
581 | down(&data->update_lock); | ||
582 | data->temp_hyst[nr] = temp_to_reg(val); | ||
583 | f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]); | ||
584 | up(&data->update_lock); | ||
585 | |||
586 | return count; | ||
587 | } | ||
588 | |||
589 | #define sysfs_temp(offset) \ | ||
590 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
591 | show_temp, NULL, offset - 1); \ | ||
592 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
593 | show_temp_max, set_temp_max, offset - 1); \ | ||
594 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ | ||
595 | show_temp_hyst, set_temp_hyst, offset - 1); \ | ||
596 | static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO, \ | ||
597 | show_temp_type, NULL, offset - 1) | ||
598 | |||
599 | sysfs_temp(1); | ||
600 | sysfs_temp(2); | ||
601 | sysfs_temp(3); | ||
602 | |||
603 | static ssize_t show_alarms_in(struct device *dev, struct device_attribute | ||
604 | *devattr, char *buf) | ||
605 | { | ||
606 | struct f71805f_data *data = f71805f_update_device(dev); | ||
607 | |||
608 | return sprintf(buf, "%d\n", data->alarms[0] | | ||
609 | ((data->alarms[1] & 0x01) << 8)); | ||
610 | } | ||
611 | |||
612 | static ssize_t show_alarms_fan(struct device *dev, struct device_attribute | ||
613 | *devattr, char *buf) | ||
614 | { | ||
615 | struct f71805f_data *data = f71805f_update_device(dev); | ||
616 | |||
617 | return sprintf(buf, "%d\n", data->alarms[2] & 0x07); | ||
618 | } | ||
619 | |||
620 | static ssize_t show_alarms_temp(struct device *dev, struct device_attribute | ||
621 | *devattr, char *buf) | ||
622 | { | ||
623 | struct f71805f_data *data = f71805f_update_device(dev); | ||
624 | |||
625 | return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07); | ||
626 | } | ||
627 | |||
628 | static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL); | ||
629 | static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL); | ||
630 | static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL); | ||
631 | |||
632 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
633 | *devattr, char *buf) | ||
634 | { | ||
635 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
636 | |||
637 | return sprintf(buf, "%s\n", data->name); | ||
638 | } | ||
639 | |||
640 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
641 | |||
642 | /* | ||
643 | * Device registration and initialization | ||
644 | */ | ||
645 | |||
646 | static void __devinit f71805f_init_device(struct f71805f_data *data) | ||
647 | { | ||
648 | u8 reg; | ||
649 | int i; | ||
650 | |||
651 | reg = f71805f_read8(data, F71805F_REG_START); | ||
652 | if ((reg & 0x41) != 0x01) { | ||
653 | printk(KERN_DEBUG DRVNAME ": Starting monitoring " | ||
654 | "operations\n"); | ||
655 | f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); | ||
656 | } | ||
657 | |||
658 | /* Fan monitoring can be disabled. If it is, we won't be polling | ||
659 | the register values, and won't create the related sysfs files. */ | ||
660 | for (i = 0; i < 3; i++) { | ||
661 | reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i)); | ||
662 | if (!(reg & 0x80)) | ||
663 | data->fan_enabled |= (1 << i); | ||
664 | } | ||
665 | } | ||
666 | |||
667 | static int __devinit f71805f_probe(struct platform_device *pdev) | ||
668 | { | ||
669 | struct f71805f_data *data; | ||
670 | struct resource *res; | ||
671 | int err; | ||
672 | |||
673 | if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { | ||
674 | err = -ENOMEM; | ||
675 | printk(KERN_ERR DRVNAME ": Out of memory\n"); | ||
676 | goto exit; | ||
677 | } | ||
678 | |||
679 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
680 | data->addr = res->start; | ||
681 | init_MUTEX(&data->lock); | ||
682 | data->name = "f71805f"; | ||
683 | init_MUTEX(&data->update_lock); | ||
684 | |||
685 | platform_set_drvdata(pdev, data); | ||
686 | |||
687 | data->class_dev = hwmon_device_register(&pdev->dev); | ||
688 | if (IS_ERR(data->class_dev)) { | ||
689 | err = PTR_ERR(data->class_dev); | ||
690 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | ||
691 | goto exit_free; | ||
692 | } | ||
693 | |||
694 | /* Initialize the F71805F chip */ | ||
695 | f71805f_init_device(data); | ||
696 | |||
697 | /* Register sysfs interface files */ | ||
698 | device_create_file(&pdev->dev, &dev_attr_in0_input); | ||
699 | device_create_file(&pdev->dev, &dev_attr_in0_max); | ||
700 | device_create_file(&pdev->dev, &dev_attr_in0_min); | ||
701 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr); | ||
702 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr); | ||
703 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr); | ||
704 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr); | ||
705 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr); | ||
706 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr); | ||
707 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr); | ||
708 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr); | ||
709 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr); | ||
710 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr); | ||
711 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr); | ||
712 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr); | ||
713 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr); | ||
714 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr); | ||
715 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr); | ||
716 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr); | ||
717 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr); | ||
718 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr); | ||
719 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr); | ||
720 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr); | ||
721 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr); | ||
722 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr); | ||
723 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr); | ||
724 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr); | ||
725 | if (data->fan_enabled & (1 << 0)) { | ||
726 | device_create_file(&pdev->dev, | ||
727 | &sensor_dev_attr_fan1_input.dev_attr); | ||
728 | device_create_file(&pdev->dev, | ||
729 | &sensor_dev_attr_fan1_min.dev_attr); | ||
730 | } | ||
731 | if (data->fan_enabled & (1 << 1)) { | ||
732 | device_create_file(&pdev->dev, | ||
733 | &sensor_dev_attr_fan2_input.dev_attr); | ||
734 | device_create_file(&pdev->dev, | ||
735 | &sensor_dev_attr_fan2_min.dev_attr); | ||
736 | } | ||
737 | if (data->fan_enabled & (1 << 2)) { | ||
738 | device_create_file(&pdev->dev, | ||
739 | &sensor_dev_attr_fan3_input.dev_attr); | ||
740 | device_create_file(&pdev->dev, | ||
741 | &sensor_dev_attr_fan3_min.dev_attr); | ||
742 | } | ||
743 | device_create_file(&pdev->dev, | ||
744 | &sensor_dev_attr_temp1_input.dev_attr); | ||
745 | device_create_file(&pdev->dev, | ||
746 | &sensor_dev_attr_temp2_input.dev_attr); | ||
747 | device_create_file(&pdev->dev, | ||
748 | &sensor_dev_attr_temp3_input.dev_attr); | ||
749 | device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
750 | device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr); | ||
751 | device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr); | ||
752 | device_create_file(&pdev->dev, | ||
753 | &sensor_dev_attr_temp1_max_hyst.dev_attr); | ||
754 | device_create_file(&pdev->dev, | ||
755 | &sensor_dev_attr_temp2_max_hyst.dev_attr); | ||
756 | device_create_file(&pdev->dev, | ||
757 | &sensor_dev_attr_temp3_max_hyst.dev_attr); | ||
758 | device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr); | ||
759 | device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr); | ||
760 | device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr); | ||
761 | device_create_file(&pdev->dev, &dev_attr_alarms_in); | ||
762 | device_create_file(&pdev->dev, &dev_attr_alarms_fan); | ||
763 | device_create_file(&pdev->dev, &dev_attr_alarms_temp); | ||
764 | device_create_file(&pdev->dev, &dev_attr_name); | ||
765 | |||
766 | return 0; | ||
767 | |||
768 | exit_free: | ||
769 | kfree(data); | ||
770 | exit: | ||
771 | return err; | ||
772 | } | ||
773 | |||
774 | static int __devexit f71805f_remove(struct platform_device *pdev) | ||
775 | { | ||
776 | struct f71805f_data *data = platform_get_drvdata(pdev); | ||
777 | |||
778 | platform_set_drvdata(pdev, NULL); | ||
779 | hwmon_device_unregister(data->class_dev); | ||
780 | kfree(data); | ||
781 | |||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static struct platform_driver f71805f_driver = { | ||
786 | .driver = { | ||
787 | .owner = THIS_MODULE, | ||
788 | .name = DRVNAME, | ||
789 | }, | ||
790 | .probe = f71805f_probe, | ||
791 | .remove = __devexit_p(f71805f_remove), | ||
792 | }; | ||
793 | |||
794 | static int __init f71805f_device_add(unsigned short address) | ||
795 | { | ||
796 | int err; | ||
797 | |||
798 | pdev = platform_device_alloc(DRVNAME, address); | ||
799 | if (!pdev) { | ||
800 | err = -ENOMEM; | ||
801 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
802 | goto exit; | ||
803 | } | ||
804 | |||
805 | f71805f_resource.start = address; | ||
806 | f71805f_resource.end = address + REGION_LENGTH - 1; | ||
807 | f71805f_resource.name = pdev->name; | ||
808 | err = platform_device_add_resources(pdev, &f71805f_resource, 1); | ||
809 | if (err) { | ||
810 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
811 | "(%d)\n", err); | ||
812 | goto exit_device_put; | ||
813 | } | ||
814 | |||
815 | err = platform_device_add(pdev); | ||
816 | if (err) { | ||
817 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
818 | err); | ||
819 | goto exit_device_put; | ||
820 | } | ||
821 | |||
822 | return 0; | ||
823 | |||
824 | exit_device_put: | ||
825 | platform_device_put(pdev); | ||
826 | exit: | ||
827 | return err; | ||
828 | } | ||
829 | |||
830 | static int __init f71805f_find(int sioaddr, unsigned short *address) | ||
831 | { | ||
832 | int err = -ENODEV; | ||
833 | u16 devid; | ||
834 | |||
835 | superio_enter(sioaddr); | ||
836 | |||
837 | devid = superio_inw(sioaddr, SIO_REG_MANID); | ||
838 | if (devid != SIO_FINTEK_ID) | ||
839 | goto exit; | ||
840 | |||
841 | devid = superio_inw(sioaddr, SIO_REG_DEVID); | ||
842 | if (devid != SIO_F71805F_ID) { | ||
843 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " | ||
844 | "skipping\n"); | ||
845 | goto exit; | ||
846 | } | ||
847 | |||
848 | superio_select(sioaddr, F71805F_LD_HWM); | ||
849 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | ||
850 | printk(KERN_WARNING DRVNAME ": Device not activated, " | ||
851 | "skipping\n"); | ||
852 | goto exit; | ||
853 | } | ||
854 | |||
855 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | ||
856 | if (*address == 0) { | ||
857 | printk(KERN_WARNING DRVNAME ": Base address not set, " | ||
858 | "skipping\n"); | ||
859 | goto exit; | ||
860 | } | ||
861 | |||
862 | err = 0; | ||
863 | printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n", | ||
864 | *address, superio_inb(sioaddr, SIO_REG_DEVREV)); | ||
865 | |||
866 | exit: | ||
867 | superio_exit(sioaddr); | ||
868 | return err; | ||
869 | } | ||
870 | |||
871 | static int __init f71805f_init(void) | ||
872 | { | ||
873 | int err; | ||
874 | unsigned short address; | ||
875 | |||
876 | if (f71805f_find(0x2e, &address) | ||
877 | && f71805f_find(0x4e, &address)) | ||
878 | return -ENODEV; | ||
879 | |||
880 | err = platform_driver_register(&f71805f_driver); | ||
881 | if (err) | ||
882 | goto exit; | ||
883 | |||
884 | /* Sets global pdev as a side effect */ | ||
885 | err = f71805f_device_add(address); | ||
886 | if (err) | ||
887 | goto exit_driver; | ||
888 | |||
889 | return 0; | ||
890 | |||
891 | exit_driver: | ||
892 | platform_driver_unregister(&f71805f_driver); | ||
893 | exit: | ||
894 | return err; | ||
895 | } | ||
896 | |||
897 | static void __exit f71805f_exit(void) | ||
898 | { | ||
899 | platform_device_unregister(pdev); | ||
900 | platform_driver_unregister(&f71805f_driver); | ||
901 | } | ||
902 | |||
903 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr>"); | ||
904 | MODULE_LICENSE("GPL"); | ||
905 | MODULE_DESCRIPTION("F71805F hardware monitoring driver"); | ||
906 | |||
907 | module_init(f71805f_init); | ||
908 | module_exit(f71805f_exit); | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 0da7c9c508c3..e87d52c59940 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -45,8 +45,7 @@ | |||
45 | 45 | ||
46 | 46 | ||
47 | /* Addresses to scan */ | 47 | /* Addresses to scan */ |
48 | static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, | 48 | static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; |
49 | 0x2e, 0x2f, I2C_CLIENT_END }; | ||
50 | static unsigned short isa_address; | 49 | static unsigned short isa_address; |
51 | 50 | ||
52 | /* Insmod parameters */ | 51 | /* Insmod parameters */ |
@@ -830,6 +829,11 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
830 | if ((err = i2c_attach_client(new_client))) | 829 | if ((err = i2c_attach_client(new_client))) |
831 | goto ERROR2; | 830 | goto ERROR2; |
832 | 831 | ||
832 | if (!is_isa) | ||
833 | dev_info(&new_client->dev, "The I2C interface to IT87xxF " | ||
834 | "hardware monitoring chips is deprecated. Please " | ||
835 | "report if you still rely on it.\n"); | ||
836 | |||
833 | /* Check PWM configuration */ | 837 | /* Check PWM configuration */ |
834 | enable_pwm_interface = it87_check_pwm(new_client); | 838 | enable_pwm_interface = it87_check_pwm(new_client); |
835 | 839 | ||
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index a2f420d01fb7..df9e02aaa70a 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -87,15 +87,15 @@ static struct i2c_driver lm77_driver = { | |||
87 | 87 | ||
88 | /* In the temperature registers, the low 3 bits are not part of the | 88 | /* In the temperature registers, the low 3 bits are not part of the |
89 | temperature values; they are the status bits. */ | 89 | temperature values; they are the status bits. */ |
90 | static inline u16 LM77_TEMP_TO_REG(int temp) | 90 | static inline s16 LM77_TEMP_TO_REG(int temp) |
91 | { | 91 | { |
92 | int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); | 92 | int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); |
93 | return (u16)((ntemp / 500) * 8); | 93 | return (ntemp / 500) * 8; |
94 | } | 94 | } |
95 | 95 | ||
96 | static inline int LM77_TEMP_FROM_REG(u16 reg) | 96 | static inline int LM77_TEMP_FROM_REG(s16 reg) |
97 | { | 97 | { |
98 | return ((int)reg / 8) * 500; | 98 | return (reg / 8) * 500; |
99 | } | 99 | } |
100 | 100 | ||
101 | /* sysfs stuff */ | 101 | /* sysfs stuff */ |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index b176bf0c4c7b..a2f6bb676235 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -303,10 +303,6 @@ struct w83792d_data { | |||
303 | static int w83792d_attach_adapter(struct i2c_adapter *adapter); | 303 | static int w83792d_attach_adapter(struct i2c_adapter *adapter); |
304 | static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); | 304 | static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); |
305 | static int w83792d_detach_client(struct i2c_client *client); | 305 | static int w83792d_detach_client(struct i2c_client *client); |
306 | |||
307 | static int w83792d_read_value(struct i2c_client *client, u8 register); | ||
308 | static int w83792d_write_value(struct i2c_client *client, u8 register, | ||
309 | u8 value); | ||
310 | static struct w83792d_data *w83792d_update_device(struct device *dev); | 306 | static struct w83792d_data *w83792d_update_device(struct device *dev); |
311 | 307 | ||
312 | #ifdef DEBUG | 308 | #ifdef DEBUG |
@@ -329,6 +325,20 @@ static inline long in_count_from_reg(int nr, struct w83792d_data *data) | |||
329 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); | 325 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); |
330 | } | 326 | } |
331 | 327 | ||
328 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, | ||
329 | but the driver only accesses registers in bank 0, so we don't have | ||
330 | to switch banks and lock access between switches. */ | ||
331 | static inline int w83792d_read_value(struct i2c_client *client, u8 reg) | ||
332 | { | ||
333 | return i2c_smbus_read_byte_data(client, reg); | ||
334 | } | ||
335 | |||
336 | static inline int | ||
337 | w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
338 | { | ||
339 | return i2c_smbus_write_byte_data(client, reg, value); | ||
340 | } | ||
341 | |||
332 | /* following are the sysfs callback functions */ | 342 | /* following are the sysfs callback functions */ |
333 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | 343 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
334 | char *buf) | 344 | char *buf) |
@@ -1386,19 +1396,6 @@ w83792d_detach_client(struct i2c_client *client) | |||
1386 | return 0; | 1396 | return 0; |
1387 | } | 1397 | } |
1388 | 1398 | ||
1389 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, | ||
1390 | but the driver only accesses registers in bank 0, so we don't have | ||
1391 | to switch banks and lock access between switches. */ | ||
1392 | static int w83792d_read_value(struct i2c_client *client, u8 reg) | ||
1393 | { | ||
1394 | return i2c_smbus_read_byte_data(client, reg); | ||
1395 | } | ||
1396 | |||
1397 | static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
1398 | { | ||
1399 | return i2c_smbus_write_byte_data(client, reg, value); | ||
1400 | } | ||
1401 | |||
1402 | static void | 1399 | static void |
1403 | w83792d_init_client(struct i2c_client *client) | 1400 | w83792d_init_client(struct i2c_client *client) |
1404 | { | 1401 | { |
diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index 938848ae162d..3df3f09995c2 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c | |||
@@ -202,7 +202,7 @@ EXPORT_SYMBOL(i2c_sibyte_del_bus); | |||
202 | #ifdef MODULE | 202 | #ifdef MODULE |
203 | MODULE_AUTHOR("Kip Walker, Broadcom Corp."); | 203 | MODULE_AUTHOR("Kip Walker, Broadcom Corp."); |
204 | MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); | 204 | MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); |
205 | MODULE_PARM(bit_scan, "i"); | 205 | module_param(bit_scan, int, 0); |
206 | MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); | 206 | MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); |
207 | MODULE_LICENSE("GPL"); | 207 | MODULE_LICENSE("GPL"); |
208 | 208 | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 08d5b8fed2dc..ff92735c7c85 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -124,6 +124,7 @@ config I2C_I801 | |||
124 | ICH6 | 124 | ICH6 |
125 | ICH7 | 125 | ICH7 |
126 | ESB2 | 126 | ESB2 |
127 | ICH8 | ||
127 | 128 | ||
128 | This driver can also be built as a module. If so, the module | 129 | This driver can also be built as a module. If so, the module |
129 | will be called i2c-i801. | 130 | will be called i2c-i801. |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 1c752ddc10e2..8e0f3158215f 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -32,6 +32,7 @@ | |||
32 | ICH6 266A | 32 | ICH6 266A |
33 | ICH7 27DA | 33 | ICH7 27DA |
34 | ESB2 269B | 34 | ESB2 269B |
35 | ICH8 283E | ||
35 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). | 36 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). |
36 | For SMBus support, they are similar to the PIIX4 and are part | 37 | For SMBus support, they are similar to the PIIX4 and are part |
37 | of Intel's '810' and other chipsets. | 38 | of Intel's '810' and other chipsets. |
@@ -527,6 +528,7 @@ static struct pci_device_id i801_ids[] = { | |||
527 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, | 528 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, |
528 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, | 529 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, |
529 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, | 530 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, |
531 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, | ||
530 | { 0, } | 532 | { 0, } |
531 | }; | 533 | }; |
532 | 534 | ||
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index 3e5eba9fcacb..c63025a4c861 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c | |||
@@ -121,14 +121,11 @@ static struct i2c_adapter parport_adapter = { | |||
121 | 121 | ||
122 | static int __init i2c_parport_init(void) | 122 | static int __init i2c_parport_init(void) |
123 | { | 123 | { |
124 | int type_count; | 124 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { |
125 | |||
126 | type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); | ||
127 | if (type < 0 || type >= type_count) { | ||
128 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 125 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
129 | type = 0; | 126 | type = 0; |
130 | } | 127 | } |
131 | 128 | ||
132 | if (base == 0) { | 129 | if (base == 0) { |
133 | printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); | 130 | printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); |
134 | base = DEFAULT_BASE; | 131 | base = DEFAULT_BASE; |
@@ -152,7 +149,7 @@ static int __init i2c_parport_init(void) | |||
152 | release_region(base, 3); | 149 | release_region(base, 3); |
153 | return -ENODEV; | 150 | return -ENODEV; |
154 | } | 151 | } |
155 | 152 | ||
156 | return 0; | 153 | return 0; |
157 | } | 154 | } |
158 | 155 | ||
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 2854d858fc9b..7e2e8cd1c14a 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
@@ -241,14 +241,11 @@ static struct parport_driver i2c_parport_driver = { | |||
241 | 241 | ||
242 | static int __init i2c_parport_init(void) | 242 | static int __init i2c_parport_init(void) |
243 | { | 243 | { |
244 | int type_count; | 244 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { |
245 | |||
246 | type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); | ||
247 | if (type < 0 || type >= type_count) { | ||
248 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 245 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
249 | type = 0; | 246 | type = 0; |
250 | } | 247 | } |
251 | 248 | ||
252 | return parport_register_driver(&i2c_parport_driver); | 249 | return parport_register_driver(&i2c_parport_driver); |
253 | } | 250 | } |
254 | 251 | ||
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 86e2234faf80..7579f4b256a8 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -861,7 +861,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *r | |||
861 | decode_ISR(isr); | 861 | decode_ISR(isr); |
862 | } | 862 | } |
863 | 863 | ||
864 | if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32)) | 864 | if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog)) |
865 | i2c->isrlog[i2c->irqlogidx++] = isr; | 865 | i2c->isrlog[i2c->irqlogidx++] = isr; |
866 | 866 | ||
867 | show_state(i2c); | 867 | show_state(i2c); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0ce58b506046..1a2c9ab5d9e3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -946,6 +946,20 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val | |||
946 | } | 946 | } |
947 | } | 947 | } |
948 | 948 | ||
949 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, | ||
950 | u8 length, u8 *values) | ||
951 | { | ||
952 | union i2c_smbus_data data; | ||
953 | |||
954 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
955 | length = I2C_SMBUS_BLOCK_MAX; | ||
956 | data.block[0] = length; | ||
957 | memcpy(data.block + 1, values, length); | ||
958 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
959 | I2C_SMBUS_WRITE, command, | ||
960 | I2C_SMBUS_I2C_BLOCK_DATA, &data); | ||
961 | } | ||
962 | |||
949 | /* Simulate a SMBus command using the i2c protocol | 963 | /* Simulate a SMBus command using the i2c protocol |
950 | No checking of parameters is done! */ | 964 | No checking of parameters is done! */ |
951 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, | 965 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, |
@@ -1150,6 +1164,7 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data); | |||
1150 | EXPORT_SYMBOL(i2c_smbus_write_word_data); | 1164 | EXPORT_SYMBOL(i2c_smbus_write_word_data); |
1151 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | 1165 | EXPORT_SYMBOL(i2c_smbus_write_block_data); |
1152 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | 1166 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); |
1167 | EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); | ||
1153 | 1168 | ||
1154 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); | 1169 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); |
1155 | MODULE_DESCRIPTION("I2C-Bus main module"); | 1170 | MODULE_DESCRIPTION("I2C-Bus main module"); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 6c60a9d2afd8..09086b8b6486 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -190,7 +190,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
190 | if (lba48) { | 190 | if (lba48) { |
191 | task_ioreg_t tasklets[10]; | 191 | task_ioreg_t tasklets[10]; |
192 | 192 | ||
193 | pr_debug("%s: LBA=0x%012llx\n", drive->name, block); | 193 | pr_debug("%s: LBA=0x%012llx\n", drive->name, |
194 | (unsigned long long)block); | ||
194 | 195 | ||
195 | tasklets[0] = 0; | 196 | tasklets[0] = 0; |
196 | tasklets[1] = 0; | 197 | tasklets[1] = 0; |
@@ -317,7 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s | |||
317 | 318 | ||
318 | pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", | 319 | pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", |
319 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", | 320 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", |
320 | block, rq->nr_sectors, (unsigned long)rq->buffer); | 321 | (unsigned long long)block, rq->nr_sectors, |
322 | (unsigned long)rq->buffer); | ||
321 | 323 | ||
322 | if (hwif->rw_disk) | 324 | if (hwif->rw_disk) |
323 | hwif->rw_disk(drive, rq); | 325 | hwif->rw_disk(drive, rq); |
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/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 0ef560144be3..6dfc94122dd9 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig | |||
@@ -351,7 +351,7 @@ config HISAX_ENTERNOW_PCI | |||
351 | 351 | ||
352 | config HISAX_AMD7930 | 352 | config HISAX_AMD7930 |
353 | bool "Am7930 (EXPERIMENTAL)" | 353 | bool "Am7930 (EXPERIMENTAL)" |
354 | depends on EXPERIMENTAL && SPARC | 354 | depends on EXPERIMENTAL && SPARC && BROKEN |
355 | help | 355 | help |
356 | This enables HiSax support for the AMD7930 chips on some SPARCs. | 356 | This enables HiSax support for the AMD7930 chips on some SPARCs. |
357 | This code is not finished yet. | 357 | This code is not finished yet. |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 7d4a0ac28c06..12ad462737ba 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -187,6 +187,14 @@ config WINDFARM_PM91 | |||
187 | This driver provides thermal control for the PowerMac9,1 | 187 | This driver provides thermal control for the PowerMac9,1 |
188 | which is the recent (SMU based) single CPU desktop G5 | 188 | which is the recent (SMU based) single CPU desktop G5 |
189 | 189 | ||
190 | config WINDFARM_PM112 | ||
191 | tristate "Support for thermal management on PowerMac11,2" | ||
192 | depends on WINDFARM && I2C && PMAC_SMU | ||
193 | select I2C_POWERMAC | ||
194 | help | ||
195 | This driver provides thermal control for the PowerMac11,2 | ||
196 | which are the recent dual and quad G5 machines using the | ||
197 | 970MP dual-core processor. | ||
190 | 198 | ||
191 | config ANSLCD | 199 | config ANSLCD |
192 | tristate "Support for ANS LCD display" | 200 | tristate "Support for ANS LCD display" |
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index f4657aa81fb0..6081acdea404 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile | |||
@@ -35,3 +35,8 @@ obj-$(CONFIG_WINDFARM_PM91) += windfarm_smu_controls.o \ | |||
35 | windfarm_smu_sensors.o \ | 35 | windfarm_smu_sensors.o \ |
36 | windfarm_lm75_sensor.o windfarm_pid.o \ | 36 | windfarm_lm75_sensor.o windfarm_pid.o \ |
37 | windfarm_cpufreq_clamp.o windfarm_pm91.o | 37 | windfarm_cpufreq_clamp.o windfarm_pm91.o |
38 | obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \ | ||
39 | windfarm_smu_controls.o \ | ||
40 | windfarm_smu_sensors.o \ | ||
41 | windfarm_max6690_sensor.o \ | ||
42 | windfarm_lm75_sensor.o windfarm_pid.o | ||
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h index 3f0cb0312ea3..7a2482cc26a7 100644 --- a/drivers/macintosh/windfarm.h +++ b/drivers/macintosh/windfarm.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/notifier.h> | 16 | #include <linux/notifier.h> |
17 | #include <linux/device.h> | ||
17 | 18 | ||
18 | /* Display a 16.16 fixed point value */ | 19 | /* Display a 16.16 fixed point value */ |
19 | #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) | 20 | #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) |
@@ -39,6 +40,7 @@ struct wf_control { | |||
39 | char *name; | 40 | char *name; |
40 | int type; | 41 | int type; |
41 | struct kref ref; | 42 | struct kref ref; |
43 | struct device_attribute attr; | ||
42 | }; | 44 | }; |
43 | 45 | ||
44 | #define WF_CONTROL_TYPE_GENERIC 0 | 46 | #define WF_CONTROL_TYPE_GENERIC 0 |
@@ -87,6 +89,7 @@ struct wf_sensor { | |||
87 | struct wf_sensor_ops *ops; | 89 | struct wf_sensor_ops *ops; |
88 | char *name; | 90 | char *name; |
89 | struct kref ref; | 91 | struct kref ref; |
92 | struct device_attribute attr; | ||
90 | }; | 93 | }; |
91 | 94 | ||
92 | /* Same lifetime rules as controls */ | 95 | /* Same lifetime rules as controls */ |
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 6c2a471ea6c0..bb8d5efe19bf 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/reboot.h> | 33 | #include <linux/reboot.h> |
34 | #include <linux/device.h> | 34 | #include <linux/device.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/mutex.h> | ||
36 | 37 | ||
37 | #include "windfarm.h" | 38 | #include "windfarm.h" |
38 | 39 | ||
@@ -48,13 +49,17 @@ | |||
48 | 49 | ||
49 | static LIST_HEAD(wf_controls); | 50 | static LIST_HEAD(wf_controls); |
50 | static LIST_HEAD(wf_sensors); | 51 | static LIST_HEAD(wf_sensors); |
51 | static DECLARE_MUTEX(wf_lock); | 52 | static DEFINE_MUTEX(wf_lock); |
52 | static struct notifier_block *wf_client_list; | 53 | static struct notifier_block *wf_client_list; |
53 | static int wf_client_count; | 54 | static int wf_client_count; |
54 | static unsigned int wf_overtemp; | 55 | static unsigned int wf_overtemp; |
55 | static unsigned int wf_overtemp_counter; | 56 | static unsigned int wf_overtemp_counter; |
56 | struct task_struct *wf_thread; | 57 | struct task_struct *wf_thread; |
57 | 58 | ||
59 | static struct platform_device wf_platform_device = { | ||
60 | .name = "windfarm", | ||
61 | }; | ||
62 | |||
58 | /* | 63 | /* |
59 | * Utilities & tick thread | 64 | * Utilities & tick thread |
60 | */ | 65 | */ |
@@ -156,26 +161,67 @@ static void wf_control_release(struct kref *kref) | |||
156 | kfree(ct); | 161 | kfree(ct); |
157 | } | 162 | } |
158 | 163 | ||
164 | static ssize_t wf_show_control(struct device *dev, | ||
165 | struct device_attribute *attr, char *buf) | ||
166 | { | ||
167 | struct wf_control *ctrl = container_of(attr, struct wf_control, attr); | ||
168 | s32 val = 0; | ||
169 | int err; | ||
170 | |||
171 | err = ctrl->ops->get_value(ctrl, &val); | ||
172 | if (err < 0) | ||
173 | return err; | ||
174 | return sprintf(buf, "%d\n", val); | ||
175 | } | ||
176 | |||
177 | /* This is really only for debugging... */ | ||
178 | static ssize_t wf_store_control(struct device *dev, | ||
179 | struct device_attribute *attr, | ||
180 | const char *buf, size_t count) | ||
181 | { | ||
182 | struct wf_control *ctrl = container_of(attr, struct wf_control, attr); | ||
183 | int val; | ||
184 | int err; | ||
185 | char *endp; | ||
186 | |||
187 | val = simple_strtoul(buf, &endp, 0); | ||
188 | while (endp < buf + count && (*endp == ' ' || *endp == '\n')) | ||
189 | ++endp; | ||
190 | if (endp - buf < count) | ||
191 | return -EINVAL; | ||
192 | err = ctrl->ops->set_value(ctrl, val); | ||
193 | if (err < 0) | ||
194 | return err; | ||
195 | return count; | ||
196 | } | ||
197 | |||
159 | int wf_register_control(struct wf_control *new_ct) | 198 | int wf_register_control(struct wf_control *new_ct) |
160 | { | 199 | { |
161 | struct wf_control *ct; | 200 | struct wf_control *ct; |
162 | 201 | ||
163 | down(&wf_lock); | 202 | mutex_lock(&wf_lock); |
164 | list_for_each_entry(ct, &wf_controls, link) { | 203 | list_for_each_entry(ct, &wf_controls, link) { |
165 | if (!strcmp(ct->name, new_ct->name)) { | 204 | if (!strcmp(ct->name, new_ct->name)) { |
166 | printk(KERN_WARNING "windfarm: trying to register" | 205 | printk(KERN_WARNING "windfarm: trying to register" |
167 | " duplicate control %s\n", ct->name); | 206 | " duplicate control %s\n", ct->name); |
168 | up(&wf_lock); | 207 | mutex_unlock(&wf_lock); |
169 | return -EEXIST; | 208 | return -EEXIST; |
170 | } | 209 | } |
171 | } | 210 | } |
172 | kref_init(&new_ct->ref); | 211 | kref_init(&new_ct->ref); |
173 | list_add(&new_ct->link, &wf_controls); | 212 | list_add(&new_ct->link, &wf_controls); |
174 | 213 | ||
214 | new_ct->attr.attr.name = new_ct->name; | ||
215 | new_ct->attr.attr.owner = THIS_MODULE; | ||
216 | new_ct->attr.attr.mode = 0644; | ||
217 | new_ct->attr.show = wf_show_control; | ||
218 | new_ct->attr.store = wf_store_control; | ||
219 | device_create_file(&wf_platform_device.dev, &new_ct->attr); | ||
220 | |||
175 | DBG("wf: Registered control %s\n", new_ct->name); | 221 | DBG("wf: Registered control %s\n", new_ct->name); |
176 | 222 | ||
177 | wf_notify(WF_EVENT_NEW_CONTROL, new_ct); | 223 | wf_notify(WF_EVENT_NEW_CONTROL, new_ct); |
178 | up(&wf_lock); | 224 | mutex_unlock(&wf_lock); |
179 | 225 | ||
180 | return 0; | 226 | return 0; |
181 | } | 227 | } |
@@ -183,9 +229,9 @@ EXPORT_SYMBOL_GPL(wf_register_control); | |||
183 | 229 | ||
184 | void wf_unregister_control(struct wf_control *ct) | 230 | void wf_unregister_control(struct wf_control *ct) |
185 | { | 231 | { |
186 | down(&wf_lock); | 232 | mutex_lock(&wf_lock); |
187 | list_del(&ct->link); | 233 | list_del(&ct->link); |
188 | up(&wf_lock); | 234 | mutex_unlock(&wf_lock); |
189 | 235 | ||
190 | DBG("wf: Unregistered control %s\n", ct->name); | 236 | DBG("wf: Unregistered control %s\n", ct->name); |
191 | 237 | ||
@@ -197,16 +243,16 @@ struct wf_control * wf_find_control(const char *name) | |||
197 | { | 243 | { |
198 | struct wf_control *ct; | 244 | struct wf_control *ct; |
199 | 245 | ||
200 | down(&wf_lock); | 246 | mutex_lock(&wf_lock); |
201 | list_for_each_entry(ct, &wf_controls, link) { | 247 | list_for_each_entry(ct, &wf_controls, link) { |
202 | if (!strcmp(ct->name, name)) { | 248 | if (!strcmp(ct->name, name)) { |
203 | if (wf_get_control(ct)) | 249 | if (wf_get_control(ct)) |
204 | ct = NULL; | 250 | ct = NULL; |
205 | up(&wf_lock); | 251 | mutex_unlock(&wf_lock); |
206 | return ct; | 252 | return ct; |
207 | } | 253 | } |
208 | } | 254 | } |
209 | up(&wf_lock); | 255 | mutex_unlock(&wf_lock); |
210 | return NULL; | 256 | return NULL; |
211 | } | 257 | } |
212 | EXPORT_SYMBOL_GPL(wf_find_control); | 258 | EXPORT_SYMBOL_GPL(wf_find_control); |
@@ -246,26 +292,46 @@ static void wf_sensor_release(struct kref *kref) | |||
246 | kfree(sr); | 292 | kfree(sr); |
247 | } | 293 | } |
248 | 294 | ||
295 | static ssize_t wf_show_sensor(struct device *dev, | ||
296 | struct device_attribute *attr, char *buf) | ||
297 | { | ||
298 | struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr); | ||
299 | s32 val = 0; | ||
300 | int err; | ||
301 | |||
302 | err = sens->ops->get_value(sens, &val); | ||
303 | if (err < 0) | ||
304 | return err; | ||
305 | return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val)); | ||
306 | } | ||
307 | |||
249 | int wf_register_sensor(struct wf_sensor *new_sr) | 308 | int wf_register_sensor(struct wf_sensor *new_sr) |
250 | { | 309 | { |
251 | struct wf_sensor *sr; | 310 | struct wf_sensor *sr; |
252 | 311 | ||
253 | down(&wf_lock); | 312 | mutex_lock(&wf_lock); |
254 | list_for_each_entry(sr, &wf_sensors, link) { | 313 | list_for_each_entry(sr, &wf_sensors, link) { |
255 | if (!strcmp(sr->name, new_sr->name)) { | 314 | if (!strcmp(sr->name, new_sr->name)) { |
256 | printk(KERN_WARNING "windfarm: trying to register" | 315 | printk(KERN_WARNING "windfarm: trying to register" |
257 | " duplicate sensor %s\n", sr->name); | 316 | " duplicate sensor %s\n", sr->name); |
258 | up(&wf_lock); | 317 | mutex_unlock(&wf_lock); |
259 | return -EEXIST; | 318 | return -EEXIST; |
260 | } | 319 | } |
261 | } | 320 | } |
262 | kref_init(&new_sr->ref); | 321 | kref_init(&new_sr->ref); |
263 | list_add(&new_sr->link, &wf_sensors); | 322 | list_add(&new_sr->link, &wf_sensors); |
264 | 323 | ||
324 | new_sr->attr.attr.name = new_sr->name; | ||
325 | new_sr->attr.attr.owner = THIS_MODULE; | ||
326 | new_sr->attr.attr.mode = 0444; | ||
327 | new_sr->attr.show = wf_show_sensor; | ||
328 | new_sr->attr.store = NULL; | ||
329 | device_create_file(&wf_platform_device.dev, &new_sr->attr); | ||
330 | |||
265 | DBG("wf: Registered sensor %s\n", new_sr->name); | 331 | DBG("wf: Registered sensor %s\n", new_sr->name); |
266 | 332 | ||
267 | wf_notify(WF_EVENT_NEW_SENSOR, new_sr); | 333 | wf_notify(WF_EVENT_NEW_SENSOR, new_sr); |
268 | up(&wf_lock); | 334 | mutex_unlock(&wf_lock); |
269 | 335 | ||
270 | return 0; | 336 | return 0; |
271 | } | 337 | } |
@@ -273,9 +339,9 @@ EXPORT_SYMBOL_GPL(wf_register_sensor); | |||
273 | 339 | ||
274 | void wf_unregister_sensor(struct wf_sensor *sr) | 340 | void wf_unregister_sensor(struct wf_sensor *sr) |
275 | { | 341 | { |
276 | down(&wf_lock); | 342 | mutex_lock(&wf_lock); |
277 | list_del(&sr->link); | 343 | list_del(&sr->link); |
278 | up(&wf_lock); | 344 | mutex_unlock(&wf_lock); |
279 | 345 | ||
280 | DBG("wf: Unregistered sensor %s\n", sr->name); | 346 | DBG("wf: Unregistered sensor %s\n", sr->name); |
281 | 347 | ||
@@ -287,16 +353,16 @@ struct wf_sensor * wf_find_sensor(const char *name) | |||
287 | { | 353 | { |
288 | struct wf_sensor *sr; | 354 | struct wf_sensor *sr; |
289 | 355 | ||
290 | down(&wf_lock); | 356 | mutex_lock(&wf_lock); |
291 | list_for_each_entry(sr, &wf_sensors, link) { | 357 | list_for_each_entry(sr, &wf_sensors, link) { |
292 | if (!strcmp(sr->name, name)) { | 358 | if (!strcmp(sr->name, name)) { |
293 | if (wf_get_sensor(sr)) | 359 | if (wf_get_sensor(sr)) |
294 | sr = NULL; | 360 | sr = NULL; |
295 | up(&wf_lock); | 361 | mutex_unlock(&wf_lock); |
296 | return sr; | 362 | return sr; |
297 | } | 363 | } |
298 | } | 364 | } |
299 | up(&wf_lock); | 365 | mutex_unlock(&wf_lock); |
300 | return NULL; | 366 | return NULL; |
301 | } | 367 | } |
302 | EXPORT_SYMBOL_GPL(wf_find_sensor); | 368 | EXPORT_SYMBOL_GPL(wf_find_sensor); |
@@ -329,7 +395,7 @@ int wf_register_client(struct notifier_block *nb) | |||
329 | struct wf_control *ct; | 395 | struct wf_control *ct; |
330 | struct wf_sensor *sr; | 396 | struct wf_sensor *sr; |
331 | 397 | ||
332 | down(&wf_lock); | 398 | mutex_lock(&wf_lock); |
333 | rc = notifier_chain_register(&wf_client_list, nb); | 399 | rc = notifier_chain_register(&wf_client_list, nb); |
334 | if (rc != 0) | 400 | if (rc != 0) |
335 | goto bail; | 401 | goto bail; |
@@ -341,19 +407,19 @@ int wf_register_client(struct notifier_block *nb) | |||
341 | if (wf_client_count == 1) | 407 | if (wf_client_count == 1) |
342 | wf_start_thread(); | 408 | wf_start_thread(); |
343 | bail: | 409 | bail: |
344 | up(&wf_lock); | 410 | mutex_unlock(&wf_lock); |
345 | return rc; | 411 | return rc; |
346 | } | 412 | } |
347 | EXPORT_SYMBOL_GPL(wf_register_client); | 413 | EXPORT_SYMBOL_GPL(wf_register_client); |
348 | 414 | ||
349 | int wf_unregister_client(struct notifier_block *nb) | 415 | int wf_unregister_client(struct notifier_block *nb) |
350 | { | 416 | { |
351 | down(&wf_lock); | 417 | mutex_lock(&wf_lock); |
352 | notifier_chain_unregister(&wf_client_list, nb); | 418 | notifier_chain_unregister(&wf_client_list, nb); |
353 | wf_client_count++; | 419 | wf_client_count++; |
354 | if (wf_client_count == 0) | 420 | if (wf_client_count == 0) |
355 | wf_stop_thread(); | 421 | wf_stop_thread(); |
356 | up(&wf_lock); | 422 | mutex_unlock(&wf_lock); |
357 | 423 | ||
358 | return 0; | 424 | return 0; |
359 | } | 425 | } |
@@ -361,23 +427,23 @@ EXPORT_SYMBOL_GPL(wf_unregister_client); | |||
361 | 427 | ||
362 | void wf_set_overtemp(void) | 428 | void wf_set_overtemp(void) |
363 | { | 429 | { |
364 | down(&wf_lock); | 430 | mutex_lock(&wf_lock); |
365 | wf_overtemp++; | 431 | wf_overtemp++; |
366 | if (wf_overtemp == 1) { | 432 | if (wf_overtemp == 1) { |
367 | printk(KERN_WARNING "windfarm: Overtemp condition detected !\n"); | 433 | printk(KERN_WARNING "windfarm: Overtemp condition detected !\n"); |
368 | wf_overtemp_counter = 0; | 434 | wf_overtemp_counter = 0; |
369 | wf_notify(WF_EVENT_OVERTEMP, NULL); | 435 | wf_notify(WF_EVENT_OVERTEMP, NULL); |
370 | } | 436 | } |
371 | up(&wf_lock); | 437 | mutex_unlock(&wf_lock); |
372 | } | 438 | } |
373 | EXPORT_SYMBOL_GPL(wf_set_overtemp); | 439 | EXPORT_SYMBOL_GPL(wf_set_overtemp); |
374 | 440 | ||
375 | void wf_clear_overtemp(void) | 441 | void wf_clear_overtemp(void) |
376 | { | 442 | { |
377 | down(&wf_lock); | 443 | mutex_lock(&wf_lock); |
378 | WARN_ON(wf_overtemp == 0); | 444 | WARN_ON(wf_overtemp == 0); |
379 | if (wf_overtemp == 0) { | 445 | if (wf_overtemp == 0) { |
380 | up(&wf_lock); | 446 | mutex_unlock(&wf_lock); |
381 | return; | 447 | return; |
382 | } | 448 | } |
383 | wf_overtemp--; | 449 | wf_overtemp--; |
@@ -385,7 +451,7 @@ void wf_clear_overtemp(void) | |||
385 | printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n"); | 451 | printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n"); |
386 | wf_notify(WF_EVENT_NORMALTEMP, NULL); | 452 | wf_notify(WF_EVENT_NORMALTEMP, NULL); |
387 | } | 453 | } |
388 | up(&wf_lock); | 454 | mutex_unlock(&wf_lock); |
389 | } | 455 | } |
390 | EXPORT_SYMBOL_GPL(wf_clear_overtemp); | 456 | EXPORT_SYMBOL_GPL(wf_clear_overtemp); |
391 | 457 | ||
@@ -395,10 +461,6 @@ int wf_is_overtemp(void) | |||
395 | } | 461 | } |
396 | EXPORT_SYMBOL_GPL(wf_is_overtemp); | 462 | EXPORT_SYMBOL_GPL(wf_is_overtemp); |
397 | 463 | ||
398 | static struct platform_device wf_platform_device = { | ||
399 | .name = "windfarm", | ||
400 | }; | ||
401 | |||
402 | static int __init windfarm_core_init(void) | 464 | static int __init windfarm_core_init(void) |
403 | { | 465 | { |
404 | DBG("wf: core loaded\n"); | 466 | DBG("wf: core loaded\n"); |
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c new file mode 100644 index 000000000000..5b9ad6ca7cba --- /dev/null +++ b/drivers/macintosh/windfarm_max6690_sensor.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * Windfarm PowerMac thermal control. MAX6690 sensor. | ||
3 | * | ||
4 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
5 | * | ||
6 | * Use and redistribute under the terms of the GNU GPL v2. | ||
7 | */ | ||
8 | #include <linux/types.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/i2c-dev.h> | ||
15 | #include <asm/prom.h> | ||
16 | #include <asm/pmac_low_i2c.h> | ||
17 | |||
18 | #include "windfarm.h" | ||
19 | |||
20 | #define VERSION "0.1" | ||
21 | |||
22 | /* This currently only exports the external temperature sensor, | ||
23 | since that's all the control loops need. */ | ||
24 | |||
25 | /* Some MAX6690 register numbers */ | ||
26 | #define MAX6690_INTERNAL_TEMP 0 | ||
27 | #define MAX6690_EXTERNAL_TEMP 1 | ||
28 | |||
29 | struct wf_6690_sensor { | ||
30 | struct i2c_client i2c; | ||
31 | struct wf_sensor sens; | ||
32 | }; | ||
33 | |||
34 | #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) | ||
35 | #define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) | ||
36 | |||
37 | static int wf_max6690_attach(struct i2c_adapter *adapter); | ||
38 | static int wf_max6690_detach(struct i2c_client *client); | ||
39 | |||
40 | static struct i2c_driver wf_max6690_driver = { | ||
41 | .driver = { | ||
42 | .name = "wf_max6690", | ||
43 | }, | ||
44 | .attach_adapter = wf_max6690_attach, | ||
45 | .detach_client = wf_max6690_detach, | ||
46 | }; | ||
47 | |||
48 | static int wf_max6690_get(struct wf_sensor *sr, s32 *value) | ||
49 | { | ||
50 | struct wf_6690_sensor *max = wf_to_6690(sr); | ||
51 | s32 data; | ||
52 | |||
53 | if (max->i2c.adapter == NULL) | ||
54 | return -ENODEV; | ||
55 | |||
56 | /* chip gets initialized by firmware */ | ||
57 | data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); | ||
58 | if (data < 0) | ||
59 | return data; | ||
60 | *value = data << 16; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void wf_max6690_release(struct wf_sensor *sr) | ||
65 | { | ||
66 | struct wf_6690_sensor *max = wf_to_6690(sr); | ||
67 | |||
68 | if (max->i2c.adapter) { | ||
69 | i2c_detach_client(&max->i2c); | ||
70 | max->i2c.adapter = NULL; | ||
71 | } | ||
72 | kfree(max); | ||
73 | } | ||
74 | |||
75 | static struct wf_sensor_ops wf_max6690_ops = { | ||
76 | .get_value = wf_max6690_get, | ||
77 | .release = wf_max6690_release, | ||
78 | .owner = THIS_MODULE, | ||
79 | }; | ||
80 | |||
81 | static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) | ||
82 | { | ||
83 | struct wf_6690_sensor *max; | ||
84 | char *name = "u4-temp"; | ||
85 | |||
86 | max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); | ||
87 | if (max == NULL) { | ||
88 | printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " | ||
89 | "no memory\n", name); | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | max->sens.ops = &wf_max6690_ops; | ||
94 | max->sens.name = name; | ||
95 | max->i2c.addr = addr >> 1; | ||
96 | max->i2c.adapter = adapter; | ||
97 | max->i2c.driver = &wf_max6690_driver; | ||
98 | strncpy(max->i2c.name, name, I2C_NAME_SIZE-1); | ||
99 | |||
100 | if (i2c_attach_client(&max->i2c)) { | ||
101 | printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); | ||
102 | goto fail; | ||
103 | } | ||
104 | |||
105 | if (wf_register_sensor(&max->sens)) { | ||
106 | i2c_detach_client(&max->i2c); | ||
107 | goto fail; | ||
108 | } | ||
109 | |||
110 | return; | ||
111 | |||
112 | fail: | ||
113 | kfree(max); | ||
114 | } | ||
115 | |||
116 | static int wf_max6690_attach(struct i2c_adapter *adapter) | ||
117 | { | ||
118 | struct device_node *busnode, *dev = NULL; | ||
119 | struct pmac_i2c_bus *bus; | ||
120 | const char *loc; | ||
121 | u32 *reg; | ||
122 | |||
123 | bus = pmac_i2c_adapter_to_bus(adapter); | ||
124 | if (bus == NULL) | ||
125 | return -ENODEV; | ||
126 | busnode = pmac_i2c_get_bus_node(bus); | ||
127 | |||
128 | while ((dev = of_get_next_child(busnode, dev)) != NULL) { | ||
129 | if (!device_is_compatible(dev, "max6690")) | ||
130 | continue; | ||
131 | loc = get_property(dev, "hwsensor-location", NULL); | ||
132 | reg = (u32 *) get_property(dev, "reg", NULL); | ||
133 | if (!loc || !reg) | ||
134 | continue; | ||
135 | printk("found max6690, loc=%s reg=%x\n", loc, *reg); | ||
136 | if (strcmp(loc, "BACKSIDE")) | ||
137 | continue; | ||
138 | wf_max6690_create(adapter, *reg); | ||
139 | } | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int wf_max6690_detach(struct i2c_client *client) | ||
145 | { | ||
146 | struct wf_6690_sensor *max = i2c_to_6690(client); | ||
147 | |||
148 | max->i2c.adapter = NULL; | ||
149 | wf_unregister_sensor(&max->sens); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int __init wf_max6690_sensor_init(void) | ||
155 | { | ||
156 | return i2c_add_driver(&wf_max6690_driver); | ||
157 | } | ||
158 | |||
159 | static void __exit wf_max6690_sensor_exit(void) | ||
160 | { | ||
161 | i2c_del_driver(&wf_max6690_driver); | ||
162 | } | ||
163 | |||
164 | module_init(wf_max6690_sensor_init); | ||
165 | module_exit(wf_max6690_sensor_exit); | ||
166 | |||
167 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
168 | MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control"); | ||
169 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c index 2e803b368757..0842432e27ad 100644 --- a/drivers/macintosh/windfarm_pid.c +++ b/drivers/macintosh/windfarm_pid.c | |||
@@ -88,8 +88,8 @@ EXPORT_SYMBOL_GPL(wf_cpu_pid_init); | |||
88 | 88 | ||
89 | s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | 89 | s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) |
90 | { | 90 | { |
91 | s64 error, integ, deriv, prop; | 91 | s64 integ, deriv, prop; |
92 | s32 target, sval, adj; | 92 | s32 error, target, sval, adj; |
93 | int i, hlen = st->param.history_len; | 93 | int i, hlen = st->param.history_len; |
94 | 94 | ||
95 | /* Calculate error term */ | 95 | /* Calculate error term */ |
@@ -117,7 +117,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | |||
117 | integ += st->errors[(st->index + hlen - i) % hlen]; | 117 | integ += st->errors[(st->index + hlen - i) % hlen]; |
118 | integ *= st->param.interval; | 118 | integ *= st->param.interval; |
119 | integ *= st->param.gr; | 119 | integ *= st->param.gr; |
120 | sval = st->param.tmax - ((integ >> 20) & 0xffffffff); | 120 | sval = st->param.tmax - (s32)(integ >> 20); |
121 | adj = min(st->param.ttarget, sval); | 121 | adj = min(st->param.ttarget, sval); |
122 | 122 | ||
123 | DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); | 123 | DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); |
@@ -129,7 +129,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | |||
129 | deriv *= st->param.gd; | 129 | deriv *= st->param.gd; |
130 | 130 | ||
131 | /* Calculate proportional term */ | 131 | /* Calculate proportional term */ |
132 | prop = (new_temp - adj); | 132 | prop = st->last_delta = (new_temp - adj); |
133 | prop *= st->param.gp; | 133 | prop *= st->param.gp; |
134 | 134 | ||
135 | DBG("deriv: %lx, prop: %lx\n", deriv, prop); | 135 | DBG("deriv: %lx, prop: %lx\n", deriv, prop); |
diff --git a/drivers/macintosh/windfarm_pid.h b/drivers/macintosh/windfarm_pid.h index a364c2a2499c..bbccc22d42b8 100644 --- a/drivers/macintosh/windfarm_pid.h +++ b/drivers/macintosh/windfarm_pid.h | |||
@@ -72,6 +72,7 @@ struct wf_cpu_pid_state { | |||
72 | int index; /* index of current power */ | 72 | int index; /* index of current power */ |
73 | int tindex; /* index of current temp */ | 73 | int tindex; /* index of current temp */ |
74 | s32 target; /* current target value */ | 74 | s32 target; /* current target value */ |
75 | s32 last_delta; /* last Tactual - Ttarget */ | ||
75 | s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ | 76 | s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ |
76 | s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ | 77 | s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ |
77 | s32 temps[2]; /* temp. history buffer */ | 78 | s32 temps[2]; /* temp. history buffer */ |
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c new file mode 100644 index 000000000000..c2a4e689c784 --- /dev/null +++ b/drivers/macintosh/windfarm_pm112.c | |||
@@ -0,0 +1,698 @@ | |||
1 | /* | ||
2 | * Windfarm PowerMac thermal control. | ||
3 | * Control loops for machines with SMU and PPC970MP processors. | ||
4 | * | ||
5 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
6 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
7 | * | ||
8 | * Use and redistribute under the terms of the GNU GPL v2. | ||
9 | */ | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <asm/prom.h> | ||
17 | #include <asm/smu.h> | ||
18 | |||
19 | #include "windfarm.h" | ||
20 | #include "windfarm_pid.h" | ||
21 | |||
22 | #define VERSION "0.2" | ||
23 | |||
24 | #define DEBUG | ||
25 | #undef LOTSA_DEBUG | ||
26 | |||
27 | #ifdef DEBUG | ||
28 | #define DBG(args...) printk(args) | ||
29 | #else | ||
30 | #define DBG(args...) do { } while(0) | ||
31 | #endif | ||
32 | |||
33 | #ifdef LOTSA_DEBUG | ||
34 | #define DBG_LOTS(args...) printk(args) | ||
35 | #else | ||
36 | #define DBG_LOTS(args...) do { } while(0) | ||
37 | #endif | ||
38 | |||
39 | /* define this to force CPU overtemp to 60 degree, useful for testing | ||
40 | * the overtemp code | ||
41 | */ | ||
42 | #undef HACKED_OVERTEMP | ||
43 | |||
44 | /* We currently only handle 2 chips, 4 cores... */ | ||
45 | #define NR_CHIPS 2 | ||
46 | #define NR_CORES 4 | ||
47 | #define NR_CPU_FANS 3 * NR_CHIPS | ||
48 | |||
49 | /* Controls and sensors */ | ||
50 | static struct wf_sensor *sens_cpu_temp[NR_CORES]; | ||
51 | static struct wf_sensor *sens_cpu_power[NR_CORES]; | ||
52 | static struct wf_sensor *hd_temp; | ||
53 | static struct wf_sensor *slots_power; | ||
54 | static struct wf_sensor *u4_temp; | ||
55 | |||
56 | static struct wf_control *cpu_fans[NR_CPU_FANS]; | ||
57 | static char *cpu_fan_names[NR_CPU_FANS] = { | ||
58 | "cpu-rear-fan-0", | ||
59 | "cpu-rear-fan-1", | ||
60 | "cpu-front-fan-0", | ||
61 | "cpu-front-fan-1", | ||
62 | "cpu-pump-0", | ||
63 | "cpu-pump-1", | ||
64 | }; | ||
65 | static struct wf_control *cpufreq_clamp; | ||
66 | |||
67 | /* Second pump isn't required (and isn't actually present) */ | ||
68 | #define CPU_FANS_REQD (NR_CPU_FANS - 2) | ||
69 | #define FIRST_PUMP 4 | ||
70 | #define LAST_PUMP 5 | ||
71 | |||
72 | /* We keep a temperature history for average calculation of 180s */ | ||
73 | #define CPU_TEMP_HIST_SIZE 180 | ||
74 | |||
75 | /* Scale factor for fan speed, *100 */ | ||
76 | static int cpu_fan_scale[NR_CPU_FANS] = { | ||
77 | 100, | ||
78 | 100, | ||
79 | 97, /* inlet fans run at 97% of exhaust fan */ | ||
80 | 97, | ||
81 | 100, /* updated later */ | ||
82 | 100, /* updated later */ | ||
83 | }; | ||
84 | |||
85 | static struct wf_control *backside_fan; | ||
86 | static struct wf_control *slots_fan; | ||
87 | static struct wf_control *drive_bay_fan; | ||
88 | |||
89 | /* PID loop state */ | ||
90 | static struct wf_cpu_pid_state cpu_pid[NR_CORES]; | ||
91 | static u32 cpu_thist[CPU_TEMP_HIST_SIZE]; | ||
92 | static int cpu_thist_pt; | ||
93 | static s64 cpu_thist_total; | ||
94 | static s32 cpu_all_tmax = 100 << 16; | ||
95 | static int cpu_last_target; | ||
96 | static struct wf_pid_state backside_pid; | ||
97 | static int backside_tick; | ||
98 | static struct wf_pid_state slots_pid; | ||
99 | static int slots_started; | ||
100 | static struct wf_pid_state drive_bay_pid; | ||
101 | static int drive_bay_tick; | ||
102 | |||
103 | static int nr_cores; | ||
104 | static int have_all_controls; | ||
105 | static int have_all_sensors; | ||
106 | static int started; | ||
107 | |||
108 | static int failure_state; | ||
109 | #define FAILURE_SENSOR 1 | ||
110 | #define FAILURE_FAN 2 | ||
111 | #define FAILURE_PERM 4 | ||
112 | #define FAILURE_LOW_OVERTEMP 8 | ||
113 | #define FAILURE_HIGH_OVERTEMP 16 | ||
114 | |||
115 | /* Overtemp values */ | ||
116 | #define LOW_OVER_AVERAGE 0 | ||
117 | #define LOW_OVER_IMMEDIATE (10 << 16) | ||
118 | #define LOW_OVER_CLEAR ((-10) << 16) | ||
119 | #define HIGH_OVER_IMMEDIATE (14 << 16) | ||
120 | #define HIGH_OVER_AVERAGE (10 << 16) | ||
121 | #define HIGH_OVER_IMMEDIATE (14 << 16) | ||
122 | |||
123 | |||
124 | /* Implementation... */ | ||
125 | static int create_cpu_loop(int cpu) | ||
126 | { | ||
127 | int chip = cpu / 2; | ||
128 | int core = cpu & 1; | ||
129 | struct smu_sdbp_header *hdr; | ||
130 | struct smu_sdbp_cpupiddata *piddata; | ||
131 | struct wf_cpu_pid_param pid; | ||
132 | struct wf_control *main_fan = cpu_fans[0]; | ||
133 | s32 tmax; | ||
134 | int fmin; | ||
135 | |||
136 | /* Get PID params from the appropriate SAT */ | ||
137 | hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); | ||
138 | if (hdr == NULL) { | ||
139 | printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; | ||
143 | |||
144 | /* Get FVT params to get Tmax; if not found, assume default */ | ||
145 | hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL); | ||
146 | if (hdr) { | ||
147 | struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1]; | ||
148 | tmax = fvt->maxtemp << 16; | ||
149 | } else | ||
150 | tmax = 95 << 16; /* default to 95 degrees C */ | ||
151 | |||
152 | /* We keep a global tmax for overtemp calculations */ | ||
153 | if (tmax < cpu_all_tmax) | ||
154 | cpu_all_tmax = tmax; | ||
155 | |||
156 | /* | ||
157 | * Darwin has a minimum fan speed of 1000 rpm for the 4-way and | ||
158 | * 515 for the 2-way. That appears to be overkill, so for now, | ||
159 | * impose a minimum of 750 or 515. | ||
160 | */ | ||
161 | fmin = (nr_cores > 2) ? 750 : 515; | ||
162 | |||
163 | /* Initialize PID loop */ | ||
164 | pid.interval = 1; /* seconds */ | ||
165 | pid.history_len = piddata->history_len; | ||
166 | pid.gd = piddata->gd; | ||
167 | pid.gp = piddata->gp; | ||
168 | pid.gr = piddata->gr / piddata->history_len; | ||
169 | pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8); | ||
170 | pid.ttarget = tmax - (piddata->target_temp_delta << 16); | ||
171 | pid.tmax = tmax; | ||
172 | pid.min = main_fan->ops->get_min(main_fan); | ||
173 | pid.max = main_fan->ops->get_max(main_fan); | ||
174 | if (pid.min < fmin) | ||
175 | pid.min = fmin; | ||
176 | |||
177 | wf_cpu_pid_init(&cpu_pid[cpu], &pid); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static void cpu_max_all_fans(void) | ||
182 | { | ||
183 | int i; | ||
184 | |||
185 | /* We max all CPU fans in case of a sensor error. We also do the | ||
186 | * cpufreq clamping now, even if it's supposedly done later by the | ||
187 | * generic code anyway, we do it earlier here to react faster | ||
188 | */ | ||
189 | if (cpufreq_clamp) | ||
190 | wf_control_set_max(cpufreq_clamp); | ||
191 | for (i = 0; i < NR_CPU_FANS; ++i) | ||
192 | if (cpu_fans[i]) | ||
193 | wf_control_set_max(cpu_fans[i]); | ||
194 | } | ||
195 | |||
196 | static int cpu_check_overtemp(s32 temp) | ||
197 | { | ||
198 | int new_state = 0; | ||
199 | s32 t_avg, t_old; | ||
200 | |||
201 | /* First check for immediate overtemps */ | ||
202 | if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) { | ||
203 | new_state |= FAILURE_LOW_OVERTEMP; | ||
204 | if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) | ||
205 | printk(KERN_ERR "windfarm: Overtemp due to immediate CPU" | ||
206 | " temperature !\n"); | ||
207 | } | ||
208 | if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) { | ||
209 | new_state |= FAILURE_HIGH_OVERTEMP; | ||
210 | if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) | ||
211 | printk(KERN_ERR "windfarm: Critical overtemp due to" | ||
212 | " immediate CPU temperature !\n"); | ||
213 | } | ||
214 | |||
215 | /* We calculate a history of max temperatures and use that for the | ||
216 | * overtemp management | ||
217 | */ | ||
218 | t_old = cpu_thist[cpu_thist_pt]; | ||
219 | cpu_thist[cpu_thist_pt] = temp; | ||
220 | cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE; | ||
221 | cpu_thist_total -= t_old; | ||
222 | cpu_thist_total += temp; | ||
223 | t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE; | ||
224 | |||
225 | DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n", | ||
226 | FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp)); | ||
227 | |||
228 | /* Now check for average overtemps */ | ||
229 | if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) { | ||
230 | new_state |= FAILURE_LOW_OVERTEMP; | ||
231 | if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) | ||
232 | printk(KERN_ERR "windfarm: Overtemp due to average CPU" | ||
233 | " temperature !\n"); | ||
234 | } | ||
235 | if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) { | ||
236 | new_state |= FAILURE_HIGH_OVERTEMP; | ||
237 | if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) | ||
238 | printk(KERN_ERR "windfarm: Critical overtemp due to" | ||
239 | " average CPU temperature !\n"); | ||
240 | } | ||
241 | |||
242 | /* Now handle overtemp conditions. We don't currently use the windfarm | ||
243 | * overtemp handling core as it's not fully suited to the needs of those | ||
244 | * new machine. This will be fixed later. | ||
245 | */ | ||
246 | if (new_state) { | ||
247 | /* High overtemp -> immediate shutdown */ | ||
248 | if (new_state & FAILURE_HIGH_OVERTEMP) | ||
249 | machine_power_off(); | ||
250 | if ((failure_state & new_state) != new_state) | ||
251 | cpu_max_all_fans(); | ||
252 | failure_state |= new_state; | ||
253 | } else if ((failure_state & FAILURE_LOW_OVERTEMP) && | ||
254 | (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) { | ||
255 | printk(KERN_ERR "windfarm: Overtemp condition cleared !\n"); | ||
256 | failure_state &= ~FAILURE_LOW_OVERTEMP; | ||
257 | } | ||
258 | |||
259 | return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP); | ||
260 | } | ||
261 | |||
262 | static void cpu_fans_tick(void) | ||
263 | { | ||
264 | int err, cpu; | ||
265 | s32 greatest_delta = 0; | ||
266 | s32 temp, power, t_max = 0; | ||
267 | int i, t, target = 0; | ||
268 | struct wf_sensor *sr; | ||
269 | struct wf_control *ct; | ||
270 | struct wf_cpu_pid_state *sp; | ||
271 | |||
272 | DBG_LOTS(KERN_DEBUG); | ||
273 | for (cpu = 0; cpu < nr_cores; ++cpu) { | ||
274 | /* Get CPU core temperature */ | ||
275 | sr = sens_cpu_temp[cpu]; | ||
276 | err = sr->ops->get_value(sr, &temp); | ||
277 | if (err) { | ||
278 | DBG("\n"); | ||
279 | printk(KERN_WARNING "windfarm: CPU %d temperature " | ||
280 | "sensor error %d\n", cpu, err); | ||
281 | failure_state |= FAILURE_SENSOR; | ||
282 | cpu_max_all_fans(); | ||
283 | return; | ||
284 | } | ||
285 | |||
286 | /* Keep track of highest temp */ | ||
287 | t_max = max(t_max, temp); | ||
288 | |||
289 | /* Get CPU power */ | ||
290 | sr = sens_cpu_power[cpu]; | ||
291 | err = sr->ops->get_value(sr, &power); | ||
292 | if (err) { | ||
293 | DBG("\n"); | ||
294 | printk(KERN_WARNING "windfarm: CPU %d power " | ||
295 | "sensor error %d\n", cpu, err); | ||
296 | failure_state |= FAILURE_SENSOR; | ||
297 | cpu_max_all_fans(); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | /* Run PID */ | ||
302 | sp = &cpu_pid[cpu]; | ||
303 | t = wf_cpu_pid_run(sp, power, temp); | ||
304 | |||
305 | if (cpu == 0 || sp->last_delta > greatest_delta) { | ||
306 | greatest_delta = sp->last_delta; | ||
307 | target = t; | ||
308 | } | ||
309 | DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ", | ||
310 | cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp)); | ||
311 | } | ||
312 | DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max)); | ||
313 | |||
314 | /* Darwin limits decrease to 20 per iteration */ | ||
315 | if (target < (cpu_last_target - 20)) | ||
316 | target = cpu_last_target - 20; | ||
317 | cpu_last_target = target; | ||
318 | for (cpu = 0; cpu < nr_cores; ++cpu) | ||
319 | cpu_pid[cpu].target = target; | ||
320 | |||
321 | /* Handle possible overtemps */ | ||
322 | if (cpu_check_overtemp(t_max)) | ||
323 | return; | ||
324 | |||
325 | /* Set fans */ | ||
326 | for (i = 0; i < NR_CPU_FANS; ++i) { | ||
327 | ct = cpu_fans[i]; | ||
328 | if (ct == NULL) | ||
329 | continue; | ||
330 | err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100); | ||
331 | if (err) { | ||
332 | printk(KERN_WARNING "windfarm: fan %s reports " | ||
333 | "error %d\n", ct->name, err); | ||
334 | failure_state |= FAILURE_FAN; | ||
335 | break; | ||
336 | } | ||
337 | } | ||
338 | } | ||
339 | |||
340 | /* Backside/U4 fan */ | ||
341 | static struct wf_pid_param backside_param = { | ||
342 | .interval = 5, | ||
343 | .history_len = 2, | ||
344 | .gd = 48 << 20, | ||
345 | .gp = 5 << 20, | ||
346 | .gr = 0, | ||
347 | .itarget = 64 << 16, | ||
348 | .additive = 1, | ||
349 | }; | ||
350 | |||
351 | static void backside_fan_tick(void) | ||
352 | { | ||
353 | s32 temp; | ||
354 | int speed; | ||
355 | int err; | ||
356 | |||
357 | if (!backside_fan || !u4_temp) | ||
358 | return; | ||
359 | if (!backside_tick) { | ||
360 | /* first time; initialize things */ | ||
361 | backside_param.min = backside_fan->ops->get_min(backside_fan); | ||
362 | backside_param.max = backside_fan->ops->get_max(backside_fan); | ||
363 | wf_pid_init(&backside_pid, &backside_param); | ||
364 | backside_tick = 1; | ||
365 | } | ||
366 | if (--backside_tick > 0) | ||
367 | return; | ||
368 | backside_tick = backside_pid.param.interval; | ||
369 | |||
370 | err = u4_temp->ops->get_value(u4_temp, &temp); | ||
371 | if (err) { | ||
372 | printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n", | ||
373 | err); | ||
374 | failure_state |= FAILURE_SENSOR; | ||
375 | wf_control_set_max(backside_fan); | ||
376 | return; | ||
377 | } | ||
378 | speed = wf_pid_run(&backside_pid, temp); | ||
379 | DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n", | ||
380 | FIX32TOPRINT(temp), speed); | ||
381 | |||
382 | err = backside_fan->ops->set_value(backside_fan, speed); | ||
383 | if (err) { | ||
384 | printk(KERN_WARNING "windfarm: backside fan error %d\n", err); | ||
385 | failure_state |= FAILURE_FAN; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | /* Drive bay fan */ | ||
390 | static struct wf_pid_param drive_bay_prm = { | ||
391 | .interval = 5, | ||
392 | .history_len = 2, | ||
393 | .gd = 30 << 20, | ||
394 | .gp = 5 << 20, | ||
395 | .gr = 0, | ||
396 | .itarget = 40 << 16, | ||
397 | .additive = 1, | ||
398 | }; | ||
399 | |||
400 | static void drive_bay_fan_tick(void) | ||
401 | { | ||
402 | s32 temp; | ||
403 | int speed; | ||
404 | int err; | ||
405 | |||
406 | if (!drive_bay_fan || !hd_temp) | ||
407 | return; | ||
408 | if (!drive_bay_tick) { | ||
409 | /* first time; initialize things */ | ||
410 | drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan); | ||
411 | drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan); | ||
412 | wf_pid_init(&drive_bay_pid, &drive_bay_prm); | ||
413 | drive_bay_tick = 1; | ||
414 | } | ||
415 | if (--drive_bay_tick > 0) | ||
416 | return; | ||
417 | drive_bay_tick = drive_bay_pid.param.interval; | ||
418 | |||
419 | err = hd_temp->ops->get_value(hd_temp, &temp); | ||
420 | if (err) { | ||
421 | printk(KERN_WARNING "windfarm: drive bay temp sensor " | ||
422 | "error %d\n", err); | ||
423 | failure_state |= FAILURE_SENSOR; | ||
424 | wf_control_set_max(drive_bay_fan); | ||
425 | return; | ||
426 | } | ||
427 | speed = wf_pid_run(&drive_bay_pid, temp); | ||
428 | DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n", | ||
429 | FIX32TOPRINT(temp), speed); | ||
430 | |||
431 | err = drive_bay_fan->ops->set_value(drive_bay_fan, speed); | ||
432 | if (err) { | ||
433 | printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err); | ||
434 | failure_state |= FAILURE_FAN; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | /* PCI slots area fan */ | ||
439 | /* This makes the fan speed proportional to the power consumed */ | ||
440 | static struct wf_pid_param slots_param = { | ||
441 | .interval = 1, | ||
442 | .history_len = 2, | ||
443 | .gd = 0, | ||
444 | .gp = 0, | ||
445 | .gr = 0x1277952, | ||
446 | .itarget = 0, | ||
447 | .min = 1560, | ||
448 | .max = 3510, | ||
449 | }; | ||
450 | |||
451 | static void slots_fan_tick(void) | ||
452 | { | ||
453 | s32 power; | ||
454 | int speed; | ||
455 | int err; | ||
456 | |||
457 | if (!slots_fan || !slots_power) | ||
458 | return; | ||
459 | if (!slots_started) { | ||
460 | /* first time; initialize things */ | ||
461 | wf_pid_init(&slots_pid, &slots_param); | ||
462 | slots_started = 1; | ||
463 | } | ||
464 | |||
465 | err = slots_power->ops->get_value(slots_power, &power); | ||
466 | if (err) { | ||
467 | printk(KERN_WARNING "windfarm: slots power sensor error %d\n", | ||
468 | err); | ||
469 | failure_state |= FAILURE_SENSOR; | ||
470 | wf_control_set_max(slots_fan); | ||
471 | return; | ||
472 | } | ||
473 | speed = wf_pid_run(&slots_pid, power); | ||
474 | DBG_LOTS("slots PID power=%d.%.3d speed=%d\n", | ||
475 | FIX32TOPRINT(power), speed); | ||
476 | |||
477 | err = slots_fan->ops->set_value(slots_fan, speed); | ||
478 | if (err) { | ||
479 | printk(KERN_WARNING "windfarm: slots fan error %d\n", err); | ||
480 | failure_state |= FAILURE_FAN; | ||
481 | } | ||
482 | } | ||
483 | |||
484 | static void set_fail_state(void) | ||
485 | { | ||
486 | int i; | ||
487 | |||
488 | if (cpufreq_clamp) | ||
489 | wf_control_set_max(cpufreq_clamp); | ||
490 | for (i = 0; i < NR_CPU_FANS; ++i) | ||
491 | if (cpu_fans[i]) | ||
492 | wf_control_set_max(cpu_fans[i]); | ||
493 | if (backside_fan) | ||
494 | wf_control_set_max(backside_fan); | ||
495 | if (slots_fan) | ||
496 | wf_control_set_max(slots_fan); | ||
497 | if (drive_bay_fan) | ||
498 | wf_control_set_max(drive_bay_fan); | ||
499 | } | ||
500 | |||
501 | static void pm112_tick(void) | ||
502 | { | ||
503 | int i, last_failure; | ||
504 | |||
505 | if (!started) { | ||
506 | started = 1; | ||
507 | for (i = 0; i < nr_cores; ++i) { | ||
508 | if (create_cpu_loop(i) < 0) { | ||
509 | failure_state = FAILURE_PERM; | ||
510 | set_fail_state(); | ||
511 | break; | ||
512 | } | ||
513 | } | ||
514 | DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax)); | ||
515 | |||
516 | #ifdef HACKED_OVERTEMP | ||
517 | cpu_all_tmax = 60 << 16; | ||
518 | #endif | ||
519 | } | ||
520 | |||
521 | /* Permanent failure, bail out */ | ||
522 | if (failure_state & FAILURE_PERM) | ||
523 | return; | ||
524 | /* Clear all failure bits except low overtemp which will be eventually | ||
525 | * cleared by the control loop itself | ||
526 | */ | ||
527 | last_failure = failure_state; | ||
528 | failure_state &= FAILURE_LOW_OVERTEMP; | ||
529 | cpu_fans_tick(); | ||
530 | backside_fan_tick(); | ||
531 | slots_fan_tick(); | ||
532 | drive_bay_fan_tick(); | ||
533 | |||
534 | DBG_LOTS("last_failure: 0x%x, failure_state: %x\n", | ||
535 | last_failure, failure_state); | ||
536 | |||
537 | /* Check for failures. Any failure causes cpufreq clamping */ | ||
538 | if (failure_state && last_failure == 0 && cpufreq_clamp) | ||
539 | wf_control_set_max(cpufreq_clamp); | ||
540 | if (failure_state == 0 && last_failure && cpufreq_clamp) | ||
541 | wf_control_set_min(cpufreq_clamp); | ||
542 | |||
543 | /* That's it for now, we might want to deal with other failures | ||
544 | * differently in the future though | ||
545 | */ | ||
546 | } | ||
547 | |||
548 | static void pm112_new_control(struct wf_control *ct) | ||
549 | { | ||
550 | int i, max_exhaust; | ||
551 | |||
552 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { | ||
553 | if (wf_get_control(ct) == 0) | ||
554 | cpufreq_clamp = ct; | ||
555 | } | ||
556 | |||
557 | for (i = 0; i < NR_CPU_FANS; ++i) { | ||
558 | if (!strcmp(ct->name, cpu_fan_names[i])) { | ||
559 | if (cpu_fans[i] == NULL && wf_get_control(ct) == 0) | ||
560 | cpu_fans[i] = ct; | ||
561 | break; | ||
562 | } | ||
563 | } | ||
564 | if (i >= NR_CPU_FANS) { | ||
565 | /* not a CPU fan, try the others */ | ||
566 | if (!strcmp(ct->name, "backside-fan")) { | ||
567 | if (backside_fan == NULL && wf_get_control(ct) == 0) | ||
568 | backside_fan = ct; | ||
569 | } else if (!strcmp(ct->name, "slots-fan")) { | ||
570 | if (slots_fan == NULL && wf_get_control(ct) == 0) | ||
571 | slots_fan = ct; | ||
572 | } else if (!strcmp(ct->name, "drive-bay-fan")) { | ||
573 | if (drive_bay_fan == NULL && wf_get_control(ct) == 0) | ||
574 | drive_bay_fan = ct; | ||
575 | } | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | for (i = 0; i < CPU_FANS_REQD; ++i) | ||
580 | if (cpu_fans[i] == NULL) | ||
581 | return; | ||
582 | |||
583 | /* work out pump scaling factors */ | ||
584 | max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]); | ||
585 | for (i = FIRST_PUMP; i <= LAST_PUMP; ++i) | ||
586 | if ((ct = cpu_fans[i]) != NULL) | ||
587 | cpu_fan_scale[i] = | ||
588 | ct->ops->get_max(ct) * 100 / max_exhaust; | ||
589 | |||
590 | have_all_controls = 1; | ||
591 | } | ||
592 | |||
593 | static void pm112_new_sensor(struct wf_sensor *sr) | ||
594 | { | ||
595 | unsigned int i; | ||
596 | |||
597 | if (have_all_sensors) | ||
598 | return; | ||
599 | if (!strncmp(sr->name, "cpu-temp-", 9)) { | ||
600 | i = sr->name[9] - '0'; | ||
601 | if (sr->name[10] == 0 && i < NR_CORES && | ||
602 | sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0) | ||
603 | sens_cpu_temp[i] = sr; | ||
604 | |||
605 | } else if (!strncmp(sr->name, "cpu-power-", 10)) { | ||
606 | i = sr->name[10] - '0'; | ||
607 | if (sr->name[11] == 0 && i < NR_CORES && | ||
608 | sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0) | ||
609 | sens_cpu_power[i] = sr; | ||
610 | } else if (!strcmp(sr->name, "hd-temp")) { | ||
611 | if (hd_temp == NULL && wf_get_sensor(sr) == 0) | ||
612 | hd_temp = sr; | ||
613 | } else if (!strcmp(sr->name, "slots-power")) { | ||
614 | if (slots_power == NULL && wf_get_sensor(sr) == 0) | ||
615 | slots_power = sr; | ||
616 | } else if (!strcmp(sr->name, "u4-temp")) { | ||
617 | if (u4_temp == NULL && wf_get_sensor(sr) == 0) | ||
618 | u4_temp = sr; | ||
619 | } else | ||
620 | return; | ||
621 | |||
622 | /* check if we have all the sensors we need */ | ||
623 | for (i = 0; i < nr_cores; ++i) | ||
624 | if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL) | ||
625 | return; | ||
626 | |||
627 | have_all_sensors = 1; | ||
628 | } | ||
629 | |||
630 | static int pm112_wf_notify(struct notifier_block *self, | ||
631 | unsigned long event, void *data) | ||
632 | { | ||
633 | switch (event) { | ||
634 | case WF_EVENT_NEW_SENSOR: | ||
635 | pm112_new_sensor(data); | ||
636 | break; | ||
637 | case WF_EVENT_NEW_CONTROL: | ||
638 | pm112_new_control(data); | ||
639 | break; | ||
640 | case WF_EVENT_TICK: | ||
641 | if (have_all_controls && have_all_sensors) | ||
642 | pm112_tick(); | ||
643 | } | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static struct notifier_block pm112_events = { | ||
648 | .notifier_call = pm112_wf_notify, | ||
649 | }; | ||
650 | |||
651 | static int wf_pm112_probe(struct device *dev) | ||
652 | { | ||
653 | wf_register_client(&pm112_events); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | static int wf_pm112_remove(struct device *dev) | ||
658 | { | ||
659 | wf_unregister_client(&pm112_events); | ||
660 | /* should release all sensors and controls */ | ||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static struct device_driver wf_pm112_driver = { | ||
665 | .name = "windfarm", | ||
666 | .bus = &platform_bus_type, | ||
667 | .probe = wf_pm112_probe, | ||
668 | .remove = wf_pm112_remove, | ||
669 | }; | ||
670 | |||
671 | static int __init wf_pm112_init(void) | ||
672 | { | ||
673 | struct device_node *cpu; | ||
674 | |||
675 | if (!machine_is_compatible("PowerMac11,2")) | ||
676 | return -ENODEV; | ||
677 | |||
678 | /* Count the number of CPU cores */ | ||
679 | nr_cores = 0; | ||
680 | for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; ) | ||
681 | ++nr_cores; | ||
682 | |||
683 | printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); | ||
684 | driver_register(&wf_pm112_driver); | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | static void __exit wf_pm112_exit(void) | ||
689 | { | ||
690 | driver_unregister(&wf_pm112_driver); | ||
691 | } | ||
692 | |||
693 | module_init(wf_pm112_init); | ||
694 | module_exit(wf_pm112_exit); | ||
695 | |||
696 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
697 | MODULE_DESCRIPTION("Thermal control for PowerMac11,2"); | ||
698 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index eb69a601e765..f1df6efcbe68 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c | |||
@@ -538,45 +538,6 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) | |||
538 | } | 538 | } |
539 | } | 539 | } |
540 | 540 | ||
541 | |||
542 | /* | ||
543 | * ****** Attributes ****** | ||
544 | * | ||
545 | */ | ||
546 | |||
547 | #define BUILD_SHOW_FUNC_FIX(name, data) \ | ||
548 | static ssize_t show_##name(struct device *dev, \ | ||
549 | struct device_attribute *attr, \ | ||
550 | char *buf) \ | ||
551 | { \ | ||
552 | ssize_t r; \ | ||
553 | s32 val = 0; \ | ||
554 | data->ops->get_value(data, &val); \ | ||
555 | r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ | ||
556 | return r; \ | ||
557 | } \ | ||
558 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
559 | |||
560 | |||
561 | #define BUILD_SHOW_FUNC_INT(name, data) \ | ||
562 | static ssize_t show_##name(struct device *dev, \ | ||
563 | struct device_attribute *attr, \ | ||
564 | char *buf) \ | ||
565 | { \ | ||
566 | s32 val = 0; \ | ||
567 | data->ops->get_value(data, &val); \ | ||
568 | return sprintf(buf, "%d", val); \ | ||
569 | } \ | ||
570 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
571 | |||
572 | BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); | ||
573 | BUILD_SHOW_FUNC_INT(sys_fan, fan_system); | ||
574 | BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); | ||
575 | |||
576 | BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); | ||
577 | BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); | ||
578 | BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); | ||
579 | |||
580 | /* | 541 | /* |
581 | * ****** Setup / Init / Misc ... ****** | 542 | * ****** Setup / Init / Misc ... ****** |
582 | * | 543 | * |
@@ -654,17 +615,13 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
654 | return; | 615 | return; |
655 | 616 | ||
656 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { | 617 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { |
657 | if (wf_get_control(ct) == 0) { | 618 | if (wf_get_control(ct) == 0) |
658 | fan_cpu_main = ct; | 619 | fan_cpu_main = ct; |
659 | device_create_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
660 | } | ||
661 | } | 620 | } |
662 | 621 | ||
663 | if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { | 622 | if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { |
664 | if (wf_get_control(ct) == 0) { | 623 | if (wf_get_control(ct) == 0) |
665 | fan_system = ct; | 624 | fan_system = ct; |
666 | device_create_file(wf_smu_dev, &dev_attr_sys_fan); | ||
667 | } | ||
668 | } | 625 | } |
669 | 626 | ||
670 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { | 627 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { |
@@ -683,10 +640,8 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
683 | } | 640 | } |
684 | 641 | ||
685 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { | 642 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { |
686 | if (wf_get_control(ct) == 0) { | 643 | if (wf_get_control(ct) == 0) |
687 | fan_hd = ct; | 644 | fan_hd = ct; |
688 | device_create_file(wf_smu_dev, &dev_attr_hd_fan); | ||
689 | } | ||
690 | } | 645 | } |
691 | 646 | ||
692 | if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) | 647 | if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) |
@@ -699,24 +654,18 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) | |||
699 | return; | 654 | return; |
700 | 655 | ||
701 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { | 656 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { |
702 | if (wf_get_sensor(sr) == 0) { | 657 | if (wf_get_sensor(sr) == 0) |
703 | sensor_cpu_power = sr; | 658 | sensor_cpu_power = sr; |
704 | device_create_file(wf_smu_dev, &dev_attr_cpu_power); | ||
705 | } | ||
706 | } | 659 | } |
707 | 660 | ||
708 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { | 661 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { |
709 | if (wf_get_sensor(sr) == 0) { | 662 | if (wf_get_sensor(sr) == 0) |
710 | sensor_cpu_temp = sr; | 663 | sensor_cpu_temp = sr; |
711 | device_create_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
712 | } | ||
713 | } | 664 | } |
714 | 665 | ||
715 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { | 666 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { |
716 | if (wf_get_sensor(sr) == 0) { | 667 | if (wf_get_sensor(sr) == 0) |
717 | sensor_hd_temp = sr; | 668 | sensor_hd_temp = sr; |
718 | device_create_file(wf_smu_dev, &dev_attr_hd_temp); | ||
719 | } | ||
720 | } | 669 | } |
721 | 670 | ||
722 | if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) | 671 | if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) |
@@ -794,32 +743,20 @@ static int wf_smu_remove(struct device *ddev) | |||
794 | * with that except by adding locks all over... I'll do that | 743 | * with that except by adding locks all over... I'll do that |
795 | * eventually but heh, who ever rmmod this module anyway ? | 744 | * eventually but heh, who ever rmmod this module anyway ? |
796 | */ | 745 | */ |
797 | if (sensor_cpu_power) { | 746 | if (sensor_cpu_power) |
798 | device_remove_file(wf_smu_dev, &dev_attr_cpu_power); | ||
799 | wf_put_sensor(sensor_cpu_power); | 747 | wf_put_sensor(sensor_cpu_power); |
800 | } | 748 | if (sensor_cpu_temp) |
801 | if (sensor_cpu_temp) { | ||
802 | device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
803 | wf_put_sensor(sensor_cpu_temp); | 749 | wf_put_sensor(sensor_cpu_temp); |
804 | } | 750 | if (sensor_hd_temp) |
805 | if (sensor_hd_temp) { | ||
806 | device_remove_file(wf_smu_dev, &dev_attr_hd_temp); | ||
807 | wf_put_sensor(sensor_hd_temp); | 751 | wf_put_sensor(sensor_hd_temp); |
808 | } | ||
809 | 752 | ||
810 | /* Release all controls */ | 753 | /* Release all controls */ |
811 | if (fan_cpu_main) { | 754 | if (fan_cpu_main) |
812 | device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
813 | wf_put_control(fan_cpu_main); | 755 | wf_put_control(fan_cpu_main); |
814 | } | 756 | if (fan_hd) |
815 | if (fan_hd) { | ||
816 | device_remove_file(wf_smu_dev, &dev_attr_hd_fan); | ||
817 | wf_put_control(fan_hd); | 757 | wf_put_control(fan_hd); |
818 | } | 758 | if (fan_system) |
819 | if (fan_system) { | ||
820 | device_remove_file(wf_smu_dev, &dev_attr_sys_fan); | ||
821 | wf_put_control(fan_system); | 759 | wf_put_control(fan_system); |
822 | } | ||
823 | if (cpufreq_clamp) | 760 | if (cpufreq_clamp) |
824 | wf_put_control(cpufreq_clamp); | 761 | wf_put_control(cpufreq_clamp); |
825 | 762 | ||
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 43243cf7410b..0d6372e96d32 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c | |||
@@ -458,45 +458,6 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st) | |||
458 | 458 | ||
459 | 459 | ||
460 | /* | 460 | /* |
461 | * ****** Attributes ****** | ||
462 | * | ||
463 | */ | ||
464 | |||
465 | #define BUILD_SHOW_FUNC_FIX(name, data) \ | ||
466 | static ssize_t show_##name(struct device *dev, \ | ||
467 | struct device_attribute *attr, \ | ||
468 | char *buf) \ | ||
469 | { \ | ||
470 | ssize_t r; \ | ||
471 | s32 val = 0; \ | ||
472 | data->ops->get_value(data, &val); \ | ||
473 | r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ | ||
474 | return r; \ | ||
475 | } \ | ||
476 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
477 | |||
478 | |||
479 | #define BUILD_SHOW_FUNC_INT(name, data) \ | ||
480 | static ssize_t show_##name(struct device *dev, \ | ||
481 | struct device_attribute *attr, \ | ||
482 | char *buf) \ | ||
483 | { \ | ||
484 | s32 val = 0; \ | ||
485 | data->ops->get_value(data, &val); \ | ||
486 | return sprintf(buf, "%d", val); \ | ||
487 | } \ | ||
488 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
489 | |||
490 | BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); | ||
491 | BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); | ||
492 | BUILD_SHOW_FUNC_INT(slots_fan, fan_slots); | ||
493 | |||
494 | BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); | ||
495 | BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); | ||
496 | BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); | ||
497 | BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power); | ||
498 | |||
499 | /* | ||
500 | * ****** Setup / Init / Misc ... ****** | 461 | * ****** Setup / Init / Misc ... ****** |
501 | * | 462 | * |
502 | */ | 463 | */ |
@@ -581,10 +542,8 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
581 | return; | 542 | return; |
582 | 543 | ||
583 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { | 544 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { |
584 | if (wf_get_control(ct) == 0) { | 545 | if (wf_get_control(ct) == 0) |
585 | fan_cpu_main = ct; | 546 | fan_cpu_main = ct; |
586 | device_create_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
587 | } | ||
588 | } | 547 | } |
589 | 548 | ||
590 | if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { | 549 | if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { |
@@ -603,17 +562,13 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
603 | } | 562 | } |
604 | 563 | ||
605 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { | 564 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { |
606 | if (wf_get_control(ct) == 0) { | 565 | if (wf_get_control(ct) == 0) |
607 | fan_hd = ct; | 566 | fan_hd = ct; |
608 | device_create_file(wf_smu_dev, &dev_attr_hd_fan); | ||
609 | } | ||
610 | } | 567 | } |
611 | 568 | ||
612 | if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { | 569 | if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { |
613 | if (wf_get_control(ct) == 0) { | 570 | if (wf_get_control(ct) == 0) |
614 | fan_slots = ct; | 571 | fan_slots = ct; |
615 | device_create_file(wf_smu_dev, &dev_attr_slots_fan); | ||
616 | } | ||
617 | } | 572 | } |
618 | 573 | ||
619 | if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && | 574 | if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && |
@@ -627,31 +582,23 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) | |||
627 | return; | 582 | return; |
628 | 583 | ||
629 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { | 584 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { |
630 | if (wf_get_sensor(sr) == 0) { | 585 | if (wf_get_sensor(sr) == 0) |
631 | sensor_cpu_power = sr; | 586 | sensor_cpu_power = sr; |
632 | device_create_file(wf_smu_dev, &dev_attr_cpu_power); | ||
633 | } | ||
634 | } | 587 | } |
635 | 588 | ||
636 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { | 589 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { |
637 | if (wf_get_sensor(sr) == 0) { | 590 | if (wf_get_sensor(sr) == 0) |
638 | sensor_cpu_temp = sr; | 591 | sensor_cpu_temp = sr; |
639 | device_create_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
640 | } | ||
641 | } | 592 | } |
642 | 593 | ||
643 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { | 594 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { |
644 | if (wf_get_sensor(sr) == 0) { | 595 | if (wf_get_sensor(sr) == 0) |
645 | sensor_hd_temp = sr; | 596 | sensor_hd_temp = sr; |
646 | device_create_file(wf_smu_dev, &dev_attr_hd_temp); | ||
647 | } | ||
648 | } | 597 | } |
649 | 598 | ||
650 | if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { | 599 | if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { |
651 | if (wf_get_sensor(sr) == 0) { | 600 | if (wf_get_sensor(sr) == 0) |
652 | sensor_slots_power = sr; | 601 | sensor_slots_power = sr; |
653 | device_create_file(wf_smu_dev, &dev_attr_slots_power); | ||
654 | } | ||
655 | } | 602 | } |
656 | 603 | ||
657 | if (sensor_cpu_power && sensor_cpu_temp && | 604 | if (sensor_cpu_power && sensor_cpu_temp && |
@@ -720,40 +667,26 @@ static int wf_smu_remove(struct device *ddev) | |||
720 | * with that except by adding locks all over... I'll do that | 667 | * with that except by adding locks all over... I'll do that |
721 | * eventually but heh, who ever rmmod this module anyway ? | 668 | * eventually but heh, who ever rmmod this module anyway ? |
722 | */ | 669 | */ |
723 | if (sensor_cpu_power) { | 670 | if (sensor_cpu_power) |
724 | device_remove_file(wf_smu_dev, &dev_attr_cpu_power); | ||
725 | wf_put_sensor(sensor_cpu_power); | 671 | wf_put_sensor(sensor_cpu_power); |
726 | } | 672 | if (sensor_cpu_temp) |
727 | if (sensor_cpu_temp) { | ||
728 | device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
729 | wf_put_sensor(sensor_cpu_temp); | 673 | wf_put_sensor(sensor_cpu_temp); |
730 | } | 674 | if (sensor_hd_temp) |
731 | if (sensor_hd_temp) { | ||
732 | device_remove_file(wf_smu_dev, &dev_attr_hd_temp); | ||
733 | wf_put_sensor(sensor_hd_temp); | 675 | wf_put_sensor(sensor_hd_temp); |
734 | } | 676 | if (sensor_slots_power) |
735 | if (sensor_slots_power) { | ||
736 | device_remove_file(wf_smu_dev, &dev_attr_slots_power); | ||
737 | wf_put_sensor(sensor_slots_power); | 677 | wf_put_sensor(sensor_slots_power); |
738 | } | ||
739 | 678 | ||
740 | /* Release all controls */ | 679 | /* Release all controls */ |
741 | if (fan_cpu_main) { | 680 | if (fan_cpu_main) |
742 | device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
743 | wf_put_control(fan_cpu_main); | 681 | wf_put_control(fan_cpu_main); |
744 | } | ||
745 | if (fan_cpu_second) | 682 | if (fan_cpu_second) |
746 | wf_put_control(fan_cpu_second); | 683 | wf_put_control(fan_cpu_second); |
747 | if (fan_cpu_third) | 684 | if (fan_cpu_third) |
748 | wf_put_control(fan_cpu_third); | 685 | wf_put_control(fan_cpu_third); |
749 | if (fan_hd) { | 686 | if (fan_hd) |
750 | device_remove_file(wf_smu_dev, &dev_attr_hd_fan); | ||
751 | wf_put_control(fan_hd); | 687 | wf_put_control(fan_hd); |
752 | } | 688 | if (fan_slots) |
753 | if (fan_slots) { | ||
754 | device_remove_file(wf_smu_dev, &dev_attr_slots_fan); | ||
755 | wf_put_control(fan_slots); | 689 | wf_put_control(fan_slots); |
756 | } | ||
757 | if (cpufreq_clamp) | 690 | if (cpufreq_clamp) |
758 | wf_put_control(cpufreq_clamp); | 691 | wf_put_control(cpufreq_clamp); |
759 | 692 | ||
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index 4d811600bdab..a9e88edc0c72 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "windfarm.h" | 25 | #include "windfarm.h" |
26 | 26 | ||
27 | #define VERSION "0.3" | 27 | #define VERSION "0.4" |
28 | 28 | ||
29 | #undef DEBUG | 29 | #undef DEBUG |
30 | 30 | ||
@@ -34,6 +34,8 @@ | |||
34 | #define DBG(args...) do { } while(0) | 34 | #define DBG(args...) do { } while(0) |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | static int smu_supports_new_fans_ops = 1; | ||
38 | |||
37 | /* | 39 | /* |
38 | * SMU fans control object | 40 | * SMU fans control object |
39 | */ | 41 | */ |
@@ -59,23 +61,49 @@ static int smu_set_fan(int pwm, u8 id, u16 value) | |||
59 | 61 | ||
60 | /* Fill SMU command structure */ | 62 | /* Fill SMU command structure */ |
61 | cmd.cmd = SMU_CMD_FAN_COMMAND; | 63 | cmd.cmd = SMU_CMD_FAN_COMMAND; |
62 | cmd.data_len = 14; | 64 | |
65 | /* The SMU has an "old" and a "new" way of setting the fan speed | ||
66 | * Unfortunately, I found no reliable way to know which one works | ||
67 | * on a given machine model. After some investigations it appears | ||
68 | * that MacOS X just tries the new one, and if it fails fallbacks | ||
69 | * to the old ones ... Ugh. | ||
70 | */ | ||
71 | retry: | ||
72 | if (smu_supports_new_fans_ops) { | ||
73 | buffer[0] = 0x30; | ||
74 | buffer[1] = id; | ||
75 | *((u16 *)(&buffer[2])) = value; | ||
76 | cmd.data_len = 4; | ||
77 | } else { | ||
78 | if (id > 7) | ||
79 | return -EINVAL; | ||
80 | /* Fill argument buffer */ | ||
81 | memset(buffer, 0, 16); | ||
82 | buffer[0] = pwm ? 0x10 : 0x00; | ||
83 | buffer[1] = 0x01 << id; | ||
84 | *((u16 *)&buffer[2 + id * 2]) = value; | ||
85 | cmd.data_len = 14; | ||
86 | } | ||
87 | |||
63 | cmd.reply_len = 16; | 88 | cmd.reply_len = 16; |
64 | cmd.data_buf = cmd.reply_buf = buffer; | 89 | cmd.data_buf = cmd.reply_buf = buffer; |
65 | cmd.status = 0; | 90 | cmd.status = 0; |
66 | cmd.done = smu_done_complete; | 91 | cmd.done = smu_done_complete; |
67 | cmd.misc = ∁ | 92 | cmd.misc = ∁ |
68 | 93 | ||
69 | /* Fill argument buffer */ | ||
70 | memset(buffer, 0, 16); | ||
71 | buffer[0] = pwm ? 0x10 : 0x00; | ||
72 | buffer[1] = 0x01 << id; | ||
73 | *((u16 *)&buffer[2 + id * 2]) = value; | ||
74 | |||
75 | rc = smu_queue_cmd(&cmd); | 94 | rc = smu_queue_cmd(&cmd); |
76 | if (rc) | 95 | if (rc) |
77 | return rc; | 96 | return rc; |
78 | wait_for_completion(&comp); | 97 | wait_for_completion(&comp); |
98 | |||
99 | /* Handle fallback (see coment above) */ | ||
100 | if (cmd.status != 0 && smu_supports_new_fans_ops) { | ||
101 | printk(KERN_WARNING "windfarm: SMU failed new fan command " | ||
102 | "falling back to old method\n"); | ||
103 | smu_supports_new_fans_ops = 0; | ||
104 | goto retry; | ||
105 | } | ||
106 | |||
79 | return cmd.status; | 107 | return cmd.status; |
80 | } | 108 | } |
81 | 109 | ||
@@ -158,19 +186,29 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, | |||
158 | 186 | ||
159 | /* Names used on desktop models */ | 187 | /* Names used on desktop models */ |
160 | if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || | 188 | if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || |
161 | !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan")) | 189 | !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") || |
190 | !strcmp(l, "CPU A EXHAUST")) | ||
162 | fct->ctrl.name = "cpu-rear-fan-0"; | 191 | fct->ctrl.name = "cpu-rear-fan-0"; |
163 | else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1")) | 192 | else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") || |
193 | !strcmp(l, "CPU B EXHAUST")) | ||
164 | fct->ctrl.name = "cpu-rear-fan-1"; | 194 | fct->ctrl.name = "cpu-rear-fan-1"; |
165 | else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || | 195 | else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || |
166 | !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan")) | 196 | !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") || |
197 | !strcmp(l, "CPU A INTAKE")) | ||
167 | fct->ctrl.name = "cpu-front-fan-0"; | 198 | fct->ctrl.name = "cpu-front-fan-0"; |
168 | else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1")) | 199 | else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") || |
200 | !strcmp(l, "CPU B INTAKE")) | ||
169 | fct->ctrl.name = "cpu-front-fan-1"; | 201 | fct->ctrl.name = "cpu-front-fan-1"; |
170 | else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan")) | 202 | else if (!strcmp(l, "CPU A PUMP")) |
203 | fct->ctrl.name = "cpu-pump-0"; | ||
204 | else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || | ||
205 | !strcmp(l, "EXPANSION SLOTS INTAKE")) | ||
171 | fct->ctrl.name = "slots-fan"; | 206 | fct->ctrl.name = "slots-fan"; |
172 | else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay")) | 207 | else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") || |
208 | !strcmp(l, "DRIVE BAY A INTAKE")) | ||
173 | fct->ctrl.name = "drive-bay-fan"; | 209 | fct->ctrl.name = "drive-bay-fan"; |
210 | else if (!strcmp(l, "BACKSIDE")) | ||
211 | fct->ctrl.name = "backside-fan"; | ||
174 | 212 | ||
175 | /* Names used on iMac models */ | 213 | /* Names used on iMac models */ |
176 | if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) | 214 | if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) |
@@ -223,7 +261,8 @@ static int __init smu_controls_init(void) | |||
223 | 261 | ||
224 | /* Look for RPM fans */ | 262 | /* Look for RPM fans */ |
225 | for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) | 263 | for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) |
226 | if (!strcmp(fans->name, "rpm-fans")) | 264 | if (!strcmp(fans->name, "rpm-fans") || |
265 | device_is_compatible(fans, "smu-rpm-fans")) | ||
227 | break; | 266 | break; |
228 | for (fan = NULL; | 267 | for (fan = NULL; |
229 | fans && (fan = of_get_next_child(fans, fan)) != NULL;) { | 268 | fans && (fan = of_get_next_child(fans, fan)) != NULL;) { |
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c new file mode 100644 index 000000000000..3a32c59494f2 --- /dev/null +++ b/drivers/macintosh/windfarm_smu_sat.c | |||
@@ -0,0 +1,418 @@ | |||
1 | /* | ||
2 | * Windfarm PowerMac thermal control. SMU "satellite" controller sensors. | ||
3 | * | ||
4 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
5 | * | ||
6 | * Released under the terms of the GNU GPL v2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/wait.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/i2c-dev.h> | ||
17 | #include <asm/semaphore.h> | ||
18 | #include <asm/prom.h> | ||
19 | #include <asm/smu.h> | ||
20 | #include <asm/pmac_low_i2c.h> | ||
21 | |||
22 | #include "windfarm.h" | ||
23 | |||
24 | #define VERSION "0.2" | ||
25 | |||
26 | #define DEBUG | ||
27 | |||
28 | #ifdef DEBUG | ||
29 | #define DBG(args...) printk(args) | ||
30 | #else | ||
31 | #define DBG(args...) do { } while(0) | ||
32 | #endif | ||
33 | |||
34 | /* If the cache is older than 800ms we'll refetch it */ | ||
35 | #define MAX_AGE msecs_to_jiffies(800) | ||
36 | |||
37 | struct wf_sat { | ||
38 | int nr; | ||
39 | atomic_t refcnt; | ||
40 | struct semaphore mutex; | ||
41 | unsigned long last_read; /* jiffies when cache last updated */ | ||
42 | u8 cache[16]; | ||
43 | struct i2c_client i2c; | ||
44 | struct device_node *node; | ||
45 | }; | ||
46 | |||
47 | static struct wf_sat *sats[2]; | ||
48 | |||
49 | struct wf_sat_sensor { | ||
50 | int index; | ||
51 | int index2; /* used for power sensors */ | ||
52 | int shift; | ||
53 | struct wf_sat *sat; | ||
54 | struct wf_sensor sens; | ||
55 | }; | ||
56 | |||
57 | #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) | ||
58 | #define i2c_to_sat(c) container_of(c, struct wf_sat, i2c) | ||
59 | |||
60 | static int wf_sat_attach(struct i2c_adapter *adapter); | ||
61 | static int wf_sat_detach(struct i2c_client *client); | ||
62 | |||
63 | static struct i2c_driver wf_sat_driver = { | ||
64 | .driver = { | ||
65 | .name = "wf_smu_sat", | ||
66 | }, | ||
67 | .attach_adapter = wf_sat_attach, | ||
68 | .detach_client = wf_sat_detach, | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested | ||
73 | * length down to the low-level driver, so we use this, which | ||
74 | * works well enough with the SMU i2c driver code... | ||
75 | */ | ||
76 | static int sat_read_block(struct i2c_client *client, u8 command, | ||
77 | u8 *values, int len) | ||
78 | { | ||
79 | union i2c_smbus_data data; | ||
80 | int err; | ||
81 | |||
82 | data.block[0] = len; | ||
83 | err = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
84 | I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA, | ||
85 | &data); | ||
86 | if (!err) | ||
87 | memcpy(values, data.block, len); | ||
88 | return err; | ||
89 | } | ||
90 | |||
91 | struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | ||
92 | unsigned int *size) | ||
93 | { | ||
94 | struct wf_sat *sat; | ||
95 | int err; | ||
96 | unsigned int i, len; | ||
97 | u8 *buf; | ||
98 | u8 data[4]; | ||
99 | |||
100 | /* TODO: Add the resulting partition to the device-tree */ | ||
101 | |||
102 | if (sat_id > 1 || (sat = sats[sat_id]) == NULL) | ||
103 | return NULL; | ||
104 | |||
105 | err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); | ||
106 | if (err) { | ||
107 | printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | len = i2c_smbus_read_word_data(&sat->i2c, 9); | ||
112 | if (len < 0) { | ||
113 | printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); | ||
114 | return NULL; | ||
115 | } | ||
116 | if (len == 0) { | ||
117 | printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id); | ||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | len = le16_to_cpu(len); | ||
122 | len = (len + 3) & ~3; | ||
123 | buf = kmalloc(len, GFP_KERNEL); | ||
124 | if (buf == NULL) | ||
125 | return NULL; | ||
126 | |||
127 | for (i = 0; i < len; i += 4) { | ||
128 | err = sat_read_block(&sat->i2c, 0xa, data, 4); | ||
129 | if (err) { | ||
130 | printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", | ||
131 | err); | ||
132 | goto fail; | ||
133 | } | ||
134 | buf[i] = data[1]; | ||
135 | buf[i+1] = data[0]; | ||
136 | buf[i+2] = data[3]; | ||
137 | buf[i+3] = data[2]; | ||
138 | } | ||
139 | #ifdef DEBUG | ||
140 | DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id); | ||
141 | for (i = 0; i < len; ++i) | ||
142 | DBG(" %x", buf[i]); | ||
143 | DBG("\n"); | ||
144 | #endif | ||
145 | |||
146 | if (size) | ||
147 | *size = len; | ||
148 | return (struct smu_sdbp_header *) buf; | ||
149 | |||
150 | fail: | ||
151 | kfree(buf); | ||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | /* refresh the cache */ | ||
156 | static int wf_sat_read_cache(struct wf_sat *sat) | ||
157 | { | ||
158 | int err; | ||
159 | |||
160 | err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16); | ||
161 | if (err) | ||
162 | return err; | ||
163 | sat->last_read = jiffies; | ||
164 | #ifdef LOTSA_DEBUG | ||
165 | { | ||
166 | int i; | ||
167 | DBG(KERN_DEBUG "wf_sat_get: data is"); | ||
168 | for (i = 0; i < 16; ++i) | ||
169 | DBG(" %.2x", sat->cache[i]); | ||
170 | DBG("\n"); | ||
171 | } | ||
172 | #endif | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int wf_sat_get(struct wf_sensor *sr, s32 *value) | ||
177 | { | ||
178 | struct wf_sat_sensor *sens = wf_to_sat(sr); | ||
179 | struct wf_sat *sat = sens->sat; | ||
180 | int i, err; | ||
181 | s32 val; | ||
182 | |||
183 | if (sat->i2c.adapter == NULL) | ||
184 | return -ENODEV; | ||
185 | |||
186 | down(&sat->mutex); | ||
187 | if (time_after(jiffies, (sat->last_read + MAX_AGE))) { | ||
188 | err = wf_sat_read_cache(sat); | ||
189 | if (err) | ||
190 | goto fail; | ||
191 | } | ||
192 | |||
193 | i = sens->index * 2; | ||
194 | val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift; | ||
195 | if (sens->index2 >= 0) { | ||
196 | i = sens->index2 * 2; | ||
197 | /* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */ | ||
198 | val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4; | ||
199 | } | ||
200 | |||
201 | *value = val; | ||
202 | err = 0; | ||
203 | |||
204 | fail: | ||
205 | up(&sat->mutex); | ||
206 | return err; | ||
207 | } | ||
208 | |||
209 | static void wf_sat_release(struct wf_sensor *sr) | ||
210 | { | ||
211 | struct wf_sat_sensor *sens = wf_to_sat(sr); | ||
212 | struct wf_sat *sat = sens->sat; | ||
213 | |||
214 | if (atomic_dec_and_test(&sat->refcnt)) { | ||
215 | if (sat->i2c.adapter) { | ||
216 | i2c_detach_client(&sat->i2c); | ||
217 | sat->i2c.adapter = NULL; | ||
218 | } | ||
219 | if (sat->nr >= 0) | ||
220 | sats[sat->nr] = NULL; | ||
221 | kfree(sat); | ||
222 | } | ||
223 | kfree(sens); | ||
224 | } | ||
225 | |||
226 | static struct wf_sensor_ops wf_sat_ops = { | ||
227 | .get_value = wf_sat_get, | ||
228 | .release = wf_sat_release, | ||
229 | .owner = THIS_MODULE, | ||
230 | }; | ||
231 | |||
232 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | ||
233 | { | ||
234 | struct wf_sat *sat; | ||
235 | struct wf_sat_sensor *sens; | ||
236 | u32 *reg; | ||
237 | char *loc, *type; | ||
238 | u8 addr, chip, core; | ||
239 | struct device_node *child; | ||
240 | int shift, cpu, index; | ||
241 | char *name; | ||
242 | int vsens[2], isens[2]; | ||
243 | |||
244 | reg = (u32 *) get_property(dev, "reg", NULL); | ||
245 | if (reg == NULL) | ||
246 | return; | ||
247 | addr = *reg; | ||
248 | DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); | ||
249 | |||
250 | sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); | ||
251 | if (sat == NULL) | ||
252 | return; | ||
253 | sat->nr = -1; | ||
254 | sat->node = of_node_get(dev); | ||
255 | atomic_set(&sat->refcnt, 0); | ||
256 | init_MUTEX(&sat->mutex); | ||
257 | sat->i2c.addr = (addr >> 1) & 0x7f; | ||
258 | sat->i2c.adapter = adapter; | ||
259 | sat->i2c.driver = &wf_sat_driver; | ||
260 | strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1); | ||
261 | |||
262 | if (i2c_attach_client(&sat->i2c)) { | ||
263 | printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); | ||
264 | goto fail; | ||
265 | } | ||
266 | |||
267 | vsens[0] = vsens[1] = -1; | ||
268 | isens[0] = isens[1] = -1; | ||
269 | child = NULL; | ||
270 | while ((child = of_get_next_child(dev, child)) != NULL) { | ||
271 | reg = (u32 *) get_property(child, "reg", NULL); | ||
272 | type = get_property(child, "device_type", NULL); | ||
273 | loc = get_property(child, "location", NULL); | ||
274 | if (reg == NULL || loc == NULL) | ||
275 | continue; | ||
276 | |||
277 | /* the cooked sensors are between 0x30 and 0x37 */ | ||
278 | if (*reg < 0x30 || *reg > 0x37) | ||
279 | continue; | ||
280 | index = *reg - 0x30; | ||
281 | |||
282 | /* expect location to be CPU [AB][01] ... */ | ||
283 | if (strncmp(loc, "CPU ", 4) != 0) | ||
284 | continue; | ||
285 | chip = loc[4] - 'A'; | ||
286 | core = loc[5] - '0'; | ||
287 | if (chip > 1 || core > 1) { | ||
288 | printk(KERN_ERR "wf_sat_create: don't understand " | ||
289 | "location %s for %s\n", loc, child->full_name); | ||
290 | continue; | ||
291 | } | ||
292 | cpu = 2 * chip + core; | ||
293 | if (sat->nr < 0) | ||
294 | sat->nr = chip; | ||
295 | else if (sat->nr != chip) { | ||
296 | printk(KERN_ERR "wf_sat_create: can't cope with " | ||
297 | "multiple CPU chips on one SAT (%s)\n", loc); | ||
298 | continue; | ||
299 | } | ||
300 | |||
301 | if (strcmp(type, "voltage-sensor") == 0) { | ||
302 | name = "cpu-voltage"; | ||
303 | shift = 4; | ||
304 | vsens[core] = index; | ||
305 | } else if (strcmp(type, "current-sensor") == 0) { | ||
306 | name = "cpu-current"; | ||
307 | shift = 8; | ||
308 | isens[core] = index; | ||
309 | } else if (strcmp(type, "temp-sensor") == 0) { | ||
310 | name = "cpu-temp"; | ||
311 | shift = 10; | ||
312 | } else | ||
313 | continue; /* hmmm shouldn't happen */ | ||
314 | |||
315 | /* the +16 is enough for "cpu-voltage-n" */ | ||
316 | sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); | ||
317 | if (sens == NULL) { | ||
318 | printk(KERN_ERR "wf_sat_create: couldn't create " | ||
319 | "%s sensor %d (no memory)\n", name, cpu); | ||
320 | continue; | ||
321 | } | ||
322 | sens->index = index; | ||
323 | sens->index2 = -1; | ||
324 | sens->shift = shift; | ||
325 | sens->sat = sat; | ||
326 | atomic_inc(&sat->refcnt); | ||
327 | sens->sens.ops = &wf_sat_ops; | ||
328 | sens->sens.name = (char *) (sens + 1); | ||
329 | snprintf(sens->sens.name, 16, "%s-%d", name, cpu); | ||
330 | |||
331 | if (wf_register_sensor(&sens->sens)) { | ||
332 | atomic_dec(&sat->refcnt); | ||
333 | kfree(sens); | ||
334 | } | ||
335 | } | ||
336 | |||
337 | /* make the power sensors */ | ||
338 | for (core = 0; core < 2; ++core) { | ||
339 | if (vsens[core] < 0 || isens[core] < 0) | ||
340 | continue; | ||
341 | cpu = 2 * sat->nr + core; | ||
342 | sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); | ||
343 | if (sens == NULL) { | ||
344 | printk(KERN_ERR "wf_sat_create: couldn't create power " | ||
345 | "sensor %d (no memory)\n", cpu); | ||
346 | continue; | ||
347 | } | ||
348 | sens->index = vsens[core]; | ||
349 | sens->index2 = isens[core]; | ||
350 | sens->shift = 0; | ||
351 | sens->sat = sat; | ||
352 | atomic_inc(&sat->refcnt); | ||
353 | sens->sens.ops = &wf_sat_ops; | ||
354 | sens->sens.name = (char *) (sens + 1); | ||
355 | snprintf(sens->sens.name, 16, "cpu-power-%d", cpu); | ||
356 | |||
357 | if (wf_register_sensor(&sens->sens)) { | ||
358 | atomic_dec(&sat->refcnt); | ||
359 | kfree(sens); | ||
360 | } | ||
361 | } | ||
362 | |||
363 | if (sat->nr >= 0) | ||
364 | sats[sat->nr] = sat; | ||
365 | |||
366 | return; | ||
367 | |||
368 | fail: | ||
369 | kfree(sat); | ||
370 | } | ||
371 | |||
372 | static int wf_sat_attach(struct i2c_adapter *adapter) | ||
373 | { | ||
374 | struct device_node *busnode, *dev = NULL; | ||
375 | struct pmac_i2c_bus *bus; | ||
376 | |||
377 | bus = pmac_i2c_adapter_to_bus(adapter); | ||
378 | if (bus == NULL) | ||
379 | return -ENODEV; | ||
380 | busnode = pmac_i2c_get_bus_node(bus); | ||
381 | |||
382 | while ((dev = of_get_next_child(busnode, dev)) != NULL) | ||
383 | if (device_is_compatible(dev, "smu-sat")) | ||
384 | wf_sat_create(adapter, dev); | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int wf_sat_detach(struct i2c_client *client) | ||
389 | { | ||
390 | struct wf_sat *sat = i2c_to_sat(client); | ||
391 | |||
392 | /* XXX TODO */ | ||
393 | |||
394 | sat->i2c.adapter = NULL; | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int __init sat_sensors_init(void) | ||
399 | { | ||
400 | int err; | ||
401 | |||
402 | err = i2c_add_driver(&wf_sat_driver); | ||
403 | if (err < 0) | ||
404 | return err; | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static void __exit sat_sensors_exit(void) | ||
409 | { | ||
410 | i2c_del_driver(&wf_sat_driver); | ||
411 | } | ||
412 | |||
413 | module_init(sat_sensors_init); | ||
414 | /*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ | ||
415 | |||
416 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
417 | MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control"); | ||
418 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index 1a00d9c75a23..bed25dcf8a1e 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c | |||
@@ -220,14 +220,29 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node) | |||
220 | !strcmp(l, "CPU T-Diode")) { | 220 | !strcmp(l, "CPU T-Diode")) { |
221 | ads->sens.ops = &smu_cputemp_ops; | 221 | ads->sens.ops = &smu_cputemp_ops; |
222 | ads->sens.name = "cpu-temp"; | 222 | ads->sens.name = "cpu-temp"; |
223 | if (cpudiode == NULL) { | ||
224 | DBG("wf: cpudiode partition (%02x) not found\n", | ||
225 | SMU_SDB_CPUDIODE_ID); | ||
226 | goto fail; | ||
227 | } | ||
223 | } else if (!strcmp(c, "current-sensor") && | 228 | } else if (!strcmp(c, "current-sensor") && |
224 | !strcmp(l, "CPU Current")) { | 229 | !strcmp(l, "CPU Current")) { |
225 | ads->sens.ops = &smu_cpuamp_ops; | 230 | ads->sens.ops = &smu_cpuamp_ops; |
226 | ads->sens.name = "cpu-current"; | 231 | ads->sens.name = "cpu-current"; |
232 | if (cpuvcp == NULL) { | ||
233 | DBG("wf: cpuvcp partition (%02x) not found\n", | ||
234 | SMU_SDB_CPUVCP_ID); | ||
235 | goto fail; | ||
236 | } | ||
227 | } else if (!strcmp(c, "voltage-sensor") && | 237 | } else if (!strcmp(c, "voltage-sensor") && |
228 | !strcmp(l, "CPU Voltage")) { | 238 | !strcmp(l, "CPU Voltage")) { |
229 | ads->sens.ops = &smu_cpuvolt_ops; | 239 | ads->sens.ops = &smu_cpuvolt_ops; |
230 | ads->sens.name = "cpu-voltage"; | 240 | ads->sens.name = "cpu-voltage"; |
241 | if (cpuvcp == NULL) { | ||
242 | DBG("wf: cpuvcp partition (%02x) not found\n", | ||
243 | SMU_SDB_CPUVCP_ID); | ||
244 | goto fail; | ||
245 | } | ||
231 | } else if (!strcmp(c, "power-sensor") && | 246 | } else if (!strcmp(c, "power-sensor") && |
232 | !strcmp(l, "Slots Power")) { | 247 | !strcmp(l, "Slots Power")) { |
233 | ads->sens.ops = &smu_slotspow_ops; | 248 | ads->sens.ops = &smu_slotspow_ops; |
@@ -365,29 +380,22 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps) | |||
365 | return NULL; | 380 | return NULL; |
366 | } | 381 | } |
367 | 382 | ||
368 | static int smu_fetch_param_partitions(void) | 383 | static void smu_fetch_param_partitions(void) |
369 | { | 384 | { |
370 | struct smu_sdbp_header *hdr; | 385 | struct smu_sdbp_header *hdr; |
371 | 386 | ||
372 | /* Get CPU voltage/current/power calibration data */ | 387 | /* Get CPU voltage/current/power calibration data */ |
373 | hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); | 388 | hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); |
374 | if (hdr == NULL) { | 389 | if (hdr != NULL) { |
375 | DBG("wf: cpuvcp partition (%02x) not found\n", | 390 | cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; |
376 | SMU_SDB_CPUVCP_ID); | 391 | /* Keep version around */ |
377 | return -ENODEV; | 392 | cpuvcp_version = hdr->version; |
378 | } | 393 | } |
379 | cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; | ||
380 | /* Keep version around */ | ||
381 | cpuvcp_version = hdr->version; | ||
382 | 394 | ||
383 | /* Get CPU diode calibration data */ | 395 | /* Get CPU diode calibration data */ |
384 | hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); | 396 | hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); |
385 | if (hdr == NULL) { | 397 | if (hdr != NULL) |
386 | DBG("wf: cpudiode partition (%02x) not found\n", | 398 | cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; |
387 | SMU_SDB_CPUDIODE_ID); | ||
388 | return -ENODEV; | ||
389 | } | ||
390 | cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; | ||
391 | 399 | ||
392 | /* Get slots power calibration data if any */ | 400 | /* Get slots power calibration data if any */ |
393 | hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); | 401 | hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); |
@@ -398,23 +406,18 @@ static int smu_fetch_param_partitions(void) | |||
398 | hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); | 406 | hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); |
399 | if (hdr != NULL) | 407 | if (hdr != NULL) |
400 | debugswitches = (u8 *)&hdr[1]; | 408 | debugswitches = (u8 *)&hdr[1]; |
401 | |||
402 | return 0; | ||
403 | } | 409 | } |
404 | 410 | ||
405 | static int __init smu_sensors_init(void) | 411 | static int __init smu_sensors_init(void) |
406 | { | 412 | { |
407 | struct device_node *smu, *sensors, *s; | 413 | struct device_node *smu, *sensors, *s; |
408 | struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; | 414 | struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; |
409 | int rc; | ||
410 | 415 | ||
411 | if (!smu_present()) | 416 | if (!smu_present()) |
412 | return -ENODEV; | 417 | return -ENODEV; |
413 | 418 | ||
414 | /* Get parameters partitions */ | 419 | /* Get parameters partitions */ |
415 | rc = smu_fetch_param_partitions(); | 420 | smu_fetch_param_partitions(); |
416 | if (rc) | ||
417 | return rc; | ||
418 | 421 | ||
419 | smu = of_find_node_by_type(NULL, "smu"); | 422 | smu = of_find_node_by_type(NULL, "smu"); |
420 | if (smu == NULL) | 423 | if (smu == NULL) |
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 130ea7f21f5e..12ebaf8bddca 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c | |||
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { | |||
151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, | 151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, |
152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, | 152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, |
153 | }, | 153 | }, |
154 | { 0 }, | 154 | { NULL }, |
155 | } | 155 | } |
156 | }; | 156 | }; |
157 | 157 | ||
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { | |||
192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, | 192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, |
193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, | 193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, |
194 | }, | 194 | }, |
195 | { 0 }, | 195 | { NULL }, |
196 | } | 196 | } |
197 | }; | 197 | }; |
198 | 198 | ||
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 028204956bb0..3835235b68df 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { | |||
247 | .cold_ids = { &vp7045_usb_table[2], NULL }, | 247 | .cold_ids = { &vp7045_usb_table[2], NULL }, |
248 | .warm_ids = { &vp7045_usb_table[3], NULL }, | 248 | .warm_ids = { &vp7045_usb_table[3], NULL }, |
249 | }, | 249 | }, |
250 | { 0 }, | 250 | { NULL }, |
251 | } | 251 | } |
252 | }; | 252 | }; |
253 | 253 | ||
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 297c32ab51e3..840fe0177121 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c | |||
@@ -167,29 +167,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user | |||
167 | if (kp->clipcount > 2048) | 167 | if (kp->clipcount > 2048) |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | if (kp->clipcount) { | 169 | if (kp->clipcount) { |
170 | struct v4l2_clip32 *uclips = compat_ptr(up->clips); | 170 | struct v4l2_clip32 __user *uclips; |
171 | struct v4l2_clip *kclips; | 171 | struct v4l2_clip __user *kclips; |
172 | int n = kp->clipcount; | 172 | int n = kp->clipcount; |
173 | compat_caddr_t p; | ||
173 | 174 | ||
175 | if (get_user(p, &up->clips)) | ||
176 | return -EFAULT; | ||
177 | uclips = compat_ptr(p); | ||
174 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); | 178 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); |
175 | kp->clips = kclips; | 179 | kp->clips = kclips; |
176 | while (--n >= 0) { | 180 | while (--n >= 0) { |
177 | if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) || | 181 | if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c))) |
178 | copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c))) | 182 | return -EFAULT; |
183 | if (put_user(n ? kclips + 1 : NULL, &kclips->next)) | ||
179 | return -EFAULT; | 184 | return -EFAULT; |
180 | kclips->next = n ? kclips + 1 : 0; | ||
181 | uclips += 1; | 185 | uclips += 1; |
182 | kclips += 1; | 186 | kclips += 1; |
183 | } | 187 | } |
184 | } else | 188 | } else |
185 | kp->clips = 0; | 189 | kp->clips = NULL; |
186 | return 0; | 190 | return 0; |
187 | } | 191 | } |
188 | 192 | ||
189 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) | 193 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) |
190 | { | 194 | { |
191 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) || | 195 | if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) || |
192 | copy_to_user(&up->w, &kp->w, sizeof(up->w)) || | ||
193 | put_user(kp->field, &up->field) || | 196 | put_user(kp->field, &up->field) || |
194 | put_user(kp->chromakey, &up->chromakey) || | 197 | put_user(kp->chromakey, &up->chromakey) || |
195 | put_user(kp->clipcount, &up->clipcount)) | 198 | put_user(kp->clipcount, &up->clipcount)) |
@@ -199,33 +202,29 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user | |||
199 | 202 | ||
200 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | 203 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
201 | { | 204 | { |
202 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) || | 205 | if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) |
203 | copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) | 206 | return -EFAULT; |
204 | return -EFAULT; | ||
205 | return 0; | 207 | return 0; |
206 | } | 208 | } |
207 | 209 | ||
208 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | 210 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
209 | { | 211 | { |
210 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) || | 212 | if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) |
211 | copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) | 213 | return -EFAULT; |
212 | return -EFAULT; | ||
213 | return 0; | 214 | return 0; |
214 | } | 215 | } |
215 | 216 | ||
216 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | 217 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
217 | { | 218 | { |
218 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) || | 219 | if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) |
219 | copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) | 220 | return -EFAULT; |
220 | return -EFAULT; | ||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | 223 | ||
224 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | 224 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
225 | { | 225 | { |
226 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) || | 226 | if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) |
227 | copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) | 227 | return -EFAULT; |
228 | return -EFAULT; | ||
229 | return 0; | 228 | return 0; |
230 | } | 229 | } |
231 | 230 | ||
@@ -279,18 +278,16 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user | |||
279 | 278 | ||
280 | static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) | 279 | static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) |
281 | { | 280 | { |
282 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) || | 281 | if (copy_from_user(kp, up, sizeof(struct v4l2_standard))) |
283 | copy_from_user(kp, up, sizeof(struct v4l2_standard))) | 282 | return -EFAULT; |
284 | return -EFAULT; | ||
285 | return 0; | 283 | return 0; |
286 | 284 | ||
287 | } | 285 | } |
288 | 286 | ||
289 | static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) | 287 | static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) |
290 | { | 288 | { |
291 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) || | 289 | if (copy_to_user(up, kp, sizeof(struct v4l2_standard))) |
292 | copy_to_user(up, kp, sizeof(struct v4l2_standard))) | 290 | return -EFAULT; |
293 | return -EFAULT; | ||
294 | return 0; | 291 | return 0; |
295 | } | 292 | } |
296 | 293 | ||
@@ -328,18 +325,16 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 | |||
328 | 325 | ||
329 | static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) | 326 | static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) |
330 | { | 327 | { |
331 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) || | 328 | if (copy_from_user(kp, up, sizeof(struct v4l2_tuner))) |
332 | copy_from_user(kp, up, sizeof(struct v4l2_tuner))) | 329 | return -EFAULT; |
333 | return -EFAULT; | ||
334 | return 0; | 330 | return 0; |
335 | 331 | ||
336 | } | 332 | } |
337 | 333 | ||
338 | static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) | 334 | static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) |
339 | { | 335 | { |
340 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) || | 336 | if (copy_to_user(up, kp, sizeof(struct v4l2_tuner))) |
341 | copy_to_user(up, kp, sizeof(struct v4l2_tuner))) | 337 | return -EFAULT; |
342 | return -EFAULT; | ||
343 | return 0; | 338 | return 0; |
344 | } | 339 | } |
345 | 340 | ||
@@ -380,11 +375,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user | |||
380 | break; | 375 | break; |
381 | case V4L2_MEMORY_USERPTR: | 376 | case V4L2_MEMORY_USERPTR: |
382 | { | 377 | { |
383 | unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); | 378 | compat_long_t tmp; |
384 | 379 | ||
385 | if(get_user(kp->length, &up->length) || | 380 | if (get_user(kp->length, &up->length) || |
386 | get_user(kp->m.userptr, &tmp)) | 381 | get_user(tmp, &up->m.userptr)) |
387 | return -EFAULT; | 382 | return -EFAULT; |
383 | |||
384 | kp->m.userptr = (unsigned long)compat_ptr(tmp); | ||
388 | } | 385 | } |
389 | break; | 386 | break; |
390 | case V4L2_MEMORY_OVERLAY: | 387 | case V4L2_MEMORY_OVERLAY: |
@@ -468,33 +465,29 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame | |||
468 | 465 | ||
469 | static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) | 466 | static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) |
470 | { | 467 | { |
471 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) || | 468 | if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) |
472 | copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) | 469 | return -EFAULT; |
473 | return -EFAULT; | ||
474 | return 0; | 470 | return 0; |
475 | } | 471 | } |
476 | 472 | ||
477 | static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) | 473 | static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) |
478 | { | 474 | { |
479 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) || | 475 | if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) |
480 | copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) | 476 | return -EFAULT; |
481 | return -EFAULT; | ||
482 | return 0; | 477 | return 0; |
483 | } | 478 | } |
484 | 479 | ||
485 | static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) | 480 | static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) |
486 | { | 481 | { |
487 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) || | 482 | if (copy_from_user(kp, up, sizeof(struct v4l2_input))) |
488 | copy_from_user(kp, up, sizeof(struct v4l2_input))) | 483 | return -EFAULT; |
489 | return -EFAULT; | ||
490 | return 0; | 484 | return 0; |
491 | } | 485 | } |
492 | 486 | ||
493 | static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) | 487 | static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) |
494 | { | 488 | { |
495 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) || | 489 | if (copy_to_user(up, kp, sizeof(struct v4l2_input))) |
496 | copy_to_user(up, kp, sizeof(struct v4l2_input))) | 490 | return -EFAULT; |
497 | return -EFAULT; | ||
498 | return 0; | 491 | return 0; |
499 | } | 492 | } |
500 | 493 | ||
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c483a863b116..5d397b7a5497 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
@@ -65,7 +65,7 @@ config MMC_AU1X | |||
65 | depends on SOC_AU1X00 && MMC | 65 | depends on SOC_AU1X00 && MMC |
66 | help | 66 | help |
67 | This selects the AMD Alchemy(R) Multimedia card interface. | 67 | This selects the AMD Alchemy(R) Multimedia card interface. |
68 | iIf you have a Alchemy platform with a MMC slot, say Y or M here. | 68 | If you have a Alchemy platform with a MMC slot, say Y or M here. |
69 | 69 | ||
70 | If unsure, say N. | 70 | If unsure, say N. |
71 | 71 | ||
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index effa0d7a73ac..205bb7083335 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig | |||
@@ -301,7 +301,7 @@ config MTD_JEDEC | |||
301 | 301 | ||
302 | config MTD_XIP | 302 | config MTD_XIP |
303 | bool "XIP aware MTD support" | 303 | bool "XIP aware MTD support" |
304 | depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM | 304 | depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP |
305 | default y if XIP_KERNEL | 305 | default y if XIP_KERNEL |
306 | help | 306 | help |
307 | This allows MTD support to work with flash memory which is also | 307 | This allows MTD support to work with flash memory which is also |
diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 18b027e73f28..86633c5f1a4b 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/string.h> | 30 | #include <linux/string.h> |
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/irq.h> | 32 | #include <asm/irq.h> |
33 | /* Used for the temporal inet entries and routing */ | 33 | /* Used for the temporal inet entries and routing */ |
34 | #include <linux/socket.h> | 34 | #include <linux/socket.h> |
35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 13b745b39667..da0c878dcba8 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c | |||
@@ -614,7 +614,7 @@ static void rebuild_rx_bufs(struct net_device *dev) | |||
614 | static int init_i596_mem(struct net_device *dev) | 614 | static int init_i596_mem(struct net_device *dev) |
615 | { | 615 | { |
616 | struct i596_private *lp = dev->priv; | 616 | struct i596_private *lp = dev->priv; |
617 | #if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) | 617 | #if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) || defined(ENABLE_APRICOT) |
618 | short ioaddr = dev->base_addr; | 618 | short ioaddr = dev->base_addr; |
619 | #endif | 619 | #endif |
620 | unsigned long flags; | 620 | unsigned long flags; |
diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h index c68ba9c2ef46..aca47f3a7b98 100644 --- a/drivers/net/appletalk/cops.h +++ b/drivers/net/appletalk/cops.h | |||
@@ -51,7 +51,7 @@ | |||
51 | struct ltfirmware | 51 | struct ltfirmware |
52 | { | 52 | { |
53 | unsigned int length; | 53 | unsigned int length; |
54 | unsigned char * data; | 54 | const unsigned char * data; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | #define DAYNA 1 | 57 | #define DAYNA 1 |
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 38c3f033f739..8c8d6c453c45 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c | |||
@@ -97,25 +97,44 @@ static int __init arcrimi_probe(struct net_device *dev) | |||
97 | "must specify the shmem and irq!\n"); | 97 | "must specify the shmem and irq!\n"); |
98 | return -ENODEV; | 98 | return -ENODEV; |
99 | } | 99 | } |
100 | if (dev->dev_addr[0] == 0) { | ||
101 | BUGMSG(D_NORMAL, "You need to specify your card's station " | ||
102 | "ID!\n"); | ||
103 | return -ENODEV; | ||
104 | } | ||
100 | /* | 105 | /* |
101 | * Grab the memory region at mem_start for BUFFER_SIZE bytes. | 106 | * Grab the memory region at mem_start for MIRROR_SIZE bytes. |
102 | * Later in arcrimi_found() the real size will be determined | 107 | * Later in arcrimi_found() the real size will be determined |
103 | * and this reserve will be released and the correct size | 108 | * and this reserve will be released and the correct size |
104 | * will be taken. | 109 | * will be taken. |
105 | */ | 110 | */ |
106 | if (!request_mem_region(dev->mem_start, BUFFER_SIZE, "arcnet (90xx)")) { | 111 | if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { |
107 | BUGMSG(D_NORMAL, "Card memory already allocated\n"); | 112 | BUGMSG(D_NORMAL, "Card memory already allocated\n"); |
108 | return -ENODEV; | 113 | return -ENODEV; |
109 | } | 114 | } |
110 | if (dev->dev_addr[0] == 0) { | ||
111 | release_mem_region(dev->mem_start, BUFFER_SIZE); | ||
112 | BUGMSG(D_NORMAL, "You need to specify your card's station " | ||
113 | "ID!\n"); | ||
114 | return -ENODEV; | ||
115 | } | ||
116 | return arcrimi_found(dev); | 115 | return arcrimi_found(dev); |
117 | } | 116 | } |
118 | 117 | ||
118 | static int check_mirror(unsigned long addr, size_t size) | ||
119 | { | ||
120 | void __iomem *p; | ||
121 | int res = -1; | ||
122 | |||
123 | if (!request_mem_region(addr, size, "arcnet (90xx)")) | ||
124 | return -1; | ||
125 | |||
126 | p = ioremap(addr, size); | ||
127 | if (p) { | ||
128 | if (readb(p) == TESTvalue) | ||
129 | res = 1; | ||
130 | else | ||
131 | res = 0; | ||
132 | iounmap(p); | ||
133 | } | ||
134 | |||
135 | release_mem_region(addr, size); | ||
136 | return res; | ||
137 | } | ||
119 | 138 | ||
120 | /* | 139 | /* |
121 | * Set up the struct net_device associated with this card. Called after | 140 | * Set up the struct net_device associated with this card. Called after |
@@ -125,19 +144,28 @@ static int __init arcrimi_found(struct net_device *dev) | |||
125 | { | 144 | { |
126 | struct arcnet_local *lp; | 145 | struct arcnet_local *lp; |
127 | unsigned long first_mirror, last_mirror, shmem; | 146 | unsigned long first_mirror, last_mirror, shmem; |
147 | void __iomem *p; | ||
128 | int mirror_size; | 148 | int mirror_size; |
129 | int err; | 149 | int err; |
130 | 150 | ||
151 | p = ioremap(dev->mem_start, MIRROR_SIZE); | ||
152 | if (!p) { | ||
153 | release_mem_region(dev->mem_start, MIRROR_SIZE); | ||
154 | BUGMSG(D_NORMAL, "Can't ioremap\n"); | ||
155 | return -ENODEV; | ||
156 | } | ||
157 | |||
131 | /* reserve the irq */ | 158 | /* reserve the irq */ |
132 | if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) { | 159 | if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) { |
133 | release_mem_region(dev->mem_start, BUFFER_SIZE); | 160 | iounmap(p); |
161 | release_mem_region(dev->mem_start, MIRROR_SIZE); | ||
134 | BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); | 162 | BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); |
135 | return -ENODEV; | 163 | return -ENODEV; |
136 | } | 164 | } |
137 | 165 | ||
138 | shmem = dev->mem_start; | 166 | shmem = dev->mem_start; |
139 | isa_writeb(TESTvalue, shmem); | 167 | writeb(TESTvalue, p); |
140 | isa_writeb(dev->dev_addr[0], shmem + 1); /* actually the node ID */ | 168 | writeb(dev->dev_addr[0], p + 1); /* actually the node ID */ |
141 | 169 | ||
142 | /* find the real shared memory start/end points, including mirrors */ | 170 | /* find the real shared memory start/end points, including mirrors */ |
143 | 171 | ||
@@ -146,17 +174,18 @@ static int __init arcrimi_found(struct net_device *dev) | |||
146 | * 2k (or there are no mirrors at all) but on some, it's 4k. | 174 | * 2k (or there are no mirrors at all) but on some, it's 4k. |
147 | */ | 175 | */ |
148 | mirror_size = MIRROR_SIZE; | 176 | mirror_size = MIRROR_SIZE; |
149 | if (isa_readb(shmem) == TESTvalue | 177 | if (readb(p) == TESTvalue |
150 | && isa_readb(shmem - mirror_size) != TESTvalue | 178 | && check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 |
151 | && isa_readb(shmem - 2 * mirror_size) == TESTvalue) | 179 | && check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) |
152 | mirror_size *= 2; | 180 | mirror_size = 2 * MIRROR_SIZE; |
153 | 181 | ||
154 | first_mirror = last_mirror = shmem; | 182 | first_mirror = shmem - mirror_size; |
155 | while (isa_readb(first_mirror) == TESTvalue) | 183 | while (check_mirror(first_mirror, mirror_size) == 1) |
156 | first_mirror -= mirror_size; | 184 | first_mirror -= mirror_size; |
157 | first_mirror += mirror_size; | 185 | first_mirror += mirror_size; |
158 | 186 | ||
159 | while (isa_readb(last_mirror) == TESTvalue) | 187 | last_mirror = shmem + mirror_size; |
188 | while (check_mirror(last_mirror, mirror_size) == 1) | ||
160 | last_mirror += mirror_size; | 189 | last_mirror += mirror_size; |
161 | last_mirror -= mirror_size; | 190 | last_mirror -= mirror_size; |
162 | 191 | ||
@@ -181,7 +210,8 @@ static int __init arcrimi_found(struct net_device *dev) | |||
181 | * with the correct size. There is a VERY slim chance this could | 210 | * with the correct size. There is a VERY slim chance this could |
182 | * fail. | 211 | * fail. |
183 | */ | 212 | */ |
184 | release_mem_region(shmem, BUFFER_SIZE); | 213 | iounmap(p); |
214 | release_mem_region(shmem, MIRROR_SIZE); | ||
185 | if (!request_mem_region(dev->mem_start, | 215 | if (!request_mem_region(dev->mem_start, |
186 | dev->mem_end - dev->mem_start + 1, | 216 | dev->mem_end - dev->mem_start + 1, |
187 | "arcnet (90xx)")) { | 217 | "arcnet (90xx)")) { |
diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 6c2c9b9ac6db..43150b2bd13f 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c | |||
@@ -53,7 +53,7 @@ | |||
53 | 53 | ||
54 | 54 | ||
55 | /* Internal function declarations */ | 55 | /* Internal function declarations */ |
56 | static int com90xx_found(int ioaddr, int airq, u_long shmem); | 56 | static int com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *); |
57 | static void com90xx_command(struct net_device *dev, int command); | 57 | static void com90xx_command(struct net_device *dev, int command); |
58 | static int com90xx_status(struct net_device *dev); | 58 | static int com90xx_status(struct net_device *dev); |
59 | static void com90xx_setmask(struct net_device *dev, int mask); | 59 | static void com90xx_setmask(struct net_device *dev, int mask); |
@@ -116,14 +116,26 @@ static void __init com90xx_probe(void) | |||
116 | unsigned long airqmask; | 116 | unsigned long airqmask; |
117 | int ports[(0x3f0 - 0x200) / 16 + 1] = | 117 | int ports[(0x3f0 - 0x200) / 16 + 1] = |
118 | {0}; | 118 | {0}; |
119 | u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] = | 119 | unsigned long *shmems; |
120 | {0}; | 120 | void __iomem **iomem; |
121 | int numports, numshmems, *port; | 121 | int numports, numshmems, *port; |
122 | u_long *p; | 122 | u_long *p; |
123 | int index; | ||
123 | 124 | ||
124 | if (!io && !irq && !shmem && !*device && com90xx_skip_probe) | 125 | if (!io && !irq && !shmem && !*device && com90xx_skip_probe) |
125 | return; | 126 | return; |
126 | 127 | ||
128 | shmems = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(unsigned long), | ||
129 | GFP_KERNEL); | ||
130 | if (!shmems) | ||
131 | return; | ||
132 | iomem = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(void __iomem *), | ||
133 | GFP_KERNEL); | ||
134 | if (!iomem) { | ||
135 | kfree(shmems); | ||
136 | return; | ||
137 | } | ||
138 | |||
127 | BUGLVL(D_NORMAL) printk(VERSION); | 139 | BUGLVL(D_NORMAL) printk(VERSION); |
128 | 140 | ||
129 | /* set up the arrays where we'll store the possible probe addresses */ | 141 | /* set up the arrays where we'll store the possible probe addresses */ |
@@ -179,6 +191,8 @@ static void __init com90xx_probe(void) | |||
179 | 191 | ||
180 | if (!numports) { | 192 | if (!numports) { |
181 | BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n"); | 193 | BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n"); |
194 | kfree(shmems); | ||
195 | kfree(iomem); | ||
182 | return; | 196 | return; |
183 | } | 197 | } |
184 | /* Stage 2: we have now reset any possible ARCnet cards, so we can't | 198 | /* Stage 2: we have now reset any possible ARCnet cards, so we can't |
@@ -202,8 +216,8 @@ static void __init com90xx_probe(void) | |||
202 | * 0xD1 byte in the right place, or are read-only. | 216 | * 0xD1 byte in the right place, or are read-only. |
203 | */ | 217 | */ |
204 | numprint = -1; | 218 | numprint = -1; |
205 | for (p = &shmems[0]; p < shmems + numshmems; p++) { | 219 | for (index = 0, p = &shmems[0]; index < numshmems; p++, index++) { |
206 | u_long ptr = *p; | 220 | void __iomem *base; |
207 | 221 | ||
208 | numprint++; | 222 | numprint++; |
209 | numprint %= 8; | 223 | numprint %= 8; |
@@ -213,38 +227,49 @@ static void __init com90xx_probe(void) | |||
213 | } | 227 | } |
214 | BUGMSG2(D_INIT, "%lXh ", *p); | 228 | BUGMSG2(D_INIT, "%lXh ", *p); |
215 | 229 | ||
216 | if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) { | 230 | if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) { |
217 | BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n"); | 231 | BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n"); |
218 | BUGMSG2(D_INIT_REASONS, "Stage 3: "); | 232 | BUGMSG2(D_INIT_REASONS, "Stage 3: "); |
219 | BUGLVL(D_INIT_REASONS) numprint = 0; | 233 | BUGLVL(D_INIT_REASONS) numprint = 0; |
220 | *p-- = shmems[--numshmems]; | 234 | goto out; |
221 | continue; | 235 | } |
236 | base = ioremap(*p, MIRROR_SIZE); | ||
237 | if (!base) { | ||
238 | BUGMSG2(D_INIT_REASONS, "(ioremap)\n"); | ||
239 | BUGMSG2(D_INIT_REASONS, "Stage 3: "); | ||
240 | BUGLVL(D_INIT_REASONS) numprint = 0; | ||
241 | goto out1; | ||
222 | } | 242 | } |
223 | if (isa_readb(ptr) != TESTvalue) { | 243 | if (readb(base) != TESTvalue) { |
224 | BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n", | 244 | BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n", |
225 | isa_readb(ptr), TESTvalue); | 245 | readb(base), TESTvalue); |
226 | BUGMSG2(D_INIT_REASONS, "S3: "); | 246 | BUGMSG2(D_INIT_REASONS, "S3: "); |
227 | BUGLVL(D_INIT_REASONS) numprint = 0; | 247 | BUGLVL(D_INIT_REASONS) numprint = 0; |
228 | release_mem_region(*p, BUFFER_SIZE); | 248 | goto out2; |
229 | *p-- = shmems[--numshmems]; | ||
230 | continue; | ||
231 | } | 249 | } |
232 | /* By writing 0x42 to the TESTvalue location, we also make | 250 | /* By writing 0x42 to the TESTvalue location, we also make |
233 | * sure no "mirror" shmem areas show up - if they occur | 251 | * sure no "mirror" shmem areas show up - if they occur |
234 | * in another pass through this loop, they will be discarded | 252 | * in another pass through this loop, they will be discarded |
235 | * because *cptr != TESTvalue. | 253 | * because *cptr != TESTvalue. |
236 | */ | 254 | */ |
237 | isa_writeb(0x42, ptr); | 255 | writeb(0x42, base); |
238 | if (isa_readb(ptr) != 0x42) { | 256 | if (readb(base) != 0x42) { |
239 | BUGMSG2(D_INIT_REASONS, "(read only)\n"); | 257 | BUGMSG2(D_INIT_REASONS, "(read only)\n"); |
240 | BUGMSG2(D_INIT_REASONS, "S3: "); | 258 | BUGMSG2(D_INIT_REASONS, "S3: "); |
241 | release_mem_region(*p, BUFFER_SIZE); | 259 | goto out2; |
242 | *p-- = shmems[--numshmems]; | ||
243 | continue; | ||
244 | } | 260 | } |
245 | BUGMSG2(D_INIT_REASONS, "\n"); | 261 | BUGMSG2(D_INIT_REASONS, "\n"); |
246 | BUGMSG2(D_INIT_REASONS, "S3: "); | 262 | BUGMSG2(D_INIT_REASONS, "S3: "); |
247 | BUGLVL(D_INIT_REASONS) numprint = 0; | 263 | BUGLVL(D_INIT_REASONS) numprint = 0; |
264 | iomem[index] = base; | ||
265 | continue; | ||
266 | out2: | ||
267 | iounmap(base); | ||
268 | out1: | ||
269 | release_mem_region(*p, MIRROR_SIZE); | ||
270 | out: | ||
271 | *p-- = shmems[--numshmems]; | ||
272 | index--; | ||
248 | } | 273 | } |
249 | BUGMSG2(D_INIT, "\n"); | 274 | BUGMSG2(D_INIT, "\n"); |
250 | 275 | ||
@@ -252,6 +277,8 @@ static void __init com90xx_probe(void) | |||
252 | BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n"); | 277 | BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n"); |
253 | for (port = &ports[0]; port < ports + numports; port++) | 278 | for (port = &ports[0]; port < ports + numports; port++) |
254 | release_region(*port, ARCNET_TOTAL_SIZE); | 279 | release_region(*port, ARCNET_TOTAL_SIZE); |
280 | kfree(shmems); | ||
281 | kfree(iomem); | ||
255 | return; | 282 | return; |
256 | } | 283 | } |
257 | /* Stage 4: something of a dummy, to report the shmems that are | 284 | /* Stage 4: something of a dummy, to report the shmems that are |
@@ -351,30 +378,32 @@ static void __init com90xx_probe(void) | |||
351 | mdelay(RESETtime); | 378 | mdelay(RESETtime); |
352 | } else { | 379 | } else { |
353 | /* just one shmem and port, assume they match */ | 380 | /* just one shmem and port, assume they match */ |
354 | isa_writeb(TESTvalue, shmems[0]); | 381 | writeb(TESTvalue, iomem[0]); |
355 | } | 382 | } |
356 | #else | 383 | #else |
357 | inb(_RESET); | 384 | inb(_RESET); |
358 | mdelay(RESETtime); | 385 | mdelay(RESETtime); |
359 | #endif | 386 | #endif |
360 | 387 | ||
361 | for (p = &shmems[0]; p < shmems + numshmems; p++) { | 388 | for (index = 0; index < numshmems; index++) { |
362 | u_long ptr = *p; | 389 | u_long ptr = shmems[index]; |
390 | void __iomem *base = iomem[index]; | ||
363 | 391 | ||
364 | if (isa_readb(ptr) == TESTvalue) { /* found one */ | 392 | if (readb(base) == TESTvalue) { /* found one */ |
365 | BUGMSG2(D_INIT, "%lXh)\n", *p); | 393 | BUGMSG2(D_INIT, "%lXh)\n", *p); |
366 | openparen = 0; | 394 | openparen = 0; |
367 | 395 | ||
368 | /* register the card */ | 396 | /* register the card */ |
369 | if (com90xx_found(*port, airq, *p) == 0) | 397 | if (com90xx_found(*port, airq, ptr, base) == 0) |
370 | found = 1; | 398 | found = 1; |
371 | numprint = -1; | 399 | numprint = -1; |
372 | 400 | ||
373 | /* remove shmem from the list */ | 401 | /* remove shmem from the list */ |
374 | *p = shmems[--numshmems]; | 402 | shmems[index] = shmems[--numshmems]; |
403 | iomem[index] = iomem[numshmems]; | ||
375 | break; /* go to the next I/O port */ | 404 | break; /* go to the next I/O port */ |
376 | } else { | 405 | } else { |
377 | BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr)); | 406 | BUGMSG2(D_INIT_REASONS, "%Xh-", readb(base)); |
378 | } | 407 | } |
379 | } | 408 | } |
380 | 409 | ||
@@ -391,17 +420,40 @@ static void __init com90xx_probe(void) | |||
391 | BUGLVL(D_INIT_REASONS) printk("\n"); | 420 | BUGLVL(D_INIT_REASONS) printk("\n"); |
392 | 421 | ||
393 | /* Now put back TESTvalue on all leftover shmems. */ | 422 | /* Now put back TESTvalue on all leftover shmems. */ |
394 | for (p = &shmems[0]; p < shmems + numshmems; p++) { | 423 | for (index = 0; index < numshmems; index++) { |
395 | isa_writeb(TESTvalue, *p); | 424 | writeb(TESTvalue, iomem[index]); |
396 | release_mem_region(*p, BUFFER_SIZE); | 425 | iounmap(iomem[index]); |
426 | release_mem_region(shmems[index], MIRROR_SIZE); | ||
397 | } | 427 | } |
428 | kfree(shmems); | ||
429 | kfree(iomem); | ||
398 | } | 430 | } |
399 | 431 | ||
432 | static int check_mirror(unsigned long addr, size_t size) | ||
433 | { | ||
434 | void __iomem *p; | ||
435 | int res = -1; | ||
436 | |||
437 | if (!request_mem_region(addr, size, "arcnet (90xx)")) | ||
438 | return -1; | ||
439 | |||
440 | p = ioremap(addr, size); | ||
441 | if (p) { | ||
442 | if (readb(p) == TESTvalue) | ||
443 | res = 1; | ||
444 | else | ||
445 | res = 0; | ||
446 | iounmap(p); | ||
447 | } | ||
448 | |||
449 | release_mem_region(addr, size); | ||
450 | return res; | ||
451 | } | ||
400 | 452 | ||
401 | /* Set up the struct net_device associated with this card. Called after | 453 | /* Set up the struct net_device associated with this card. Called after |
402 | * probing succeeds. | 454 | * probing succeeds. |
403 | */ | 455 | */ |
404 | static int __init com90xx_found(int ioaddr, int airq, u_long shmem) | 456 | static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *p) |
405 | { | 457 | { |
406 | struct net_device *dev = NULL; | 458 | struct net_device *dev = NULL; |
407 | struct arcnet_local *lp; | 459 | struct arcnet_local *lp; |
@@ -412,7 +464,8 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem) | |||
412 | dev = alloc_arcdev(device); | 464 | dev = alloc_arcdev(device); |
413 | if (!dev) { | 465 | if (!dev) { |
414 | BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n"); | 466 | BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n"); |
415 | release_mem_region(shmem, BUFFER_SIZE); | 467 | iounmap(p); |
468 | release_mem_region(shmem, MIRROR_SIZE); | ||
416 | return -ENOMEM; | 469 | return -ENOMEM; |
417 | } | 470 | } |
418 | lp = dev->priv; | 471 | lp = dev->priv; |
@@ -423,24 +476,27 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem) | |||
423 | * 2k (or there are no mirrors at all) but on some, it's 4k. | 476 | * 2k (or there are no mirrors at all) but on some, it's 4k. |
424 | */ | 477 | */ |
425 | mirror_size = MIRROR_SIZE; | 478 | mirror_size = MIRROR_SIZE; |
426 | if (isa_readb(shmem) == TESTvalue | 479 | if (readb(p) == TESTvalue && |
427 | && isa_readb(shmem - mirror_size) != TESTvalue | 480 | check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 && |
428 | && isa_readb(shmem - 2 * mirror_size) == TESTvalue) | 481 | check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) |
429 | mirror_size *= 2; | 482 | mirror_size = 2 * MIRROR_SIZE; |
430 | 483 | ||
431 | first_mirror = last_mirror = shmem; | 484 | first_mirror = shmem - mirror_size; |
432 | while (isa_readb(first_mirror) == TESTvalue) | 485 | while (check_mirror(first_mirror, mirror_size) == 1) |
433 | first_mirror -= mirror_size; | 486 | first_mirror -= mirror_size; |
434 | first_mirror += mirror_size; | 487 | first_mirror += mirror_size; |
435 | 488 | ||
436 | while (isa_readb(last_mirror) == TESTvalue) | 489 | last_mirror = shmem + mirror_size; |
490 | while (check_mirror(last_mirror, mirror_size) == 1) | ||
437 | last_mirror += mirror_size; | 491 | last_mirror += mirror_size; |
438 | last_mirror -= mirror_size; | 492 | last_mirror -= mirror_size; |
439 | 493 | ||
440 | dev->mem_start = first_mirror; | 494 | dev->mem_start = first_mirror; |
441 | dev->mem_end = last_mirror + MIRROR_SIZE - 1; | 495 | dev->mem_end = last_mirror + MIRROR_SIZE - 1; |
442 | 496 | ||
443 | release_mem_region(shmem, BUFFER_SIZE); | 497 | iounmap(p); |
498 | release_mem_region(shmem, MIRROR_SIZE); | ||
499 | |||
444 | if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)")) | 500 | if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)")) |
445 | goto err_free_dev; | 501 | goto err_free_dev; |
446 | 502 | ||
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 3b1bef1ee215..77411a00d1ee 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c | |||
@@ -86,7 +86,6 @@ | |||
86 | #include <linux/bitops.h> | 86 | #include <linux/bitops.h> |
87 | #include <linux/jiffies.h> | 87 | #include <linux/jiffies.h> |
88 | 88 | ||
89 | #include <asm/bug.h> | ||
90 | #include <asm/system.h> | 89 | #include <asm/system.h> |
91 | #include <asm/uaccess.h> | 90 | #include <asm/uaccess.h> |
92 | 91 | ||
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index a37b82ebca37..247c8ca86033 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c | |||
@@ -1719,17 +1719,10 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1719 | hp100_outw(i, FRAGMENT_LEN); /* and first/only fragment length */ | 1719 | hp100_outw(i, FRAGMENT_LEN); /* and first/only fragment length */ |
1720 | 1720 | ||
1721 | if (lp->mode == 2) { /* memory mapped */ | 1721 | if (lp->mode == 2) { /* memory mapped */ |
1722 | if (lp->mem_ptr_virt) { /* high pci memory was remapped */ | 1722 | /* Note: The J2585B needs alignment to 32bits here! */ |
1723 | /* Note: The J2585B needs alignment to 32bits here! */ | 1723 | memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3); |
1724 | memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3); | 1724 | if (!ok_flag) |
1725 | if (!ok_flag) | 1725 | memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len); |
1726 | memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len); | ||
1727 | } else { | ||
1728 | /* Note: The J2585B needs alignment to 32bits here! */ | ||
1729 | isa_memcpy_toio(lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3); | ||
1730 | if (!ok_flag) | ||
1731 | isa_memset_io(lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len); | ||
1732 | } | ||
1733 | } else { /* programmed i/o */ | 1726 | } else { /* programmed i/o */ |
1734 | outsl(ioaddr + HP100_REG_DATA32, skb->data, | 1727 | outsl(ioaddr + HP100_REG_DATA32, skb->data, |
1735 | (skb->len + 3) >> 2); | 1728 | (skb->len + 3) >> 2); |
@@ -1799,10 +1792,7 @@ static void hp100_rx(struct net_device *dev) | |||
1799 | /* First we get the header, which contains information about the */ | 1792 | /* First we get the header, which contains information about the */ |
1800 | /* actual length of the received packet. */ | 1793 | /* actual length of the received packet. */ |
1801 | if (lp->mode == 2) { /* memory mapped mode */ | 1794 | if (lp->mode == 2) { /* memory mapped mode */ |
1802 | if (lp->mem_ptr_virt) /* if memory was remapped */ | 1795 | header = readl(lp->mem_ptr_virt); |
1803 | header = readl(lp->mem_ptr_virt); | ||
1804 | else | ||
1805 | header = isa_readl(lp->mem_ptr_phys); | ||
1806 | } else /* programmed i/o */ | 1796 | } else /* programmed i/o */ |
1807 | header = hp100_inl(DATA32); | 1797 | header = hp100_inl(DATA32); |
1808 | 1798 | ||
@@ -1834,13 +1824,9 @@ static void hp100_rx(struct net_device *dev) | |||
1834 | ptr = skb->data; | 1824 | ptr = skb->data; |
1835 | 1825 | ||
1836 | /* Now transfer the data from the card into that area */ | 1826 | /* Now transfer the data from the card into that area */ |
1837 | if (lp->mode == 2) { | 1827 | if (lp->mode == 2) |
1838 | if (lp->mem_ptr_virt) | 1828 | memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len); |
1839 | memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len); | 1829 | else /* io mapped */ |
1840 | /* Note alignment to 32bit transfers */ | ||
1841 | else | ||
1842 | isa_memcpy_fromio(ptr, lp->mem_ptr_phys, pkt_len); | ||
1843 | } else /* io mapped */ | ||
1844 | insl(ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2); | 1830 | insl(ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2); |
1845 | 1831 | ||
1846 | skb->protocol = eth_type_trans(skb, dev); | 1832 | skb->protocol = eth_type_trans(skb, dev); |
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 591c5864ffb1..7e49522b8b3c 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c | |||
@@ -204,7 +204,7 @@ static inline int emac_phy_gpcs(int phy_mode) | |||
204 | 204 | ||
205 | static inline void emac_tx_enable(struct ocp_enet_private *dev) | 205 | static inline void emac_tx_enable(struct ocp_enet_private *dev) |
206 | { | 206 | { |
207 | struct emac_regs *p = dev->emacp; | 207 | struct emac_regs __iomem *p = dev->emacp; |
208 | unsigned long flags; | 208 | unsigned long flags; |
209 | u32 r; | 209 | u32 r; |
210 | 210 | ||
@@ -220,7 +220,7 @@ static inline void emac_tx_enable(struct ocp_enet_private *dev) | |||
220 | 220 | ||
221 | static void emac_tx_disable(struct ocp_enet_private *dev) | 221 | static void emac_tx_disable(struct ocp_enet_private *dev) |
222 | { | 222 | { |
223 | struct emac_regs *p = dev->emacp; | 223 | struct emac_regs __iomem *p = dev->emacp; |
224 | unsigned long flags; | 224 | unsigned long flags; |
225 | u32 r; | 225 | u32 r; |
226 | 226 | ||
@@ -244,7 +244,7 @@ static void emac_tx_disable(struct ocp_enet_private *dev) | |||
244 | 244 | ||
245 | static void emac_rx_enable(struct ocp_enet_private *dev) | 245 | static void emac_rx_enable(struct ocp_enet_private *dev) |
246 | { | 246 | { |
247 | struct emac_regs *p = dev->emacp; | 247 | struct emac_regs __iomem *p = dev->emacp; |
248 | unsigned long flags; | 248 | unsigned long flags; |
249 | u32 r; | 249 | u32 r; |
250 | 250 | ||
@@ -275,7 +275,7 @@ static void emac_rx_enable(struct ocp_enet_private *dev) | |||
275 | 275 | ||
276 | static void emac_rx_disable(struct ocp_enet_private *dev) | 276 | static void emac_rx_disable(struct ocp_enet_private *dev) |
277 | { | 277 | { |
278 | struct emac_regs *p = dev->emacp; | 278 | struct emac_regs __iomem *p = dev->emacp; |
279 | unsigned long flags; | 279 | unsigned long flags; |
280 | u32 r; | 280 | u32 r; |
281 | 281 | ||
@@ -299,7 +299,7 @@ static void emac_rx_disable(struct ocp_enet_private *dev) | |||
299 | 299 | ||
300 | static inline void emac_rx_disable_async(struct ocp_enet_private *dev) | 300 | static inline void emac_rx_disable_async(struct ocp_enet_private *dev) |
301 | { | 301 | { |
302 | struct emac_regs *p = dev->emacp; | 302 | struct emac_regs __iomem *p = dev->emacp; |
303 | unsigned long flags; | 303 | unsigned long flags; |
304 | u32 r; | 304 | u32 r; |
305 | 305 | ||
@@ -315,7 +315,7 @@ static inline void emac_rx_disable_async(struct ocp_enet_private *dev) | |||
315 | 315 | ||
316 | static int emac_reset(struct ocp_enet_private *dev) | 316 | static int emac_reset(struct ocp_enet_private *dev) |
317 | { | 317 | { |
318 | struct emac_regs *p = dev->emacp; | 318 | struct emac_regs __iomem *p = dev->emacp; |
319 | unsigned long flags; | 319 | unsigned long flags; |
320 | int n = 20; | 320 | int n = 20; |
321 | 321 | ||
@@ -348,7 +348,7 @@ static int emac_reset(struct ocp_enet_private *dev) | |||
348 | 348 | ||
349 | static void emac_hash_mc(struct ocp_enet_private *dev) | 349 | static void emac_hash_mc(struct ocp_enet_private *dev) |
350 | { | 350 | { |
351 | struct emac_regs *p = dev->emacp; | 351 | struct emac_regs __iomem *p = dev->emacp; |
352 | u16 gaht[4] = { 0 }; | 352 | u16 gaht[4] = { 0 }; |
353 | struct dev_mc_list *dmi; | 353 | struct dev_mc_list *dmi; |
354 | 354 | ||
@@ -393,7 +393,7 @@ static inline int emac_opb_mhz(void) | |||
393 | /* BHs disabled */ | 393 | /* BHs disabled */ |
394 | static int emac_configure(struct ocp_enet_private *dev) | 394 | static int emac_configure(struct ocp_enet_private *dev) |
395 | { | 395 | { |
396 | struct emac_regs *p = dev->emacp; | 396 | struct emac_regs __iomem *p = dev->emacp; |
397 | struct net_device *ndev = dev->ndev; | 397 | struct net_device *ndev = dev->ndev; |
398 | int gige; | 398 | int gige; |
399 | u32 r; | 399 | u32 r; |
@@ -555,7 +555,7 @@ static void emac_full_tx_reset(struct net_device *ndev) | |||
555 | 555 | ||
556 | static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) | 556 | static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) |
557 | { | 557 | { |
558 | struct emac_regs *p = dev->emacp; | 558 | struct emac_regs __iomem *p = dev->emacp; |
559 | u32 r; | 559 | u32 r; |
560 | int n; | 560 | int n; |
561 | 561 | ||
@@ -604,7 +604,7 @@ static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg) | |||
604 | static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg, | 604 | static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg, |
605 | u16 val) | 605 | u16 val) |
606 | { | 606 | { |
607 | struct emac_regs *p = dev->emacp; | 607 | struct emac_regs __iomem *p = dev->emacp; |
608 | int n; | 608 | int n; |
609 | 609 | ||
610 | DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg, | 610 | DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg, |
@@ -666,7 +666,7 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val) | |||
666 | static void emac_set_multicast_list(struct net_device *ndev) | 666 | static void emac_set_multicast_list(struct net_device *ndev) |
667 | { | 667 | { |
668 | struct ocp_enet_private *dev = ndev->priv; | 668 | struct ocp_enet_private *dev = ndev->priv; |
669 | struct emac_regs *p = dev->emacp; | 669 | struct emac_regs __iomem *p = dev->emacp; |
670 | u32 rmr = emac_iff2rmr(ndev); | 670 | u32 rmr = emac_iff2rmr(ndev); |
671 | 671 | ||
672 | DBG("%d: multicast %08x" NL, dev->def->index, rmr); | 672 | DBG("%d: multicast %08x" NL, dev->def->index, rmr); |
@@ -825,7 +825,7 @@ static void emac_clean_rx_ring(struct ocp_enet_private *dev) | |||
825 | } | 825 | } |
826 | 826 | ||
827 | static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot, | 827 | static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot, |
828 | int flags) | 828 | gfp_t flags) |
829 | { | 829 | { |
830 | struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags); | 830 | struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags); |
831 | if (unlikely(!skb)) | 831 | if (unlikely(!skb)) |
@@ -1047,7 +1047,7 @@ static inline u16 emac_tx_csum(struct ocp_enet_private *dev, | |||
1047 | 1047 | ||
1048 | static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len) | 1048 | static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len) |
1049 | { | 1049 | { |
1050 | struct emac_regs *p = dev->emacp; | 1050 | struct emac_regs __iomem *p = dev->emacp; |
1051 | struct net_device *ndev = dev->ndev; | 1051 | struct net_device *ndev = dev->ndev; |
1052 | 1052 | ||
1053 | /* Send the packet out */ | 1053 | /* Send the packet out */ |
@@ -1519,7 +1519,7 @@ static void emac_rxde(void *param) | |||
1519 | static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs) | 1519 | static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs) |
1520 | { | 1520 | { |
1521 | struct ocp_enet_private *dev = dev_instance; | 1521 | struct ocp_enet_private *dev = dev_instance; |
1522 | struct emac_regs *p = dev->emacp; | 1522 | struct emac_regs __iomem *p = dev->emacp; |
1523 | struct ibm_emac_error_stats *st = &dev->estats; | 1523 | struct ibm_emac_error_stats *st = &dev->estats; |
1524 | 1524 | ||
1525 | u32 isr = in_be32(&p->isr); | 1525 | u32 isr = in_be32(&p->isr); |
@@ -1619,17 +1619,17 @@ static void emac_remove(struct ocp_device *ocpdev) | |||
1619 | 1619 | ||
1620 | DBG("%d: remove" NL, dev->def->index); | 1620 | DBG("%d: remove" NL, dev->def->index); |
1621 | 1621 | ||
1622 | ocp_set_drvdata(ocpdev, 0); | 1622 | ocp_set_drvdata(ocpdev, NULL); |
1623 | unregister_netdev(dev->ndev); | 1623 | unregister_netdev(dev->ndev); |
1624 | 1624 | ||
1625 | tah_fini(dev->tah_dev); | 1625 | tah_fini(dev->tah_dev); |
1626 | rgmii_fini(dev->rgmii_dev, dev->rgmii_input); | 1626 | rgmii_fini(dev->rgmii_dev, dev->rgmii_input); |
1627 | zmii_fini(dev->zmii_dev, dev->zmii_input); | 1627 | zmii_fini(dev->zmii_dev, dev->zmii_input); |
1628 | 1628 | ||
1629 | emac_dbg_register(dev->def->index, 0); | 1629 | emac_dbg_register(dev->def->index, NULL); |
1630 | 1630 | ||
1631 | mal_unregister_commac(dev->mal, &dev->commac); | 1631 | mal_unregister_commac(dev->mal, &dev->commac); |
1632 | iounmap((void *)dev->emacp); | 1632 | iounmap(dev->emacp); |
1633 | kfree(dev->ndev); | 1633 | kfree(dev->ndev); |
1634 | } | 1634 | } |
1635 | 1635 | ||
@@ -2048,9 +2048,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) | |||
2048 | goto out4; | 2048 | goto out4; |
2049 | 2049 | ||
2050 | /* Map EMAC regs */ | 2050 | /* Map EMAC regs */ |
2051 | dev->emacp = | 2051 | dev->emacp = ioremap(dev->def->paddr, sizeof(struct emac_regs)); |
2052 | (struct emac_regs *)ioremap(dev->def->paddr, | ||
2053 | sizeof(struct emac_regs)); | ||
2054 | if (!dev->emacp) { | 2052 | if (!dev->emacp) { |
2055 | printk(KERN_ERR "emac%d: could not ioremap device registers!\n", | 2053 | printk(KERN_ERR "emac%d: could not ioremap device registers!\n", |
2056 | dev->def->index); | 2054 | dev->def->index); |
@@ -2210,7 +2208,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) | |||
2210 | 2208 | ||
2211 | return 0; | 2209 | return 0; |
2212 | out6: | 2210 | out6: |
2213 | iounmap((void *)dev->emacp); | 2211 | iounmap(dev->emacp); |
2214 | out5: | 2212 | out5: |
2215 | tah_fini(dev->tah_dev); | 2213 | tah_fini(dev->tah_dev); |
2216 | out4: | 2214 | out4: |
diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h index 911abbaf471b..f61273b2e94f 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.h +++ b/drivers/net/ibm_emac/ibm_emac_core.h | |||
@@ -155,7 +155,7 @@ struct ibm_emac_error_stats { | |||
155 | 155 | ||
156 | struct ocp_enet_private { | 156 | struct ocp_enet_private { |
157 | struct net_device *ndev; /* 0 */ | 157 | struct net_device *ndev; /* 0 */ |
158 | struct emac_regs *emacp; | 158 | struct emac_regs __iomem *emacp; |
159 | 159 | ||
160 | struct mal_descriptor *tx_desc; | 160 | struct mal_descriptor *tx_desc; |
161 | int tx_cnt; | 161 | int tx_cnt; |
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c index 75d3b8639041..c7e1ecfa08fe 100644 --- a/drivers/net/ibm_emac/ibm_emac_debug.c +++ b/drivers/net/ibm_emac/ibm_emac_debug.c | |||
@@ -58,7 +58,7 @@ static void emac_desc_dump(int idx, struct ocp_enet_private *p) | |||
58 | 58 | ||
59 | static void emac_mac_dump(int idx, struct ocp_enet_private *dev) | 59 | static void emac_mac_dump(int idx, struct ocp_enet_private *dev) |
60 | { | 60 | { |
61 | struct emac_regs *p = dev->emacp; | 61 | struct emac_regs __iomem *p = dev->emacp; |
62 | 62 | ||
63 | printk("** EMAC%d registers **\n" | 63 | printk("** EMAC%d registers **\n" |
64 | "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" | 64 | "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" |
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h index a1ffb8a44fff..7f03d536c9a3 100644 --- a/drivers/net/ibm_emac/ibm_emac_rgmii.h +++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h | |||
@@ -31,7 +31,7 @@ struct rgmii_regs { | |||
31 | 31 | ||
32 | /* RGMII device */ | 32 | /* RGMII device */ |
33 | struct ibm_ocp_rgmii { | 33 | struct ibm_ocp_rgmii { |
34 | struct rgmii_regs *base; | 34 | struct rgmii_regs __iomem *base; |
35 | int users; /* number of EMACs using this RGMII bridge */ | 35 | int users; /* number of EMACs using this RGMII bridge */ |
36 | }; | 36 | }; |
37 | 37 | ||
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c index 35c1185079ed..e129e0aaa045 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.c +++ b/drivers/net/ibm_emac/ibm_emac_zmii.c | |||
@@ -80,7 +80,7 @@ static inline u32 zmii_mode_mask(int mode, int input) | |||
80 | static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) | 80 | static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) |
81 | { | 81 | { |
82 | struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); | 82 | struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev); |
83 | struct zmii_regs *p; | 83 | struct zmii_regs __iomem *p; |
84 | 84 | ||
85 | ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode); | 85 | ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode); |
86 | 86 | ||
@@ -94,8 +94,7 @@ static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode) | |||
94 | } | 94 | } |
95 | dev->mode = PHY_MODE_NA; | 95 | dev->mode = PHY_MODE_NA; |
96 | 96 | ||
97 | p = (struct zmii_regs *)ioremap(ocpdev->def->paddr, | 97 | p = ioremap(ocpdev->def->paddr, sizeof(struct zmii_regs)); |
98 | sizeof(struct zmii_regs)); | ||
99 | if (!p) { | 98 | if (!p) { |
100 | printk(KERN_ERR | 99 | printk(KERN_ERR |
101 | "zmii%d: could not ioremap device registers!\n", | 100 | "zmii%d: could not ioremap device registers!\n", |
@@ -231,7 +230,7 @@ void __exit __zmii_fini(struct ocp_device *ocpdev, int input) | |||
231 | if (!--dev->users) { | 230 | if (!--dev->users) { |
232 | /* Free everything if this is the last user */ | 231 | /* Free everything if this is the last user */ |
233 | ocp_set_drvdata(ocpdev, NULL); | 232 | ocp_set_drvdata(ocpdev, NULL); |
234 | iounmap((void *)dev->base); | 233 | iounmap(dev->base); |
235 | kfree(dev); | 234 | kfree(dev); |
236 | } | 235 | } |
237 | } | 236 | } |
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h index 0bb26062c0ad..92c854410753 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.h +++ b/drivers/net/ibm_emac/ibm_emac_zmii.h | |||
@@ -32,7 +32,7 @@ struct zmii_regs { | |||
32 | 32 | ||
33 | /* ZMII device */ | 33 | /* ZMII device */ |
34 | struct ibm_ocp_zmii { | 34 | struct ibm_ocp_zmii { |
35 | struct zmii_regs *base; | 35 | struct zmii_regs __iomem *base; |
36 | int mode; /* subset of PHY_MODE_XXXX */ | 36 | int mode; /* subset of PHY_MODE_XXXX */ |
37 | int users; /* number of EMACs using this ZMII bridge */ | 37 | int users; /* number of EMACs using this ZMII bridge */ |
38 | u32 fer_save; /* FER value left by firmware */ | 38 | u32 fer_save; /* FER value left by firmware */ |
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 02d5c6822733..f6f3dafe83ee 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -622,7 +622,7 @@ static int __init mac_sonic_init_module(void) | |||
622 | return 0; | 622 | return 0; |
623 | 623 | ||
624 | out_unregister: | 624 | out_unregister: |
625 | driver_unregister(&mac_sonic_driver); | 625 | platform_driver_unregister(&mac_sonic_driver); |
626 | 626 | ||
627 | return -ENOMEM; | 627 | return -ENOMEM; |
628 | } | 628 | } |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index df572018595e..6b4fff80ae5f 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -32,6 +32,8 @@ | |||
32 | */ | 32 | */ |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/in.h> | ||
36 | #include <linux/ip.h> | ||
35 | #include <linux/tcp.h> | 37 | #include <linux/tcp.h> |
36 | #include <linux/udp.h> | 38 | #include <linux/udp.h> |
37 | #include <linux/etherdevice.h> | 39 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index c5c738a51ee3..56344103ac23 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c | |||
@@ -32,6 +32,9 @@ | |||
32 | 32 | ||
33 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
34 | #include <asm/io.h> | 34 | #include <asm/io.h> |
35 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
36 | #include <asm/irq.h> | ||
37 | #endif | ||
35 | 38 | ||
36 | #ifdef DEBUG | 39 | #ifdef DEBUG |
37 | #define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) | 40 | #define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) |
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 7db1d1d0bb34..cf5c805452a3 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
30 | #include <net/arp.h> | 30 | #include <net/arp.h> |
31 | 31 | ||
32 | #include <asm/irq.h> | ||
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
33 | #include <asm/dma.h> | 34 | #include <asm/dma.h> |
34 | #include <asm/byteorder.h> | 35 | #include <asm/byteorder.h> |
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 8dea07b47999..eba8e5cfacc2 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
30 | #include <linux/hdlc.h> | 30 | #include <linux/hdlc.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <asm/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | 34 | ||
35 | #include "hd64572.h" | 35 | #include "hd64572.h" |
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 5380ddfcd7d5..050e854e7774 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <net/arp.h> | 24 | #include <net/arp.h> |
25 | 25 | ||
26 | #include <asm/irq.h> | ||
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | #include <asm/dma.h> | 28 | #include <asm/dma.h> |
28 | #include <asm/byteorder.h> | 29 | #include <asm/byteorder.h> |
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 9c1e10602f2b..9d3b51c3ef54 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c | |||
@@ -27,8 +27,8 @@ | |||
27 | #include <linux/hdlc.h> | 27 | #include <linux/hdlc.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
30 | #include <linux/delay.h> | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | #include <asm/delay.h> | ||
32 | 32 | ||
33 | #include "wanxl.h" | 33 | #include "wanxl.h" |
34 | 34 | ||
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index c5cd61c7f927..e5bb9f5ae429 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, | |||
748 | if (essid->length) { | 748 | if (essid->length) { |
749 | dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ | 749 | dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ |
750 | /* if it is to big, trunk it */ | 750 | /* if it is to big, trunk it */ |
751 | dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length); | 751 | dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length); |
752 | } else { | 752 | } else { |
753 | dwrq->flags = 0; | 753 | dwrq->flags = 0; |
754 | dwrq->length = 0; | 754 | dwrq->length = 0; |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 38d6d00fb0fc..014cc8d54a9f 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -38,10 +38,10 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/completion.h> | 39 | #include <linux/completion.h> |
40 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | ||
41 | #include <scsi/scsi_host.h> | 42 | #include <scsi/scsi_host.h> |
42 | #include <scsi/scsi_device.h> | 43 | #include <scsi/scsi_device.h> |
43 | #include <asm/semaphore.h> | 44 | #include <asm/semaphore.h> |
44 | #include <asm/delay.h> | ||
45 | 45 | ||
46 | #include "aacraid.h" | 46 | #include "aacraid.h" |
47 | 47 | ||
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 311a4122bd70..93edaa8696cf 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c | |||
@@ -537,9 +537,9 @@ static int mac53c94_remove(struct macio_dev *mdev) | |||
537 | free_irq(fp->intr, fp); | 537 | free_irq(fp->intr, fp); |
538 | 538 | ||
539 | if (fp->regs) | 539 | if (fp->regs) |
540 | iounmap((void *) fp->regs); | 540 | iounmap(fp->regs); |
541 | if (fp->dma) | 541 | if (fp->dma) |
542 | iounmap((void *) fp->dma); | 542 | iounmap(fp->dma); |
543 | kfree(fp->dma_cmd_space); | 543 | kfree(fp->dma_cmd_space); |
544 | 544 | ||
545 | scsi_host_put(host); | 545 | scsi_host_put(host); |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 59a1c9d9d3bd..723f7acbeb12 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -463,7 +463,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) | |||
463 | } | 463 | } |
464 | 464 | ||
465 | static void* | 465 | static void* |
466 | mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) | 466 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) |
467 | { | 467 | { |
468 | struct mempool_zone *zone = pool_data; | 468 | struct mempool_zone *zone = pool_data; |
469 | 469 | ||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 7d0700091f3d..2a547538d444 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1679,7 +1679,7 @@ static int | |||
1679 | sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize) | 1679 | sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize) |
1680 | { | 1680 | { |
1681 | int sg_bufflen = tablesize * sizeof(struct scatterlist); | 1681 | int sg_bufflen = tablesize * sizeof(struct scatterlist); |
1682 | unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN; | 1682 | gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN; |
1683 | 1683 | ||
1684 | /* | 1684 | /* |
1685 | * TODO: test without low_dma, we should not need it since | 1685 | * TODO: test without low_dma, we should not need it since |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 7aef7518b0d1..8c5c276c5577 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -362,7 +362,7 @@ static struct uart_ops serial21285_ops = { | |||
362 | 362 | ||
363 | static struct uart_port serial21285_port = { | 363 | static struct uart_port serial21285_port = { |
364 | .mapbase = 0x42000160, | 364 | .mapbase = 0x42000160, |
365 | .iotype = SERIAL_IO_MEM, | 365 | .iotype = UPIO_MEM, |
366 | .irq = NO_IRQ, | 366 | .irq = NO_IRQ, |
367 | .fifosize = 16, | 367 | .fifosize = 16, |
368 | .ops = &serial21285_ops, | 368 | .ops = &serial21285_ops, |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 8cbf0fc5a225..7f0f35a05dca 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -332,7 +332,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
332 | * Make sure that we do not overflow the buffer | 332 | * Make sure that we do not overflow the buffer |
333 | */ | 333 | */ |
334 | if (tty_request_buffer_room(tty, 1) == 0) { | 334 | if (tty_request_buffer_room(tty, 1) == 0) { |
335 | schedule_work(&tty->flip.work); | 335 | tty_schedule_flip(tty); |
336 | return; | 336 | return; |
337 | } | 337 | } |
338 | 338 | ||
@@ -353,7 +353,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
353 | } while((rx = uart->urx.w) & URX_DATA_READY); | 353 | } while((rx = uart->urx.w) & URX_DATA_READY); |
354 | #endif | 354 | #endif |
355 | 355 | ||
356 | schedule_work(&tty->flip.work); | 356 | tty_schedule_flip(tty); |
357 | 357 | ||
358 | clear_and_exit: | 358 | clear_and_exit: |
359 | return; | 359 | return; |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 60f5a5dc17f1..9843ae3d420e 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -509,7 +509,7 @@ static _INLINE_ void receive_chars(ser_info_t *info) | |||
509 | 509 | ||
510 | info->rx_cur = (QUICC_BD *)bdp; | 510 | info->rx_cur = (QUICC_BD *)bdp; |
511 | 511 | ||
512 | schedule_work(&tty->flip.work); | 512 | tty_schedule_flip(tty); |
513 | } | 513 | } |
514 | 514 | ||
515 | static _INLINE_ void receive_break(ser_info_t *info) | 515 | static _INLINE_ void receive_break(ser_info_t *info) |
@@ -521,7 +521,7 @@ static _INLINE_ void receive_break(ser_info_t *info) | |||
521 | * the break. If not, we exit now, losing the break. FIXME | 521 | * the break. If not, we exit now, losing the break. FIXME |
522 | */ | 522 | */ |
523 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 523 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
524 | schedule_work(&tty->flip.work); | 524 | tty_schedule_flip(tty); |
525 | } | 525 | } |
526 | 526 | ||
527 | static _INLINE_ void transmit_chars(ser_info_t *info) | 527 | static _INLINE_ void transmit_chars(ser_info_t *info) |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 179c1f065e60..b1fc97d5f643 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2229,6 +2229,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2229 | * and restore the IER | 2229 | * and restore the IER |
2230 | */ | 2230 | */ |
2231 | wait_for_xmitr(up, BOTH_EMPTY); | 2231 | wait_for_xmitr(up, BOTH_EMPTY); |
2232 | up->ier |= UART_IER_THRI; | ||
2232 | serial_out(up, UART_IER, ier | UART_IER_THRI); | 2233 | serial_out(up, UART_IER, ier | UART_IER_THRI); |
2233 | } | 2234 | } |
2234 | 2235 | ||
diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c index 06ae8fbcc947..8d8d7a70d03e 100644 --- a/drivers/serial/8250_au1x00.c +++ b/drivers/serial/8250_au1x00.c | |||
@@ -56,7 +56,6 @@ static struct plat_serial8250_port au1x00_data[] = { | |||
56 | #elif defined(CONFIG_SOC_AU1550) | 56 | #elif defined(CONFIG_SOC_AU1550) |
57 | PORT(UART0_ADDR, AU1550_UART0_INT), | 57 | PORT(UART0_ADDR, AU1550_UART0_INT), |
58 | PORT(UART1_ADDR, AU1550_UART1_INT), | 58 | PORT(UART1_ADDR, AU1550_UART1_INT), |
59 | PORT(UART2_ADDR, AU1550_UART2_INT), | ||
60 | PORT(UART3_ADDR, AU1550_UART3_INT), | 59 | PORT(UART3_ADDR, AU1550_UART3_INT), |
61 | #elif defined(CONFIG_SOC_AU1200) | 60 | #elif defined(CONFIG_SOC_AU1200) |
62 | PORT(UART0_ADDR, AU1200_UART0_INT), | 61 | PORT(UART0_ADDR, AU1200_UART0_INT), |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index bb9ec28ccc2b..94886c000d2a 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -1882,6 +1882,10 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
1882 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 1882 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
1883 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, | 1883 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, |
1884 | pbn_b0_4_1843200 }, | 1884 | pbn_b0_4_1843200 }, |
1885 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | ||
1886 | PCI_VENDOR_ID_AFAVLAB, | ||
1887 | PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, | ||
1888 | pbn_b0_4_1152000 }, | ||
1885 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 1889 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
1886 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 1890 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
1887 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, | 1891 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 429de2723a1c..321a3b3a5728 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -561,7 +561,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
561 | .port = { | 561 | .port = { |
562 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), | 562 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), |
563 | .mapbase = INTEGRATOR_UART0_BASE, | 563 | .mapbase = INTEGRATOR_UART0_BASE, |
564 | .iotype = SERIAL_IO_MEM, | 564 | .iotype = UPIO_MEM, |
565 | .irq = IRQ_UARTINT0, | 565 | .irq = IRQ_UARTINT0, |
566 | .uartclk = 14745600, | 566 | .uartclk = 14745600, |
567 | .fifosize = 16, | 567 | .fifosize = 16, |
@@ -576,7 +576,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
576 | .port = { | 576 | .port = { |
577 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), | 577 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), |
578 | .mapbase = INTEGRATOR_UART1_BASE, | 578 | .mapbase = INTEGRATOR_UART1_BASE, |
579 | .iotype = SERIAL_IO_MEM, | 579 | .iotype = UPIO_MEM, |
580 | .irq = IRQ_UARTINT1, | 580 | .irq = IRQ_UARTINT1, |
581 | .uartclk = 14745600, | 581 | .uartclk = 14745600, |
582 | .fifosize = 16, | 582 | .fifosize = 16, |
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index ceb5d7f37bbd..344022fe53ef 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c | |||
@@ -892,7 +892,7 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res | |||
892 | int ret = 0; | 892 | int ret = 0; |
893 | 893 | ||
894 | switch (up->port.iotype) { | 894 | switch (up->port.iotype) { |
895 | case SERIAL_IO_MEM: | 895 | case UPIO_MEM: |
896 | if (up->port.mapbase) { | 896 | if (up->port.mapbase) { |
897 | *res = request_mem_region(up->port.mapbase, size, "serial"); | 897 | *res = request_mem_region(up->port.mapbase, size, "serial"); |
898 | if (!*res) | 898 | if (!*res) |
@@ -900,8 +900,8 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res | |||
900 | } | 900 | } |
901 | break; | 901 | break; |
902 | 902 | ||
903 | case SERIAL_IO_HUB6: | 903 | case UPIO_HUB6: |
904 | case SERIAL_IO_PORT: | 904 | case UPIO_PORT: |
905 | *res = request_region(up->port.iobase, size, "serial"); | 905 | *res = request_region(up->port.iobase, size, "serial"); |
906 | if (!*res) | 906 | if (!*res) |
907 | ret = -EBUSY; | 907 | ret = -EBUSY; |
@@ -919,7 +919,7 @@ static void serial8250_release_port(struct uart_port *port) | |||
919 | size <<= up->port.regshift; | 919 | size <<= up->port.regshift; |
920 | 920 | ||
921 | switch (up->port.iotype) { | 921 | switch (up->port.iotype) { |
922 | case SERIAL_IO_MEM: | 922 | case UPIO_MEM: |
923 | if (up->port.mapbase) { | 923 | if (up->port.mapbase) { |
924 | /* | 924 | /* |
925 | * Unmap the area. | 925 | * Unmap the area. |
@@ -935,8 +935,8 @@ static void serial8250_release_port(struct uart_port *port) | |||
935 | } | 935 | } |
936 | break; | 936 | break; |
937 | 937 | ||
938 | case SERIAL_IO_HUB6: | 938 | case UPIO_HUB6: |
939 | case SERIAL_IO_PORT: | 939 | case UPIO_PORT: |
940 | start = up->port.iobase; | 940 | start = up->port.iobase; |
941 | 941 | ||
942 | if (size) | 942 | if (size) |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 16af5626c243..b7bf4c698a47 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -252,12 +252,9 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
252 | /* If we have not enough room in tty flip buffer, then we try | 252 | /* If we have not enough room in tty flip buffer, then we try |
253 | * later, which will be the next rx-interrupt or a timeout | 253 | * later, which will be the next rx-interrupt or a timeout |
254 | */ | 254 | */ |
255 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 255 | if(tty_buffer_request_room(tty, i) < i) { |
256 | tty->flip.work.func((void *)tty); | 256 | printk(KERN_WARNING "No room in flip buffer\n"); |
257 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 257 | return; |
258 | printk(KERN_WARNING "TTY_DONT_FLIP set\n"); | ||
259 | return; | ||
260 | } | ||
261 | } | 258 | } |
262 | 259 | ||
263 | /* get pointer */ | 260 | /* get pointer */ |
@@ -276,9 +273,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
276 | continue; | 273 | continue; |
277 | 274 | ||
278 | error_return: | 275 | error_return: |
279 | *tty->flip.char_buf_ptr++ = ch; | 276 | tty_insert_flip_char(tty, ch, flg); |
280 | *tty->flip.flag_buf_ptr++ = flg; | ||
281 | tty->flip.count++; | ||
282 | 277 | ||
283 | } /* End while (i--) */ | 278 | } /* End while (i--) */ |
284 | 279 | ||
@@ -908,7 +903,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
908 | .port = { | 903 | .port = { |
909 | .irq = SMC1_IRQ, | 904 | .irq = SMC1_IRQ, |
910 | .ops = &cpm_uart_pops, | 905 | .ops = &cpm_uart_pops, |
911 | .iotype = SERIAL_IO_MEM, | 906 | .iotype = UPIO_MEM, |
912 | .lock = SPIN_LOCK_UNLOCKED, | 907 | .lock = SPIN_LOCK_UNLOCKED, |
913 | }, | 908 | }, |
914 | .flags = FLAG_SMC, | 909 | .flags = FLAG_SMC, |
@@ -922,7 +917,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
922 | .port = { | 917 | .port = { |
923 | .irq = SMC2_IRQ, | 918 | .irq = SMC2_IRQ, |
924 | .ops = &cpm_uart_pops, | 919 | .ops = &cpm_uart_pops, |
925 | .iotype = SERIAL_IO_MEM, | 920 | .iotype = UPIO_MEM, |
926 | .lock = SPIN_LOCK_UNLOCKED, | 921 | .lock = SPIN_LOCK_UNLOCKED, |
927 | }, | 922 | }, |
928 | .flags = FLAG_SMC, | 923 | .flags = FLAG_SMC, |
@@ -939,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
939 | .port = { | 934 | .port = { |
940 | .irq = SCC1_IRQ, | 935 | .irq = SCC1_IRQ, |
941 | .ops = &cpm_uart_pops, | 936 | .ops = &cpm_uart_pops, |
942 | .iotype = SERIAL_IO_MEM, | 937 | .iotype = UPIO_MEM, |
943 | .lock = SPIN_LOCK_UNLOCKED, | 938 | .lock = SPIN_LOCK_UNLOCKED, |
944 | }, | 939 | }, |
945 | .tx_nrfifos = TX_NUM_FIFO, | 940 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -953,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
953 | .port = { | 948 | .port = { |
954 | .irq = SCC2_IRQ, | 949 | .irq = SCC2_IRQ, |
955 | .ops = &cpm_uart_pops, | 950 | .ops = &cpm_uart_pops, |
956 | .iotype = SERIAL_IO_MEM, | 951 | .iotype = UPIO_MEM, |
957 | .lock = SPIN_LOCK_UNLOCKED, | 952 | .lock = SPIN_LOCK_UNLOCKED, |
958 | }, | 953 | }, |
959 | .tx_nrfifos = TX_NUM_FIFO, | 954 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -967,7 +962,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
967 | .port = { | 962 | .port = { |
968 | .irq = SCC3_IRQ, | 963 | .irq = SCC3_IRQ, |
969 | .ops = &cpm_uart_pops, | 964 | .ops = &cpm_uart_pops, |
970 | .iotype = SERIAL_IO_MEM, | 965 | .iotype = UPIO_MEM, |
971 | .lock = SPIN_LOCK_UNLOCKED, | 966 | .lock = SPIN_LOCK_UNLOCKED, |
972 | }, | 967 | }, |
973 | .tx_nrfifos = TX_NUM_FIFO, | 968 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -981,7 +976,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
981 | .port = { | 976 | .port = { |
982 | .irq = SCC4_IRQ, | 977 | .irq = SCC4_IRQ, |
983 | .ops = &cpm_uart_pops, | 978 | .ops = &cpm_uart_pops, |
984 | .iotype = SERIAL_IO_MEM, | 979 | .iotype = UPIO_MEM, |
985 | .lock = SPIN_LOCK_UNLOCKED, | 980 | .lock = SPIN_LOCK_UNLOCKED, |
986 | }, | 981 | }, |
987 | .tx_nrfifos = TX_NUM_FIFO, | 982 | .tx_nrfifos = TX_NUM_FIFO, |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index a64ba26a94e8..ba5541de673b 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -262,6 +262,7 @@ static inline void dz_receive_chars(struct dz_port *dport) | |||
262 | } | 262 | } |
263 | tty_insert_flip_char(tty, ch, flag); | 263 | tty_insert_flip_char(tty, ch, flag); |
264 | ignore_char: | 264 | ignore_char: |
265 | ; | ||
265 | } while (status & DZ_DVAL); | 266 | } while (status & DZ_DVAL); |
266 | 267 | ||
267 | if (tty) | 268 | if (tty) |
@@ -650,7 +651,7 @@ static void __init dz_init_ports(void) | |||
650 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { | 651 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { |
651 | spin_lock_init(&dport->port.lock); | 652 | spin_lock_init(&dport->port.lock); |
652 | dport->port.membase = (char *) base; | 653 | dport->port.membase = (char *) base; |
653 | dport->port.iotype = SERIAL_IO_PORT; | 654 | dport->port.iotype = UPIO_PORT; |
654 | dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; | 655 | dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; |
655 | dport->port.line = i; | 656 | dport->port.line = i; |
656 | dport->port.fifosize = 1; | 657 | dport->port.fifosize = 1; |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 858048efe1ed..4d53fb5ca87b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -668,7 +668,7 @@ static struct imx_port imx_ports[] = { | |||
668 | .rtsirq = UART1_MINT_RTS, | 668 | .rtsirq = UART1_MINT_RTS, |
669 | .port = { | 669 | .port = { |
670 | .type = PORT_IMX, | 670 | .type = PORT_IMX, |
671 | .iotype = SERIAL_IO_MEM, | 671 | .iotype = UPIO_MEM, |
672 | .membase = (void *)IMX_UART1_BASE, | 672 | .membase = (void *)IMX_UART1_BASE, |
673 | .mapbase = IMX_UART1_BASE, /* FIXME */ | 673 | .mapbase = IMX_UART1_BASE, /* FIXME */ |
674 | .irq = UART1_MINT_RX, | 674 | .irq = UART1_MINT_RX, |
@@ -684,7 +684,7 @@ static struct imx_port imx_ports[] = { | |||
684 | .rtsirq = UART2_MINT_RTS, | 684 | .rtsirq = UART2_MINT_RTS, |
685 | .port = { | 685 | .port = { |
686 | .type = PORT_IMX, | 686 | .type = PORT_IMX, |
687 | .iotype = SERIAL_IO_MEM, | 687 | .iotype = UPIO_MEM, |
688 | .membase = (void *)IMX_UART2_BASE, | 688 | .membase = (void *)IMX_UART2_BASE, |
689 | .mapbase = IMX_UART2_BASE, /* FIXME */ | 689 | .mapbase = IMX_UART2_BASE, /* FIXME */ |
690 | .irq = UART2_MINT_RX, | 690 | .irq = UART2_MINT_RX, |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 66f117d15065..419dd3cd7862 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -215,7 +215,7 @@ static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs) | |||
215 | /* Lower and upper byte of baud rate generator divisor. */ | 215 | /* Lower and upper byte of baud rate generator divisor. */ |
216 | write_zsreg(channel, R12, regs[R12]); | 216 | write_zsreg(channel, R12, regs[R12]); |
217 | write_zsreg(channel, R13, regs[R13]); | 217 | write_zsreg(channel, R13, regs[R13]); |
218 | 218 | ||
219 | /* Now rewrite R14, with BRENAB (if set). */ | 219 | /* Now rewrite R14, with BRENAB (if set). */ |
220 | write_zsreg(channel, R14, regs[R14]); | 220 | write_zsreg(channel, R14, regs[R14]); |
221 | 221 | ||
@@ -571,7 +571,7 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
571 | else | 571 | else |
572 | clear_bits |= DTR; | 572 | clear_bits |= DTR; |
573 | 573 | ||
574 | /* NOTE: Not subject to 'transmitter active' rule. */ | 574 | /* NOTE: Not subject to 'transmitter active' rule. */ |
575 | up->curregs[R5] |= set_bits; | 575 | up->curregs[R5] |= set_bits; |
576 | up->curregs[R5] &= ~clear_bits; | 576 | up->curregs[R5] &= ~clear_bits; |
577 | write_zsreg(channel, R5, up->curregs[R5]); | 577 | write_zsreg(channel, R5, up->curregs[R5]); |
@@ -654,7 +654,7 @@ static void ip22zilog_enable_ms(struct uart_port *port) | |||
654 | if (new_reg != up->curregs[R15]) { | 654 | if (new_reg != up->curregs[R15]) { |
655 | up->curregs[R15] = new_reg; | 655 | up->curregs[R15] = new_reg; |
656 | 656 | ||
657 | /* NOTE: Not subject to 'transmitter active' rule. */ | 657 | /* NOTE: Not subject to 'transmitter active' rule. */ |
658 | write_zsreg(channel, R15, up->curregs[R15]); | 658 | write_zsreg(channel, R15, up->curregs[R15]); |
659 | } | 659 | } |
660 | } | 660 | } |
@@ -680,7 +680,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) | |||
680 | if (new_reg != up->curregs[R5]) { | 680 | if (new_reg != up->curregs[R5]) { |
681 | up->curregs[R5] = new_reg; | 681 | up->curregs[R5] = new_reg; |
682 | 682 | ||
683 | /* NOTE: Not subject to 'transmitter active' rule. */ | 683 | /* NOTE: Not subject to 'transmitter active' rule. */ |
684 | write_zsreg(channel, R5, up->curregs[R5]); | 684 | write_zsreg(channel, R5, up->curregs[R5]); |
685 | } | 685 | } |
686 | 686 | ||
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index b48066a64a7d..242a04104393 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -80,7 +80,7 @@ | |||
80 | #include <asm/serial.h> | 80 | #include <asm/serial.h> |
81 | 81 | ||
82 | /* Standard COM flags */ | 82 | /* Standard COM flags */ |
83 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 83 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 86 | * SERIAL_PORT_DFNS tells us about built-in ports that have no |
diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h index 07d0dd80aa3d..7c3ec24f7e50 100644 --- a/drivers/serial/m32r_sio.h +++ b/drivers/serial/m32r_sio.h | |||
@@ -37,7 +37,7 @@ struct old_serial_port { | |||
37 | unsigned int irq; | 37 | unsigned int irq; |
38 | unsigned int flags; | 38 | unsigned int flags; |
39 | unsigned char io_type; | 39 | unsigned char io_type; |
40 | unsigned char *iomem_base; | 40 | unsigned char __iomem *iomem_base; |
41 | unsigned short iomem_reg_shift; | 41 | unsigned short iomem_reg_shift; |
42 | }; | 42 | }; |
43 | 43 | ||
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 0ef648fa4b2d..8cbbb954df2c 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
@@ -57,20 +57,16 @@ struct timer_list mcfrs_timer_struct; | |||
57 | * keep going. Perhaps one day the cflag settings for the | 57 | * keep going. Perhaps one day the cflag settings for the |
58 | * console can be used instead. | 58 | * console can be used instead. |
59 | */ | 59 | */ |
60 | #if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | ||
61 | defined(CONFIG_senTec) || defined(CONFIG_SNEHA) | ||
62 | #define CONSOLE_BAUD_RATE 19200 | ||
63 | #define DEFAULT_CBAUD B19200 | ||
64 | #endif | ||
65 | |||
66 | #if defined(CONFIG_HW_FEITH) | 60 | #if defined(CONFIG_HW_FEITH) |
67 | #define CONSOLE_BAUD_RATE 38400 | 61 | #define CONSOLE_BAUD_RATE 38400 |
68 | #define DEFAULT_CBAUD B38400 | 62 | #define DEFAULT_CBAUD B38400 |
69 | #endif | 63 | #elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) |
70 | |||
71 | #if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) | ||
72 | #define CONSOLE_BAUD_RATE 115200 | 64 | #define CONSOLE_BAUD_RATE 115200 |
73 | #define DEFAULT_CBAUD B115200 | 65 | #define DEFAULT_CBAUD B115200 |
66 | #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | ||
67 | defined(CONFIG_senTec) || defined(CONFIG_SNEHA) | ||
68 | #define CONSOLE_BAUD_RATE 19200 | ||
69 | #define DEFAULT_CBAUD B19200 | ||
74 | #endif | 70 | #endif |
75 | 71 | ||
76 | #ifndef CONSOLE_BAUD_RATE | 72 | #ifndef CONSOLE_BAUD_RATE |
@@ -350,7 +346,7 @@ static inline void receive_chars(struct mcf_serial *info) | |||
350 | } | 346 | } |
351 | tty_insert_flip_char(tty, ch, flag); | 347 | tty_insert_flip_char(tty, ch, flag); |
352 | } | 348 | } |
353 | tty_flip_buffer_push(tty); | 349 | tty_schedule_flip(tty); |
354 | return; | 350 | return; |
355 | } | 351 | } |
356 | 352 | ||
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 4e49168c3176..868eaf4a1a68 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
@@ -462,7 +462,7 @@ static int __init mux_probe(struct parisc_device *dev) | |||
462 | port->mapbase = dev->hpa.start + MUX_OFFSET + | 462 | port->mapbase = dev->hpa.start + MUX_OFFSET + |
463 | (i * MUX_LINE_OFFSET); | 463 | (i * MUX_LINE_OFFSET); |
464 | port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); | 464 | port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); |
465 | port->iotype = SERIAL_IO_MEM; | 465 | port->iotype = UPIO_MEM; |
466 | port->type = PORT_MUX; | 466 | port->type = PORT_MUX; |
467 | port->irq = NO_IRQ; | 467 | port->irq = NO_IRQ; |
468 | port->uartclk = 0; | 468 | port->uartclk = 0; |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 4e03a87f3fb4..9b7ed58cb53b 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -1492,7 +1492,7 @@ no_dma: | |||
1492 | /* | 1492 | /* |
1493 | * Init remaining bits of "port" structure | 1493 | * Init remaining bits of "port" structure |
1494 | */ | 1494 | */ |
1495 | uap->port.iotype = SERIAL_IO_MEM; | 1495 | uap->port.iotype = UPIO_MEM; |
1496 | uap->port.irq = np->intrs[0].line; | 1496 | uap->port.irq = np->intrs[0].line; |
1497 | uap->port.uartclk = ZS_CLOCK; | 1497 | uap->port.uartclk = ZS_CLOCK; |
1498 | uap->port.fifosize = 1; | 1498 | uap->port.fifosize = 1; |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 0a2dd6c5b95f..7410e093a6b9 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -161,7 +161,11 @@ s3c24xx_serial_dbg(const char *fmt, ...) | |||
161 | 161 | ||
162 | /* we can support 3 uarts, but not always use them */ | 162 | /* we can support 3 uarts, but not always use them */ |
163 | 163 | ||
164 | #ifdef CONFIG_CPU_S3C2400 | ||
165 | #define NR_PORTS (2) | ||
166 | #else | ||
164 | #define NR_PORTS (3) | 167 | #define NR_PORTS (3) |
168 | #endif | ||
165 | 169 | ||
166 | /* port irq numbers */ | 170 | /* port irq numbers */ |
167 | 171 | ||
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index ff7b60b4de37..2c00b8625852 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -628,7 +628,7 @@ static void __init sa1100_init_ports(void) | |||
628 | sa1100_ports[i].port.ops = &sa1100_pops; | 628 | sa1100_ports[i].port.ops = &sa1100_pops; |
629 | sa1100_ports[i].port.fifosize = 8; | 629 | sa1100_ports[i].port.fifosize = 8; |
630 | sa1100_ports[i].port.line = i; | 630 | sa1100_ports[i].port.line = i; |
631 | sa1100_ports[i].port.iotype = SERIAL_IO_MEM; | 631 | sa1100_ports[i].port.iotype = UPIO_MEM; |
632 | init_timer(&sa1100_ports[i].timer); | 632 | init_timer(&sa1100_ports[i].timer); |
633 | sa1100_ports[i].timer.function = sa1100_timeout; | 633 | sa1100_ports[i].timer.function = sa1100_timeout; |
634 | sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i]; | 634 | sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i]; |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index d0490f67f597..04186eaae227 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -501,7 +501,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
501 | .port = { | 501 | .port = { |
502 | .membase = (void*) io_p2v (UART1_PHYS), | 502 | .membase = (void*) io_p2v (UART1_PHYS), |
503 | .mapbase = UART1_PHYS, | 503 | .mapbase = UART1_PHYS, |
504 | .iotype = SERIAL_IO_MEM, | 504 | .iotype = UPIO_MEM, |
505 | .irq = IRQ_UART1INTR, | 505 | .irq = IRQ_UART1INTR, |
506 | .uartclk = 14745600/2, | 506 | .uartclk = 14745600/2, |
507 | .fifosize = 16, | 507 | .fifosize = 16, |
@@ -514,7 +514,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
514 | .port = { | 514 | .port = { |
515 | .membase = (void*) io_p2v (UART2_PHYS), | 515 | .membase = (void*) io_p2v (UART2_PHYS), |
516 | .mapbase = UART2_PHYS, | 516 | .mapbase = UART2_PHYS, |
517 | .iotype = SERIAL_IO_MEM, | 517 | .iotype = UPIO_MEM, |
518 | .irq = IRQ_UART2INTR, | 518 | .irq = IRQ_UART2INTR, |
519 | .uartclk = 14745600/2, | 519 | .uartclk = 14745600/2, |
520 | .fifosize = 16, | 520 | .fifosize = 16, |
@@ -527,7 +527,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
527 | .port = { | 527 | .port = { |
528 | .membase = (void*) io_p2v (UART3_PHYS), | 528 | .membase = (void*) io_p2v (UART3_PHYS), |
529 | .mapbase = UART3_PHYS, | 529 | .mapbase = UART3_PHYS, |
530 | .iotype = SERIAL_IO_MEM, | 530 | .iotype = UPIO_MEM, |
531 | .irq = IRQ_UART3INTR, | 531 | .irq = IRQ_UART3INTR, |
532 | .uartclk = 14745600/2, | 532 | .uartclk = 14745600/2, |
533 | .fifosize = 16, | 533 | .fifosize = 16, |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 80737c131ce7..44f6bf79bbe1 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1468,10 +1468,10 @@ static struct sci_port sci_ports[] = { | |||
1468 | .port = { | 1468 | .port = { |
1469 | .membase = (void *)0xff923000, | 1469 | .membase = (void *)0xff923000, |
1470 | .mapbase = 0xff923000, | 1470 | .mapbase = 0xff923000, |
1471 | .iotype = SERIAL_IO_MEM, | 1471 | .iotype = UPIO_MEM, |
1472 | .irq = 61, | 1472 | .irq = 61, |
1473 | .ops = &sci_uart_ops, | 1473 | .ops = &sci_uart_ops, |
1474 | .flags = ASYNC_BOOT_AUTOCONF, | 1474 | .flags = UPF_BOOT_AUTOCONF, |
1475 | .line = 0, | 1475 | .line = 0, |
1476 | }, | 1476 | }, |
1477 | .type = PORT_SCIF, | 1477 | .type = PORT_SCIF, |
@@ -1482,10 +1482,10 @@ static struct sci_port sci_ports[] = { | |||
1482 | .port = { | 1482 | .port = { |
1483 | .membase = (void *)0xff924000, | 1483 | .membase = (void *)0xff924000, |
1484 | .mapbase = 0xff924000, | 1484 | .mapbase = 0xff924000, |
1485 | .iotype = SERIAL_IO_MEM, | 1485 | .iotype = UPIO_MEM, |
1486 | .irq = 62, | 1486 | .irq = 62, |
1487 | .ops = &sci_uart_ops, | 1487 | .ops = &sci_uart_ops, |
1488 | .flags = ASYNC_BOOT_AUTOCONF, | 1488 | .flags = UPF_BOOT_AUTOCONF, |
1489 | .line = 1, | 1489 | .line = 1, |
1490 | }, | 1490 | }, |
1491 | .type = PORT_SCIF, | 1491 | .type = PORT_SCIF, |
@@ -1496,10 +1496,10 @@ static struct sci_port sci_ports[] = { | |||
1496 | .port = { | 1496 | .port = { |
1497 | .membase = (void *)0xff925000, | 1497 | .membase = (void *)0xff925000, |
1498 | .mapbase = 0xff925000, | 1498 | .mapbase = 0xff925000, |
1499 | .iotype = SERIAL_IO_MEM, | 1499 | .iotype = UPIO_MEM, |
1500 | .irq = 63, | 1500 | .irq = 63, |
1501 | .ops = &sci_uart_ops, | 1501 | .ops = &sci_uart_ops, |
1502 | .flags = ASYNC_BOOT_AUTOCONF, | 1502 | .flags = UPF_BOOT_AUTOCONF, |
1503 | .line = 2, | 1503 | .line = 2, |
1504 | }, | 1504 | }, |
1505 | .type = PORT_SCIF, | 1505 | .type = PORT_SCIF, |
@@ -1511,10 +1511,10 @@ static struct sci_port sci_ports[] = { | |||
1511 | .port = { | 1511 | .port = { |
1512 | .membase = (void *)0xffe00000, | 1512 | .membase = (void *)0xffe00000, |
1513 | .mapbase = 0xffe00000, | 1513 | .mapbase = 0xffe00000, |
1514 | .iotype = SERIAL_IO_MEM, | 1514 | .iotype = UPIO_MEM, |
1515 | .irq = 43, | 1515 | .irq = 43, |
1516 | .ops = &sci_uart_ops, | 1516 | .ops = &sci_uart_ops, |
1517 | .flags = ASYNC_BOOT_AUTOCONF, | 1517 | .flags = UPF_BOOT_AUTOCONF, |
1518 | .line = 0, | 1518 | .line = 0, |
1519 | }, | 1519 | }, |
1520 | .type = PORT_SCIF, | 1520 | .type = PORT_SCIF, |
@@ -1525,10 +1525,10 @@ static struct sci_port sci_ports[] = { | |||
1525 | .port = { | 1525 | .port = { |
1526 | .membase = (void *)0xffe10000, | 1526 | .membase = (void *)0xffe10000, |
1527 | .mapbase = 0xffe10000, | 1527 | .mapbase = 0xffe10000, |
1528 | .iotype = SERIAL_IO_MEM, | 1528 | .iotype = UPIO_MEM, |
1529 | .irq = 79, | 1529 | .irq = 79, |
1530 | .ops = &sci_uart_ops, | 1530 | .ops = &sci_uart_ops, |
1531 | .flags = ASYNC_BOOT_AUTOCONF, | 1531 | .flags = UPF_BOOT_AUTOCONF, |
1532 | .line = 1, | 1532 | .line = 1, |
1533 | }, | 1533 | }, |
1534 | .type = PORT_SCIF, | 1534 | .type = PORT_SCIF, |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 8bcaebcc0ad7..85664228a0b6 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -1036,7 +1036,7 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg | |||
1036 | up->port.irq = edev->irqs[0]; | 1036 | up->port.irq = edev->irqs[0]; |
1037 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; | 1037 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; |
1038 | up->port.mapbase = (unsigned long)up->regs; | 1038 | up->port.mapbase = (unsigned long)up->regs; |
1039 | up->port.iotype = SERIAL_IO_MEM; | 1039 | up->port.iotype = UPIO_MEM; |
1040 | 1040 | ||
1041 | writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); | 1041 | writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); |
1042 | 1042 | ||
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index bc67442c6b4c..308704566948 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -109,11 +109,11 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset) | |||
109 | offset <<= up->port.regshift; | 109 | offset <<= up->port.regshift; |
110 | 110 | ||
111 | switch (up->port.iotype) { | 111 | switch (up->port.iotype) { |
112 | case SERIAL_IO_HUB6: | 112 | case UPIO_HUB6: |
113 | outb(up->port.hub6 - 1 + offset, up->port.iobase); | 113 | outb(up->port.hub6 - 1 + offset, up->port.iobase); |
114 | return inb(up->port.iobase + 1); | 114 | return inb(up->port.iobase + 1); |
115 | 115 | ||
116 | case SERIAL_IO_MEM: | 116 | case UPIO_MEM: |
117 | return readb(up->port.membase + offset); | 117 | return readb(up->port.membase + offset); |
118 | 118 | ||
119 | default: | 119 | default: |
@@ -139,12 +139,12 @@ serial_out(struct uart_sunsu_port *up, int offset, int value) | |||
139 | offset <<= up->port.regshift; | 139 | offset <<= up->port.regshift; |
140 | 140 | ||
141 | switch (up->port.iotype) { | 141 | switch (up->port.iotype) { |
142 | case SERIAL_IO_HUB6: | 142 | case UPIO_HUB6: |
143 | outb(up->port.hub6 - 1 + offset, up->port.iobase); | 143 | outb(up->port.hub6 - 1 + offset, up->port.iobase); |
144 | outb(value, up->port.iobase + 1); | 144 | outb(value, up->port.iobase + 1); |
145 | break; | 145 | break; |
146 | 146 | ||
147 | case SERIAL_IO_MEM: | 147 | case UPIO_MEM: |
148 | writeb(value, up->port.membase + offset); | 148 | writeb(value, up->port.membase + offset); |
149 | break; | 149 | break; |
150 | 150 | ||
@@ -1052,7 +1052,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) | |||
1052 | return; | 1052 | return; |
1053 | 1053 | ||
1054 | up->type_probed = PORT_UNKNOWN; | 1054 | up->type_probed = PORT_UNKNOWN; |
1055 | up->port.iotype = SERIAL_IO_MEM; | 1055 | up->port.iotype = UPIO_MEM; |
1056 | 1056 | ||
1057 | /* | 1057 | /* |
1058 | * First we look for Ebus-bases su's | 1058 | * First we look for Ebus-bases su's |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 3c72484adea7..5cc4d4c2935c 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1487,7 +1487,7 @@ static void __init sunzilog_prepare(void) | |||
1487 | up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB; | 1487 | up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB; |
1488 | 1488 | ||
1489 | /* Channel A */ | 1489 | /* Channel A */ |
1490 | up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM; | 1490 | up[(chip * 2) + 0].port.iotype = UPIO_MEM; |
1491 | up[(chip * 2) + 0].port.irq = zilog_irq; | 1491 | up[(chip * 2) + 0].port.irq = zilog_irq; |
1492 | up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; | 1492 | up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; |
1493 | up[(chip * 2) + 0].port.fifosize = 1; | 1493 | up[(chip * 2) + 0].port.fifosize = 1; |
@@ -1498,7 +1498,7 @@ static void __init sunzilog_prepare(void) | |||
1498 | up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; | 1498 | up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; |
1499 | 1499 | ||
1500 | /* Channel B */ | 1500 | /* Channel B */ |
1501 | up[(chip * 2) + 1].port.iotype = SERIAL_IO_MEM; | 1501 | up[(chip * 2) + 1].port.iotype = UPIO_MEM; |
1502 | up[(chip * 2) + 1].port.irq = zilog_irq; | 1502 | up[(chip * 2) + 1].port.irq = zilog_irq; |
1503 | up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; | 1503 | up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; |
1504 | up[(chip * 2) + 1].port.fifosize = 1; | 1504 | up[(chip * 2) + 1].port.fifosize = 1; |
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c index 9378895a8d56..df705fda4243 100644 --- a/drivers/serial/v850e_uart.c +++ b/drivers/serial/v850e_uart.c | |||
@@ -496,7 +496,7 @@ static int __init v850e_uart_init (void) | |||
496 | 496 | ||
497 | port->ops = &v850e_uart_ops; | 497 | port->ops = &v850e_uart_ops; |
498 | port->line = chan; | 498 | port->line = chan; |
499 | port->iotype = SERIAL_IO_MEM; | 499 | port->iotype = UPIO_MEM; |
500 | port->flags = UPF_BOOT_AUTOCONF; | 500 | port->flags = UPF_BOOT_AUTOCONF; |
501 | 501 | ||
502 | /* We actually use multiple IRQs, but the serial | 502 | /* We actually use multiple IRQs, but the serial |
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index c70ae81b5d98..12357e1fa558 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c | |||
@@ -38,10 +38,10 @@ static inline unsigned mcr_pack(unsigned pulse, unsigned sample) | |||
38 | 38 | ||
39 | static int nic_wait(struct ioc3_driver_data *idd) | 39 | static int nic_wait(struct ioc3_driver_data *idd) |
40 | { | 40 | { |
41 | volatile unsigned mcr; | 41 | unsigned mcr; |
42 | 42 | ||
43 | do { | 43 | do { |
44 | mcr = (volatile unsigned)idd->vma->mcr; | 44 | mcr = readl(&idd->vma->mcr); |
45 | } while (!(mcr & 2)); | 45 | } while (!(mcr & 2)); |
46 | 46 | ||
47 | return mcr & 1; | 47 | return mcr & 1; |
@@ -53,7 +53,7 @@ static int nic_reset(struct ioc3_driver_data *idd) | |||
53 | unsigned long flags; | 53 | unsigned long flags; |
54 | 54 | ||
55 | local_irq_save(flags); | 55 | local_irq_save(flags); |
56 | idd->vma->mcr = mcr_pack(500, 65); | 56 | writel(mcr_pack(500, 65), &idd->vma->mcr); |
57 | presence = nic_wait(idd); | 57 | presence = nic_wait(idd); |
58 | local_irq_restore(flags); | 58 | local_irq_restore(flags); |
59 | 59 | ||
@@ -68,7 +68,7 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) | |||
68 | unsigned long flags; | 68 | unsigned long flags; |
69 | 69 | ||
70 | local_irq_save(flags); | 70 | local_irq_save(flags); |
71 | idd->vma->mcr = mcr_pack(6, 13); | 71 | writel(mcr_pack(6, 13), &idd->vma->mcr); |
72 | result = nic_wait(idd); | 72 | result = nic_wait(idd); |
73 | local_irq_restore(flags); | 73 | local_irq_restore(flags); |
74 | 74 | ||
@@ -80,9 +80,9 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) | |||
80 | static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit) | 80 | static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit) |
81 | { | 81 | { |
82 | if (bit) | 82 | if (bit) |
83 | idd->vma->mcr = mcr_pack(6, 110); | 83 | writel(mcr_pack(6, 110), &idd->vma->mcr); |
84 | else | 84 | else |
85 | idd->vma->mcr = mcr_pack(80, 30); | 85 | writel(mcr_pack(80, 30), &idd->vma->mcr); |
86 | 86 | ||
87 | nic_wait(idd); | 87 | nic_wait(idd); |
88 | } | 88 | } |
@@ -337,7 +337,7 @@ static void probe_nic(struct ioc3_driver_data *idd) | |||
337 | int save = 0, loops = 3; | 337 | int save = 0, loops = 3; |
338 | unsigned long first, addr; | 338 | unsigned long first, addr; |
339 | 339 | ||
340 | idd->vma->gpcr_s = GPCR_MLAN_EN; | 340 | writel(GPCR_MLAN_EN, &idd->vma->gpcr_s); |
341 | 341 | ||
342 | while(loops>0) { | 342 | while(loops>0) { |
343 | idd->nic_part[0] = 0; | 343 | idd->nic_part[0] = 0; |
@@ -408,7 +408,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) | |||
408 | 408 | ||
409 | read_lock_irqsave(&ioc3_submodules_lock, flags); | 409 | read_lock_irqsave(&ioc3_submodules_lock, flags); |
410 | 410 | ||
411 | if(idd->dual_irq && idd->vma->eisr) { | 411 | if(idd->dual_irq && readb(&idd->vma->eisr)) { |
412 | /* send Ethernet IRQ to the driver */ | 412 | /* send Ethernet IRQ to the driver */ |
413 | if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && | 413 | if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && |
414 | ioc3_ethernet->intr) { | 414 | ioc3_ethernet->intr) { |
@@ -682,7 +682,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
682 | idd->id = ioc3_counter++; | 682 | idd->id = ioc3_counter++; |
683 | up_write(&ioc3_devices_rwsem); | 683 | up_write(&ioc3_devices_rwsem); |
684 | 684 | ||
685 | idd->gpdr_shadow = idd->vma->gpdr; | 685 | idd->gpdr_shadow = readl(&idd->vma->gpdr); |
686 | 686 | ||
687 | /* Read IOC3 NIC contents */ | 687 | /* Read IOC3 NIC contents */ |
688 | probe_nic(idd); | 688 | probe_nic(idd); |
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"); |
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index a0e5af638e0e..4a51e56f85b6 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | 18 | ||
19 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
20 | #include <asm/bug.h> | ||
21 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
22 | #include <asm/io.h> | 21 | #include <asm/io.h> |
23 | #include <asm/paccess.h> | 22 | #include <asm/paccess.h> |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 9d5015e99372..bd39bbd88d41 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/ctype.h> | 13 | #include <linux/ctype.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include <asm/bug.h> | ||
17 | 16 | ||
18 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) | 17 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) |
19 | { | 18 | { |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 68c690605aa7..9e32485ee7bb 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/ctype.h> | 13 | #include <linux/ctype.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include <asm/bug.h> | ||
17 | 16 | ||
18 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) | 17 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) |
19 | { | 18 | { |
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index f3927b6cda9d..f5361cd8ccce 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | 32 | ||
33 | #include <asm/bug.h> | ||
34 | #include <asm/io.h> | 33 | #include <asm/io.h> |
35 | #include <asm/system.h> | 34 | #include <asm/system.h> |
36 | 35 | ||
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 25148de5fe67..eeeac924b500 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | 29 | ||
30 | #include <asm/bug.h> | ||
31 | #include <asm/io.h> | 30 | #include <asm/io.h> |
32 | #include <asm/system.h> | 31 | #include <asm/system.h> |
33 | 32 | ||