diff options
Diffstat (limited to 'drivers')
379 files changed, 10683 insertions, 3528 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 8a5bf3b356fa..55b5b90c2a44 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -395,7 +395,7 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle) | |||
395 | fn = adr & 0xffff; | 395 | fn = adr & 0xffff; |
396 | 396 | ||
397 | pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); | 397 | pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); |
398 | if (hnd == handle) | 398 | if (!pdev || hnd == handle) |
399 | break; | 399 | break; |
400 | 400 | ||
401 | pbus = pdev->subordinate; | 401 | pbus = pdev->subordinate; |
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 768d973d0ded..f60b2b6a0931 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -208,6 +208,16 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) | |||
208 | void __iomem *tmp; | 208 | void __iomem *tmp; |
209 | int i, ret; | 209 | int i, ret; |
210 | 210 | ||
211 | device_initialize(&dev->dev); | ||
212 | |||
213 | /* | ||
214 | * Copy from device_add | ||
215 | */ | ||
216 | if (dev->dev.init_name) { | ||
217 | dev_set_name(&dev->dev, "%s", dev->dev.init_name); | ||
218 | dev->dev.init_name = NULL; | ||
219 | } | ||
220 | |||
211 | dev->dev.release = amba_device_release; | 221 | dev->dev.release = amba_device_release; |
212 | dev->dev.bus = &amba_bustype; | 222 | dev->dev.bus = &amba_bustype; |
213 | dev->dev.dma_mask = &dev->dma_mask; | 223 | dev->dev.dma_mask = &dev->dma_mask; |
@@ -250,7 +260,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) | |||
250 | goto err_release; | 260 | goto err_release; |
251 | } | 261 | } |
252 | 262 | ||
253 | ret = device_register(&dev->dev); | 263 | ret = device_add(&dev->dev); |
254 | if (ret) | 264 | if (ret) |
255 | goto err_release; | 265 | goto err_release; |
256 | 266 | ||
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index ddeb819c8f87..fc466531260e 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -357,7 +357,7 @@ static void fw_dev_release(struct device *dev) | |||
357 | kfree(fw_priv->pages); | 357 | kfree(fw_priv->pages); |
358 | kfree(fw_priv->fw_id); | 358 | kfree(fw_priv->fw_id); |
359 | kfree(fw_priv); | 359 | kfree(fw_priv); |
360 | put_device(dev); | 360 | kfree(dev); |
361 | 361 | ||
362 | module_put(THIS_MODULE); | 362 | module_put(THIS_MODULE); |
363 | } | 363 | } |
@@ -408,13 +408,11 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, | |||
408 | if (retval) { | 408 | if (retval) { |
409 | dev_err(device, "%s: device_register failed\n", __func__); | 409 | dev_err(device, "%s: device_register failed\n", __func__); |
410 | put_device(f_dev); | 410 | put_device(f_dev); |
411 | goto error_kfree_fw_id; | 411 | return retval; |
412 | } | 412 | } |
413 | *dev_p = f_dev; | 413 | *dev_p = f_dev; |
414 | return 0; | 414 | return 0; |
415 | 415 | ||
416 | error_kfree_fw_id: | ||
417 | kfree(fw_priv->fw_id); | ||
418 | error_kfree: | 416 | error_kfree: |
419 | kfree(f_dev); | 417 | kfree(f_dev); |
420 | kfree(fw_priv); | 418 | kfree(fw_priv); |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index fae725458981..58a3e572f2c9 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -762,6 +762,7 @@ static int dpm_prepare(pm_message_t state) | |||
762 | dev->power.status = DPM_ON; | 762 | dev->power.status = DPM_ON; |
763 | if (error == -EAGAIN) { | 763 | if (error == -EAGAIN) { |
764 | put_device(dev); | 764 | put_device(dev); |
765 | error = 0; | ||
765 | continue; | 766 | continue; |
766 | } | 767 | } |
767 | printk(KERN_ERR "PM: Failed to prepare device %s " | 768 | printk(KERN_ERR "PM: Failed to prepare device %s " |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index bb72ada9f074..1d886e079c58 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -298,6 +298,22 @@ config BLK_DEV_NBD | |||
298 | 298 | ||
299 | If unsure, say N. | 299 | If unsure, say N. |
300 | 300 | ||
301 | config BLK_DEV_OSD | ||
302 | tristate "OSD object-as-blkdev support" | ||
303 | depends on SCSI_OSD_ULD | ||
304 | ---help--- | ||
305 | Saying Y or M here will allow the exporting of a single SCSI | ||
306 | OSD (object-based storage) object as a Linux block device. | ||
307 | |||
308 | For example, if you create a 2G object on an OSD device, | ||
309 | you can then use this module to present that 2G object as | ||
310 | a Linux block device. | ||
311 | |||
312 | To compile this driver as a module, choose M here: the | ||
313 | module will be called osdblk. | ||
314 | |||
315 | If unsure, say N. | ||
316 | |||
301 | config BLK_DEV_SX8 | 317 | config BLK_DEV_SX8 |
302 | tristate "Promise SATA SX8 support" | 318 | tristate "Promise SATA SX8 support" |
303 | depends on PCI | 319 | depends on PCI |
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 7755a5e2a85e..cdaa3f8fddf0 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_XILINX_SYSACE) += xsysace.o | |||
23 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o | 23 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o |
24 | obj-$(CONFIG_MG_DISK) += mg_disk.o | 24 | obj-$(CONFIG_MG_DISK) += mg_disk.o |
25 | obj-$(CONFIG_SUNVDC) += sunvdc.o | 25 | obj-$(CONFIG_SUNVDC) += sunvdc.o |
26 | obj-$(CONFIG_BLK_DEV_OSD) += osdblk.o | ||
26 | 27 | ||
27 | obj-$(CONFIG_BLK_DEV_UMEM) += umem.o | 28 | obj-$(CONFIG_BLK_DEV_UMEM) += umem.o |
28 | obj-$(CONFIG_BLK_DEV_NBD) += nbd.o | 29 | obj-$(CONFIG_BLK_DEV_NBD) += nbd.o |
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 9c6e5b0fe894..2f07b7c99a95 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c | |||
@@ -1645,7 +1645,7 @@ static int __init fd_probe_drives(void) | |||
1645 | { | 1645 | { |
1646 | int drive,drives,nomem; | 1646 | int drive,drives,nomem; |
1647 | 1647 | ||
1648 | printk(KERN_INFO "FD: probing units\n" KERN_INFO "found "); | 1648 | printk(KERN_INFO "FD: probing units\nfound "); |
1649 | drives=0; | 1649 | drives=0; |
1650 | nomem=0; | 1650 | nomem=0; |
1651 | for(drive=0;drive<FD_MAX_UNITS;drive++) { | 1651 | for(drive=0;drive<FD_MAX_UNITS;drive++) { |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index c7a527c08a09..65a0655e7fc8 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -226,8 +226,18 @@ static inline void addQ(struct hlist_head *list, CommandList_struct *c) | |||
226 | 226 | ||
227 | static inline void removeQ(CommandList_struct *c) | 227 | static inline void removeQ(CommandList_struct *c) |
228 | { | 228 | { |
229 | if (WARN_ON(hlist_unhashed(&c->list))) | 229 | /* |
230 | * After kexec/dump some commands might still | ||
231 | * be in flight, which the firmware will try | ||
232 | * to complete. Resetting the firmware doesn't work | ||
233 | * with old fw revisions, so we have to mark | ||
234 | * them off as 'stale' to prevent the driver from | ||
235 | * falling over. | ||
236 | */ | ||
237 | if (WARN_ON(hlist_unhashed(&c->list))) { | ||
238 | c->cmd_type = CMD_MSG_STALE; | ||
230 | return; | 239 | return; |
240 | } | ||
231 | 241 | ||
232 | hlist_del_init(&c->list); | 242 | hlist_del_init(&c->list); |
233 | } | 243 | } |
@@ -4246,7 +4256,8 @@ static void fail_all_cmds(unsigned long ctlr) | |||
4246 | while (!hlist_empty(&h->cmpQ)) { | 4256 | while (!hlist_empty(&h->cmpQ)) { |
4247 | c = hlist_entry(h->cmpQ.first, CommandList_struct, list); | 4257 | c = hlist_entry(h->cmpQ.first, CommandList_struct, list); |
4248 | removeQ(c); | 4258 | removeQ(c); |
4249 | c->err_info->CommandStatus = CMD_HARDWARE_ERR; | 4259 | if (c->cmd_type != CMD_MSG_STALE) |
4260 | c->err_info->CommandStatus = CMD_HARDWARE_ERR; | ||
4250 | if (c->cmd_type == CMD_RWREQ) { | 4261 | if (c->cmd_type == CMD_RWREQ) { |
4251 | complete_command(h, c, 0); | 4262 | complete_command(h, c, 0); |
4252 | } else if (c->cmd_type == CMD_IOCTL_PEND) | 4263 | } else if (c->cmd_type == CMD_IOCTL_PEND) |
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index cd665b00c7c5..dbaed1ea0da3 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h | |||
@@ -274,6 +274,7 @@ typedef struct _ErrorInfo_struct { | |||
274 | #define CMD_SCSI 0x03 | 274 | #define CMD_SCSI 0x03 |
275 | #define CMD_MSG_DONE 0x04 | 275 | #define CMD_MSG_DONE 0x04 |
276 | #define CMD_MSG_TIMEOUT 0x05 | 276 | #define CMD_MSG_TIMEOUT 0x05 |
277 | #define CMD_MSG_STALE 0xff | ||
277 | 278 | ||
278 | /* This structure needs to be divisible by 8 for new | 279 | /* This structure needs to be divisible by 8 for new |
279 | * indexing method. | 280 | * indexing method. |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 862b40c90181..91b753013780 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3327,7 +3327,10 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3327 | if (!capable(CAP_SYS_ADMIN)) | 3327 | if (!capable(CAP_SYS_ADMIN)) |
3328 | return -EPERM; | 3328 | return -EPERM; |
3329 | mutex_lock(&open_lock); | 3329 | mutex_lock(&open_lock); |
3330 | LOCK_FDC(drive, 1); | 3330 | if (lock_fdc(drive, 1)) { |
3331 | mutex_unlock(&open_lock); | ||
3332 | return -EINTR; | ||
3333 | } | ||
3331 | floppy_type[type] = *g; | 3334 | floppy_type[type] = *g; |
3332 | floppy_type[type].name = "user format"; | 3335 | floppy_type[type].name = "user format"; |
3333 | for (cnt = type << 2; cnt < (type << 2) + 4; cnt++) | 3336 | for (cnt = type << 2; cnt < (type << 2) + 4; cnt++) |
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c new file mode 100644 index 000000000000..13c1aee6aa3f --- /dev/null +++ b/drivers/block/osdblk.c | |||
@@ -0,0 +1,701 @@ | |||
1 | |||
2 | /* | ||
3 | osdblk.c -- Export a single SCSI OSD object as a Linux block device | ||
4 | |||
5 | |||
6 | Copyright 2009 Red Hat, Inc. | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; see the file COPYING. If not, write to | ||
19 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | |||
22 | Instructions for use | ||
23 | -------------------- | ||
24 | |||
25 | 1) Map a Linux block device to an existing OSD object. | ||
26 | |||
27 | In this example, we will use partition id 1234, object id 5678, | ||
28 | OSD device /dev/osd1. | ||
29 | |||
30 | $ echo "1234 5678 /dev/osd1" > /sys/class/osdblk/add | ||
31 | |||
32 | |||
33 | 2) List all active blkdev<->object mappings. | ||
34 | |||
35 | In this example, we have performed step #1 twice, creating two blkdevs, | ||
36 | mapped to two separate OSD objects. | ||
37 | |||
38 | $ cat /sys/class/osdblk/list | ||
39 | 0 174 1234 5678 /dev/osd1 | ||
40 | 1 179 1994 897123 /dev/osd0 | ||
41 | |||
42 | The columns, in order, are: | ||
43 | - blkdev unique id | ||
44 | - blkdev assigned major | ||
45 | - OSD object partition id | ||
46 | - OSD object id | ||
47 | - OSD device | ||
48 | |||
49 | |||
50 | 3) Remove an active blkdev<->object mapping. | ||
51 | |||
52 | In this example, we remove the mapping with blkdev unique id 1. | ||
53 | |||
54 | $ echo 1 > /sys/class/osdblk/remove | ||
55 | |||
56 | |||
57 | NOTE: The actual creation and deletion of OSD objects is outside the scope | ||
58 | of this driver. | ||
59 | |||
60 | */ | ||
61 | |||
62 | #include <linux/kernel.h> | ||
63 | #include <linux/device.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/fs.h> | ||
66 | #include <scsi/osd_initiator.h> | ||
67 | #include <scsi/osd_attributes.h> | ||
68 | #include <scsi/osd_sec.h> | ||
69 | #include <scsi/scsi_device.h> | ||
70 | |||
71 | #define DRV_NAME "osdblk" | ||
72 | #define PFX DRV_NAME ": " | ||
73 | |||
74 | /* #define _OSDBLK_DEBUG */ | ||
75 | #ifdef _OSDBLK_DEBUG | ||
76 | #define OSDBLK_DEBUG(fmt, a...) \ | ||
77 | printk(KERN_NOTICE "osdblk @%s:%d: " fmt, __func__, __LINE__, ##a) | ||
78 | #else | ||
79 | #define OSDBLK_DEBUG(fmt, a...) \ | ||
80 | do { if (0) printk(fmt, ##a); } while (0) | ||
81 | #endif | ||
82 | |||
83 | MODULE_AUTHOR("Jeff Garzik <jeff@garzik.org>"); | ||
84 | MODULE_DESCRIPTION("block device inside an OSD object osdblk.ko"); | ||
85 | MODULE_LICENSE("GPL"); | ||
86 | |||
87 | struct osdblk_device; | ||
88 | |||
89 | enum { | ||
90 | OSDBLK_MINORS_PER_MAJOR = 256, /* max minors per blkdev */ | ||
91 | OSDBLK_MAX_REQ = 32, /* max parallel requests */ | ||
92 | OSDBLK_OP_TIMEOUT = 4 * 60, /* sync OSD req timeout */ | ||
93 | }; | ||
94 | |||
95 | struct osdblk_request { | ||
96 | struct request *rq; /* blk layer request */ | ||
97 | struct bio *bio; /* cloned bio */ | ||
98 | struct osdblk_device *osdev; /* associated blkdev */ | ||
99 | }; | ||
100 | |||
101 | struct osdblk_device { | ||
102 | int id; /* blkdev unique id */ | ||
103 | |||
104 | int major; /* blkdev assigned major */ | ||
105 | struct gendisk *disk; /* blkdev's gendisk and rq */ | ||
106 | struct request_queue *q; | ||
107 | |||
108 | struct osd_dev *osd; /* associated OSD */ | ||
109 | |||
110 | char name[32]; /* blkdev name, e.g. osdblk34 */ | ||
111 | |||
112 | spinlock_t lock; /* queue lock */ | ||
113 | |||
114 | struct osd_obj_id obj; /* OSD partition, obj id */ | ||
115 | uint8_t obj_cred[OSD_CAP_LEN]; /* OSD cred */ | ||
116 | |||
117 | struct osdblk_request req[OSDBLK_MAX_REQ]; /* request table */ | ||
118 | |||
119 | struct list_head node; | ||
120 | |||
121 | char osd_path[0]; /* OSD device path */ | ||
122 | }; | ||
123 | |||
124 | static struct class *class_osdblk; /* /sys/class/osdblk */ | ||
125 | static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ | ||
126 | static LIST_HEAD(osdblkdev_list); | ||
127 | |||
128 | static struct block_device_operations osdblk_bd_ops = { | ||
129 | .owner = THIS_MODULE, | ||
130 | }; | ||
131 | |||
132 | static const struct osd_attr g_attr_logical_length = ATTR_DEF( | ||
133 | OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); | ||
134 | |||
135 | static void osdblk_make_credential(u8 cred_a[OSD_CAP_LEN], | ||
136 | const struct osd_obj_id *obj) | ||
137 | { | ||
138 | osd_sec_init_nosec_doall_caps(cred_a, obj, false, true); | ||
139 | } | ||
140 | |||
141 | /* copied from exofs; move to libosd? */ | ||
142 | /* | ||
143 | * Perform a synchronous OSD operation. copied from exofs; move to libosd? | ||
144 | */ | ||
145 | static int osd_sync_op(struct osd_request *or, int timeout, uint8_t *credential) | ||
146 | { | ||
147 | int ret; | ||
148 | |||
149 | or->timeout = timeout; | ||
150 | ret = osd_finalize_request(or, 0, credential, NULL); | ||
151 | if (ret) | ||
152 | return ret; | ||
153 | |||
154 | ret = osd_execute_request(or); | ||
155 | |||
156 | /* osd_req_decode_sense(or, ret); */ | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Perform an asynchronous OSD operation. copied from exofs; move to libosd? | ||
162 | */ | ||
163 | static int osd_async_op(struct osd_request *or, osd_req_done_fn *async_done, | ||
164 | void *caller_context, u8 *cred) | ||
165 | { | ||
166 | int ret; | ||
167 | |||
168 | ret = osd_finalize_request(or, 0, cred, NULL); | ||
169 | if (ret) | ||
170 | return ret; | ||
171 | |||
172 | ret = osd_execute_request_async(or, async_done, caller_context); | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | /* copied from exofs; move to libosd? */ | ||
178 | static int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr) | ||
179 | { | ||
180 | struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */ | ||
181 | void *iter = NULL; | ||
182 | int nelem; | ||
183 | |||
184 | do { | ||
185 | nelem = 1; | ||
186 | osd_req_decode_get_attr_list(or, &cur_attr, &nelem, &iter); | ||
187 | if ((cur_attr.attr_page == attr->attr_page) && | ||
188 | (cur_attr.attr_id == attr->attr_id)) { | ||
189 | attr->len = cur_attr.len; | ||
190 | attr->val_ptr = cur_attr.val_ptr; | ||
191 | return 0; | ||
192 | } | ||
193 | } while (iter); | ||
194 | |||
195 | return -EIO; | ||
196 | } | ||
197 | |||
198 | static int osdblk_get_obj_size(struct osdblk_device *osdev, u64 *size_out) | ||
199 | { | ||
200 | struct osd_request *or; | ||
201 | struct osd_attr attr; | ||
202 | int ret; | ||
203 | |||
204 | /* start request */ | ||
205 | or = osd_start_request(osdev->osd, GFP_KERNEL); | ||
206 | if (!or) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | /* create a get-attributes(length) request */ | ||
210 | osd_req_get_attributes(or, &osdev->obj); | ||
211 | |||
212 | osd_req_add_get_attr_list(or, &g_attr_logical_length, 1); | ||
213 | |||
214 | /* execute op synchronously */ | ||
215 | ret = osd_sync_op(or, OSDBLK_OP_TIMEOUT, osdev->obj_cred); | ||
216 | if (ret) | ||
217 | goto out; | ||
218 | |||
219 | /* extract length from returned attribute info */ | ||
220 | attr = g_attr_logical_length; | ||
221 | ret = extract_attr_from_req(or, &attr); | ||
222 | if (ret) | ||
223 | goto out; | ||
224 | |||
225 | *size_out = get_unaligned_be64(attr.val_ptr); | ||
226 | |||
227 | out: | ||
228 | osd_end_request(or); | ||
229 | return ret; | ||
230 | |||
231 | } | ||
232 | |||
233 | static void osdblk_osd_complete(struct osd_request *or, void *private) | ||
234 | { | ||
235 | struct osdblk_request *orq = private; | ||
236 | struct osd_sense_info osi; | ||
237 | int ret = osd_req_decode_sense(or, &osi); | ||
238 | |||
239 | if (ret) { | ||
240 | ret = -EIO; | ||
241 | OSDBLK_DEBUG("osdblk_osd_complete with err=%d\n", ret); | ||
242 | } | ||
243 | |||
244 | /* complete OSD request */ | ||
245 | osd_end_request(or); | ||
246 | |||
247 | /* complete request passed to osdblk by block layer */ | ||
248 | __blk_end_request_all(orq->rq, ret); | ||
249 | } | ||
250 | |||
251 | static void bio_chain_put(struct bio *chain) | ||
252 | { | ||
253 | struct bio *tmp; | ||
254 | |||
255 | while (chain) { | ||
256 | tmp = chain; | ||
257 | chain = chain->bi_next; | ||
258 | |||
259 | bio_put(tmp); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static struct bio *bio_chain_clone(struct bio *old_chain, gfp_t gfpmask) | ||
264 | { | ||
265 | struct bio *tmp, *new_chain = NULL, *tail = NULL; | ||
266 | |||
267 | while (old_chain) { | ||
268 | tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs); | ||
269 | if (!tmp) | ||
270 | goto err_out; | ||
271 | |||
272 | __bio_clone(tmp, old_chain); | ||
273 | tmp->bi_bdev = NULL; | ||
274 | gfpmask &= ~__GFP_WAIT; | ||
275 | tmp->bi_next = NULL; | ||
276 | |||
277 | if (!new_chain) | ||
278 | new_chain = tail = tmp; | ||
279 | else { | ||
280 | tail->bi_next = tmp; | ||
281 | tail = tmp; | ||
282 | } | ||
283 | |||
284 | old_chain = old_chain->bi_next; | ||
285 | } | ||
286 | |||
287 | return new_chain; | ||
288 | |||
289 | err_out: | ||
290 | OSDBLK_DEBUG("bio_chain_clone with err\n"); | ||
291 | bio_chain_put(new_chain); | ||
292 | return NULL; | ||
293 | } | ||
294 | |||
295 | static void osdblk_rq_fn(struct request_queue *q) | ||
296 | { | ||
297 | struct osdblk_device *osdev = q->queuedata; | ||
298 | |||
299 | while (1) { | ||
300 | struct request *rq; | ||
301 | struct osdblk_request *orq; | ||
302 | struct osd_request *or; | ||
303 | struct bio *bio; | ||
304 | bool do_write, do_flush; | ||
305 | |||
306 | /* peek at request from block layer */ | ||
307 | rq = blk_fetch_request(q); | ||
308 | if (!rq) | ||
309 | break; | ||
310 | |||
311 | /* filter out block requests we don't understand */ | ||
312 | if (!blk_fs_request(rq) && !blk_barrier_rq(rq)) { | ||
313 | blk_end_request_all(rq, 0); | ||
314 | continue; | ||
315 | } | ||
316 | |||
317 | /* deduce our operation (read, write, flush) */ | ||
318 | /* I wish the block layer simplified cmd_type/cmd_flags/cmd[] | ||
319 | * into a clearly defined set of RPC commands: | ||
320 | * read, write, flush, scsi command, power mgmt req, | ||
321 | * driver-specific, etc. | ||
322 | */ | ||
323 | |||
324 | do_flush = (rq->special == (void *) 0xdeadbeefUL); | ||
325 | do_write = (rq_data_dir(rq) == WRITE); | ||
326 | |||
327 | if (!do_flush) { /* osd_flush does not use a bio */ | ||
328 | /* a bio clone to be passed down to OSD request */ | ||
329 | bio = bio_chain_clone(rq->bio, GFP_ATOMIC); | ||
330 | if (!bio) | ||
331 | break; | ||
332 | } else | ||
333 | bio = NULL; | ||
334 | |||
335 | /* alloc internal OSD request, for OSD command execution */ | ||
336 | or = osd_start_request(osdev->osd, GFP_ATOMIC); | ||
337 | if (!or) { | ||
338 | bio_chain_put(bio); | ||
339 | OSDBLK_DEBUG("osd_start_request with err\n"); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | orq = &osdev->req[rq->tag]; | ||
344 | orq->rq = rq; | ||
345 | orq->bio = bio; | ||
346 | orq->osdev = osdev; | ||
347 | |||
348 | /* init OSD command: flush, write or read */ | ||
349 | if (do_flush) | ||
350 | osd_req_flush_object(or, &osdev->obj, | ||
351 | OSD_CDB_FLUSH_ALL, 0, 0); | ||
352 | else if (do_write) | ||
353 | osd_req_write(or, &osdev->obj, blk_rq_pos(rq) * 512ULL, | ||
354 | bio, blk_rq_bytes(rq)); | ||
355 | else | ||
356 | osd_req_read(or, &osdev->obj, blk_rq_pos(rq) * 512ULL, | ||
357 | bio, blk_rq_bytes(rq)); | ||
358 | |||
359 | OSDBLK_DEBUG("%s 0x%x bytes at 0x%llx\n", | ||
360 | do_flush ? "flush" : do_write ? | ||
361 | "write" : "read", blk_rq_bytes(rq), | ||
362 | blk_rq_pos(rq) * 512ULL); | ||
363 | |||
364 | /* begin OSD command execution */ | ||
365 | if (osd_async_op(or, osdblk_osd_complete, orq, | ||
366 | osdev->obj_cred)) { | ||
367 | osd_end_request(or); | ||
368 | blk_requeue_request(q, rq); | ||
369 | bio_chain_put(bio); | ||
370 | OSDBLK_DEBUG("osd_execute_request_async with err\n"); | ||
371 | break; | ||
372 | } | ||
373 | |||
374 | /* remove the special 'flush' marker, now that the command | ||
375 | * is executing | ||
376 | */ | ||
377 | rq->special = NULL; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static void osdblk_prepare_flush(struct request_queue *q, struct request *rq) | ||
382 | { | ||
383 | /* add driver-specific marker, to indicate that this request | ||
384 | * is a flush command | ||
385 | */ | ||
386 | rq->special = (void *) 0xdeadbeefUL; | ||
387 | } | ||
388 | |||
389 | static void osdblk_free_disk(struct osdblk_device *osdev) | ||
390 | { | ||
391 | struct gendisk *disk = osdev->disk; | ||
392 | |||
393 | if (!disk) | ||
394 | return; | ||
395 | |||
396 | if (disk->flags & GENHD_FL_UP) | ||
397 | del_gendisk(disk); | ||
398 | if (disk->queue) | ||
399 | blk_cleanup_queue(disk->queue); | ||
400 | put_disk(disk); | ||
401 | } | ||
402 | |||
403 | static int osdblk_init_disk(struct osdblk_device *osdev) | ||
404 | { | ||
405 | struct gendisk *disk; | ||
406 | struct request_queue *q; | ||
407 | int rc; | ||
408 | u64 obj_size = 0; | ||
409 | |||
410 | /* contact OSD, request size info about the object being mapped */ | ||
411 | rc = osdblk_get_obj_size(osdev, &obj_size); | ||
412 | if (rc) | ||
413 | return rc; | ||
414 | |||
415 | /* create gendisk info */ | ||
416 | disk = alloc_disk(OSDBLK_MINORS_PER_MAJOR); | ||
417 | if (!disk) | ||
418 | return -ENOMEM; | ||
419 | |||
420 | sprintf(disk->disk_name, DRV_NAME "%d", osdev->id); | ||
421 | disk->major = osdev->major; | ||
422 | disk->first_minor = 0; | ||
423 | disk->fops = &osdblk_bd_ops; | ||
424 | disk->private_data = osdev; | ||
425 | |||
426 | /* init rq */ | ||
427 | q = blk_init_queue(osdblk_rq_fn, &osdev->lock); | ||
428 | if (!q) { | ||
429 | put_disk(disk); | ||
430 | return -ENOMEM; | ||
431 | } | ||
432 | |||
433 | /* switch queue to TCQ mode; allocate tag map */ | ||
434 | rc = blk_queue_init_tags(q, OSDBLK_MAX_REQ, NULL); | ||
435 | if (rc) { | ||
436 | blk_cleanup_queue(q); | ||
437 | put_disk(disk); | ||
438 | return rc; | ||
439 | } | ||
440 | |||
441 | /* Set our limits to the lower device limits, because osdblk cannot | ||
442 | * sleep when allocating a lower-request and therefore cannot be | ||
443 | * bouncing. | ||
444 | */ | ||
445 | blk_queue_stack_limits(q, osd_request_queue(osdev->osd)); | ||
446 | |||
447 | blk_queue_prep_rq(q, blk_queue_start_tag); | ||
448 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, osdblk_prepare_flush); | ||
449 | |||
450 | disk->queue = q; | ||
451 | |||
452 | q->queuedata = osdev; | ||
453 | |||
454 | osdev->disk = disk; | ||
455 | osdev->q = q; | ||
456 | |||
457 | /* finally, announce the disk to the world */ | ||
458 | set_capacity(disk, obj_size / 512ULL); | ||
459 | add_disk(disk); | ||
460 | |||
461 | printk(KERN_INFO "%s: Added of size 0x%llx\n", | ||
462 | disk->disk_name, (unsigned long long)obj_size); | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | /******************************************************************** | ||
468 | * /sys/class/osdblk/ | ||
469 | * add map OSD object to blkdev | ||
470 | * remove unmap OSD object | ||
471 | * list show mappings | ||
472 | *******************************************************************/ | ||
473 | |||
474 | static void class_osdblk_release(struct class *cls) | ||
475 | { | ||
476 | kfree(cls); | ||
477 | } | ||
478 | |||
479 | static ssize_t class_osdblk_list(struct class *c, char *data) | ||
480 | { | ||
481 | int n = 0; | ||
482 | struct list_head *tmp; | ||
483 | |||
484 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
485 | |||
486 | list_for_each(tmp, &osdblkdev_list) { | ||
487 | struct osdblk_device *osdev; | ||
488 | |||
489 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
490 | |||
491 | n += sprintf(data+n, "%d %d %llu %llu %s\n", | ||
492 | osdev->id, | ||
493 | osdev->major, | ||
494 | osdev->obj.partition, | ||
495 | osdev->obj.id, | ||
496 | osdev->osd_path); | ||
497 | } | ||
498 | |||
499 | mutex_unlock(&ctl_mutex); | ||
500 | return n; | ||
501 | } | ||
502 | |||
503 | static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count) | ||
504 | { | ||
505 | struct osdblk_device *osdev; | ||
506 | ssize_t rc; | ||
507 | int irc, new_id = 0; | ||
508 | struct list_head *tmp; | ||
509 | |||
510 | if (!try_module_get(THIS_MODULE)) | ||
511 | return -ENODEV; | ||
512 | |||
513 | /* new osdblk_device object */ | ||
514 | osdev = kzalloc(sizeof(*osdev) + strlen(buf) + 1, GFP_KERNEL); | ||
515 | if (!osdev) { | ||
516 | rc = -ENOMEM; | ||
517 | goto err_out_mod; | ||
518 | } | ||
519 | |||
520 | /* static osdblk_device initialization */ | ||
521 | spin_lock_init(&osdev->lock); | ||
522 | INIT_LIST_HEAD(&osdev->node); | ||
523 | |||
524 | /* generate unique id: find highest unique id, add one */ | ||
525 | |||
526 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
527 | |||
528 | list_for_each(tmp, &osdblkdev_list) { | ||
529 | struct osdblk_device *osdev; | ||
530 | |||
531 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
532 | if (osdev->id > new_id) | ||
533 | new_id = osdev->id + 1; | ||
534 | } | ||
535 | |||
536 | osdev->id = new_id; | ||
537 | |||
538 | /* add to global list */ | ||
539 | list_add_tail(&osdev->node, &osdblkdev_list); | ||
540 | |||
541 | mutex_unlock(&ctl_mutex); | ||
542 | |||
543 | /* parse add command */ | ||
544 | if (sscanf(buf, "%llu %llu %s", &osdev->obj.partition, &osdev->obj.id, | ||
545 | osdev->osd_path) != 3) { | ||
546 | rc = -EINVAL; | ||
547 | goto err_out_slot; | ||
548 | } | ||
549 | |||
550 | /* initialize rest of new object */ | ||
551 | sprintf(osdev->name, DRV_NAME "%d", osdev->id); | ||
552 | |||
553 | /* contact requested OSD */ | ||
554 | osdev->osd = osduld_path_lookup(osdev->osd_path); | ||
555 | if (IS_ERR(osdev->osd)) { | ||
556 | rc = PTR_ERR(osdev->osd); | ||
557 | goto err_out_slot; | ||
558 | } | ||
559 | |||
560 | /* build OSD credential */ | ||
561 | osdblk_make_credential(osdev->obj_cred, &osdev->obj); | ||
562 | |||
563 | /* register our block device */ | ||
564 | irc = register_blkdev(0, osdev->name); | ||
565 | if (irc < 0) { | ||
566 | rc = irc; | ||
567 | goto err_out_osd; | ||
568 | } | ||
569 | |||
570 | osdev->major = irc; | ||
571 | |||
572 | /* set up and announce blkdev mapping */ | ||
573 | rc = osdblk_init_disk(osdev); | ||
574 | if (rc) | ||
575 | goto err_out_blkdev; | ||
576 | |||
577 | return count; | ||
578 | |||
579 | err_out_blkdev: | ||
580 | unregister_blkdev(osdev->major, osdev->name); | ||
581 | err_out_osd: | ||
582 | osduld_put_device(osdev->osd); | ||
583 | err_out_slot: | ||
584 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
585 | list_del_init(&osdev->node); | ||
586 | mutex_unlock(&ctl_mutex); | ||
587 | |||
588 | kfree(osdev); | ||
589 | err_out_mod: | ||
590 | OSDBLK_DEBUG("Error adding device %s\n", buf); | ||
591 | module_put(THIS_MODULE); | ||
592 | return rc; | ||
593 | } | ||
594 | |||
595 | static ssize_t class_osdblk_remove(struct class *c, const char *buf, | ||
596 | size_t count) | ||
597 | { | ||
598 | struct osdblk_device *osdev = NULL; | ||
599 | int target_id, rc; | ||
600 | unsigned long ul; | ||
601 | struct list_head *tmp; | ||
602 | |||
603 | rc = strict_strtoul(buf, 10, &ul); | ||
604 | if (rc) | ||
605 | return rc; | ||
606 | |||
607 | /* convert to int; abort if we lost anything in the conversion */ | ||
608 | target_id = (int) ul; | ||
609 | if (target_id != ul) | ||
610 | return -EINVAL; | ||
611 | |||
612 | /* remove object from list immediately */ | ||
613 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
614 | |||
615 | list_for_each(tmp, &osdblkdev_list) { | ||
616 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
617 | if (osdev->id == target_id) { | ||
618 | list_del_init(&osdev->node); | ||
619 | break; | ||
620 | } | ||
621 | osdev = NULL; | ||
622 | } | ||
623 | |||
624 | mutex_unlock(&ctl_mutex); | ||
625 | |||
626 | if (!osdev) | ||
627 | return -ENOENT; | ||
628 | |||
629 | /* clean up and free blkdev and associated OSD connection */ | ||
630 | osdblk_free_disk(osdev); | ||
631 | unregister_blkdev(osdev->major, osdev->name); | ||
632 | osduld_put_device(osdev->osd); | ||
633 | kfree(osdev); | ||
634 | |||
635 | /* release module ref */ | ||
636 | module_put(THIS_MODULE); | ||
637 | |||
638 | return count; | ||
639 | } | ||
640 | |||
641 | static struct class_attribute class_osdblk_attrs[] = { | ||
642 | __ATTR(add, 0200, NULL, class_osdblk_add), | ||
643 | __ATTR(remove, 0200, NULL, class_osdblk_remove), | ||
644 | __ATTR(list, 0444, class_osdblk_list, NULL), | ||
645 | __ATTR_NULL | ||
646 | }; | ||
647 | |||
648 | static int osdblk_sysfs_init(void) | ||
649 | { | ||
650 | int ret = 0; | ||
651 | |||
652 | /* | ||
653 | * create control files in sysfs | ||
654 | * /sys/class/osdblk/... | ||
655 | */ | ||
656 | class_osdblk = kzalloc(sizeof(*class_osdblk), GFP_KERNEL); | ||
657 | if (!class_osdblk) | ||
658 | return -ENOMEM; | ||
659 | |||
660 | class_osdblk->name = DRV_NAME; | ||
661 | class_osdblk->owner = THIS_MODULE; | ||
662 | class_osdblk->class_release = class_osdblk_release; | ||
663 | class_osdblk->class_attrs = class_osdblk_attrs; | ||
664 | |||
665 | ret = class_register(class_osdblk); | ||
666 | if (ret) { | ||
667 | kfree(class_osdblk); | ||
668 | class_osdblk = NULL; | ||
669 | printk(PFX "failed to create class osdblk\n"); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static void osdblk_sysfs_cleanup(void) | ||
677 | { | ||
678 | if (class_osdblk) | ||
679 | class_destroy(class_osdblk); | ||
680 | class_osdblk = NULL; | ||
681 | } | ||
682 | |||
683 | static int __init osdblk_init(void) | ||
684 | { | ||
685 | int rc; | ||
686 | |||
687 | rc = osdblk_sysfs_init(); | ||
688 | if (rc) | ||
689 | return rc; | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | static void __exit osdblk_exit(void) | ||
695 | { | ||
696 | osdblk_sysfs_cleanup(); | ||
697 | } | ||
698 | |||
699 | module_init(osdblk_init); | ||
700 | module_exit(osdblk_exit); | ||
701 | |||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 83650e00632d..99a506f619b7 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -1372,8 +1372,10 @@ try_next_bio: | |||
1372 | wakeup = (pd->write_congestion_on > 0 | 1372 | wakeup = (pd->write_congestion_on > 0 |
1373 | && pd->bio_queue_size <= pd->write_congestion_off); | 1373 | && pd->bio_queue_size <= pd->write_congestion_off); |
1374 | spin_unlock(&pd->lock); | 1374 | spin_unlock(&pd->lock); |
1375 | if (wakeup) | 1375 | if (wakeup) { |
1376 | clear_bdi_congested(&pd->disk->queue->backing_dev_info, WRITE); | 1376 | clear_bdi_congested(&pd->disk->queue->backing_dev_info, |
1377 | BLK_RW_ASYNC); | ||
1378 | } | ||
1377 | 1379 | ||
1378 | pkt->sleep_time = max(PACKET_WAIT_TIME, 1); | 1380 | pkt->sleep_time = max(PACKET_WAIT_TIME, 1); |
1379 | pkt_set_state(pkt, PACKET_WAITING_STATE); | 1381 | pkt_set_state(pkt, PACKET_WAITING_STATE); |
@@ -2592,10 +2594,10 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio) | |||
2592 | spin_lock(&pd->lock); | 2594 | spin_lock(&pd->lock); |
2593 | if (pd->write_congestion_on > 0 | 2595 | if (pd->write_congestion_on > 0 |
2594 | && pd->bio_queue_size >= pd->write_congestion_on) { | 2596 | && pd->bio_queue_size >= pd->write_congestion_on) { |
2595 | set_bdi_congested(&q->backing_dev_info, WRITE); | 2597 | set_bdi_congested(&q->backing_dev_info, BLK_RW_ASYNC); |
2596 | do { | 2598 | do { |
2597 | spin_unlock(&pd->lock); | 2599 | spin_unlock(&pd->lock); |
2598 | congestion_wait(WRITE, HZ); | 2600 | congestion_wait(BLK_RW_ASYNC, HZ); |
2599 | spin_lock(&pd->lock); | 2601 | spin_lock(&pd->lock); |
2600 | } while(pd->bio_queue_size > pd->write_congestion_off); | 2602 | } while(pd->bio_queue_size > pd->write_congestion_off); |
2601 | } | 2603 | } |
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index f08491a3a813..b20abe102a2b 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -390,9 +390,10 @@ static inline void ace_dump_mem(void *base, int len) | |||
390 | 390 | ||
391 | static void ace_dump_regs(struct ace_device *ace) | 391 | static void ace_dump_regs(struct ace_device *ace) |
392 | { | 392 | { |
393 | dev_info(ace->dev, " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n" | 393 | dev_info(ace->dev, |
394 | KERN_INFO " status:%.8x mpu_lba:%.8x busmode:%4x\n" | 394 | " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n" |
395 | KERN_INFO " error: %.8x cfg_lba:%.8x fatstat:%.4x\n", | 395 | " status:%.8x mpu_lba:%.8x busmode:%4x\n" |
396 | " error: %.8x cfg_lba:%.8x fatstat:%.4x\n", | ||
396 | ace_in32(ace, ACE_CTRL), | 397 | ace_in32(ace, ACE_CTRL), |
397 | ace_in(ace, ACE_SECCNTCMD), | 398 | ace_in(ace, ACE_SECCNTCMD), |
398 | ace_in(ace, ACE_VERSION), | 399 | ace_in(ace, ACE_VERSION), |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 0bd01f49cfd8..6a06913b01d3 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -1029,10 +1029,6 @@ config CS5535_GPIO | |||
1029 | 1029 | ||
1030 | If compiled as a module, it will be called cs5535_gpio. | 1030 | If compiled as a module, it will be called cs5535_gpio. |
1031 | 1031 | ||
1032 | config GPIO_VR41XX | ||
1033 | tristate "NEC VR4100 series General-purpose I/O Unit support" | ||
1034 | depends on CPU_VR41XX | ||
1035 | |||
1036 | config RAW_DRIVER | 1032 | config RAW_DRIVER |
1037 | tristate "RAW driver (/dev/raw/rawN)" | 1033 | tristate "RAW driver (/dev/raw/rawN)" |
1038 | depends on BLOCK | 1034 | depends on BLOCK |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 189efcff08ce..66f779ad4f4c 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -95,7 +95,6 @@ obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o | |||
95 | obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o | 95 | obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o |
96 | obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o | 96 | obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o |
97 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o | 97 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o |
98 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o | ||
99 | obj-$(CONFIG_GPIO_TB0219) += tb0219.o | 98 | obj-$(CONFIG_GPIO_TB0219) += tb0219.o |
100 | obj-$(CONFIG_TELCLOCK) += tlclk.o | 99 | obj-$(CONFIG_TELCLOCK) += tlclk.o |
101 | 100 | ||
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 140ea10ecb88..c02db01f736e 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/cdev.h> | 27 | #include <linux/cdev.h> |
28 | #include <linux/list.h> | 28 | #include <linux/list.h> |
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <asm/pgtable.h> | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -75,12 +76,13 @@ static struct class *bsr_class; | |||
75 | static int bsr_major; | 76 | static int bsr_major; |
76 | 77 | ||
77 | enum { | 78 | enum { |
78 | BSR_8 = 0, | 79 | BSR_8 = 0, |
79 | BSR_16 = 1, | 80 | BSR_16 = 1, |
80 | BSR_64 = 2, | 81 | BSR_64 = 2, |
81 | BSR_128 = 3, | 82 | BSR_128 = 3, |
82 | BSR_UNKNOWN = 4, | 83 | BSR_4096 = 4, |
83 | BSR_MAX = 5, | 84 | BSR_UNKNOWN = 5, |
85 | BSR_MAX = 6, | ||
84 | }; | 86 | }; |
85 | 87 | ||
86 | static unsigned bsr_types[BSR_MAX]; | 88 | static unsigned bsr_types[BSR_MAX]; |
@@ -117,15 +119,22 @@ static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) | |||
117 | { | 119 | { |
118 | unsigned long size = vma->vm_end - vma->vm_start; | 120 | unsigned long size = vma->vm_end - vma->vm_start; |
119 | struct bsr_dev *dev = filp->private_data; | 121 | struct bsr_dev *dev = filp->private_data; |
122 | int ret; | ||
120 | 123 | ||
121 | if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) | ||
122 | return -EINVAL; | ||
123 | |||
124 | vma->vm_flags |= (VM_IO | VM_DONTEXPAND); | ||
125 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 124 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
126 | 125 | ||
127 | if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, | 126 | /* check for the case of a small BSR device and map one 4k page for it*/ |
128 | size, vma->vm_page_prot)) | 127 | if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE) |
128 | ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12, | ||
129 | vma->vm_page_prot); | ||
130 | else if (size <= dev->bsr_len) | ||
131 | ret = io_remap_pfn_range(vma, vma->vm_start, | ||
132 | dev->bsr_addr >> PAGE_SHIFT, | ||
133 | size, vma->vm_page_prot); | ||
134 | else | ||
135 | return -EINVAL; | ||
136 | |||
137 | if (ret) | ||
129 | return -EAGAIN; | 138 | return -EAGAIN; |
130 | 139 | ||
131 | return 0; | 140 | return 0; |
@@ -205,6 +214,11 @@ static int bsr_add_node(struct device_node *bn) | |||
205 | cur->bsr_stride = bsr_stride[i]; | 214 | cur->bsr_stride = bsr_stride[i]; |
206 | cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs); | 215 | cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs); |
207 | 216 | ||
217 | /* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */ | ||
218 | /* we can only map 4k of it, so only advertise the 4k in sysfs */ | ||
219 | if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE) | ||
220 | cur->bsr_len = 4096; | ||
221 | |||
208 | switch(cur->bsr_bytes) { | 222 | switch(cur->bsr_bytes) { |
209 | case 8: | 223 | case 8: |
210 | cur->bsr_type = BSR_8; | 224 | cur->bsr_type = BSR_8; |
@@ -218,9 +232,11 @@ static int bsr_add_node(struct device_node *bn) | |||
218 | case 128: | 232 | case 128: |
219 | cur->bsr_type = BSR_128; | 233 | cur->bsr_type = BSR_128; |
220 | break; | 234 | break; |
235 | case 4096: | ||
236 | cur->bsr_type = BSR_4096; | ||
237 | break; | ||
221 | default: | 238 | default: |
222 | cur->bsr_type = BSR_UNKNOWN; | 239 | cur->bsr_type = BSR_UNKNOWN; |
223 | printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes); | ||
224 | } | 240 | } |
225 | 241 | ||
226 | cur->bsr_num = bsr_types[cur->bsr_type]; | 242 | cur->bsr_num = bsr_types[cur->bsr_type]; |
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 5dcbe603eca2..91b53eb1c053 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c | |||
@@ -305,10 +305,11 @@ static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw, | |||
305 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) | 305 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) |
306 | == BIOS_CNTL_LOCK_ENABLE_MASK) { | 306 | == BIOS_CNTL_LOCK_ENABLE_MASK) { |
307 | static __initdata /*const*/ char warning[] = | 307 | static __initdata /*const*/ char warning[] = |
308 | KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n" | 308 | KERN_WARNING |
309 | KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n" | 309 | PFX "Firmware space is locked read-only. If you can't or\n" |
310 | KERN_WARNING PFX "you are certain that your system has a functional\n" | 310 | PFX "don't want to disable this in firmware setup, and if\n" |
311 | KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n"; | 311 | PFX "you are certain that your system has a functional\n" |
312 | PFX "RNG, try using the 'no_fwh_detect' option.\n"; | ||
312 | 313 | ||
313 | if (no_fwh_detect) | 314 | if (no_fwh_detect) |
314 | return -ENODEV; | 315 | return -ENODEV; |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 4159292e35cf..621d1184673c 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1478,10 +1478,10 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1478 | status = inw(base + 0x4); | 1478 | status = inw(base + 0x4); |
1479 | if (status != 0) { | 1479 | if (status != 0) { |
1480 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" | 1480 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" |
1481 | KERN_WARNING "Address:0x%x\n" | 1481 | "Address:0x%x\n" |
1482 | KERN_WARNING "Count:0x%x\n" | 1482 | "Count:0x%x\n" |
1483 | KERN_WARNING "Status:0x%x\n", | 1483 | "Status:0x%x\n", |
1484 | index + 1, frame->addr, frame->count, status); | 1484 | index + 1, frame->addr, frame->count, status); |
1485 | goto errrelfw; | 1485 | goto errrelfw; |
1486 | } | 1486 | } |
1487 | outsw(base, frame->data, word_count); | 1487 | outsw(base, frame->data, word_count); |
@@ -1526,10 +1526,10 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1526 | status = inw(base + 0x4); | 1526 | status = inw(base + 0x4); |
1527 | if (status != 0) { | 1527 | if (status != 0) { |
1528 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" | 1528 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" |
1529 | KERN_WARNING "Address:0x%x\n" | 1529 | "Address:0x%x\n" |
1530 | KERN_WARNING "Count:0x%x\n" | 1530 | "Count:0x%x\n" |
1531 | KERN_WARNING "Status: 0x%x\n", | 1531 | "Status: 0x%x\n", |
1532 | index + 1, frame->addr, frame->count, status); | 1532 | index + 1, frame->addr, frame->count, status); |
1533 | goto errrelfw; | 1533 | goto errrelfw; |
1534 | } | 1534 | } |
1535 | 1535 | ||
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index daebe1ba43d4..9d1b4f548f67 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -75,114 +75,88 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
75 | */ | 75 | */ |
76 | static void pty_unthrottle(struct tty_struct *tty) | 76 | static void pty_unthrottle(struct tty_struct *tty) |
77 | { | 77 | { |
78 | struct tty_struct *o_tty = tty->link; | 78 | tty_wakeup(tty->link); |
79 | |||
80 | if (!o_tty) | ||
81 | return; | ||
82 | |||
83 | tty_wakeup(o_tty); | ||
84 | set_bit(TTY_THROTTLED, &tty->flags); | 79 | set_bit(TTY_THROTTLED, &tty->flags); |
85 | } | 80 | } |
86 | 81 | ||
87 | /* | 82 | /** |
88 | * WSH 05/24/97: modified to | 83 | * pty_space - report space left for writing |
89 | * (1) use space in tty->flip instead of a shared temp buffer | 84 | * @to: tty we are writing into |
90 | * The flip buffers aren't being used for a pty, so there's lots | ||
91 | * of space available. The buffer is protected by a per-pty | ||
92 | * semaphore that should almost never come under contention. | ||
93 | * (2) avoid redundant copying for cases where count >> receive_room | ||
94 | * N.B. Calls from user space may now return an error code instead of | ||
95 | * a count. | ||
96 | * | 85 | * |
97 | * FIXME: Our pty_write method is called with our ldisc lock held but | 86 | * The tty buffers allow 64K but we sneak a peak and clip at 8K this |
98 | * not our partners. We can't just wait on the other one blindly without | 87 | * allows a lot of overspill room for echo and other fun messes to |
99 | * risking deadlocks. At some point when everything has settled down we need | 88 | * be handled properly |
100 | * to look into making pty_write at least able to sleep over an ldisc change. | 89 | */ |
90 | |||
91 | static int pty_space(struct tty_struct *to) | ||
92 | { | ||
93 | int n = 8192 - to->buf.memory_used; | ||
94 | if (n < 0) | ||
95 | return 0; | ||
96 | return n; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * pty_write - write to a pty | ||
101 | * @tty: the tty we write from | ||
102 | * @buf: kernel buffer of data | ||
103 | * @count: bytes to write | ||
101 | * | 104 | * |
102 | * The return on no ldisc is a bit counter intuitive but the logic works | 105 | * Our "hardware" write method. Data is coming from the ldisc which |
103 | * like this. During an ldisc change the other end will flush its buffers. We | 106 | * may be in a non sleeping state. We simply throw this at the other |
104 | * thus return the full length which is identical to the case where we had | 107 | * end of the link as if we were an IRQ handler receiving stuff for |
105 | * proper locking and happened to queue the bytes just before the flush during | 108 | * the other side of the pty/tty pair. |
106 | * the ldisc change. | ||
107 | */ | 109 | */ |
110 | |||
108 | static int pty_write(struct tty_struct *tty, const unsigned char *buf, | 111 | static int pty_write(struct tty_struct *tty, const unsigned char *buf, |
109 | int count) | 112 | int count) |
110 | { | 113 | { |
111 | struct tty_struct *to = tty->link; | 114 | struct tty_struct *to = tty->link; |
112 | struct tty_ldisc *ld; | 115 | int c; |
113 | int c = count; | ||
114 | 116 | ||
115 | if (!to || tty->stopped) | 117 | if (tty->stopped) |
116 | return 0; | 118 | return 0; |
117 | ld = tty_ldisc_ref(to); | 119 | |
118 | 120 | /* This isn't locked but our 8K is quite sloppy so no | |
119 | if (ld) { | 121 | big deal */ |
120 | c = to->receive_room; | 122 | |
121 | if (c > count) | 123 | c = pty_space(to); |
122 | c = count; | 124 | if (c > count) |
123 | ld->ops->receive_buf(to, buf, NULL, c); | 125 | c = count; |
124 | tty_ldisc_deref(ld); | 126 | if (c > 0) { |
127 | /* Stuff the data into the input queue of the other end */ | ||
128 | c = tty_insert_flip_string(to, buf, c); | ||
129 | /* And shovel */ | ||
130 | tty_flip_buffer_push(to); | ||
131 | tty_wakeup(tty); | ||
125 | } | 132 | } |
126 | return c; | 133 | return c; |
127 | } | 134 | } |
128 | 135 | ||
136 | /** | ||
137 | * pty_write_room - write space | ||
138 | * @tty: tty we are writing from | ||
139 | * | ||
140 | * Report how many bytes the ldisc can send into the queue for | ||
141 | * the other device. | ||
142 | */ | ||
143 | |||
129 | static int pty_write_room(struct tty_struct *tty) | 144 | static int pty_write_room(struct tty_struct *tty) |
130 | { | 145 | { |
131 | struct tty_struct *to = tty->link; | 146 | return pty_space(tty->link); |
132 | |||
133 | if (!to || tty->stopped) | ||
134 | return 0; | ||
135 | |||
136 | return to->receive_room; | ||
137 | } | 147 | } |
138 | 148 | ||
139 | /* | 149 | /** |
140 | * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior | 150 | * pty_chars_in_buffer - characters currently in our tx queue |
141 | * The chars_in_buffer() value is used by the ldisc select() function | 151 | * @tty: our tty |
142 | * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256). | ||
143 | * The pty driver chars_in_buffer() Master/Slave must behave differently: | ||
144 | * | ||
145 | * The Master side needs to allow typed-ahead commands to accumulate | ||
146 | * while being canonicalized, so we report "our buffer" as empty until | ||
147 | * some threshold is reached, and then report the count. (Any count > | ||
148 | * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock | ||
149 | * the count returned must be 0 if no canonical data is available to be | ||
150 | * read. (The N_TTY ldisc.chars_in_buffer now knows this.) | ||
151 | * | 152 | * |
152 | * The Slave side passes all characters in raw mode to the Master side's | 153 | * Report how much we have in the transmit queue. As everything is |
153 | * buffer where they can be read immediately, so in this case we can | 154 | * instantly at the other end this is easy to implement. |
154 | * return the true count in the buffer. | ||
155 | */ | 155 | */ |
156 | |||
156 | static int pty_chars_in_buffer(struct tty_struct *tty) | 157 | static int pty_chars_in_buffer(struct tty_struct *tty) |
157 | { | 158 | { |
158 | struct tty_struct *to = tty->link; | 159 | return 0; |
159 | struct tty_ldisc *ld; | ||
160 | int count = 0; | ||
161 | |||
162 | /* We should get the line discipline lock for "tty->link" */ | ||
163 | if (!to) | ||
164 | return 0; | ||
165 | /* We cannot take a sleeping reference here without deadlocking with | ||
166 | an ldisc change - but it doesn't really matter */ | ||
167 | ld = tty_ldisc_ref(to); | ||
168 | if (ld == NULL) | ||
169 | return 0; | ||
170 | |||
171 | /* The ldisc must report 0 if no characters available to be read */ | ||
172 | if (ld->ops->chars_in_buffer) | ||
173 | count = ld->ops->chars_in_buffer(to); | ||
174 | |||
175 | tty_ldisc_deref(ld); | ||
176 | |||
177 | if (tty->driver->subtype == PTY_TYPE_SLAVE) | ||
178 | return count; | ||
179 | |||
180 | /* Master side driver ... if the other side's read buffer is less than | ||
181 | * half full, return 0 to allow writers to proceed; otherwise return | ||
182 | * the count. This leaves a comfortable margin to avoid overflow, | ||
183 | * and still allows half a buffer's worth of typed-ahead commands. | ||
184 | */ | ||
185 | return (count < N_TTY_BUF_SIZE/2) ? 0 : count; | ||
186 | } | 160 | } |
187 | 161 | ||
188 | /* Set the lock flag on a pty */ | 162 | /* Set the lock flag on a pty */ |
@@ -202,20 +176,10 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
202 | { | 176 | { |
203 | struct tty_struct *to = tty->link; | 177 | struct tty_struct *to = tty->link; |
204 | unsigned long flags; | 178 | unsigned long flags; |
205 | struct tty_ldisc *ld; | ||
206 | 179 | ||
207 | if (!to) | 180 | if (!to) |
208 | return; | 181 | return; |
209 | ld = tty_ldisc_ref(to); | 182 | /* tty_buffer_flush(to); FIXME */ |
210 | |||
211 | /* The other end is changing discipline */ | ||
212 | if (!ld) | ||
213 | return; | ||
214 | |||
215 | if (ld->ops->flush_buffer) | ||
216 | to->ldisc->ops->flush_buffer(to); | ||
217 | tty_ldisc_deref(ld); | ||
218 | |||
219 | if (to->packet) { | 183 | if (to->packet) { |
220 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 184 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
221 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; | 185 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index 6062b62800fd..b3ec9b10e292 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for TANBAC TB0219 base board. | 2 | * Driver for TANBAC TB0219 base board. |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2005 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/vr41xx/giu.h> | 28 | #include <asm/vr41xx/giu.h> |
29 | #include <asm/vr41xx/tb0219.h> | 29 | #include <asm/vr41xx/tb0219.h> |
30 | 30 | ||
31 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | 31 | MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); |
32 | MODULE_DESCRIPTION("TANBAC TB0219 base board driver"); | 32 | MODULE_DESCRIPTION("TANBAC TB0219 base board driver"); |
33 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
34 | 34 | ||
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index a19e935847b0..913aa8d3f1c5 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -867,15 +867,22 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
867 | tty_ldisc_wait_idle(tty); | 867 | tty_ldisc_wait_idle(tty); |
868 | 868 | ||
869 | /* | 869 | /* |
870 | * Shutdown the current line discipline, and reset it to N_TTY. | 870 | * Now kill off the ldisc |
871 | * | ||
872 | * FIXME: this MUST get fixed for the new reflocking | ||
873 | */ | 871 | */ |
872 | tty_ldisc_close(tty, tty->ldisc); | ||
873 | tty_ldisc_put(tty->ldisc); | ||
874 | /* Force an oops if we mess this up */ | ||
875 | tty->ldisc = NULL; | ||
876 | |||
877 | /* Ensure the next open requests the N_TTY ldisc */ | ||
878 | tty_set_termios_ldisc(tty, N_TTY); | ||
874 | 879 | ||
875 | tty_ldisc_reinit(tty); | ||
876 | /* This will need doing differently if we need to lock */ | 880 | /* This will need doing differently if we need to lock */ |
877 | if (o_tty) | 881 | if (o_tty) |
878 | tty_ldisc_release(o_tty, NULL); | 882 | tty_ldisc_release(o_tty, NULL); |
883 | |||
884 | /* And the memory resources remaining (buffers, termios) will be | ||
885 | disposed of when the kref hits zero */ | ||
879 | } | 886 | } |
880 | 887 | ||
881 | /** | 888 | /** |
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 54c837288d19..e69de29bb2d1 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -1,680 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for NEC VR4100 series General-purpose I/O Unit. | ||
3 | * | ||
4 | * Copyright (C) 2002 MontaVista Software Inc. | ||
5 | * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> | ||
6 | * Copyright (C) 2003-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/types.h> | ||
33 | |||
34 | #include <asm/io.h> | ||
35 | #include <asm/vr41xx/giu.h> | ||
36 | #include <asm/vr41xx/irq.h> | ||
37 | #include <asm/vr41xx/vr41xx.h> | ||
38 | |||
39 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | ||
40 | MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); | ||
41 | MODULE_LICENSE("GPL"); | ||
42 | |||
43 | static int major; /* default is dynamic major device number */ | ||
44 | module_param(major, int, 0); | ||
45 | MODULE_PARM_DESC(major, "Major device number"); | ||
46 | |||
47 | #define GIUIOSELL 0x00 | ||
48 | #define GIUIOSELH 0x02 | ||
49 | #define GIUPIODL 0x04 | ||
50 | #define GIUPIODH 0x06 | ||
51 | #define GIUINTSTATL 0x08 | ||
52 | #define GIUINTSTATH 0x0a | ||
53 | #define GIUINTENL 0x0c | ||
54 | #define GIUINTENH 0x0e | ||
55 | #define GIUINTTYPL 0x10 | ||
56 | #define GIUINTTYPH 0x12 | ||
57 | #define GIUINTALSELL 0x14 | ||
58 | #define GIUINTALSELH 0x16 | ||
59 | #define GIUINTHTSELL 0x18 | ||
60 | #define GIUINTHTSELH 0x1a | ||
61 | #define GIUPODATL 0x1c | ||
62 | #define GIUPODATEN 0x1c | ||
63 | #define GIUPODATH 0x1e | ||
64 | #define PIOEN0 0x0100 | ||
65 | #define PIOEN1 0x0200 | ||
66 | #define GIUPODAT 0x1e | ||
67 | #define GIUFEDGEINHL 0x20 | ||
68 | #define GIUFEDGEINHH 0x22 | ||
69 | #define GIUREDGEINHL 0x24 | ||
70 | #define GIUREDGEINHH 0x26 | ||
71 | |||
72 | #define GIUUSEUPDN 0x1e0 | ||
73 | #define GIUTERMUPDN 0x1e2 | ||
74 | |||
75 | #define GPIO_HAS_PULLUPDOWN_IO 0x0001 | ||
76 | #define GPIO_HAS_OUTPUT_ENABLE 0x0002 | ||
77 | #define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 | ||
78 | |||
79 | static spinlock_t giu_lock; | ||
80 | static unsigned long giu_flags; | ||
81 | static unsigned int giu_nr_pins; | ||
82 | |||
83 | static void __iomem *giu_base; | ||
84 | |||
85 | #define giu_read(offset) readw(giu_base + (offset)) | ||
86 | #define giu_write(offset, value) writew((value), giu_base + (offset)) | ||
87 | |||
88 | #define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) | ||
89 | #define GIUINT_HIGH_OFFSET 16 | ||
90 | #define GIUINT_HIGH_MAX 32 | ||
91 | |||
92 | static inline uint16_t giu_set(uint16_t offset, uint16_t set) | ||
93 | { | ||
94 | uint16_t data; | ||
95 | |||
96 | data = giu_read(offset); | ||
97 | data |= set; | ||
98 | giu_write(offset, data); | ||
99 | |||
100 | return data; | ||
101 | } | ||
102 | |||
103 | static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) | ||
104 | { | ||
105 | uint16_t data; | ||
106 | |||
107 | data = giu_read(offset); | ||
108 | data &= ~clear; | ||
109 | giu_write(offset, data); | ||
110 | |||
111 | return data; | ||
112 | } | ||
113 | |||
114 | static void ack_giuint_low(unsigned int irq) | ||
115 | { | ||
116 | giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); | ||
117 | } | ||
118 | |||
119 | static void mask_giuint_low(unsigned int irq) | ||
120 | { | ||
121 | giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); | ||
122 | } | ||
123 | |||
124 | static void mask_ack_giuint_low(unsigned int irq) | ||
125 | { | ||
126 | unsigned int pin; | ||
127 | |||
128 | pin = GPIO_PIN_OF_IRQ(irq); | ||
129 | giu_clear(GIUINTENL, 1 << pin); | ||
130 | giu_write(GIUINTSTATL, 1 << pin); | ||
131 | } | ||
132 | |||
133 | static void unmask_giuint_low(unsigned int irq) | ||
134 | { | ||
135 | giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); | ||
136 | } | ||
137 | |||
138 | static struct irq_chip giuint_low_irq_chip = { | ||
139 | .name = "GIUINTL", | ||
140 | .ack = ack_giuint_low, | ||
141 | .mask = mask_giuint_low, | ||
142 | .mask_ack = mask_ack_giuint_low, | ||
143 | .unmask = unmask_giuint_low, | ||
144 | }; | ||
145 | |||
146 | static void ack_giuint_high(unsigned int irq) | ||
147 | { | ||
148 | giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | ||
149 | } | ||
150 | |||
151 | static void mask_giuint_high(unsigned int irq) | ||
152 | { | ||
153 | giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | ||
154 | } | ||
155 | |||
156 | static void mask_ack_giuint_high(unsigned int irq) | ||
157 | { | ||
158 | unsigned int pin; | ||
159 | |||
160 | pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; | ||
161 | giu_clear(GIUINTENH, 1 << pin); | ||
162 | giu_write(GIUINTSTATH, 1 << pin); | ||
163 | } | ||
164 | |||
165 | static void unmask_giuint_high(unsigned int irq) | ||
166 | { | ||
167 | giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | ||
168 | } | ||
169 | |||
170 | static struct irq_chip giuint_high_irq_chip = { | ||
171 | .name = "GIUINTH", | ||
172 | .ack = ack_giuint_high, | ||
173 | .mask = mask_giuint_high, | ||
174 | .mask_ack = mask_ack_giuint_high, | ||
175 | .unmask = unmask_giuint_high, | ||
176 | }; | ||
177 | |||
178 | static int giu_get_irq(unsigned int irq) | ||
179 | { | ||
180 | uint16_t pendl, pendh, maskl, maskh; | ||
181 | int i; | ||
182 | |||
183 | pendl = giu_read(GIUINTSTATL); | ||
184 | pendh = giu_read(GIUINTSTATH); | ||
185 | maskl = giu_read(GIUINTENL); | ||
186 | maskh = giu_read(GIUINTENH); | ||
187 | |||
188 | maskl &= pendl; | ||
189 | maskh &= pendh; | ||
190 | |||
191 | if (maskl) { | ||
192 | for (i = 0; i < 16; i++) { | ||
193 | if (maskl & (1 << i)) | ||
194 | return GIU_IRQ(i); | ||
195 | } | ||
196 | } else if (maskh) { | ||
197 | for (i = 0; i < 16; i++) { | ||
198 | if (maskh & (1 << i)) | ||
199 | return GIU_IRQ(i + GIUINT_HIGH_OFFSET); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", | ||
204 | maskl, pendl, maskh, pendh); | ||
205 | |||
206 | atomic_inc(&irq_err_count); | ||
207 | |||
208 | return -EINVAL; | ||
209 | } | ||
210 | |||
211 | void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal) | ||
212 | { | ||
213 | uint16_t mask; | ||
214 | |||
215 | if (pin < GIUINT_HIGH_OFFSET) { | ||
216 | mask = 1 << pin; | ||
217 | if (trigger != IRQ_TRIGGER_LEVEL) { | ||
218 | giu_set(GIUINTTYPL, mask); | ||
219 | if (signal == IRQ_SIGNAL_HOLD) | ||
220 | giu_set(GIUINTHTSELL, mask); | ||
221 | else | ||
222 | giu_clear(GIUINTHTSELL, mask); | ||
223 | if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { | ||
224 | switch (trigger) { | ||
225 | case IRQ_TRIGGER_EDGE_FALLING: | ||
226 | giu_set(GIUFEDGEINHL, mask); | ||
227 | giu_clear(GIUREDGEINHL, mask); | ||
228 | break; | ||
229 | case IRQ_TRIGGER_EDGE_RISING: | ||
230 | giu_clear(GIUFEDGEINHL, mask); | ||
231 | giu_set(GIUREDGEINHL, mask); | ||
232 | break; | ||
233 | default: | ||
234 | giu_set(GIUFEDGEINHL, mask); | ||
235 | giu_set(GIUREDGEINHL, mask); | ||
236 | break; | ||
237 | } | ||
238 | } | ||
239 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
240 | &giuint_low_irq_chip, | ||
241 | handle_edge_irq); | ||
242 | } else { | ||
243 | giu_clear(GIUINTTYPL, mask); | ||
244 | giu_clear(GIUINTHTSELL, mask); | ||
245 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
246 | &giuint_low_irq_chip, | ||
247 | handle_level_irq); | ||
248 | } | ||
249 | giu_write(GIUINTSTATL, mask); | ||
250 | } else if (pin < GIUINT_HIGH_MAX) { | ||
251 | mask = 1 << (pin - GIUINT_HIGH_OFFSET); | ||
252 | if (trigger != IRQ_TRIGGER_LEVEL) { | ||
253 | giu_set(GIUINTTYPH, mask); | ||
254 | if (signal == IRQ_SIGNAL_HOLD) | ||
255 | giu_set(GIUINTHTSELH, mask); | ||
256 | else | ||
257 | giu_clear(GIUINTHTSELH, mask); | ||
258 | if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { | ||
259 | switch (trigger) { | ||
260 | case IRQ_TRIGGER_EDGE_FALLING: | ||
261 | giu_set(GIUFEDGEINHH, mask); | ||
262 | giu_clear(GIUREDGEINHH, mask); | ||
263 | break; | ||
264 | case IRQ_TRIGGER_EDGE_RISING: | ||
265 | giu_clear(GIUFEDGEINHH, mask); | ||
266 | giu_set(GIUREDGEINHH, mask); | ||
267 | break; | ||
268 | default: | ||
269 | giu_set(GIUFEDGEINHH, mask); | ||
270 | giu_set(GIUREDGEINHH, mask); | ||
271 | break; | ||
272 | } | ||
273 | } | ||
274 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
275 | &giuint_high_irq_chip, | ||
276 | handle_edge_irq); | ||
277 | } else { | ||
278 | giu_clear(GIUINTTYPH, mask); | ||
279 | giu_clear(GIUINTHTSELH, mask); | ||
280 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
281 | &giuint_high_irq_chip, | ||
282 | handle_level_irq); | ||
283 | } | ||
284 | giu_write(GIUINTSTATH, mask); | ||
285 | } | ||
286 | } | ||
287 | EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); | ||
288 | |||
289 | void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) | ||
290 | { | ||
291 | uint16_t mask; | ||
292 | |||
293 | if (pin < GIUINT_HIGH_OFFSET) { | ||
294 | mask = 1 << pin; | ||
295 | if (level == IRQ_LEVEL_HIGH) | ||
296 | giu_set(GIUINTALSELL, mask); | ||
297 | else | ||
298 | giu_clear(GIUINTALSELL, mask); | ||
299 | giu_write(GIUINTSTATL, mask); | ||
300 | } else if (pin < GIUINT_HIGH_MAX) { | ||
301 | mask = 1 << (pin - GIUINT_HIGH_OFFSET); | ||
302 | if (level == IRQ_LEVEL_HIGH) | ||
303 | giu_set(GIUINTALSELH, mask); | ||
304 | else | ||
305 | giu_clear(GIUINTALSELH, mask); | ||
306 | giu_write(GIUINTSTATH, mask); | ||
307 | } | ||
308 | } | ||
309 | EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); | ||
310 | |||
311 | gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) | ||
312 | { | ||
313 | uint16_t reg, mask; | ||
314 | |||
315 | if (pin >= giu_nr_pins) | ||
316 | return GPIO_DATA_INVAL; | ||
317 | |||
318 | if (pin < 16) { | ||
319 | reg = giu_read(GIUPIODL); | ||
320 | mask = (uint16_t)1 << pin; | ||
321 | } else if (pin < 32) { | ||
322 | reg = giu_read(GIUPIODH); | ||
323 | mask = (uint16_t)1 << (pin - 16); | ||
324 | } else if (pin < 48) { | ||
325 | reg = giu_read(GIUPODATL); | ||
326 | mask = (uint16_t)1 << (pin - 32); | ||
327 | } else { | ||
328 | reg = giu_read(GIUPODATH); | ||
329 | mask = (uint16_t)1 << (pin - 48); | ||
330 | } | ||
331 | |||
332 | if (reg & mask) | ||
333 | return GPIO_DATA_HIGH; | ||
334 | |||
335 | return GPIO_DATA_LOW; | ||
336 | } | ||
337 | EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin); | ||
338 | |||
339 | int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) | ||
340 | { | ||
341 | uint16_t offset, mask, reg; | ||
342 | unsigned long flags; | ||
343 | |||
344 | if (pin >= giu_nr_pins) | ||
345 | return -EINVAL; | ||
346 | |||
347 | if (pin < 16) { | ||
348 | offset = GIUPIODL; | ||
349 | mask = (uint16_t)1 << pin; | ||
350 | } else if (pin < 32) { | ||
351 | offset = GIUPIODH; | ||
352 | mask = (uint16_t)1 << (pin - 16); | ||
353 | } else if (pin < 48) { | ||
354 | offset = GIUPODATL; | ||
355 | mask = (uint16_t)1 << (pin - 32); | ||
356 | } else { | ||
357 | offset = GIUPODATH; | ||
358 | mask = (uint16_t)1 << (pin - 48); | ||
359 | } | ||
360 | |||
361 | spin_lock_irqsave(&giu_lock, flags); | ||
362 | |||
363 | reg = giu_read(offset); | ||
364 | if (data == GPIO_DATA_HIGH) | ||
365 | reg |= mask; | ||
366 | else | ||
367 | reg &= ~mask; | ||
368 | giu_write(offset, reg); | ||
369 | |||
370 | spin_unlock_irqrestore(&giu_lock, flags); | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin); | ||
375 | |||
376 | int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) | ||
377 | { | ||
378 | uint16_t offset, mask, reg; | ||
379 | unsigned long flags; | ||
380 | |||
381 | if (pin >= giu_nr_pins) | ||
382 | return -EINVAL; | ||
383 | |||
384 | if (pin < 16) { | ||
385 | offset = GIUIOSELL; | ||
386 | mask = (uint16_t)1 << pin; | ||
387 | } else if (pin < 32) { | ||
388 | offset = GIUIOSELH; | ||
389 | mask = (uint16_t)1 << (pin - 16); | ||
390 | } else { | ||
391 | if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { | ||
392 | offset = GIUPODATEN; | ||
393 | mask = (uint16_t)1 << (pin - 32); | ||
394 | } else { | ||
395 | switch (pin) { | ||
396 | case 48: | ||
397 | offset = GIUPODATH; | ||
398 | mask = PIOEN0; | ||
399 | break; | ||
400 | case 49: | ||
401 | offset = GIUPODATH; | ||
402 | mask = PIOEN1; | ||
403 | break; | ||
404 | default: | ||
405 | return -EINVAL; | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | |||
410 | spin_lock_irqsave(&giu_lock, flags); | ||
411 | |||
412 | reg = giu_read(offset); | ||
413 | if (dir == GPIO_OUTPUT) | ||
414 | reg |= mask; | ||
415 | else | ||
416 | reg &= ~mask; | ||
417 | giu_write(offset, reg); | ||
418 | |||
419 | spin_unlock_irqrestore(&giu_lock, flags); | ||
420 | |||
421 | return 0; | ||
422 | } | ||
423 | EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction); | ||
424 | |||
425 | int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) | ||
426 | { | ||
427 | uint16_t reg, mask; | ||
428 | unsigned long flags; | ||
429 | |||
430 | if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) | ||
431 | return -EPERM; | ||
432 | |||
433 | if (pin >= 15) | ||
434 | return -EINVAL; | ||
435 | |||
436 | mask = (uint16_t)1 << pin; | ||
437 | |||
438 | spin_lock_irqsave(&giu_lock, flags); | ||
439 | |||
440 | if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { | ||
441 | reg = giu_read(GIUTERMUPDN); | ||
442 | if (pull == GPIO_PULL_UP) | ||
443 | reg |= mask; | ||
444 | else | ||
445 | reg &= ~mask; | ||
446 | giu_write(GIUTERMUPDN, reg); | ||
447 | |||
448 | reg = giu_read(GIUUSEUPDN); | ||
449 | reg |= mask; | ||
450 | giu_write(GIUUSEUPDN, reg); | ||
451 | } else { | ||
452 | reg = giu_read(GIUUSEUPDN); | ||
453 | reg &= ~mask; | ||
454 | giu_write(GIUUSEUPDN, reg); | ||
455 | } | ||
456 | |||
457 | spin_unlock_irqrestore(&giu_lock, flags); | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); | ||
462 | |||
463 | static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, | ||
464 | loff_t *ppos) | ||
465 | { | ||
466 | unsigned int pin; | ||
467 | char value = '0'; | ||
468 | |||
469 | pin = iminor(file->f_path.dentry->d_inode); | ||
470 | if (pin >= giu_nr_pins) | ||
471 | return -EBADF; | ||
472 | |||
473 | if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH) | ||
474 | value = '1'; | ||
475 | |||
476 | if (len <= 0) | ||
477 | return -EFAULT; | ||
478 | |||
479 | if (put_user(value, buf)) | ||
480 | return -EFAULT; | ||
481 | |||
482 | return 1; | ||
483 | } | ||
484 | |||
485 | static ssize_t gpio_write(struct file *file, const char __user *data, | ||
486 | size_t len, loff_t *ppos) | ||
487 | { | ||
488 | unsigned int pin; | ||
489 | size_t i; | ||
490 | char c; | ||
491 | int retval = 0; | ||
492 | |||
493 | pin = iminor(file->f_path.dentry->d_inode); | ||
494 | if (pin >= giu_nr_pins) | ||
495 | return -EBADF; | ||
496 | |||
497 | for (i = 0; i < len; i++) { | ||
498 | if (get_user(c, data + i)) | ||
499 | return -EFAULT; | ||
500 | |||
501 | switch (c) { | ||
502 | case '0': | ||
503 | retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW); | ||
504 | break; | ||
505 | case '1': | ||
506 | retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH); | ||
507 | break; | ||
508 | case 'D': | ||
509 | printk(KERN_INFO "GPIO%d: pull down\n", pin); | ||
510 | retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN); | ||
511 | break; | ||
512 | case 'd': | ||
513 | printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); | ||
514 | retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); | ||
515 | break; | ||
516 | case 'I': | ||
517 | printk(KERN_INFO "GPIO%d: input\n", pin); | ||
518 | retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT); | ||
519 | break; | ||
520 | case 'O': | ||
521 | printk(KERN_INFO "GPIO%d: output\n", pin); | ||
522 | retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT); | ||
523 | break; | ||
524 | case 'o': | ||
525 | printk(KERN_INFO "GPIO%d: output disable\n", pin); | ||
526 | retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE); | ||
527 | break; | ||
528 | case 'P': | ||
529 | printk(KERN_INFO "GPIO%d: pull up\n", pin); | ||
530 | retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP); | ||
531 | break; | ||
532 | case 'p': | ||
533 | printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); | ||
534 | retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); | ||
535 | break; | ||
536 | default: | ||
537 | break; | ||
538 | } | ||
539 | |||
540 | if (retval < 0) | ||
541 | break; | ||
542 | } | ||
543 | |||
544 | return i; | ||
545 | } | ||
546 | |||
547 | static int gpio_open(struct inode *inode, struct file *file) | ||
548 | { | ||
549 | unsigned int pin; | ||
550 | |||
551 | cycle_kernel_lock(); | ||
552 | pin = iminor(inode); | ||
553 | if (pin >= giu_nr_pins) | ||
554 | return -EBADF; | ||
555 | |||
556 | return nonseekable_open(inode, file); | ||
557 | } | ||
558 | |||
559 | static int gpio_release(struct inode *inode, struct file *file) | ||
560 | { | ||
561 | unsigned int pin; | ||
562 | |||
563 | pin = iminor(inode); | ||
564 | if (pin >= giu_nr_pins) | ||
565 | return -EBADF; | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static const struct file_operations gpio_fops = { | ||
571 | .owner = THIS_MODULE, | ||
572 | .read = gpio_read, | ||
573 | .write = gpio_write, | ||
574 | .open = gpio_open, | ||
575 | .release = gpio_release, | ||
576 | }; | ||
577 | |||
578 | static int __devinit giu_probe(struct platform_device *dev) | ||
579 | { | ||
580 | struct resource *res; | ||
581 | unsigned int trigger, i, pin; | ||
582 | struct irq_chip *chip; | ||
583 | int irq, retval; | ||
584 | |||
585 | switch (dev->id) { | ||
586 | case GPIO_50PINS_PULLUPDOWN: | ||
587 | giu_flags = GPIO_HAS_PULLUPDOWN_IO; | ||
588 | giu_nr_pins = 50; | ||
589 | break; | ||
590 | case GPIO_36PINS: | ||
591 | giu_nr_pins = 36; | ||
592 | break; | ||
593 | case GPIO_48PINS_EDGE_SELECT: | ||
594 | giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; | ||
595 | giu_nr_pins = 48; | ||
596 | break; | ||
597 | default: | ||
598 | printk(KERN_ERR "GIU: unknown ID %d\n", dev->id); | ||
599 | return -ENODEV; | ||
600 | } | ||
601 | |||
602 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
603 | if (!res) | ||
604 | return -EBUSY; | ||
605 | |||
606 | giu_base = ioremap(res->start, res->end - res->start + 1); | ||
607 | if (!giu_base) | ||
608 | return -ENOMEM; | ||
609 | |||
610 | retval = register_chrdev(major, "GIU", &gpio_fops); | ||
611 | if (retval < 0) { | ||
612 | iounmap(giu_base); | ||
613 | giu_base = NULL; | ||
614 | return retval; | ||
615 | } | ||
616 | |||
617 | if (major == 0) { | ||
618 | major = retval; | ||
619 | printk(KERN_INFO "GIU: major number %d\n", major); | ||
620 | } | ||
621 | |||
622 | spin_lock_init(&giu_lock); | ||
623 | |||
624 | giu_write(GIUINTENL, 0); | ||
625 | giu_write(GIUINTENH, 0); | ||
626 | |||
627 | trigger = giu_read(GIUINTTYPH) << 16; | ||
628 | trigger |= giu_read(GIUINTTYPL); | ||
629 | for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { | ||
630 | pin = GPIO_PIN_OF_IRQ(i); | ||
631 | if (pin < GIUINT_HIGH_OFFSET) | ||
632 | chip = &giuint_low_irq_chip; | ||
633 | else | ||
634 | chip = &giuint_high_irq_chip; | ||
635 | |||
636 | if (trigger & (1 << pin)) | ||
637 | set_irq_chip_and_handler(i, chip, handle_edge_irq); | ||
638 | else | ||
639 | set_irq_chip_and_handler(i, chip, handle_level_irq); | ||
640 | |||
641 | } | ||
642 | |||
643 | irq = platform_get_irq(dev, 0); | ||
644 | if (irq < 0 || irq >= nr_irqs) | ||
645 | return -EBUSY; | ||
646 | |||
647 | return cascade_irq(irq, giu_get_irq); | ||
648 | } | ||
649 | |||
650 | static int __devexit giu_remove(struct platform_device *dev) | ||
651 | { | ||
652 | if (giu_base) { | ||
653 | iounmap(giu_base); | ||
654 | giu_base = NULL; | ||
655 | } | ||
656 | |||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static struct platform_driver giu_device_driver = { | ||
661 | .probe = giu_probe, | ||
662 | .remove = __devexit_p(giu_remove), | ||
663 | .driver = { | ||
664 | .name = "GIU", | ||
665 | .owner = THIS_MODULE, | ||
666 | }, | ||
667 | }; | ||
668 | |||
669 | static int __init vr41xx_giu_init(void) | ||
670 | { | ||
671 | return platform_driver_register(&giu_device_driver); | ||
672 | } | ||
673 | |||
674 | static void __exit vr41xx_giu_exit(void) | ||
675 | { | ||
676 | platform_driver_unregister(&giu_device_driver); | ||
677 | } | ||
678 | |||
679 | module_init(vr41xx_giu_init); | ||
680 | module_exit(vr41xx_giu_exit); | ||
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 9ffb05f4095d..93c2322feab7 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
@@ -161,7 +161,7 @@ static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, | |||
161 | if (periodic) | 161 | if (periodic) |
162 | sh_tmu_write(p, TCOR, delta); | 162 | sh_tmu_write(p, TCOR, delta); |
163 | else | 163 | else |
164 | sh_tmu_write(p, TCOR, 0); | 164 | sh_tmu_write(p, TCOR, 0xffffffff); |
165 | 165 | ||
166 | sh_tmu_write(p, TCNT, delta); | 166 | sh_tmu_write(p, TCNT, delta); |
167 | 167 | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 6e2ec0b18948..b90eda8b3440 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -761,6 +761,10 @@ static struct kobj_type ktype_cpufreq = { | |||
761 | * cpufreq_add_dev - add a CPU device | 761 | * cpufreq_add_dev - add a CPU device |
762 | * | 762 | * |
763 | * Adds the cpufreq interface for a CPU device. | 763 | * Adds the cpufreq interface for a CPU device. |
764 | * | ||
765 | * The Oracle says: try running cpufreq registration/unregistration concurrently | ||
766 | * with with cpu hotplugging and all hell will break loose. Tried to clean this | ||
767 | * mess up, but more thorough testing is needed. - Mathieu | ||
764 | */ | 768 | */ |
765 | static int cpufreq_add_dev(struct sys_device *sys_dev) | 769 | static int cpufreq_add_dev(struct sys_device *sys_dev) |
766 | { | 770 | { |
@@ -772,9 +776,6 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
772 | struct sys_device *cpu_sys_dev; | 776 | struct sys_device *cpu_sys_dev; |
773 | unsigned long flags; | 777 | unsigned long flags; |
774 | unsigned int j; | 778 | unsigned int j; |
775 | #ifdef CONFIG_SMP | ||
776 | struct cpufreq_policy *managed_policy; | ||
777 | #endif | ||
778 | 779 | ||
779 | if (cpu_is_offline(cpu)) | 780 | if (cpu_is_offline(cpu)) |
780 | return 0; | 781 | return 0; |
@@ -804,15 +805,12 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
804 | goto nomem_out; | 805 | goto nomem_out; |
805 | } | 806 | } |
806 | if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) { | 807 | if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) { |
807 | kfree(policy); | ||
808 | ret = -ENOMEM; | 808 | ret = -ENOMEM; |
809 | goto nomem_out; | 809 | goto err_free_policy; |
810 | } | 810 | } |
811 | if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) { | 811 | if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) { |
812 | free_cpumask_var(policy->cpus); | ||
813 | kfree(policy); | ||
814 | ret = -ENOMEM; | 812 | ret = -ENOMEM; |
815 | goto nomem_out; | 813 | goto err_free_cpumask; |
816 | } | 814 | } |
817 | 815 | ||
818 | policy->cpu = cpu; | 816 | policy->cpu = cpu; |
@@ -820,7 +818,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
820 | 818 | ||
821 | /* Initially set CPU itself as the policy_cpu */ | 819 | /* Initially set CPU itself as the policy_cpu */ |
822 | per_cpu(policy_cpu, cpu) = cpu; | 820 | per_cpu(policy_cpu, cpu) = cpu; |
823 | lock_policy_rwsem_write(cpu); | 821 | ret = (lock_policy_rwsem_write(cpu) < 0); |
822 | WARN_ON(ret); | ||
824 | 823 | ||
825 | init_completion(&policy->kobj_unregister); | 824 | init_completion(&policy->kobj_unregister); |
826 | INIT_WORK(&policy->update, handle_update); | 825 | INIT_WORK(&policy->update, handle_update); |
@@ -833,7 +832,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
833 | ret = cpufreq_driver->init(policy); | 832 | ret = cpufreq_driver->init(policy); |
834 | if (ret) { | 833 | if (ret) { |
835 | dprintk("initialization failed\n"); | 834 | dprintk("initialization failed\n"); |
836 | goto err_out; | 835 | goto err_unlock_policy; |
837 | } | 836 | } |
838 | policy->user_policy.min = policy->min; | 837 | policy->user_policy.min = policy->min; |
839 | policy->user_policy.max = policy->max; | 838 | policy->user_policy.max = policy->max; |
@@ -852,21 +851,29 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
852 | #endif | 851 | #endif |
853 | 852 | ||
854 | for_each_cpu(j, policy->cpus) { | 853 | for_each_cpu(j, policy->cpus) { |
854 | struct cpufreq_policy *managed_policy; | ||
855 | |||
855 | if (cpu == j) | 856 | if (cpu == j) |
856 | continue; | 857 | continue; |
857 | 858 | ||
858 | /* Check for existing affected CPUs. | 859 | /* Check for existing affected CPUs. |
859 | * They may not be aware of it due to CPU Hotplug. | 860 | * They may not be aware of it due to CPU Hotplug. |
860 | */ | 861 | */ |
861 | managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */ | 862 | managed_policy = cpufreq_cpu_get(j); |
862 | if (unlikely(managed_policy)) { | 863 | if (unlikely(managed_policy)) { |
863 | 864 | ||
864 | /* Set proper policy_cpu */ | 865 | /* Set proper policy_cpu */ |
865 | unlock_policy_rwsem_write(cpu); | 866 | unlock_policy_rwsem_write(cpu); |
866 | per_cpu(policy_cpu, cpu) = managed_policy->cpu; | 867 | per_cpu(policy_cpu, cpu) = managed_policy->cpu; |
867 | 868 | ||
868 | if (lock_policy_rwsem_write(cpu) < 0) | 869 | if (lock_policy_rwsem_write(cpu) < 0) { |
869 | goto err_out_driver_exit; | 870 | /* Should not go through policy unlock path */ |
871 | if (cpufreq_driver->exit) | ||
872 | cpufreq_driver->exit(policy); | ||
873 | ret = -EBUSY; | ||
874 | cpufreq_cpu_put(managed_policy); | ||
875 | goto err_free_cpumask; | ||
876 | } | ||
870 | 877 | ||
871 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 878 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
872 | cpumask_copy(managed_policy->cpus, policy->cpus); | 879 | cpumask_copy(managed_policy->cpus, policy->cpus); |
@@ -877,12 +884,14 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
877 | ret = sysfs_create_link(&sys_dev->kobj, | 884 | ret = sysfs_create_link(&sys_dev->kobj, |
878 | &managed_policy->kobj, | 885 | &managed_policy->kobj, |
879 | "cpufreq"); | 886 | "cpufreq"); |
880 | if (ret) | 887 | if (!ret) |
881 | goto err_out_driver_exit; | 888 | cpufreq_cpu_put(managed_policy); |
882 | 889 | /* | |
883 | cpufreq_debug_enable_ratelimit(); | 890 | * Success. We only needed to be added to the mask. |
884 | ret = 0; | 891 | * Call driver->exit() because only the cpu parent of |
885 | goto err_out_driver_exit; /* call driver->exit() */ | 892 | * the kobj needed to call init(). |
893 | */ | ||
894 | goto out_driver_exit; /* call driver->exit() */ | ||
886 | } | 895 | } |
887 | } | 896 | } |
888 | #endif | 897 | #endif |
@@ -892,25 +901,25 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
892 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj, | 901 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj, |
893 | "cpufreq"); | 902 | "cpufreq"); |
894 | if (ret) | 903 | if (ret) |
895 | goto err_out_driver_exit; | 904 | goto out_driver_exit; |
896 | 905 | ||
897 | /* set up files for this cpu device */ | 906 | /* set up files for this cpu device */ |
898 | drv_attr = cpufreq_driver->attr; | 907 | drv_attr = cpufreq_driver->attr; |
899 | while ((drv_attr) && (*drv_attr)) { | 908 | while ((drv_attr) && (*drv_attr)) { |
900 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); | 909 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); |
901 | if (ret) | 910 | if (ret) |
902 | goto err_out_driver_exit; | 911 | goto err_out_kobj_put; |
903 | drv_attr++; | 912 | drv_attr++; |
904 | } | 913 | } |
905 | if (cpufreq_driver->get) { | 914 | if (cpufreq_driver->get) { |
906 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); | 915 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); |
907 | if (ret) | 916 | if (ret) |
908 | goto err_out_driver_exit; | 917 | goto err_out_kobj_put; |
909 | } | 918 | } |
910 | if (cpufreq_driver->target) { | 919 | if (cpufreq_driver->target) { |
911 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); | 920 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); |
912 | if (ret) | 921 | if (ret) |
913 | goto err_out_driver_exit; | 922 | goto err_out_kobj_put; |
914 | } | 923 | } |
915 | 924 | ||
916 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 925 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
@@ -922,18 +931,22 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
922 | 931 | ||
923 | /* symlink affected CPUs */ | 932 | /* symlink affected CPUs */ |
924 | for_each_cpu(j, policy->cpus) { | 933 | for_each_cpu(j, policy->cpus) { |
934 | struct cpufreq_policy *managed_policy; | ||
935 | |||
925 | if (j == cpu) | 936 | if (j == cpu) |
926 | continue; | 937 | continue; |
927 | if (!cpu_online(j)) | 938 | if (!cpu_online(j)) |
928 | continue; | 939 | continue; |
929 | 940 | ||
930 | dprintk("CPU %u already managed, adding link\n", j); | 941 | dprintk("CPU %u already managed, adding link\n", j); |
931 | cpufreq_cpu_get(cpu); | 942 | managed_policy = cpufreq_cpu_get(cpu); |
932 | cpu_sys_dev = get_cpu_sysdev(j); | 943 | cpu_sys_dev = get_cpu_sysdev(j); |
933 | ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, | 944 | ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, |
934 | "cpufreq"); | 945 | "cpufreq"); |
935 | if (ret) | 946 | if (ret) { |
947 | cpufreq_cpu_put(managed_policy); | ||
936 | goto err_out_unregister; | 948 | goto err_out_unregister; |
949 | } | ||
937 | } | 950 | } |
938 | 951 | ||
939 | policy->governor = NULL; /* to assure that the starting sequence is | 952 | policy->governor = NULL; /* to assure that the starting sequence is |
@@ -965,17 +978,20 @@ err_out_unregister: | |||
965 | per_cpu(cpufreq_cpu_data, j) = NULL; | 978 | per_cpu(cpufreq_cpu_data, j) = NULL; |
966 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 979 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
967 | 980 | ||
981 | err_out_kobj_put: | ||
968 | kobject_put(&policy->kobj); | 982 | kobject_put(&policy->kobj); |
969 | wait_for_completion(&policy->kobj_unregister); | 983 | wait_for_completion(&policy->kobj_unregister); |
970 | 984 | ||
971 | err_out_driver_exit: | 985 | out_driver_exit: |
972 | if (cpufreq_driver->exit) | 986 | if (cpufreq_driver->exit) |
973 | cpufreq_driver->exit(policy); | 987 | cpufreq_driver->exit(policy); |
974 | 988 | ||
975 | err_out: | 989 | err_unlock_policy: |
976 | unlock_policy_rwsem_write(cpu); | 990 | unlock_policy_rwsem_write(cpu); |
991 | err_free_cpumask: | ||
992 | free_cpumask_var(policy->cpus); | ||
993 | err_free_policy: | ||
977 | kfree(policy); | 994 | kfree(policy); |
978 | |||
979 | nomem_out: | 995 | nomem_out: |
980 | module_put(cpufreq_driver->owner); | 996 | module_put(cpufreq_driver->owner); |
981 | module_out: | 997 | module_out: |
@@ -1070,8 +1086,6 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
1070 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1086 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1071 | #endif | 1087 | #endif |
1072 | 1088 | ||
1073 | unlock_policy_rwsem_write(cpu); | ||
1074 | |||
1075 | if (cpufreq_driver->target) | 1089 | if (cpufreq_driver->target) |
1076 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 1090 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); |
1077 | 1091 | ||
@@ -1088,6 +1102,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
1088 | if (cpufreq_driver->exit) | 1102 | if (cpufreq_driver->exit) |
1089 | cpufreq_driver->exit(data); | 1103 | cpufreq_driver->exit(data); |
1090 | 1104 | ||
1105 | unlock_policy_rwsem_write(cpu); | ||
1106 | |||
1091 | free_cpumask_var(data->related_cpus); | 1107 | free_cpumask_var(data->related_cpus); |
1092 | free_cpumask_var(data->cpus); | 1108 | free_cpumask_var(data->cpus); |
1093 | kfree(data); | 1109 | kfree(data); |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 7fc58af748b4..57490502b21c 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -63,22 +63,20 @@ struct cpu_dbs_info_s { | |||
63 | unsigned int down_skip; | 63 | unsigned int down_skip; |
64 | unsigned int requested_freq; | 64 | unsigned int requested_freq; |
65 | int cpu; | 65 | int cpu; |
66 | unsigned int enable:1; | 66 | /* |
67 | * percpu mutex that serializes governor limit change with | ||
68 | * do_dbs_timer invocation. We do not want do_dbs_timer to run | ||
69 | * when user is changing the governor or limits. | ||
70 | */ | ||
71 | struct mutex timer_mutex; | ||
67 | }; | 72 | }; |
68 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 73 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); |
69 | 74 | ||
70 | static unsigned int dbs_enable; /* number of CPUs using this policy */ | 75 | static unsigned int dbs_enable; /* number of CPUs using this policy */ |
71 | 76 | ||
72 | /* | 77 | /* |
73 | * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug | 78 | * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on |
74 | * lock and dbs_mutex. cpu_hotplug lock should always be held before | 79 | * different CPUs. It protects dbs_enable in governor start/stop. |
75 | * dbs_mutex. If any function that can potentially take cpu_hotplug lock | ||
76 | * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then | ||
77 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | ||
78 | * is recursive for the same process. -Venki | ||
79 | * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it | ||
80 | * would deadlock with cancel_delayed_work_sync(), which is needed for proper | ||
81 | * raceless workqueue teardown. | ||
82 | */ | 80 | */ |
83 | static DEFINE_MUTEX(dbs_mutex); | 81 | static DEFINE_MUTEX(dbs_mutex); |
84 | 82 | ||
@@ -143,9 +141,6 @@ dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
143 | 141 | ||
144 | struct cpufreq_policy *policy; | 142 | struct cpufreq_policy *policy; |
145 | 143 | ||
146 | if (!this_dbs_info->enable) | ||
147 | return 0; | ||
148 | |||
149 | policy = this_dbs_info->cur_policy; | 144 | policy = this_dbs_info->cur_policy; |
150 | 145 | ||
151 | /* | 146 | /* |
@@ -488,18 +483,12 @@ static void do_dbs_timer(struct work_struct *work) | |||
488 | 483 | ||
489 | delay -= jiffies % delay; | 484 | delay -= jiffies % delay; |
490 | 485 | ||
491 | if (lock_policy_rwsem_write(cpu) < 0) | 486 | mutex_lock(&dbs_info->timer_mutex); |
492 | return; | ||
493 | |||
494 | if (!dbs_info->enable) { | ||
495 | unlock_policy_rwsem_write(cpu); | ||
496 | return; | ||
497 | } | ||
498 | 487 | ||
499 | dbs_check_cpu(dbs_info); | 488 | dbs_check_cpu(dbs_info); |
500 | 489 | ||
501 | queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); | 490 | queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); |
502 | unlock_policy_rwsem_write(cpu); | 491 | mutex_unlock(&dbs_info->timer_mutex); |
503 | } | 492 | } |
504 | 493 | ||
505 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | 494 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) |
@@ -508,7 +497,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
508 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 497 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
509 | delay -= jiffies % delay; | 498 | delay -= jiffies % delay; |
510 | 499 | ||
511 | dbs_info->enable = 1; | ||
512 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); | 500 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); |
513 | queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work, | 501 | queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work, |
514 | delay); | 502 | delay); |
@@ -516,7 +504,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
516 | 504 | ||
517 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) | 505 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) |
518 | { | 506 | { |
519 | dbs_info->enable = 0; | ||
520 | cancel_delayed_work_sync(&dbs_info->work); | 507 | cancel_delayed_work_sync(&dbs_info->work); |
521 | } | 508 | } |
522 | 509 | ||
@@ -535,9 +522,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
535 | if ((!cpu_online(cpu)) || (!policy->cur)) | 522 | if ((!cpu_online(cpu)) || (!policy->cur)) |
536 | return -EINVAL; | 523 | return -EINVAL; |
537 | 524 | ||
538 | if (this_dbs_info->enable) /* Already enabled */ | ||
539 | break; | ||
540 | |||
541 | mutex_lock(&dbs_mutex); | 525 | mutex_lock(&dbs_mutex); |
542 | 526 | ||
543 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); | 527 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); |
@@ -561,6 +545,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
561 | this_dbs_info->down_skip = 0; | 545 | this_dbs_info->down_skip = 0; |
562 | this_dbs_info->requested_freq = policy->cur; | 546 | this_dbs_info->requested_freq = policy->cur; |
563 | 547 | ||
548 | mutex_init(&this_dbs_info->timer_mutex); | ||
564 | dbs_enable++; | 549 | dbs_enable++; |
565 | /* | 550 | /* |
566 | * Start the timerschedule work, when this governor | 551 | * Start the timerschedule work, when this governor |
@@ -590,17 +575,19 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
590 | &dbs_cpufreq_notifier_block, | 575 | &dbs_cpufreq_notifier_block, |
591 | CPUFREQ_TRANSITION_NOTIFIER); | 576 | CPUFREQ_TRANSITION_NOTIFIER); |
592 | } | 577 | } |
593 | dbs_timer_init(this_dbs_info); | ||
594 | |||
595 | mutex_unlock(&dbs_mutex); | 578 | mutex_unlock(&dbs_mutex); |
596 | 579 | ||
580 | dbs_timer_init(this_dbs_info); | ||
581 | |||
597 | break; | 582 | break; |
598 | 583 | ||
599 | case CPUFREQ_GOV_STOP: | 584 | case CPUFREQ_GOV_STOP: |
600 | mutex_lock(&dbs_mutex); | ||
601 | dbs_timer_exit(this_dbs_info); | 585 | dbs_timer_exit(this_dbs_info); |
586 | |||
587 | mutex_lock(&dbs_mutex); | ||
602 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 588 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); |
603 | dbs_enable--; | 589 | dbs_enable--; |
590 | mutex_destroy(&this_dbs_info->timer_mutex); | ||
604 | 591 | ||
605 | /* | 592 | /* |
606 | * Stop the timerschedule work, when this governor | 593 | * Stop the timerschedule work, when this governor |
@@ -616,7 +603,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
616 | break; | 603 | break; |
617 | 604 | ||
618 | case CPUFREQ_GOV_LIMITS: | 605 | case CPUFREQ_GOV_LIMITS: |
619 | mutex_lock(&dbs_mutex); | 606 | mutex_lock(&this_dbs_info->timer_mutex); |
620 | if (policy->max < this_dbs_info->cur_policy->cur) | 607 | if (policy->max < this_dbs_info->cur_policy->cur) |
621 | __cpufreq_driver_target( | 608 | __cpufreq_driver_target( |
622 | this_dbs_info->cur_policy, | 609 | this_dbs_info->cur_policy, |
@@ -625,7 +612,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
625 | __cpufreq_driver_target( | 612 | __cpufreq_driver_target( |
626 | this_dbs_info->cur_policy, | 613 | this_dbs_info->cur_policy, |
627 | policy->min, CPUFREQ_RELATION_L); | 614 | policy->min, CPUFREQ_RELATION_L); |
628 | mutex_unlock(&dbs_mutex); | 615 | mutex_unlock(&this_dbs_info->timer_mutex); |
629 | 616 | ||
630 | break; | 617 | break; |
631 | } | 618 | } |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 1911d1729353..d6ba14276bb1 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -70,23 +70,21 @@ struct cpu_dbs_info_s { | |||
70 | unsigned int freq_lo_jiffies; | 70 | unsigned int freq_lo_jiffies; |
71 | unsigned int freq_hi_jiffies; | 71 | unsigned int freq_hi_jiffies; |
72 | int cpu; | 72 | int cpu; |
73 | unsigned int enable:1, | 73 | unsigned int sample_type:1; |
74 | sample_type:1; | 74 | /* |
75 | * percpu mutex that serializes governor limit change with | ||
76 | * do_dbs_timer invocation. We do not want do_dbs_timer to run | ||
77 | * when user is changing the governor or limits. | ||
78 | */ | ||
79 | struct mutex timer_mutex; | ||
75 | }; | 80 | }; |
76 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 81 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); |
77 | 82 | ||
78 | static unsigned int dbs_enable; /* number of CPUs using this policy */ | 83 | static unsigned int dbs_enable; /* number of CPUs using this policy */ |
79 | 84 | ||
80 | /* | 85 | /* |
81 | * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug | 86 | * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on |
82 | * lock and dbs_mutex. cpu_hotplug lock should always be held before | 87 | * different CPUs. It protects dbs_enable in governor start/stop. |
83 | * dbs_mutex. If any function that can potentially take cpu_hotplug lock | ||
84 | * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then | ||
85 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | ||
86 | * is recursive for the same process. -Venki | ||
87 | * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it | ||
88 | * would deadlock with cancel_delayed_work_sync(), which is needed for proper | ||
89 | * raceless workqueue teardown. | ||
90 | */ | 88 | */ |
91 | static DEFINE_MUTEX(dbs_mutex); | 89 | static DEFINE_MUTEX(dbs_mutex); |
92 | 90 | ||
@@ -192,13 +190,18 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy, | |||
192 | return freq_hi; | 190 | return freq_hi; |
193 | } | 191 | } |
194 | 192 | ||
193 | static void ondemand_powersave_bias_init_cpu(int cpu) | ||
194 | { | ||
195 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
196 | dbs_info->freq_table = cpufreq_frequency_get_table(cpu); | ||
197 | dbs_info->freq_lo = 0; | ||
198 | } | ||
199 | |||
195 | static void ondemand_powersave_bias_init(void) | 200 | static void ondemand_powersave_bias_init(void) |
196 | { | 201 | { |
197 | int i; | 202 | int i; |
198 | for_each_online_cpu(i) { | 203 | for_each_online_cpu(i) { |
199 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, i); | 204 | ondemand_powersave_bias_init_cpu(i); |
200 | dbs_info->freq_table = cpufreq_frequency_get_table(i); | ||
201 | dbs_info->freq_lo = 0; | ||
202 | } | 205 | } |
203 | } | 206 | } |
204 | 207 | ||
@@ -240,12 +243,10 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | |||
240 | unsigned int input; | 243 | unsigned int input; |
241 | int ret; | 244 | int ret; |
242 | ret = sscanf(buf, "%u", &input); | 245 | ret = sscanf(buf, "%u", &input); |
246 | if (ret != 1) | ||
247 | return -EINVAL; | ||
243 | 248 | ||
244 | mutex_lock(&dbs_mutex); | 249 | mutex_lock(&dbs_mutex); |
245 | if (ret != 1) { | ||
246 | mutex_unlock(&dbs_mutex); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate); | 250 | dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate); |
250 | mutex_unlock(&dbs_mutex); | 251 | mutex_unlock(&dbs_mutex); |
251 | 252 | ||
@@ -259,13 +260,12 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
259 | int ret; | 260 | int ret; |
260 | ret = sscanf(buf, "%u", &input); | 261 | ret = sscanf(buf, "%u", &input); |
261 | 262 | ||
262 | mutex_lock(&dbs_mutex); | ||
263 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | 263 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || |
264 | input < MIN_FREQUENCY_UP_THRESHOLD) { | 264 | input < MIN_FREQUENCY_UP_THRESHOLD) { |
265 | mutex_unlock(&dbs_mutex); | ||
266 | return -EINVAL; | 265 | return -EINVAL; |
267 | } | 266 | } |
268 | 267 | ||
268 | mutex_lock(&dbs_mutex); | ||
269 | dbs_tuners_ins.up_threshold = input; | 269 | dbs_tuners_ins.up_threshold = input; |
270 | mutex_unlock(&dbs_mutex); | 270 | mutex_unlock(&dbs_mutex); |
271 | 271 | ||
@@ -363,9 +363,6 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
363 | struct cpufreq_policy *policy; | 363 | struct cpufreq_policy *policy; |
364 | unsigned int j; | 364 | unsigned int j; |
365 | 365 | ||
366 | if (!this_dbs_info->enable) | ||
367 | return; | ||
368 | |||
369 | this_dbs_info->freq_lo = 0; | 366 | this_dbs_info->freq_lo = 0; |
370 | policy = this_dbs_info->cur_policy; | 367 | policy = this_dbs_info->cur_policy; |
371 | 368 | ||
@@ -493,14 +490,7 @@ static void do_dbs_timer(struct work_struct *work) | |||
493 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 490 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
494 | 491 | ||
495 | delay -= jiffies % delay; | 492 | delay -= jiffies % delay; |
496 | 493 | mutex_lock(&dbs_info->timer_mutex); | |
497 | if (lock_policy_rwsem_write(cpu) < 0) | ||
498 | return; | ||
499 | |||
500 | if (!dbs_info->enable) { | ||
501 | unlock_policy_rwsem_write(cpu); | ||
502 | return; | ||
503 | } | ||
504 | 494 | ||
505 | /* Common NORMAL_SAMPLE setup */ | 495 | /* Common NORMAL_SAMPLE setup */ |
506 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; | 496 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; |
@@ -517,7 +507,7 @@ static void do_dbs_timer(struct work_struct *work) | |||
517 | dbs_info->freq_lo, CPUFREQ_RELATION_H); | 507 | dbs_info->freq_lo, CPUFREQ_RELATION_H); |
518 | } | 508 | } |
519 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); | 509 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); |
520 | unlock_policy_rwsem_write(cpu); | 510 | mutex_unlock(&dbs_info->timer_mutex); |
521 | } | 511 | } |
522 | 512 | ||
523 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | 513 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) |
@@ -526,8 +516,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
526 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 516 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
527 | delay -= jiffies % delay; | 517 | delay -= jiffies % delay; |
528 | 518 | ||
529 | dbs_info->enable = 1; | ||
530 | ondemand_powersave_bias_init(); | ||
531 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; | 519 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; |
532 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); | 520 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); |
533 | queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, | 521 | queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, |
@@ -536,7 +524,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
536 | 524 | ||
537 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) | 525 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) |
538 | { | 526 | { |
539 | dbs_info->enable = 0; | ||
540 | cancel_delayed_work_sync(&dbs_info->work); | 527 | cancel_delayed_work_sync(&dbs_info->work); |
541 | } | 528 | } |
542 | 529 | ||
@@ -555,19 +542,15 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
555 | if ((!cpu_online(cpu)) || (!policy->cur)) | 542 | if ((!cpu_online(cpu)) || (!policy->cur)) |
556 | return -EINVAL; | 543 | return -EINVAL; |
557 | 544 | ||
558 | if (this_dbs_info->enable) /* Already enabled */ | ||
559 | break; | ||
560 | |||
561 | mutex_lock(&dbs_mutex); | 545 | mutex_lock(&dbs_mutex); |
562 | dbs_enable++; | ||
563 | 546 | ||
564 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); | 547 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); |
565 | if (rc) { | 548 | if (rc) { |
566 | dbs_enable--; | ||
567 | mutex_unlock(&dbs_mutex); | 549 | mutex_unlock(&dbs_mutex); |
568 | return rc; | 550 | return rc; |
569 | } | 551 | } |
570 | 552 | ||
553 | dbs_enable++; | ||
571 | for_each_cpu(j, policy->cpus) { | 554 | for_each_cpu(j, policy->cpus) { |
572 | struct cpu_dbs_info_s *j_dbs_info; | 555 | struct cpu_dbs_info_s *j_dbs_info; |
573 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 556 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
@@ -581,6 +564,8 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
581 | } | 564 | } |
582 | } | 565 | } |
583 | this_dbs_info->cpu = cpu; | 566 | this_dbs_info->cpu = cpu; |
567 | ondemand_powersave_bias_init_cpu(cpu); | ||
568 | mutex_init(&this_dbs_info->timer_mutex); | ||
584 | /* | 569 | /* |
585 | * Start the timerschedule work, when this governor | 570 | * Start the timerschedule work, when this governor |
586 | * is used for first time | 571 | * is used for first time |
@@ -598,29 +583,31 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
598 | max(min_sampling_rate, | 583 | max(min_sampling_rate, |
599 | latency * LATENCY_MULTIPLIER); | 584 | latency * LATENCY_MULTIPLIER); |
600 | } | 585 | } |
601 | dbs_timer_init(this_dbs_info); | ||
602 | |||
603 | mutex_unlock(&dbs_mutex); | 586 | mutex_unlock(&dbs_mutex); |
587 | |||
588 | dbs_timer_init(this_dbs_info); | ||
604 | break; | 589 | break; |
605 | 590 | ||
606 | case CPUFREQ_GOV_STOP: | 591 | case CPUFREQ_GOV_STOP: |
607 | mutex_lock(&dbs_mutex); | ||
608 | dbs_timer_exit(this_dbs_info); | 592 | dbs_timer_exit(this_dbs_info); |
593 | |||
594 | mutex_lock(&dbs_mutex); | ||
609 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 595 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); |
596 | mutex_destroy(&this_dbs_info->timer_mutex); | ||
610 | dbs_enable--; | 597 | dbs_enable--; |
611 | mutex_unlock(&dbs_mutex); | 598 | mutex_unlock(&dbs_mutex); |
612 | 599 | ||
613 | break; | 600 | break; |
614 | 601 | ||
615 | case CPUFREQ_GOV_LIMITS: | 602 | case CPUFREQ_GOV_LIMITS: |
616 | mutex_lock(&dbs_mutex); | 603 | mutex_lock(&this_dbs_info->timer_mutex); |
617 | if (policy->max < this_dbs_info->cur_policy->cur) | 604 | if (policy->max < this_dbs_info->cur_policy->cur) |
618 | __cpufreq_driver_target(this_dbs_info->cur_policy, | 605 | __cpufreq_driver_target(this_dbs_info->cur_policy, |
619 | policy->max, CPUFREQ_RELATION_H); | 606 | policy->max, CPUFREQ_RELATION_H); |
620 | else if (policy->min > this_dbs_info->cur_policy->cur) | 607 | else if (policy->min > this_dbs_info->cur_policy->cur) |
621 | __cpufreq_driver_target(this_dbs_info->cur_policy, | 608 | __cpufreq_driver_target(this_dbs_info->cur_policy, |
622 | policy->min, CPUFREQ_RELATION_L); | 609 | policy->min, CPUFREQ_RELATION_L); |
623 | mutex_unlock(&dbs_mutex); | 610 | mutex_unlock(&this_dbs_info->timer_mutex); |
624 | break; | 611 | break; |
625 | } | 612 | } |
626 | return 0; | 613 | return 0; |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index c36bf40568cf..858fe6037223 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -754,13 +754,13 @@ static void amd64_cpu_display_info(struct amd64_pvt *pvt) | |||
754 | static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) | 754 | static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) |
755 | { | 755 | { |
756 | int bit; | 756 | int bit; |
757 | enum dev_type edac_cap = EDAC_NONE; | 757 | enum dev_type edac_cap = EDAC_FLAG_NONE; |
758 | 758 | ||
759 | bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F) | 759 | bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F) |
760 | ? 19 | 760 | ? 19 |
761 | : 17; | 761 | : 17; |
762 | 762 | ||
763 | if (pvt->dclr0 >> BIT(bit)) | 763 | if (pvt->dclr0 & BIT(bit)) |
764 | edac_cap = EDAC_FLAG_SECDED; | 764 | edac_cap = EDAC_FLAG_SECDED; |
765 | 765 | ||
766 | return edac_cap; | 766 | return edac_cap; |
@@ -1269,7 +1269,7 @@ static int f10_early_channel_count(struct amd64_pvt *pvt) | |||
1269 | if (channels == 0) | 1269 | if (channels == 0) |
1270 | channels = 1; | 1270 | channels = 1; |
1271 | 1271 | ||
1272 | debugf0("DIMM count= %d\n", channels); | 1272 | debugf0("MCT channel count: %d\n", channels); |
1273 | 1273 | ||
1274 | return channels; | 1274 | return channels; |
1275 | 1275 | ||
@@ -2966,7 +2966,12 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) | |||
2966 | " Use of the override can cause " | 2966 | " Use of the override can cause " |
2967 | "unknown side effects.\n"); | 2967 | "unknown side effects.\n"); |
2968 | ret = -ENODEV; | 2968 | ret = -ENODEV; |
2969 | } | 2969 | } else |
2970 | /* | ||
2971 | * enable further driver loading if ECC enable is | ||
2972 | * overridden. | ||
2973 | */ | ||
2974 | ret = 0; | ||
2970 | } else { | 2975 | } else { |
2971 | amd64_printk(KERN_INFO, | 2976 | amd64_printk(KERN_INFO, |
2972 | "ECC is enabled by BIOS, Proceeding " | 2977 | "ECC is enabled by BIOS, Proceeding " |
@@ -3006,7 +3011,6 @@ static void amd64_setup_mci_misc_attributes(struct mem_ctl_info *mci) | |||
3006 | 3011 | ||
3007 | mci->mtype_cap = MEM_FLAG_DDR2 | MEM_FLAG_RDDR2; | 3012 | mci->mtype_cap = MEM_FLAG_DDR2 | MEM_FLAG_RDDR2; |
3008 | mci->edac_ctl_cap = EDAC_FLAG_NONE; | 3013 | mci->edac_ctl_cap = EDAC_FLAG_NONE; |
3009 | mci->edac_cap = EDAC_FLAG_NONE; | ||
3010 | 3014 | ||
3011 | if (pvt->nbcap & K8_NBCAP_SECDED) | 3015 | if (pvt->nbcap & K8_NBCAP_SECDED) |
3012 | mci->edac_ctl_cap |= EDAC_FLAG_SECDED; | 3016 | mci->edac_ctl_cap |= EDAC_FLAG_SECDED; |
@@ -3052,7 +3056,7 @@ static int amd64_probe_one_instance(struct pci_dev *dram_f2_ctl, | |||
3052 | if (!pvt) | 3056 | if (!pvt) |
3053 | goto err_exit; | 3057 | goto err_exit; |
3054 | 3058 | ||
3055 | pvt->mc_node_id = get_mc_node_id_from_pdev(dram_f2_ctl); | 3059 | pvt->mc_node_id = get_node_id(dram_f2_ctl); |
3056 | 3060 | ||
3057 | pvt->dram_f2_ctl = dram_f2_ctl; | 3061 | pvt->dram_f2_ctl = dram_f2_ctl; |
3058 | pvt->ext_model = boot_cpu_data.x86_model >> 4; | 3062 | pvt->ext_model = boot_cpu_data.x86_model >> 4; |
@@ -3179,8 +3183,7 @@ static int __devinit amd64_init_one_instance(struct pci_dev *pdev, | |||
3179 | { | 3183 | { |
3180 | int ret = 0; | 3184 | int ret = 0; |
3181 | 3185 | ||
3182 | debugf0("(MC node=%d,mc_type='%s')\n", | 3186 | debugf0("(MC node=%d,mc_type='%s')\n", get_node_id(pdev), |
3183 | get_mc_node_id_from_pdev(pdev), | ||
3184 | get_amd_family_name(mc_type->driver_data)); | 3187 | get_amd_family_name(mc_type->driver_data)); |
3185 | 3188 | ||
3186 | ret = pci_enable_device(pdev); | 3189 | ret = pci_enable_device(pdev); |
@@ -3319,15 +3322,17 @@ static int __init amd64_edac_init(void) | |||
3319 | 3322 | ||
3320 | err = amd64_init_2nd_stage(pvt_lookup[nb]); | 3323 | err = amd64_init_2nd_stage(pvt_lookup[nb]); |
3321 | if (err) | 3324 | if (err) |
3322 | goto err_exit; | 3325 | goto err_2nd_stage; |
3323 | } | 3326 | } |
3324 | 3327 | ||
3325 | amd64_setup_pci_device(); | 3328 | amd64_setup_pci_device(); |
3326 | 3329 | ||
3327 | return 0; | 3330 | return 0; |
3328 | 3331 | ||
3332 | err_2nd_stage: | ||
3333 | debugf0("2nd stage failed\n"); | ||
3334 | |||
3329 | err_exit: | 3335 | err_exit: |
3330 | debugf0("'finish_setup' stage failed\n"); | ||
3331 | pci_unregister_driver(&amd64_pci_driver); | 3336 | pci_unregister_driver(&amd64_pci_driver); |
3332 | 3337 | ||
3333 | return err; | 3338 | return err; |
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index a159957e167b..ba73015af8e4 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -444,7 +444,7 @@ enum { | |||
444 | #define K8_MSR_MC4ADDR 0x0412 | 444 | #define K8_MSR_MC4ADDR 0x0412 |
445 | 445 | ||
446 | /* AMD sets the first MC device at device ID 0x18. */ | 446 | /* AMD sets the first MC device at device ID 0x18. */ |
447 | static inline int get_mc_node_id_from_pdev(struct pci_dev *pdev) | 447 | static inline int get_node_id(struct pci_dev *pdev) |
448 | { | 448 | { |
449 | return PCI_SLOT(pdev->devfn) - 0x18; | 449 | return PCI_SLOT(pdev->devfn) - 0x18; |
450 | } | 450 | } |
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 3493c6bdb820..871c13b4c148 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h | |||
@@ -150,6 +150,8 @@ enum mem_type { | |||
150 | MEM_FB_DDR2, /* fully buffered DDR2 */ | 150 | MEM_FB_DDR2, /* fully buffered DDR2 */ |
151 | MEM_RDDR2, /* Registered DDR2 RAM */ | 151 | MEM_RDDR2, /* Registered DDR2 RAM */ |
152 | MEM_XDR, /* Rambus XDR */ | 152 | MEM_XDR, /* Rambus XDR */ |
153 | MEM_DDR3, /* DDR3 RAM */ | ||
154 | MEM_RDDR3, /* Registered DDR3 RAM */ | ||
153 | }; | 155 | }; |
154 | 156 | ||
155 | #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) | 157 | #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) |
@@ -167,6 +169,8 @@ enum mem_type { | |||
167 | #define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2) | 169 | #define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2) |
168 | #define MEM_FLAG_RDDR2 BIT(MEM_RDDR2) | 170 | #define MEM_FLAG_RDDR2 BIT(MEM_RDDR2) |
169 | #define MEM_FLAG_XDR BIT(MEM_XDR) | 171 | #define MEM_FLAG_XDR BIT(MEM_XDR) |
172 | #define MEM_FLAG_DDR3 BIT(MEM_DDR3) | ||
173 | #define MEM_FLAG_RDDR3 BIT(MEM_RDDR3) | ||
170 | 174 | ||
171 | /* chipset Error Detection and Correction capabilities and mode */ | 175 | /* chipset Error Detection and Correction capabilities and mode */ |
172 | enum edac_type { | 176 | enum edac_type { |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index ad218fe4942d..e1d4ce083481 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -94,7 +94,9 @@ static const char *mem_types[] = { | |||
94 | [MEM_DDR2] = "Unbuffered-DDR2", | 94 | [MEM_DDR2] = "Unbuffered-DDR2", |
95 | [MEM_FB_DDR2] = "FullyBuffered-DDR2", | 95 | [MEM_FB_DDR2] = "FullyBuffered-DDR2", |
96 | [MEM_RDDR2] = "Registered-DDR2", | 96 | [MEM_RDDR2] = "Registered-DDR2", |
97 | [MEM_XDR] = "XDR" | 97 | [MEM_XDR] = "XDR", |
98 | [MEM_DDR3] = "Unbuffered-DDR3", | ||
99 | [MEM_RDDR3] = "Registered-DDR3" | ||
98 | }; | 100 | }; |
99 | 101 | ||
100 | static const char *dev_types[] = { | 102 | static const char *dev_types[] = { |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 7c8c2d72916f..3f2ccfc6407c 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -757,6 +757,9 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) | |||
757 | case DSC_SDTYPE_DDR2: | 757 | case DSC_SDTYPE_DDR2: |
758 | mtype = MEM_RDDR2; | 758 | mtype = MEM_RDDR2; |
759 | break; | 759 | break; |
760 | case DSC_SDTYPE_DDR3: | ||
761 | mtype = MEM_RDDR3; | ||
762 | break; | ||
760 | default: | 763 | default: |
761 | mtype = MEM_UNKNOWN; | 764 | mtype = MEM_UNKNOWN; |
762 | break; | 765 | break; |
@@ -769,6 +772,9 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) | |||
769 | case DSC_SDTYPE_DDR2: | 772 | case DSC_SDTYPE_DDR2: |
770 | mtype = MEM_DDR2; | 773 | mtype = MEM_DDR2; |
771 | break; | 774 | break; |
775 | case DSC_SDTYPE_DDR3: | ||
776 | mtype = MEM_DDR3; | ||
777 | break; | ||
772 | default: | 778 | default: |
773 | mtype = MEM_UNKNOWN; | 779 | mtype = MEM_UNKNOWN; |
774 | break; | 780 | break; |
diff --git a/drivers/edac/mpc85xx_edac.h b/drivers/edac/mpc85xx_edac.h index 135b3539a030..52432ee7c4b9 100644 --- a/drivers/edac/mpc85xx_edac.h +++ b/drivers/edac/mpc85xx_edac.h | |||
@@ -53,6 +53,7 @@ | |||
53 | 53 | ||
54 | #define DSC_SDTYPE_DDR 0x02000000 | 54 | #define DSC_SDTYPE_DDR 0x02000000 |
55 | #define DSC_SDTYPE_DDR2 0x03000000 | 55 | #define DSC_SDTYPE_DDR2 0x03000000 |
56 | #define DSC_SDTYPE_DDR3 0x07000000 | ||
56 | #define DSC_X32_EN 0x00000020 | 57 | #define DSC_X32_EN 0x00000020 |
57 | 58 | ||
58 | /* Err_Int_En */ | 59 | /* Err_Int_En */ |
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 543fccac81bb..f74edae5cb4c 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -196,8 +196,8 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation) | |||
196 | { | 196 | { |
197 | int channel, bandwidth = 0; | 197 | int channel, bandwidth = 0; |
198 | 198 | ||
199 | fw_iso_resource_manage(card, generation, 1ULL << 31, | 199 | fw_iso_resource_manage(card, generation, 1ULL << 31, &channel, |
200 | &channel, &bandwidth, true); | 200 | &bandwidth, true, card->bm_transaction_data); |
201 | if (channel == 31) { | 201 | if (channel == 31) { |
202 | card->broadcast_channel_allocated = true; | 202 | card->broadcast_channel_allocated = true; |
203 | device_for_each_child(card->device, (void *)(long)generation, | 203 | device_for_each_child(card->device, (void *)(long)generation, |
@@ -230,7 +230,6 @@ static void fw_card_bm_work(struct work_struct *work) | |||
230 | bool do_reset = false; | 230 | bool do_reset = false; |
231 | bool root_device_is_running; | 231 | bool root_device_is_running; |
232 | bool root_device_is_cmc; | 232 | bool root_device_is_cmc; |
233 | __be32 lock_data[2]; | ||
234 | 233 | ||
235 | spin_lock_irqsave(&card->lock, flags); | 234 | spin_lock_irqsave(&card->lock, flags); |
236 | 235 | ||
@@ -273,22 +272,23 @@ static void fw_card_bm_work(struct work_struct *work) | |||
273 | goto pick_me; | 272 | goto pick_me; |
274 | } | 273 | } |
275 | 274 | ||
276 | lock_data[0] = cpu_to_be32(0x3f); | 275 | card->bm_transaction_data[0] = cpu_to_be32(0x3f); |
277 | lock_data[1] = cpu_to_be32(local_id); | 276 | card->bm_transaction_data[1] = cpu_to_be32(local_id); |
278 | 277 | ||
279 | spin_unlock_irqrestore(&card->lock, flags); | 278 | spin_unlock_irqrestore(&card->lock, flags); |
280 | 279 | ||
281 | rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, | 280 | rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, |
282 | irm_id, generation, SCODE_100, | 281 | irm_id, generation, SCODE_100, |
283 | CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, | 282 | CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, |
284 | lock_data, sizeof(lock_data)); | 283 | card->bm_transaction_data, |
284 | sizeof(card->bm_transaction_data)); | ||
285 | 285 | ||
286 | if (rcode == RCODE_GENERATION) | 286 | if (rcode == RCODE_GENERATION) |
287 | /* Another bus reset, BM work has been rescheduled. */ | 287 | /* Another bus reset, BM work has been rescheduled. */ |
288 | goto out; | 288 | goto out; |
289 | 289 | ||
290 | if (rcode == RCODE_COMPLETE && | 290 | if (rcode == RCODE_COMPLETE && |
291 | lock_data[0] != cpu_to_be32(0x3f)) { | 291 | card->bm_transaction_data[0] != cpu_to_be32(0x3f)) { |
292 | 292 | ||
293 | /* Somebody else is BM. Only act as IRM. */ | 293 | /* Somebody else is BM. Only act as IRM. */ |
294 | if (local_id == irm_id) | 294 | if (local_id == irm_id) |
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index d1d30c615b0f..ced186d7e9a9 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -125,6 +125,7 @@ struct iso_resource { | |||
125 | int generation; | 125 | int generation; |
126 | u64 channels; | 126 | u64 channels; |
127 | s32 bandwidth; | 127 | s32 bandwidth; |
128 | __be32 transaction_data[2]; | ||
128 | struct iso_resource_event *e_alloc, *e_dealloc; | 129 | struct iso_resource_event *e_alloc, *e_dealloc; |
129 | }; | 130 | }; |
130 | 131 | ||
@@ -1049,7 +1050,8 @@ static void iso_resource_work(struct work_struct *work) | |||
1049 | r->channels, &channel, &bandwidth, | 1050 | r->channels, &channel, &bandwidth, |
1050 | todo == ISO_RES_ALLOC || | 1051 | todo == ISO_RES_ALLOC || |
1051 | todo == ISO_RES_REALLOC || | 1052 | todo == ISO_RES_REALLOC || |
1052 | todo == ISO_RES_ALLOC_ONCE); | 1053 | todo == ISO_RES_ALLOC_ONCE, |
1054 | r->transaction_data); | ||
1053 | /* | 1055 | /* |
1054 | * Is this generation outdated already? As long as this resource sticks | 1056 | * Is this generation outdated already? As long as this resource sticks |
1055 | * in the idr, it will be scheduled again for a newer generation or at | 1057 | * in the idr, it will be scheduled again for a newer generation or at |
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 166f19c6d38d..110e731f5574 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c | |||
@@ -177,9 +177,8 @@ EXPORT_SYMBOL(fw_iso_context_stop); | |||
177 | */ | 177 | */ |
178 | 178 | ||
179 | static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, | 179 | static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, |
180 | int bandwidth, bool allocate) | 180 | int bandwidth, bool allocate, __be32 data[2]) |
181 | { | 181 | { |
182 | __be32 data[2]; | ||
183 | int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0; | 182 | int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0; |
184 | 183 | ||
185 | /* | 184 | /* |
@@ -215,9 +214,9 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, | |||
215 | } | 214 | } |
216 | 215 | ||
217 | static int manage_channel(struct fw_card *card, int irm_id, int generation, | 216 | static int manage_channel(struct fw_card *card, int irm_id, int generation, |
218 | u32 channels_mask, u64 offset, bool allocate) | 217 | u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) |
219 | { | 218 | { |
220 | __be32 data[2], c, all, old; | 219 | __be32 c, all, old; |
221 | int i, retry = 5; | 220 | int i, retry = 5; |
222 | 221 | ||
223 | old = all = allocate ? cpu_to_be32(~0) : 0; | 222 | old = all = allocate ? cpu_to_be32(~0) : 0; |
@@ -260,7 +259,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, | |||
260 | } | 259 | } |
261 | 260 | ||
262 | static void deallocate_channel(struct fw_card *card, int irm_id, | 261 | static void deallocate_channel(struct fw_card *card, int irm_id, |
263 | int generation, int channel) | 262 | int generation, int channel, __be32 buffer[2]) |
264 | { | 263 | { |
265 | u32 mask; | 264 | u32 mask; |
266 | u64 offset; | 265 | u64 offset; |
@@ -269,7 +268,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, | |||
269 | offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI : | 268 | offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI : |
270 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO; | 269 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO; |
271 | 270 | ||
272 | manage_channel(card, irm_id, generation, mask, offset, false); | 271 | manage_channel(card, irm_id, generation, mask, offset, false, buffer); |
273 | } | 272 | } |
274 | 273 | ||
275 | /** | 274 | /** |
@@ -298,7 +297,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, | |||
298 | */ | 297 | */ |
299 | void fw_iso_resource_manage(struct fw_card *card, int generation, | 298 | void fw_iso_resource_manage(struct fw_card *card, int generation, |
300 | u64 channels_mask, int *channel, int *bandwidth, | 299 | u64 channels_mask, int *channel, int *bandwidth, |
301 | bool allocate) | 300 | bool allocate, __be32 buffer[2]) |
302 | { | 301 | { |
303 | u32 channels_hi = channels_mask; /* channels 31...0 */ | 302 | u32 channels_hi = channels_mask; /* channels 31...0 */ |
304 | u32 channels_lo = channels_mask >> 32; /* channels 63...32 */ | 303 | u32 channels_lo = channels_mask >> 32; /* channels 63...32 */ |
@@ -310,10 +309,12 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, | |||
310 | 309 | ||
311 | if (channels_hi) | 310 | if (channels_hi) |
312 | c = manage_channel(card, irm_id, generation, channels_hi, | 311 | c = manage_channel(card, irm_id, generation, channels_hi, |
313 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate); | 312 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, |
313 | allocate, buffer); | ||
314 | if (channels_lo && c < 0) { | 314 | if (channels_lo && c < 0) { |
315 | c = manage_channel(card, irm_id, generation, channels_lo, | 315 | c = manage_channel(card, irm_id, generation, channels_lo, |
316 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate); | 316 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, |
317 | allocate, buffer); | ||
317 | if (c >= 0) | 318 | if (c >= 0) |
318 | c += 32; | 319 | c += 32; |
319 | } | 320 | } |
@@ -325,12 +326,13 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, | |||
325 | if (*bandwidth == 0) | 326 | if (*bandwidth == 0) |
326 | return; | 327 | return; |
327 | 328 | ||
328 | ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate); | 329 | ret = manage_bandwidth(card, irm_id, generation, *bandwidth, |
330 | allocate, buffer); | ||
329 | if (ret < 0) | 331 | if (ret < 0) |
330 | *bandwidth = 0; | 332 | *bandwidth = 0; |
331 | 333 | ||
332 | if (allocate && ret < 0 && c >= 0) { | 334 | if (allocate && ret < 0 && c >= 0) { |
333 | deallocate_channel(card, irm_id, generation, c); | 335 | deallocate_channel(card, irm_id, generation, c, buffer); |
334 | *channel = ret; | 336 | *channel = ret; |
335 | } | 337 | } |
336 | } | 338 | } |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index c3cfc647e5e3..6052816be353 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -120,7 +120,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event); | |||
120 | 120 | ||
121 | int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma); | 121 | int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma); |
122 | void fw_iso_resource_manage(struct fw_card *card, int generation, | 122 | void fw_iso_resource_manage(struct fw_card *card, int generation, |
123 | u64 channels_mask, int *channel, int *bandwidth, bool allocate); | 123 | u64 channels_mask, int *channel, int *bandwidth, |
124 | bool allocate, __be32 buffer[2]); | ||
124 | 125 | ||
125 | 126 | ||
126 | /* -topology */ | 127 | /* -topology */ |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 24c45635376a..8d51568ee143 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -201,6 +201,12 @@ static struct fw_device *target_device(struct sbp2_target *tgt) | |||
201 | #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ | 201 | #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ |
202 | 202 | ||
203 | /* | 203 | /* |
204 | * There is no transport protocol limit to the CDB length, but we implement | ||
205 | * a fixed length only. 16 bytes is enough for disks larger than 2 TB. | ||
206 | */ | ||
207 | #define SBP2_MAX_CDB_SIZE 16 | ||
208 | |||
209 | /* | ||
204 | * The default maximum s/g segment size of a FireWire controller is | 210 | * The default maximum s/g segment size of a FireWire controller is |
205 | * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to | 211 | * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to |
206 | * be quadlet-aligned, we set the length limit to 0xffff & ~3. | 212 | * be quadlet-aligned, we set the length limit to 0xffff & ~3. |
@@ -312,7 +318,7 @@ struct sbp2_command_orb { | |||
312 | struct sbp2_pointer next; | 318 | struct sbp2_pointer next; |
313 | struct sbp2_pointer data_descriptor; | 319 | struct sbp2_pointer data_descriptor; |
314 | __be32 misc; | 320 | __be32 misc; |
315 | u8 command_block[12]; | 321 | u8 command_block[SBP2_MAX_CDB_SIZE]; |
316 | } request; | 322 | } request; |
317 | struct scsi_cmnd *cmd; | 323 | struct scsi_cmnd *cmd; |
318 | scsi_done_fn_t done; | 324 | scsi_done_fn_t done; |
@@ -1146,6 +1152,8 @@ static int sbp2_probe(struct device *dev) | |||
1146 | if (fw_device_enable_phys_dma(device) < 0) | 1152 | if (fw_device_enable_phys_dma(device) < 0) |
1147 | goto fail_shost_put; | 1153 | goto fail_shost_put; |
1148 | 1154 | ||
1155 | shost->max_cmd_len = SBP2_MAX_CDB_SIZE; | ||
1156 | |||
1149 | if (scsi_add_host(shost, &unit->device) < 0) | 1157 | if (scsi_add_host(shost, &unit->device) < 0) |
1150 | goto fail_shost_put; | 1158 | goto fail_shost_put; |
1151 | 1159 | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3582c39f9725..96dda81c9228 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -79,6 +79,12 @@ config GPIO_XILINX | |||
79 | help | 79 | help |
80 | Say yes here to support the Xilinx FPGA GPIO device | 80 | Say yes here to support the Xilinx FPGA GPIO device |
81 | 81 | ||
82 | config GPIO_VR41XX | ||
83 | tristate "NEC VR4100 series General-purpose I/O Uint support" | ||
84 | depends on CPU_VR41XX | ||
85 | help | ||
86 | Say yes here to support the NEC VR4100 series General-purpose I/O Uint | ||
87 | |||
82 | comment "I2C GPIO expanders:" | 88 | comment "I2C GPIO expanders:" |
83 | 89 | ||
84 | config GPIO_MAX732X | 90 | config GPIO_MAX732X |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ef90203e8f3c..9244c6fcd8be 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -13,3 +13,4 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o | |||
13 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o | 13 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o |
14 | obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o | 14 | obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o |
15 | obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o | 15 | obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o |
16 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o | ||
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c index aa8e7cb020d9..4ee4c8367a3f 100644 --- a/drivers/gpio/pl061.c +++ b/drivers/gpio/pl061.c | |||
@@ -109,6 +109,16 @@ static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) | |||
109 | writeb(!!value << offset, chip->base + (1 << (offset + 2))); | 109 | writeb(!!value << offset, chip->base + (1 << (offset + 2))); |
110 | } | 110 | } |
111 | 111 | ||
112 | static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) | ||
113 | { | ||
114 | struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); | ||
115 | |||
116 | if (chip->irq_base == (unsigned) -1) | ||
117 | return -EINVAL; | ||
118 | |||
119 | return chip->irq_base + offset; | ||
120 | } | ||
121 | |||
112 | /* | 122 | /* |
113 | * PL061 GPIO IRQ | 123 | * PL061 GPIO IRQ |
114 | */ | 124 | */ |
@@ -200,7 +210,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) | |||
200 | desc->chip->ack(irq); | 210 | desc->chip->ack(irq); |
201 | list_for_each(ptr, chip_list) { | 211 | list_for_each(ptr, chip_list) { |
202 | unsigned long pending; | 212 | unsigned long pending; |
203 | int gpio; | 213 | int offset; |
204 | 214 | ||
205 | chip = list_entry(ptr, struct pl061_gpio, list); | 215 | chip = list_entry(ptr, struct pl061_gpio, list); |
206 | pending = readb(chip->base + GPIOMIS); | 216 | pending = readb(chip->base + GPIOMIS); |
@@ -209,8 +219,8 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) | |||
209 | if (pending == 0) | 219 | if (pending == 0) |
210 | continue; | 220 | continue; |
211 | 221 | ||
212 | for_each_bit(gpio, &pending, PL061_GPIO_NR) | 222 | for_each_bit(offset, &pending, PL061_GPIO_NR) |
213 | generic_handle_irq(gpio_to_irq(gpio)); | 223 | generic_handle_irq(pl061_to_irq(&chip->gc, offset)); |
214 | } | 224 | } |
215 | desc->chip->unmask(irq); | 225 | desc->chip->unmask(irq); |
216 | } | 226 | } |
@@ -221,7 +231,7 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) | |||
221 | struct pl061_gpio *chip; | 231 | struct pl061_gpio *chip; |
222 | struct list_head *chip_list; | 232 | struct list_head *chip_list; |
223 | int ret, irq, i; | 233 | int ret, irq, i; |
224 | static unsigned long init_irq[BITS_TO_LONGS(NR_IRQS)]; | 234 | static DECLARE_BITMAP(init_irq, NR_IRQS); |
225 | 235 | ||
226 | pdata = dev->dev.platform_data; | 236 | pdata = dev->dev.platform_data; |
227 | if (pdata == NULL) | 237 | if (pdata == NULL) |
@@ -251,6 +261,7 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) | |||
251 | chip->gc.direction_output = pl061_direction_output; | 261 | chip->gc.direction_output = pl061_direction_output; |
252 | chip->gc.get = pl061_get_value; | 262 | chip->gc.get = pl061_get_value; |
253 | chip->gc.set = pl061_set_value; | 263 | chip->gc.set = pl061_set_value; |
264 | chip->gc.to_irq = pl061_to_irq; | ||
254 | chip->gc.base = pdata->gpio_base; | 265 | chip->gc.base = pdata->gpio_base; |
255 | chip->gc.ngpio = PL061_GPIO_NR; | 266 | chip->gc.ngpio = PL061_GPIO_NR; |
256 | chip->gc.label = dev_name(&dev->dev); | 267 | chip->gc.label = dev_name(&dev->dev); |
@@ -280,6 +291,7 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) | |||
280 | if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */ | 291 | if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */ |
281 | chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL); | 292 | chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL); |
282 | if (chip_list == NULL) { | 293 | if (chip_list == NULL) { |
294 | clear_bit(irq, init_irq); | ||
283 | ret = -ENOMEM; | 295 | ret = -ENOMEM; |
284 | goto iounmap; | 296 | goto iounmap; |
285 | } | 297 | } |
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/vr41xx_giu.c new file mode 100644 index 000000000000..b70e06133e78 --- /dev/null +++ b/drivers/gpio/vr41xx_giu.c | |||
@@ -0,0 +1,586 @@ | |||
1 | /* | ||
2 | * Driver for NEC VR4100 series General-purpose I/O Unit. | ||
3 | * | ||
4 | * Copyright (C) 2002 MontaVista Software Inc. | ||
5 | * Author: Yoichi Yuasa <source@mvista.com> | ||
6 | * Copyright (C) 2003-2009 Yoichi Yuasa <yuasa@linux-mips.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/gpio.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/spinlock.h> | ||
34 | #include <linux/types.h> | ||
35 | |||
36 | #include <asm/vr41xx/giu.h> | ||
37 | #include <asm/vr41xx/irq.h> | ||
38 | #include <asm/vr41xx/vr41xx.h> | ||
39 | |||
40 | MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); | ||
41 | MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); | ||
42 | MODULE_LICENSE("GPL"); | ||
43 | |||
44 | #define GIUIOSELL 0x00 | ||
45 | #define GIUIOSELH 0x02 | ||
46 | #define GIUPIODL 0x04 | ||
47 | #define GIUPIODH 0x06 | ||
48 | #define GIUINTSTATL 0x08 | ||
49 | #define GIUINTSTATH 0x0a | ||
50 | #define GIUINTENL 0x0c | ||
51 | #define GIUINTENH 0x0e | ||
52 | #define GIUINTTYPL 0x10 | ||
53 | #define GIUINTTYPH 0x12 | ||
54 | #define GIUINTALSELL 0x14 | ||
55 | #define GIUINTALSELH 0x16 | ||
56 | #define GIUINTHTSELL 0x18 | ||
57 | #define GIUINTHTSELH 0x1a | ||
58 | #define GIUPODATL 0x1c | ||
59 | #define GIUPODATEN 0x1c | ||
60 | #define GIUPODATH 0x1e | ||
61 | #define PIOEN0 0x0100 | ||
62 | #define PIOEN1 0x0200 | ||
63 | #define GIUPODAT 0x1e | ||
64 | #define GIUFEDGEINHL 0x20 | ||
65 | #define GIUFEDGEINHH 0x22 | ||
66 | #define GIUREDGEINHL 0x24 | ||
67 | #define GIUREDGEINHH 0x26 | ||
68 | |||
69 | #define GIUUSEUPDN 0x1e0 | ||
70 | #define GIUTERMUPDN 0x1e2 | ||
71 | |||
72 | #define GPIO_HAS_PULLUPDOWN_IO 0x0001 | ||
73 | #define GPIO_HAS_OUTPUT_ENABLE 0x0002 | ||
74 | #define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 | ||
75 | |||
76 | enum { | ||
77 | GPIO_INPUT, | ||
78 | GPIO_OUTPUT, | ||
79 | }; | ||
80 | |||
81 | static DEFINE_SPINLOCK(giu_lock); | ||
82 | static unsigned long giu_flags; | ||
83 | |||
84 | static void __iomem *giu_base; | ||
85 | |||
86 | #define giu_read(offset) readw(giu_base + (offset)) | ||
87 | #define giu_write(offset, value) writew((value), giu_base + (offset)) | ||
88 | |||
89 | #define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) | ||
90 | #define GIUINT_HIGH_OFFSET 16 | ||
91 | #define GIUINT_HIGH_MAX 32 | ||
92 | |||
93 | static inline u16 giu_set(u16 offset, u16 set) | ||
94 | { | ||
95 | u16 data; | ||
96 | |||
97 | data = giu_read(offset); | ||
98 | data |= set; | ||
99 | giu_write(offset, data); | ||
100 | |||
101 | return data; | ||
102 | } | ||
103 | |||
104 | static inline u16 giu_clear(u16 offset, u16 clear) | ||
105 | { | ||
106 | u16 data; | ||
107 | |||
108 | data = giu_read(offset); | ||
109 | data &= ~clear; | ||
110 | giu_write(offset, data); | ||
111 | |||
112 | return data; | ||
113 | } | ||
114 | |||
115 | static void ack_giuint_low(unsigned int irq) | ||
116 | { | ||
117 | giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); | ||
118 | } | ||
119 | |||
120 | static void mask_giuint_low(unsigned int irq) | ||
121 | { | ||
122 | giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); | ||
123 | } | ||
124 | |||
125 | static void mask_ack_giuint_low(unsigned int irq) | ||
126 | { | ||
127 | unsigned int pin; | ||
128 | |||
129 | pin = GPIO_PIN_OF_IRQ(irq); | ||
130 | giu_clear(GIUINTENL, 1 << pin); | ||
131 | giu_write(GIUINTSTATL, 1 << pin); | ||
132 | } | ||
133 | |||
134 | static void unmask_giuint_low(unsigned int irq) | ||
135 | { | ||
136 | giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); | ||
137 | } | ||
138 | |||
139 | static struct irq_chip giuint_low_irq_chip = { | ||
140 | .name = "GIUINTL", | ||
141 | .ack = ack_giuint_low, | ||
142 | .mask = mask_giuint_low, | ||
143 | .mask_ack = mask_ack_giuint_low, | ||
144 | .unmask = unmask_giuint_low, | ||
145 | }; | ||
146 | |||
147 | static void ack_giuint_high(unsigned int irq) | ||
148 | { | ||
149 | giu_write(GIUINTSTATH, | ||
150 | 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | ||
151 | } | ||
152 | |||
153 | static void mask_giuint_high(unsigned int irq) | ||
154 | { | ||
155 | giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | ||
156 | } | ||
157 | |||
158 | static void mask_ack_giuint_high(unsigned int irq) | ||
159 | { | ||
160 | unsigned int pin; | ||
161 | |||
162 | pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; | ||
163 | giu_clear(GIUINTENH, 1 << pin); | ||
164 | giu_write(GIUINTSTATH, 1 << pin); | ||
165 | } | ||
166 | |||
167 | static void unmask_giuint_high(unsigned int irq) | ||
168 | { | ||
169 | giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | ||
170 | } | ||
171 | |||
172 | static struct irq_chip giuint_high_irq_chip = { | ||
173 | .name = "GIUINTH", | ||
174 | .ack = ack_giuint_high, | ||
175 | .mask = mask_giuint_high, | ||
176 | .mask_ack = mask_ack_giuint_high, | ||
177 | .unmask = unmask_giuint_high, | ||
178 | }; | ||
179 | |||
180 | static int giu_get_irq(unsigned int irq) | ||
181 | { | ||
182 | u16 pendl, pendh, maskl, maskh; | ||
183 | int i; | ||
184 | |||
185 | pendl = giu_read(GIUINTSTATL); | ||
186 | pendh = giu_read(GIUINTSTATH); | ||
187 | maskl = giu_read(GIUINTENL); | ||
188 | maskh = giu_read(GIUINTENH); | ||
189 | |||
190 | maskl &= pendl; | ||
191 | maskh &= pendh; | ||
192 | |||
193 | if (maskl) { | ||
194 | for (i = 0; i < 16; i++) { | ||
195 | if (maskl & (1 << i)) | ||
196 | return GIU_IRQ(i); | ||
197 | } | ||
198 | } else if (maskh) { | ||
199 | for (i = 0; i < 16; i++) { | ||
200 | if (maskh & (1 << i)) | ||
201 | return GIU_IRQ(i + GIUINT_HIGH_OFFSET); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", | ||
206 | maskl, pendl, maskh, pendh); | ||
207 | |||
208 | atomic_inc(&irq_err_count); | ||
209 | |||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, | ||
214 | irq_signal_t signal) | ||
215 | { | ||
216 | u16 mask; | ||
217 | |||
218 | if (pin < GIUINT_HIGH_OFFSET) { | ||
219 | mask = 1 << pin; | ||
220 | if (trigger != IRQ_TRIGGER_LEVEL) { | ||
221 | giu_set(GIUINTTYPL, mask); | ||
222 | if (signal == IRQ_SIGNAL_HOLD) | ||
223 | giu_set(GIUINTHTSELL, mask); | ||
224 | else | ||
225 | giu_clear(GIUINTHTSELL, mask); | ||
226 | if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { | ||
227 | switch (trigger) { | ||
228 | case IRQ_TRIGGER_EDGE_FALLING: | ||
229 | giu_set(GIUFEDGEINHL, mask); | ||
230 | giu_clear(GIUREDGEINHL, mask); | ||
231 | break; | ||
232 | case IRQ_TRIGGER_EDGE_RISING: | ||
233 | giu_clear(GIUFEDGEINHL, mask); | ||
234 | giu_set(GIUREDGEINHL, mask); | ||
235 | break; | ||
236 | default: | ||
237 | giu_set(GIUFEDGEINHL, mask); | ||
238 | giu_set(GIUREDGEINHL, mask); | ||
239 | break; | ||
240 | } | ||
241 | } | ||
242 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
243 | &giuint_low_irq_chip, | ||
244 | handle_edge_irq); | ||
245 | } else { | ||
246 | giu_clear(GIUINTTYPL, mask); | ||
247 | giu_clear(GIUINTHTSELL, mask); | ||
248 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
249 | &giuint_low_irq_chip, | ||
250 | handle_level_irq); | ||
251 | } | ||
252 | giu_write(GIUINTSTATL, mask); | ||
253 | } else if (pin < GIUINT_HIGH_MAX) { | ||
254 | mask = 1 << (pin - GIUINT_HIGH_OFFSET); | ||
255 | if (trigger != IRQ_TRIGGER_LEVEL) { | ||
256 | giu_set(GIUINTTYPH, mask); | ||
257 | if (signal == IRQ_SIGNAL_HOLD) | ||
258 | giu_set(GIUINTHTSELH, mask); | ||
259 | else | ||
260 | giu_clear(GIUINTHTSELH, mask); | ||
261 | if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { | ||
262 | switch (trigger) { | ||
263 | case IRQ_TRIGGER_EDGE_FALLING: | ||
264 | giu_set(GIUFEDGEINHH, mask); | ||
265 | giu_clear(GIUREDGEINHH, mask); | ||
266 | break; | ||
267 | case IRQ_TRIGGER_EDGE_RISING: | ||
268 | giu_clear(GIUFEDGEINHH, mask); | ||
269 | giu_set(GIUREDGEINHH, mask); | ||
270 | break; | ||
271 | default: | ||
272 | giu_set(GIUFEDGEINHH, mask); | ||
273 | giu_set(GIUREDGEINHH, mask); | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
278 | &giuint_high_irq_chip, | ||
279 | handle_edge_irq); | ||
280 | } else { | ||
281 | giu_clear(GIUINTTYPH, mask); | ||
282 | giu_clear(GIUINTHTSELH, mask); | ||
283 | set_irq_chip_and_handler(GIU_IRQ(pin), | ||
284 | &giuint_high_irq_chip, | ||
285 | handle_level_irq); | ||
286 | } | ||
287 | giu_write(GIUINTSTATH, mask); | ||
288 | } | ||
289 | } | ||
290 | EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); | ||
291 | |||
292 | void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) | ||
293 | { | ||
294 | u16 mask; | ||
295 | |||
296 | if (pin < GIUINT_HIGH_OFFSET) { | ||
297 | mask = 1 << pin; | ||
298 | if (level == IRQ_LEVEL_HIGH) | ||
299 | giu_set(GIUINTALSELL, mask); | ||
300 | else | ||
301 | giu_clear(GIUINTALSELL, mask); | ||
302 | giu_write(GIUINTSTATL, mask); | ||
303 | } else if (pin < GIUINT_HIGH_MAX) { | ||
304 | mask = 1 << (pin - GIUINT_HIGH_OFFSET); | ||
305 | if (level == IRQ_LEVEL_HIGH) | ||
306 | giu_set(GIUINTALSELH, mask); | ||
307 | else | ||
308 | giu_clear(GIUINTALSELH, mask); | ||
309 | giu_write(GIUINTSTATH, mask); | ||
310 | } | ||
311 | } | ||
312 | EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); | ||
313 | |||
314 | static int giu_set_direction(struct gpio_chip *chip, unsigned pin, int dir) | ||
315 | { | ||
316 | u16 offset, mask, reg; | ||
317 | unsigned long flags; | ||
318 | |||
319 | if (pin >= chip->ngpio) | ||
320 | return -EINVAL; | ||
321 | |||
322 | if (pin < 16) { | ||
323 | offset = GIUIOSELL; | ||
324 | mask = 1 << pin; | ||
325 | } else if (pin < 32) { | ||
326 | offset = GIUIOSELH; | ||
327 | mask = 1 << (pin - 16); | ||
328 | } else { | ||
329 | if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { | ||
330 | offset = GIUPODATEN; | ||
331 | mask = 1 << (pin - 32); | ||
332 | } else { | ||
333 | switch (pin) { | ||
334 | case 48: | ||
335 | offset = GIUPODATH; | ||
336 | mask = PIOEN0; | ||
337 | break; | ||
338 | case 49: | ||
339 | offset = GIUPODATH; | ||
340 | mask = PIOEN1; | ||
341 | break; | ||
342 | default: | ||
343 | return -EINVAL; | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | |||
348 | spin_lock_irqsave(&giu_lock, flags); | ||
349 | |||
350 | reg = giu_read(offset); | ||
351 | if (dir == GPIO_OUTPUT) | ||
352 | reg |= mask; | ||
353 | else | ||
354 | reg &= ~mask; | ||
355 | giu_write(offset, reg); | ||
356 | |||
357 | spin_unlock_irqrestore(&giu_lock, flags); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) | ||
363 | { | ||
364 | u16 reg, mask; | ||
365 | unsigned long flags; | ||
366 | |||
367 | if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) | ||
368 | return -EPERM; | ||
369 | |||
370 | if (pin >= 15) | ||
371 | return -EINVAL; | ||
372 | |||
373 | mask = 1 << pin; | ||
374 | |||
375 | spin_lock_irqsave(&giu_lock, flags); | ||
376 | |||
377 | if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { | ||
378 | reg = giu_read(GIUTERMUPDN); | ||
379 | if (pull == GPIO_PULL_UP) | ||
380 | reg |= mask; | ||
381 | else | ||
382 | reg &= ~mask; | ||
383 | giu_write(GIUTERMUPDN, reg); | ||
384 | |||
385 | reg = giu_read(GIUUSEUPDN); | ||
386 | reg |= mask; | ||
387 | giu_write(GIUUSEUPDN, reg); | ||
388 | } else { | ||
389 | reg = giu_read(GIUUSEUPDN); | ||
390 | reg &= ~mask; | ||
391 | giu_write(GIUUSEUPDN, reg); | ||
392 | } | ||
393 | |||
394 | spin_unlock_irqrestore(&giu_lock, flags); | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); | ||
399 | |||
400 | static int vr41xx_gpio_get(struct gpio_chip *chip, unsigned pin) | ||
401 | { | ||
402 | u16 reg, mask; | ||
403 | |||
404 | if (pin >= chip->ngpio) | ||
405 | return -EINVAL; | ||
406 | |||
407 | if (pin < 16) { | ||
408 | reg = giu_read(GIUPIODL); | ||
409 | mask = 1 << pin; | ||
410 | } else if (pin < 32) { | ||
411 | reg = giu_read(GIUPIODH); | ||
412 | mask = 1 << (pin - 16); | ||
413 | } else if (pin < 48) { | ||
414 | reg = giu_read(GIUPODATL); | ||
415 | mask = 1 << (pin - 32); | ||
416 | } else { | ||
417 | reg = giu_read(GIUPODATH); | ||
418 | mask = 1 << (pin - 48); | ||
419 | } | ||
420 | |||
421 | if (reg & mask) | ||
422 | return 1; | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static void vr41xx_gpio_set(struct gpio_chip *chip, unsigned pin, | ||
428 | int value) | ||
429 | { | ||
430 | u16 offset, mask, reg; | ||
431 | unsigned long flags; | ||
432 | |||
433 | if (pin >= chip->ngpio) | ||
434 | return; | ||
435 | |||
436 | if (pin < 16) { | ||
437 | offset = GIUPIODL; | ||
438 | mask = 1 << pin; | ||
439 | } else if (pin < 32) { | ||
440 | offset = GIUPIODH; | ||
441 | mask = 1 << (pin - 16); | ||
442 | } else if (pin < 48) { | ||
443 | offset = GIUPODATL; | ||
444 | mask = 1 << (pin - 32); | ||
445 | } else { | ||
446 | offset = GIUPODATH; | ||
447 | mask = 1 << (pin - 48); | ||
448 | } | ||
449 | |||
450 | spin_lock_irqsave(&giu_lock, flags); | ||
451 | |||
452 | reg = giu_read(offset); | ||
453 | if (value) | ||
454 | reg |= mask; | ||
455 | else | ||
456 | reg &= ~mask; | ||
457 | giu_write(offset, reg); | ||
458 | |||
459 | spin_unlock_irqrestore(&giu_lock, flags); | ||
460 | } | ||
461 | |||
462 | |||
463 | static int vr41xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
464 | { | ||
465 | return giu_set_direction(chip, offset, GPIO_INPUT); | ||
466 | } | ||
467 | |||
468 | static int vr41xx_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
469 | int value) | ||
470 | { | ||
471 | vr41xx_gpio_set(chip, offset, value); | ||
472 | |||
473 | return giu_set_direction(chip, offset, GPIO_OUTPUT); | ||
474 | } | ||
475 | |||
476 | static int vr41xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
477 | { | ||
478 | if (offset >= chip->ngpio) | ||
479 | return -EINVAL; | ||
480 | |||
481 | return GIU_IRQ_BASE + offset; | ||
482 | } | ||
483 | |||
484 | static struct gpio_chip vr41xx_gpio_chip = { | ||
485 | .label = "vr41xx", | ||
486 | .owner = THIS_MODULE, | ||
487 | .direction_input = vr41xx_gpio_direction_input, | ||
488 | .get = vr41xx_gpio_get, | ||
489 | .direction_output = vr41xx_gpio_direction_output, | ||
490 | .set = vr41xx_gpio_set, | ||
491 | .to_irq = vr41xx_gpio_to_irq, | ||
492 | }; | ||
493 | |||
494 | static int __devinit giu_probe(struct platform_device *pdev) | ||
495 | { | ||
496 | struct resource *res; | ||
497 | unsigned int trigger, i, pin; | ||
498 | struct irq_chip *chip; | ||
499 | int irq, retval; | ||
500 | |||
501 | switch (pdev->id) { | ||
502 | case GPIO_50PINS_PULLUPDOWN: | ||
503 | giu_flags = GPIO_HAS_PULLUPDOWN_IO; | ||
504 | vr41xx_gpio_chip.ngpio = 50; | ||
505 | break; | ||
506 | case GPIO_36PINS: | ||
507 | vr41xx_gpio_chip.ngpio = 36; | ||
508 | break; | ||
509 | case GPIO_48PINS_EDGE_SELECT: | ||
510 | giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; | ||
511 | vr41xx_gpio_chip.ngpio = 48; | ||
512 | break; | ||
513 | default: | ||
514 | dev_err(&pdev->dev, "GIU: unknown ID %d\n", pdev->id); | ||
515 | return -ENODEV; | ||
516 | } | ||
517 | |||
518 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
519 | if (!res) | ||
520 | return -EBUSY; | ||
521 | |||
522 | giu_base = ioremap(res->start, res->end - res->start + 1); | ||
523 | if (!giu_base) | ||
524 | return -ENOMEM; | ||
525 | |||
526 | vr41xx_gpio_chip.dev = &pdev->dev; | ||
527 | |||
528 | retval = gpiochip_add(&vr41xx_gpio_chip); | ||
529 | |||
530 | giu_write(GIUINTENL, 0); | ||
531 | giu_write(GIUINTENH, 0); | ||
532 | |||
533 | trigger = giu_read(GIUINTTYPH) << 16; | ||
534 | trigger |= giu_read(GIUINTTYPL); | ||
535 | for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { | ||
536 | pin = GPIO_PIN_OF_IRQ(i); | ||
537 | if (pin < GIUINT_HIGH_OFFSET) | ||
538 | chip = &giuint_low_irq_chip; | ||
539 | else | ||
540 | chip = &giuint_high_irq_chip; | ||
541 | |||
542 | if (trigger & (1 << pin)) | ||
543 | set_irq_chip_and_handler(i, chip, handle_edge_irq); | ||
544 | else | ||
545 | set_irq_chip_and_handler(i, chip, handle_level_irq); | ||
546 | |||
547 | } | ||
548 | |||
549 | irq = platform_get_irq(pdev, 0); | ||
550 | if (irq < 0 || irq >= nr_irqs) | ||
551 | return -EBUSY; | ||
552 | |||
553 | return cascade_irq(irq, giu_get_irq); | ||
554 | } | ||
555 | |||
556 | static int __devexit giu_remove(struct platform_device *pdev) | ||
557 | { | ||
558 | if (giu_base) { | ||
559 | iounmap(giu_base); | ||
560 | giu_base = NULL; | ||
561 | } | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static struct platform_driver giu_device_driver = { | ||
567 | .probe = giu_probe, | ||
568 | .remove = __devexit_p(giu_remove), | ||
569 | .driver = { | ||
570 | .name = "GIU", | ||
571 | .owner = THIS_MODULE, | ||
572 | }, | ||
573 | }; | ||
574 | |||
575 | static int __init vr41xx_giu_init(void) | ||
576 | { | ||
577 | return platform_driver_register(&giu_device_driver); | ||
578 | } | ||
579 | |||
580 | static void __exit vr41xx_giu_exit(void) | ||
581 | { | ||
582 | platform_driver_unregister(&giu_device_driver); | ||
583 | } | ||
584 | |||
585 | module_init(vr41xx_giu_init); | ||
586 | module_exit(vr41xx_giu_exit); | ||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index c961fe415aef..39b393d38bb3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -81,6 +81,7 @@ config DRM_I830 | |||
81 | 81 | ||
82 | config DRM_I915 | 82 | config DRM_I915 |
83 | tristate "i915 driver" | 83 | tristate "i915 driver" |
84 | depends on AGP_INTEL | ||
84 | select FB_CFB_FILLRECT | 85 | select FB_CFB_FILLRECT |
85 | select FB_CFB_COPYAREA | 86 | select FB_CFB_COPYAREA |
86 | select FB_CFB_IMAGEBLIT | 87 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4e89ab08b7b8..fe23f29f7cba 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -16,6 +16,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ | |||
16 | drm-$(CONFIG_COMPAT) += drm_ioc32.o | 16 | drm-$(CONFIG_COMPAT) += drm_ioc32.o |
17 | 17 | ||
18 | obj-$(CONFIG_DRM) += drm.o | 18 | obj-$(CONFIG_DRM) += drm.o |
19 | obj-$(CONFIG_DRM_TTM) += ttm/ | ||
19 | obj-$(CONFIG_DRM_TDFX) += tdfx/ | 20 | obj-$(CONFIG_DRM_TDFX) += tdfx/ |
20 | obj-$(CONFIG_DRM_R128) += r128/ | 21 | obj-$(CONFIG_DRM_R128) += r128/ |
21 | obj-$(CONFIG_DRM_RADEON)+= radeon/ | 22 | obj-$(CONFIG_DRM_RADEON)+= radeon/ |
@@ -26,4 +27,3 @@ obj-$(CONFIG_DRM_I915) += i915/ | |||
26 | obj-$(CONFIG_DRM_SIS) += sis/ | 27 | obj-$(CONFIG_DRM_SIS) += sis/ |
27 | obj-$(CONFIG_DRM_SAVAGE)+= savage/ | 28 | obj-$(CONFIG_DRM_SAVAGE)+= savage/ |
28 | obj-$(CONFIG_DRM_VIA) +=via/ | 29 | obj-$(CONFIG_DRM_VIA) +=via/ |
29 | obj-$(CONFIG_DRM_TTM) += ttm/ | ||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a6f73f1e99d9..3da9cfa31848 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -1090,6 +1090,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev) | |||
1090 | if (ret == false) | 1090 | if (ret == false) |
1091 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); | 1091 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); |
1092 | } | 1092 | } |
1093 | /* disable the unused connectors while restoring the modesetting */ | ||
1094 | drm_helper_disable_unused_functions(dev); | ||
1093 | return 0; | 1095 | return 0; |
1094 | } | 1096 | } |
1095 | EXPORT_SYMBOL(drm_helper_resume_force_mode); | 1097 | EXPORT_SYMBOL(drm_helper_resume_force_mode); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 7d0835226f6e..80cc6d06d61b 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -294,10 +294,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
294 | unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; | 294 | unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; |
295 | unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; | 295 | unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; |
296 | unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; | 296 | unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; |
297 | unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 8 | pt->hsync_offset_lo; | 297 | unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; |
298 | unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 6 | pt->hsync_pulse_width_lo; | 298 | unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; |
299 | unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) | (pt->vsync_offset_pulse_width_lo & 0xf); | 299 | unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; |
300 | unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; | 300 | unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); |
301 | 301 | ||
302 | /* ignore tiny modes */ | 302 | /* ignore tiny modes */ |
303 | if (hactive < 64 || vactive < 64) | 303 | if (hactive < 64 || vactive < 64) |
@@ -347,8 +347,8 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
347 | mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? | 347 | mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? |
348 | DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; | 348 | DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; |
349 | 349 | ||
350 | mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; | 350 | mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; |
351 | mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; | 351 | mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; |
352 | 352 | ||
353 | if (quirks & EDID_QUIRK_DETAILED_IN_CM) { | 353 | if (quirks & EDID_QUIRK_DETAILED_IN_CM) { |
354 | mode->width_mm *= 10; | 354 | mode->width_mm *= 10; |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 51c5a050aa73..30d6b99fb302 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -13,6 +13,8 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
13 | intel_crt.o \ | 13 | intel_crt.o \ |
14 | intel_lvds.o \ | 14 | intel_lvds.o \ |
15 | intel_bios.o \ | 15 | intel_bios.o \ |
16 | intel_dp.o \ | ||
17 | intel_dp_i2c.o \ | ||
16 | intel_hdmi.o \ | 18 | intel_hdmi.o \ |
17 | intel_sdvo.o \ | 19 | intel_sdvo.o \ |
18 | intel_modes.o \ | 20 | intel_modes.o \ |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index e747ac42fe3a..288fc50627e2 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -37,7 +37,7 @@ struct intel_dvo_device { | |||
37 | /* GPIO register used for i2c bus to control this device */ | 37 | /* GPIO register used for i2c bus to control this device */ |
38 | u32 gpio; | 38 | u32 gpio; |
39 | int slave_addr; | 39 | int slave_addr; |
40 | struct intel_i2c_chan *i2c_bus; | 40 | struct i2c_adapter *i2c_bus; |
41 | 41 | ||
42 | const struct intel_dvo_dev_ops *dev_ops; | 42 | const struct intel_dvo_dev_ops *dev_ops; |
43 | void *dev_priv; | 43 | void *dev_priv; |
@@ -52,7 +52,7 @@ struct intel_dvo_dev_ops { | |||
52 | * Returns NULL if the device does not exist. | 52 | * Returns NULL if the device does not exist. |
53 | */ | 53 | */ |
54 | bool (*init)(struct intel_dvo_device *dvo, | 54 | bool (*init)(struct intel_dvo_device *dvo, |
55 | struct intel_i2c_chan *i2cbus); | 55 | struct i2c_adapter *i2cbus); |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * Called to allow the output a chance to create properties after the | 58 | * Called to allow the output a chance to create properties after the |
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index 03d4b4973b02..621815b531db 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -176,19 +176,20 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode); | |||
176 | 176 | ||
177 | static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) | 177 | static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) |
178 | { | 178 | { |
179 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 179 | struct i2c_adapter *adapter = dvo->i2c_bus; |
180 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
180 | u8 out_buf[2]; | 181 | u8 out_buf[2]; |
181 | u8 in_buf[2]; | 182 | u8 in_buf[2]; |
182 | 183 | ||
183 | struct i2c_msg msgs[] = { | 184 | struct i2c_msg msgs[] = { |
184 | { | 185 | { |
185 | .addr = i2cbus->slave_addr, | 186 | .addr = dvo->slave_addr, |
186 | .flags = 0, | 187 | .flags = 0, |
187 | .len = 1, | 188 | .len = 1, |
188 | .buf = out_buf, | 189 | .buf = out_buf, |
189 | }, | 190 | }, |
190 | { | 191 | { |
191 | .addr = i2cbus->slave_addr, | 192 | .addr = dvo->slave_addr, |
192 | .flags = I2C_M_RD, | 193 | .flags = I2C_M_RD, |
193 | .len = 1, | 194 | .len = 1, |
194 | .buf = in_buf, | 195 | .buf = in_buf, |
@@ -208,10 +209,11 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) | |||
208 | 209 | ||
209 | static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) | 210 | static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) |
210 | { | 211 | { |
211 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 212 | struct i2c_adapter *adapter = dvo->i2c_bus; |
213 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
212 | uint8_t out_buf[2]; | 214 | uint8_t out_buf[2]; |
213 | struct i2c_msg msg = { | 215 | struct i2c_msg msg = { |
214 | .addr = i2cbus->slave_addr, | 216 | .addr = dvo->slave_addr, |
215 | .flags = 0, | 217 | .flags = 0, |
216 | .len = 2, | 218 | .len = 2, |
217 | .buf = out_buf, | 219 | .buf = out_buf, |
@@ -228,8 +230,9 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) | |||
228 | 230 | ||
229 | /** Probes for a CH7017 on the given bus and slave address. */ | 231 | /** Probes for a CH7017 on the given bus and slave address. */ |
230 | static bool ch7017_init(struct intel_dvo_device *dvo, | 232 | static bool ch7017_init(struct intel_dvo_device *dvo, |
231 | struct intel_i2c_chan *i2cbus) | 233 | struct i2c_adapter *adapter) |
232 | { | 234 | { |
235 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
233 | struct ch7017_priv *priv; | 236 | struct ch7017_priv *priv; |
234 | uint8_t val; | 237 | uint8_t val; |
235 | 238 | ||
@@ -237,8 +240,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, | |||
237 | if (priv == NULL) | 240 | if (priv == NULL) |
238 | return false; | 241 | return false; |
239 | 242 | ||
240 | dvo->i2c_bus = i2cbus; | 243 | dvo->i2c_bus = adapter; |
241 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
242 | dvo->dev_priv = priv; | 244 | dvo->dev_priv = priv; |
243 | 245 | ||
244 | if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) | 246 | if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) |
@@ -248,7 +250,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, | |||
248 | val != CH7018_DEVICE_ID_VALUE && | 250 | val != CH7018_DEVICE_ID_VALUE && |
249 | val != CH7019_DEVICE_ID_VALUE) { | 251 | val != CH7019_DEVICE_ID_VALUE) { |
250 | DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n", | 252 | DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n", |
251 | val, i2cbus->adapter.name,i2cbus->slave_addr); | 253 | val, i2cbus->adapter.name,dvo->slave_addr); |
252 | goto fail; | 254 | goto fail; |
253 | } | 255 | } |
254 | 256 | ||
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index d2fd95dbd034..a9b896289680 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
@@ -123,19 +123,20 @@ static char *ch7xxx_get_id(uint8_t vid) | |||
123 | static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | 123 | static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) |
124 | { | 124 | { |
125 | struct ch7xxx_priv *ch7xxx= dvo->dev_priv; | 125 | struct ch7xxx_priv *ch7xxx= dvo->dev_priv; |
126 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 126 | struct i2c_adapter *adapter = dvo->i2c_bus; |
127 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
127 | u8 out_buf[2]; | 128 | u8 out_buf[2]; |
128 | u8 in_buf[2]; | 129 | u8 in_buf[2]; |
129 | 130 | ||
130 | struct i2c_msg msgs[] = { | 131 | struct i2c_msg msgs[] = { |
131 | { | 132 | { |
132 | .addr = i2cbus->slave_addr, | 133 | .addr = dvo->slave_addr, |
133 | .flags = 0, | 134 | .flags = 0, |
134 | .len = 1, | 135 | .len = 1, |
135 | .buf = out_buf, | 136 | .buf = out_buf, |
136 | }, | 137 | }, |
137 | { | 138 | { |
138 | .addr = i2cbus->slave_addr, | 139 | .addr = dvo->slave_addr, |
139 | .flags = I2C_M_RD, | 140 | .flags = I2C_M_RD, |
140 | .len = 1, | 141 | .len = 1, |
141 | .buf = in_buf, | 142 | .buf = in_buf, |
@@ -152,7 +153,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
152 | 153 | ||
153 | if (!ch7xxx->quiet) { | 154 | if (!ch7xxx->quiet) { |
154 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 155 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
155 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 156 | addr, i2cbus->adapter.name, dvo->slave_addr); |
156 | } | 157 | } |
157 | return false; | 158 | return false; |
158 | } | 159 | } |
@@ -161,10 +162,11 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
161 | static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | 162 | static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) |
162 | { | 163 | { |
163 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; | 164 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; |
164 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 165 | struct i2c_adapter *adapter = dvo->i2c_bus; |
166 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
165 | uint8_t out_buf[2]; | 167 | uint8_t out_buf[2]; |
166 | struct i2c_msg msg = { | 168 | struct i2c_msg msg = { |
167 | .addr = i2cbus->slave_addr, | 169 | .addr = dvo->slave_addr, |
168 | .flags = 0, | 170 | .flags = 0, |
169 | .len = 2, | 171 | .len = 2, |
170 | .buf = out_buf, | 172 | .buf = out_buf, |
@@ -178,14 +180,14 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
178 | 180 | ||
179 | if (!ch7xxx->quiet) { | 181 | if (!ch7xxx->quiet) { |
180 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 182 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
181 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 183 | addr, i2cbus->adapter.name, dvo->slave_addr); |
182 | } | 184 | } |
183 | 185 | ||
184 | return false; | 186 | return false; |
185 | } | 187 | } |
186 | 188 | ||
187 | static bool ch7xxx_init(struct intel_dvo_device *dvo, | 189 | static bool ch7xxx_init(struct intel_dvo_device *dvo, |
188 | struct intel_i2c_chan *i2cbus) | 190 | struct i2c_adapter *adapter) |
189 | { | 191 | { |
190 | /* this will detect the CH7xxx chip on the specified i2c bus */ | 192 | /* this will detect the CH7xxx chip on the specified i2c bus */ |
191 | struct ch7xxx_priv *ch7xxx; | 193 | struct ch7xxx_priv *ch7xxx; |
@@ -196,8 +198,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, | |||
196 | if (ch7xxx == NULL) | 198 | if (ch7xxx == NULL) |
197 | return false; | 199 | return false; |
198 | 200 | ||
199 | dvo->i2c_bus = i2cbus; | 201 | dvo->i2c_bus = adapter; |
200 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
201 | dvo->dev_priv = ch7xxx; | 202 | dvo->dev_priv = ch7xxx; |
202 | ch7xxx->quiet = true; | 203 | ch7xxx->quiet = true; |
203 | 204 | ||
@@ -207,7 +208,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, | |||
207 | name = ch7xxx_get_id(vendor); | 208 | name = ch7xxx_get_id(vendor); |
208 | if (!name) { | 209 | if (!name) { |
209 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", | 210 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", |
210 | vendor, i2cbus->adapter.name, i2cbus->slave_addr); | 211 | vendor, adapter->name, dvo->slave_addr); |
211 | goto out; | 212 | goto out; |
212 | } | 213 | } |
213 | 214 | ||
@@ -217,7 +218,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, | |||
217 | 218 | ||
218 | if (device != CH7xxx_DID) { | 219 | if (device != CH7xxx_DID) { |
219 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", | 220 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", |
220 | vendor, i2cbus->adapter.name, i2cbus->slave_addr); | 221 | vendor, adapter->name, dvo->slave_addr); |
221 | goto out; | 222 | goto out; |
222 | } | 223 | } |
223 | 224 | ||
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c index 0c8d375e8e37..aa176f9921fe 100644 --- a/drivers/gpu/drm/i915/dvo_ivch.c +++ b/drivers/gpu/drm/i915/dvo_ivch.c | |||
@@ -169,13 +169,14 @@ static void ivch_dump_regs(struct intel_dvo_device *dvo); | |||
169 | static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | 169 | static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) |
170 | { | 170 | { |
171 | struct ivch_priv *priv = dvo->dev_priv; | 171 | struct ivch_priv *priv = dvo->dev_priv; |
172 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 172 | struct i2c_adapter *adapter = dvo->i2c_bus; |
173 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
173 | u8 out_buf[1]; | 174 | u8 out_buf[1]; |
174 | u8 in_buf[2]; | 175 | u8 in_buf[2]; |
175 | 176 | ||
176 | struct i2c_msg msgs[] = { | 177 | struct i2c_msg msgs[] = { |
177 | { | 178 | { |
178 | .addr = i2cbus->slave_addr, | 179 | .addr = dvo->slave_addr, |
179 | .flags = I2C_M_RD, | 180 | .flags = I2C_M_RD, |
180 | .len = 0, | 181 | .len = 0, |
181 | }, | 182 | }, |
@@ -186,7 +187,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
186 | .buf = out_buf, | 187 | .buf = out_buf, |
187 | }, | 188 | }, |
188 | { | 189 | { |
189 | .addr = i2cbus->slave_addr, | 190 | .addr = dvo->slave_addr, |
190 | .flags = I2C_M_RD | I2C_M_NOSTART, | 191 | .flags = I2C_M_RD | I2C_M_NOSTART, |
191 | .len = 2, | 192 | .len = 2, |
192 | .buf = in_buf, | 193 | .buf = in_buf, |
@@ -202,7 +203,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
202 | 203 | ||
203 | if (!priv->quiet) { | 204 | if (!priv->quiet) { |
204 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 205 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
205 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 206 | addr, i2cbus->adapter.name, dvo->slave_addr); |
206 | } | 207 | } |
207 | return false; | 208 | return false; |
208 | } | 209 | } |
@@ -211,10 +212,11 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
211 | static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | 212 | static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) |
212 | { | 213 | { |
213 | struct ivch_priv *priv = dvo->dev_priv; | 214 | struct ivch_priv *priv = dvo->dev_priv; |
214 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 215 | struct i2c_adapter *adapter = dvo->i2c_bus; |
216 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
215 | u8 out_buf[3]; | 217 | u8 out_buf[3]; |
216 | struct i2c_msg msg = { | 218 | struct i2c_msg msg = { |
217 | .addr = i2cbus->slave_addr, | 219 | .addr = dvo->slave_addr, |
218 | .flags = 0, | 220 | .flags = 0, |
219 | .len = 3, | 221 | .len = 3, |
220 | .buf = out_buf, | 222 | .buf = out_buf, |
@@ -229,7 +231,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | |||
229 | 231 | ||
230 | if (!priv->quiet) { | 232 | if (!priv->quiet) { |
231 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 233 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
232 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 234 | addr, i2cbus->adapter.name, dvo->slave_addr); |
233 | } | 235 | } |
234 | 236 | ||
235 | return false; | 237 | return false; |
@@ -237,7 +239,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | |||
237 | 239 | ||
238 | /** Probes the given bus and slave address for an ivch */ | 240 | /** Probes the given bus and slave address for an ivch */ |
239 | static bool ivch_init(struct intel_dvo_device *dvo, | 241 | static bool ivch_init(struct intel_dvo_device *dvo, |
240 | struct intel_i2c_chan *i2cbus) | 242 | struct i2c_adapter *adapter) |
241 | { | 243 | { |
242 | struct ivch_priv *priv; | 244 | struct ivch_priv *priv; |
243 | uint16_t temp; | 245 | uint16_t temp; |
@@ -246,8 +248,7 @@ static bool ivch_init(struct intel_dvo_device *dvo, | |||
246 | if (priv == NULL) | 248 | if (priv == NULL) |
247 | return false; | 249 | return false; |
248 | 250 | ||
249 | dvo->i2c_bus = i2cbus; | 251 | dvo->i2c_bus = adapter; |
250 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
251 | dvo->dev_priv = priv; | 252 | dvo->dev_priv = priv; |
252 | priv->quiet = true; | 253 | priv->quiet = true; |
253 | 254 | ||
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c index 033a4bb070b2..e1c1f7341e5c 100644 --- a/drivers/gpu/drm/i915/dvo_sil164.c +++ b/drivers/gpu/drm/i915/dvo_sil164.c | |||
@@ -76,19 +76,20 @@ struct sil164_priv { | |||
76 | static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | 76 | static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) |
77 | { | 77 | { |
78 | struct sil164_priv *sil = dvo->dev_priv; | 78 | struct sil164_priv *sil = dvo->dev_priv; |
79 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 79 | struct i2c_adapter *adapter = dvo->i2c_bus; |
80 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
80 | u8 out_buf[2]; | 81 | u8 out_buf[2]; |
81 | u8 in_buf[2]; | 82 | u8 in_buf[2]; |
82 | 83 | ||
83 | struct i2c_msg msgs[] = { | 84 | struct i2c_msg msgs[] = { |
84 | { | 85 | { |
85 | .addr = i2cbus->slave_addr, | 86 | .addr = dvo->slave_addr, |
86 | .flags = 0, | 87 | .flags = 0, |
87 | .len = 1, | 88 | .len = 1, |
88 | .buf = out_buf, | 89 | .buf = out_buf, |
89 | }, | 90 | }, |
90 | { | 91 | { |
91 | .addr = i2cbus->slave_addr, | 92 | .addr = dvo->slave_addr, |
92 | .flags = I2C_M_RD, | 93 | .flags = I2C_M_RD, |
93 | .len = 1, | 94 | .len = 1, |
94 | .buf = in_buf, | 95 | .buf = in_buf, |
@@ -105,7 +106,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
105 | 106 | ||
106 | if (!sil->quiet) { | 107 | if (!sil->quiet) { |
107 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 108 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
108 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 109 | addr, i2cbus->adapter.name, dvo->slave_addr); |
109 | } | 110 | } |
110 | return false; | 111 | return false; |
111 | } | 112 | } |
@@ -113,10 +114,11 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
113 | static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | 114 | static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) |
114 | { | 115 | { |
115 | struct sil164_priv *sil= dvo->dev_priv; | 116 | struct sil164_priv *sil= dvo->dev_priv; |
116 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 117 | struct i2c_adapter *adapter = dvo->i2c_bus; |
118 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
117 | uint8_t out_buf[2]; | 119 | uint8_t out_buf[2]; |
118 | struct i2c_msg msg = { | 120 | struct i2c_msg msg = { |
119 | .addr = i2cbus->slave_addr, | 121 | .addr = dvo->slave_addr, |
120 | .flags = 0, | 122 | .flags = 0, |
121 | .len = 2, | 123 | .len = 2, |
122 | .buf = out_buf, | 124 | .buf = out_buf, |
@@ -130,7 +132,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
130 | 132 | ||
131 | if (!sil->quiet) { | 133 | if (!sil->quiet) { |
132 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 134 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
133 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 135 | addr, i2cbus->adapter.name, dvo->slave_addr); |
134 | } | 136 | } |
135 | 137 | ||
136 | return false; | 138 | return false; |
@@ -138,7 +140,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
138 | 140 | ||
139 | /* Silicon Image 164 driver for chip on i2c bus */ | 141 | /* Silicon Image 164 driver for chip on i2c bus */ |
140 | static bool sil164_init(struct intel_dvo_device *dvo, | 142 | static bool sil164_init(struct intel_dvo_device *dvo, |
141 | struct intel_i2c_chan *i2cbus) | 143 | struct i2c_adapter *adapter) |
142 | { | 144 | { |
143 | /* this will detect the SIL164 chip on the specified i2c bus */ | 145 | /* this will detect the SIL164 chip on the specified i2c bus */ |
144 | struct sil164_priv *sil; | 146 | struct sil164_priv *sil; |
@@ -148,8 +150,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, | |||
148 | if (sil == NULL) | 150 | if (sil == NULL) |
149 | return false; | 151 | return false; |
150 | 152 | ||
151 | dvo->i2c_bus = i2cbus; | 153 | dvo->i2c_bus = adapter; |
152 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
153 | dvo->dev_priv = sil; | 154 | dvo->dev_priv = sil; |
154 | sil->quiet = true; | 155 | sil->quiet = true; |
155 | 156 | ||
@@ -158,7 +159,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, | |||
158 | 159 | ||
159 | if (ch != (SIL164_VID & 0xff)) { | 160 | if (ch != (SIL164_VID & 0xff)) { |
160 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", | 161 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", |
161 | ch, i2cbus->adapter.name, i2cbus->slave_addr); | 162 | ch, adapter->name, dvo->slave_addr); |
162 | goto out; | 163 | goto out; |
163 | } | 164 | } |
164 | 165 | ||
@@ -167,7 +168,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, | |||
167 | 168 | ||
168 | if (ch != (SIL164_DID & 0xff)) { | 169 | if (ch != (SIL164_DID & 0xff)) { |
169 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", | 170 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", |
170 | ch, i2cbus->adapter.name, i2cbus->slave_addr); | 171 | ch, adapter->name, dvo->slave_addr); |
171 | goto out; | 172 | goto out; |
172 | } | 173 | } |
173 | sil->quiet = false; | 174 | sil->quiet = false; |
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index 207fda806ebf..9ecc907384ec 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c | |||
@@ -101,19 +101,20 @@ struct tfp410_priv { | |||
101 | static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | 101 | static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) |
102 | { | 102 | { |
103 | struct tfp410_priv *tfp = dvo->dev_priv; | 103 | struct tfp410_priv *tfp = dvo->dev_priv; |
104 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 104 | struct i2c_adapter *adapter = dvo->i2c_bus; |
105 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
105 | u8 out_buf[2]; | 106 | u8 out_buf[2]; |
106 | u8 in_buf[2]; | 107 | u8 in_buf[2]; |
107 | 108 | ||
108 | struct i2c_msg msgs[] = { | 109 | struct i2c_msg msgs[] = { |
109 | { | 110 | { |
110 | .addr = i2cbus->slave_addr, | 111 | .addr = dvo->slave_addr, |
111 | .flags = 0, | 112 | .flags = 0, |
112 | .len = 1, | 113 | .len = 1, |
113 | .buf = out_buf, | 114 | .buf = out_buf, |
114 | }, | 115 | }, |
115 | { | 116 | { |
116 | .addr = i2cbus->slave_addr, | 117 | .addr = dvo->slave_addr, |
117 | .flags = I2C_M_RD, | 118 | .flags = I2C_M_RD, |
118 | .len = 1, | 119 | .len = 1, |
119 | .buf = in_buf, | 120 | .buf = in_buf, |
@@ -130,7 +131,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
130 | 131 | ||
131 | if (!tfp->quiet) { | 132 | if (!tfp->quiet) { |
132 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 133 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
133 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 134 | addr, i2cbus->adapter.name, dvo->slave_addr); |
134 | } | 135 | } |
135 | return false; | 136 | return false; |
136 | } | 137 | } |
@@ -138,10 +139,11 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
138 | static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | 139 | static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) |
139 | { | 140 | { |
140 | struct tfp410_priv *tfp = dvo->dev_priv; | 141 | struct tfp410_priv *tfp = dvo->dev_priv; |
141 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 142 | struct i2c_adapter *adapter = dvo->i2c_bus; |
143 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
142 | uint8_t out_buf[2]; | 144 | uint8_t out_buf[2]; |
143 | struct i2c_msg msg = { | 145 | struct i2c_msg msg = { |
144 | .addr = i2cbus->slave_addr, | 146 | .addr = dvo->slave_addr, |
145 | .flags = 0, | 147 | .flags = 0, |
146 | .len = 2, | 148 | .len = 2, |
147 | .buf = out_buf, | 149 | .buf = out_buf, |
@@ -155,7 +157,7 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
155 | 157 | ||
156 | if (!tfp->quiet) { | 158 | if (!tfp->quiet) { |
157 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 159 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
158 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 160 | addr, i2cbus->adapter.name, dvo->slave_addr); |
159 | } | 161 | } |
160 | 162 | ||
161 | return false; | 163 | return false; |
@@ -174,7 +176,7 @@ static int tfp410_getid(struct intel_dvo_device *dvo, int addr) | |||
174 | 176 | ||
175 | /* Ti TFP410 driver for chip on i2c bus */ | 177 | /* Ti TFP410 driver for chip on i2c bus */ |
176 | static bool tfp410_init(struct intel_dvo_device *dvo, | 178 | static bool tfp410_init(struct intel_dvo_device *dvo, |
177 | struct intel_i2c_chan *i2cbus) | 179 | struct i2c_adapter *adapter) |
178 | { | 180 | { |
179 | /* this will detect the tfp410 chip on the specified i2c bus */ | 181 | /* this will detect the tfp410 chip on the specified i2c bus */ |
180 | struct tfp410_priv *tfp; | 182 | struct tfp410_priv *tfp; |
@@ -184,20 +186,19 @@ static bool tfp410_init(struct intel_dvo_device *dvo, | |||
184 | if (tfp == NULL) | 186 | if (tfp == NULL) |
185 | return false; | 187 | return false; |
186 | 188 | ||
187 | dvo->i2c_bus = i2cbus; | 189 | dvo->i2c_bus = adapter; |
188 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
189 | dvo->dev_priv = tfp; | 190 | dvo->dev_priv = tfp; |
190 | tfp->quiet = true; | 191 | tfp->quiet = true; |
191 | 192 | ||
192 | if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { | 193 | if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { |
193 | DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n", | 194 | DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n", |
194 | id, i2cbus->adapter.name, i2cbus->slave_addr); | 195 | id, adapter->name, dvo->slave_addr); |
195 | goto out; | 196 | goto out; |
196 | } | 197 | } |
197 | 198 | ||
198 | if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { | 199 | if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { |
199 | DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n", | 200 | DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n", |
200 | id, i2cbus->adapter.name, i2cbus->slave_addr); | 201 | id, adapter->name, dvo->slave_addr); |
201 | goto out; | 202 | goto out; |
202 | } | 203 | } |
203 | tfp->quiet = false; | 204 | tfp->quiet = false; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f112c769d533..8c4783180bf6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -846,7 +846,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
846 | return 0; | 846 | return 0; |
847 | } | 847 | } |
848 | 848 | ||
849 | printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); | 849 | DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); |
850 | 850 | ||
851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); | 851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); |
852 | 852 | ||
@@ -885,8 +885,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
885 | * some RAM for the framebuffer at early boot. This code figures out | 885 | * some RAM for the framebuffer at early boot. This code figures out |
886 | * how much was set aside so we can use it for our own purposes. | 886 | * how much was set aside so we can use it for our own purposes. |
887 | */ | 887 | */ |
888 | static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | 888 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, |
889 | unsigned long *preallocated_size) | 889 | uint32_t *preallocated_size) |
890 | { | 890 | { |
891 | struct pci_dev *bridge_dev; | 891 | struct pci_dev *bridge_dev; |
892 | u16 tmp = 0; | 892 | u16 tmp = 0; |
@@ -984,10 +984,11 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | |||
984 | return 0; | 984 | return 0; |
985 | } | 985 | } |
986 | 986 | ||
987 | static int i915_load_modeset_init(struct drm_device *dev) | 987 | static int i915_load_modeset_init(struct drm_device *dev, |
988 | unsigned long prealloc_size, | ||
989 | unsigned long agp_size) | ||
988 | { | 990 | { |
989 | struct drm_i915_private *dev_priv = dev->dev_private; | 991 | struct drm_i915_private *dev_priv = dev->dev_private; |
990 | unsigned long agp_size, prealloc_size; | ||
991 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | 992 | int fb_bar = IS_I9XX(dev) ? 2 : 0; |
992 | int ret = 0; | 993 | int ret = 0; |
993 | 994 | ||
@@ -1002,10 +1003,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1002 | if (IS_I965G(dev) || IS_G33(dev)) | 1003 | if (IS_I965G(dev) || IS_G33(dev)) |
1003 | dev_priv->cursor_needs_physical = false; | 1004 | dev_priv->cursor_needs_physical = false; |
1004 | 1005 | ||
1005 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1006 | if (ret) | ||
1007 | goto out; | ||
1008 | |||
1009 | /* Basic memrange allocator for stolen space (aka vram) */ | 1006 | /* Basic memrange allocator for stolen space (aka vram) */ |
1010 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1007 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); |
1011 | 1008 | ||
@@ -1082,6 +1079,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) | |||
1082 | master->driver_priv = NULL; | 1079 | master->driver_priv = NULL; |
1083 | } | 1080 | } |
1084 | 1081 | ||
1082 | static void i915_get_mem_freq(struct drm_device *dev) | ||
1083 | { | ||
1084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1085 | u32 tmp; | ||
1086 | |||
1087 | if (!IS_IGD(dev)) | ||
1088 | return; | ||
1089 | |||
1090 | tmp = I915_READ(CLKCFG); | ||
1091 | |||
1092 | switch (tmp & CLKCFG_FSB_MASK) { | ||
1093 | case CLKCFG_FSB_533: | ||
1094 | dev_priv->fsb_freq = 533; /* 133*4 */ | ||
1095 | break; | ||
1096 | case CLKCFG_FSB_800: | ||
1097 | dev_priv->fsb_freq = 800; /* 200*4 */ | ||
1098 | break; | ||
1099 | case CLKCFG_FSB_667: | ||
1100 | dev_priv->fsb_freq = 667; /* 167*4 */ | ||
1101 | break; | ||
1102 | case CLKCFG_FSB_400: | ||
1103 | dev_priv->fsb_freq = 400; /* 100*4 */ | ||
1104 | break; | ||
1105 | } | ||
1106 | |||
1107 | switch (tmp & CLKCFG_MEM_MASK) { | ||
1108 | case CLKCFG_MEM_533: | ||
1109 | dev_priv->mem_freq = 533; | ||
1110 | break; | ||
1111 | case CLKCFG_MEM_667: | ||
1112 | dev_priv->mem_freq = 667; | ||
1113 | break; | ||
1114 | case CLKCFG_MEM_800: | ||
1115 | dev_priv->mem_freq = 800; | ||
1116 | break; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1085 | /** | 1120 | /** |
1086 | * i915_driver_load - setup chip and create an initial config | 1121 | * i915_driver_load - setup chip and create an initial config |
1087 | * @dev: DRM device | 1122 | * @dev: DRM device |
@@ -1098,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1098 | struct drm_i915_private *dev_priv = dev->dev_private; | 1133 | struct drm_i915_private *dev_priv = dev->dev_private; |
1099 | resource_size_t base, size; | 1134 | resource_size_t base, size; |
1100 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; | 1135 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; |
1136 | uint32_t agp_size, prealloc_size; | ||
1101 | 1137 | ||
1102 | /* i915 has 4 more counters */ | 1138 | /* i915 has 4 more counters */ |
1103 | dev->counters += 4; | 1139 | dev->counters += 4; |
@@ -1146,9 +1182,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1146 | "performance may suffer.\n"); | 1182 | "performance may suffer.\n"); |
1147 | } | 1183 | } |
1148 | 1184 | ||
1185 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1186 | if (ret) | ||
1187 | goto out_iomapfree; | ||
1188 | |||
1149 | /* enable GEM by default */ | 1189 | /* enable GEM by default */ |
1150 | dev_priv->has_gem = 1; | 1190 | dev_priv->has_gem = 1; |
1151 | 1191 | ||
1192 | if (prealloc_size > agp_size * 3 / 4) { | ||
1193 | DRM_ERROR("Detected broken video BIOS with %d/%dkB of video " | ||
1194 | "memory stolen.\n", | ||
1195 | prealloc_size / 1024, agp_size / 1024); | ||
1196 | DRM_ERROR("Disabling GEM. (try reducing stolen memory or " | ||
1197 | "updating the BIOS to fix).\n"); | ||
1198 | dev_priv->has_gem = 0; | ||
1199 | } | ||
1200 | |||
1152 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1201 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1153 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 1202 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
1154 | if (IS_G4X(dev) || IS_IGDNG(dev)) { | 1203 | if (IS_G4X(dev) || IS_IGDNG(dev)) { |
@@ -1165,6 +1214,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1165 | goto out_iomapfree; | 1214 | goto out_iomapfree; |
1166 | } | 1215 | } |
1167 | 1216 | ||
1217 | i915_get_mem_freq(dev); | ||
1218 | |||
1168 | /* On the 945G/GM, the chipset reports the MSI capability on the | 1219 | /* On the 945G/GM, the chipset reports the MSI capability on the |
1169 | * integrated graphics even though the support isn't actually there | 1220 | * integrated graphics even though the support isn't actually there |
1170 | * according to the published specs. It doesn't appear to function | 1221 | * according to the published specs. It doesn't appear to function |
@@ -1180,6 +1231,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1180 | pci_enable_msi(dev->pdev); | 1231 | pci_enable_msi(dev->pdev); |
1181 | 1232 | ||
1182 | spin_lock_init(&dev_priv->user_irq_lock); | 1233 | spin_lock_init(&dev_priv->user_irq_lock); |
1234 | spin_lock_init(&dev_priv->error_lock); | ||
1183 | dev_priv->user_irq_refcount = 0; | 1235 | dev_priv->user_irq_refcount = 0; |
1184 | 1236 | ||
1185 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 1237 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
@@ -1190,7 +1242,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1190 | } | 1242 | } |
1191 | 1243 | ||
1192 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1244 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1193 | ret = i915_load_modeset_init(dev); | 1245 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); |
1194 | if (ret < 0) { | 1246 | if (ret < 0) { |
1195 | DRM_ERROR("failed to init modeset\n"); | 1247 | DRM_ERROR("failed to init modeset\n"); |
1196 | goto out_rmmap; | 1248 | goto out_rmmap; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 98560e1e899a..fc4b68aa2d05 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "drm_pciids.h" | 36 | #include "drm_pciids.h" |
37 | #include <linux/console.h> | 37 | #include <linux/console.h> |
38 | #include "drm_crtc_helper.h" | ||
38 | 39 | ||
39 | static unsigned int i915_modeset = -1; | 40 | static unsigned int i915_modeset = -1; |
40 | module_param_named(modeset, i915_modeset, int, 0400); | 41 | module_param_named(modeset, i915_modeset, int, 0400); |
@@ -57,8 +58,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
57 | struct drm_i915_private *dev_priv = dev->dev_private; | 58 | struct drm_i915_private *dev_priv = dev->dev_private; |
58 | 59 | ||
59 | if (!dev || !dev_priv) { | 60 | if (!dev || !dev_priv) { |
60 | printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); | 61 | DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv); |
61 | printk(KERN_ERR "DRM not initialized, aborting suspend.\n"); | 62 | DRM_ERROR("DRM not initialized, aborting suspend.\n"); |
62 | return -ENODEV; | 63 | return -ENODEV; |
63 | } | 64 | } |
64 | 65 | ||
@@ -67,8 +68,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
67 | 68 | ||
68 | pci_save_state(dev->pdev); | 69 | pci_save_state(dev->pdev); |
69 | 70 | ||
70 | i915_save_state(dev); | ||
71 | |||
72 | /* If KMS is active, we do the leavevt stuff here */ | 71 | /* If KMS is active, we do the leavevt stuff here */ |
73 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 72 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
74 | if (i915_gem_idle(dev)) | 73 | if (i915_gem_idle(dev)) |
@@ -77,6 +76,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
77 | drm_irq_uninstall(dev); | 76 | drm_irq_uninstall(dev); |
78 | } | 77 | } |
79 | 78 | ||
79 | i915_save_state(dev); | ||
80 | |||
80 | intel_opregion_free(dev, 1); | 81 | intel_opregion_free(dev, 1); |
81 | 82 | ||
82 | if (state.event == PM_EVENT_SUSPEND) { | 83 | if (state.event == PM_EVENT_SUSPEND) { |
@@ -115,6 +116,10 @@ static int i915_resume(struct drm_device *dev) | |||
115 | 116 | ||
116 | drm_irq_install(dev); | 117 | drm_irq_install(dev); |
117 | } | 118 | } |
119 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
120 | /* Resume the modeset for every activated CRTC */ | ||
121 | drm_helper_resume_force_mode(dev); | ||
122 | } | ||
118 | 123 | ||
119 | return ret; | 124 | return ret; |
120 | } | 125 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7a84f04e8439..d08752875885 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -133,6 +133,22 @@ struct sdvo_device_mapping { | |||
133 | u8 initialized; | 133 | u8 initialized; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | struct drm_i915_error_state { | ||
137 | u32 eir; | ||
138 | u32 pgtbl_er; | ||
139 | u32 pipeastat; | ||
140 | u32 pipebstat; | ||
141 | u32 ipeir; | ||
142 | u32 ipehr; | ||
143 | u32 instdone; | ||
144 | u32 acthd; | ||
145 | u32 instpm; | ||
146 | u32 instps; | ||
147 | u32 instdone1; | ||
148 | u32 seqno; | ||
149 | struct timeval time; | ||
150 | }; | ||
151 | |||
136 | typedef struct drm_i915_private { | 152 | typedef struct drm_i915_private { |
137 | struct drm_device *dev; | 153 | struct drm_device *dev; |
138 | 154 | ||
@@ -209,6 +225,11 @@ typedef struct drm_i915_private { | |||
209 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 225 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
210 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 226 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
211 | 227 | ||
228 | unsigned int fsb_freq, mem_freq; | ||
229 | |||
230 | spinlock_t error_lock; | ||
231 | struct drm_i915_error_state *first_error; | ||
232 | |||
212 | /* Register state */ | 233 | /* Register state */ |
213 | u8 saveLBB; | 234 | u8 saveLBB; |
214 | u32 saveDSPACNTR; | 235 | u32 saveDSPACNTR; |
@@ -306,6 +327,17 @@ typedef struct drm_i915_private { | |||
306 | u32 saveCURBPOS; | 327 | u32 saveCURBPOS; |
307 | u32 saveCURBBASE; | 328 | u32 saveCURBBASE; |
308 | u32 saveCURSIZE; | 329 | u32 saveCURSIZE; |
330 | u32 saveDP_B; | ||
331 | u32 saveDP_C; | ||
332 | u32 saveDP_D; | ||
333 | u32 savePIPEA_GMCH_DATA_M; | ||
334 | u32 savePIPEB_GMCH_DATA_M; | ||
335 | u32 savePIPEA_GMCH_DATA_N; | ||
336 | u32 savePIPEB_GMCH_DATA_N; | ||
337 | u32 savePIPEA_DP_LINK_M; | ||
338 | u32 savePIPEB_DP_LINK_M; | ||
339 | u32 savePIPEA_DP_LINK_N; | ||
340 | u32 savePIPEB_DP_LINK_N; | ||
309 | 341 | ||
310 | struct { | 342 | struct { |
311 | struct drm_mm gtt_space; | 343 | struct drm_mm gtt_space; |
@@ -457,9 +489,6 @@ struct drm_i915_gem_object { | |||
457 | */ | 489 | */ |
458 | int fence_reg; | 490 | int fence_reg; |
459 | 491 | ||
460 | /** Boolean whether this object has a valid gtt offset. */ | ||
461 | int gtt_bound; | ||
462 | |||
463 | /** How many users have pinned this object in GTT space */ | 492 | /** How many users have pinned this object in GTT space */ |
464 | int pin_count; | 493 | int pin_count; |
465 | 494 | ||
@@ -644,6 +673,7 @@ void i915_gem_free_object(struct drm_gem_object *obj); | |||
644 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | 673 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); |
645 | void i915_gem_object_unpin(struct drm_gem_object *obj); | 674 | void i915_gem_object_unpin(struct drm_gem_object *obj); |
646 | int i915_gem_object_unbind(struct drm_gem_object *obj); | 675 | int i915_gem_object_unbind(struct drm_gem_object *obj); |
676 | void i915_gem_release_mmap(struct drm_gem_object *obj); | ||
647 | void i915_gem_lastclose(struct drm_device *dev); | 677 | void i915_gem_lastclose(struct drm_device *dev); |
648 | uint32_t i915_get_gem_seqno(struct drm_device *dev); | 678 | uint32_t i915_get_gem_seqno(struct drm_device *dev); |
649 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | 679 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); |
@@ -857,7 +887,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
857 | #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ | 887 | #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ |
858 | IS_I915GM(dev))) | 888 | IS_I915GM(dev))) |
859 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 889 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
890 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
860 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | 891 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) |
892 | /* dsparb controlled by hw only */ | ||
893 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
861 | 894 | ||
862 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 895 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
863 | 896 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fd2b8bdffe3f..5bf420378b6d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1006,7 +1006,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1006 | 1006 | ||
1007 | mutex_lock(&dev->struct_mutex); | 1007 | mutex_lock(&dev->struct_mutex); |
1008 | #if WATCH_BUF | 1008 | #if WATCH_BUF |
1009 | DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", | 1009 | DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", |
1010 | obj, obj->size, read_domains, write_domain); | 1010 | obj, obj->size, read_domains, write_domain); |
1011 | #endif | 1011 | #endif |
1012 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1012 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
@@ -1050,7 +1050,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | #if WATCH_BUF | 1052 | #if WATCH_BUF |
1053 | DRM_INFO("%s: sw_finish %d (%p %d)\n", | 1053 | DRM_INFO("%s: sw_finish %d (%p %zd)\n", |
1054 | __func__, args->handle, obj, obj->size); | 1054 | __func__, args->handle, obj, obj->size); |
1055 | #endif | 1055 | #endif |
1056 | obj_priv = obj->driver_private; | 1056 | obj_priv = obj->driver_private; |
@@ -1252,6 +1252,31 @@ out_free_list: | |||
1252 | return ret; | 1252 | return ret; |
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | /** | ||
1256 | * i915_gem_release_mmap - remove physical page mappings | ||
1257 | * @obj: obj in question | ||
1258 | * | ||
1259 | * Preserve the reservation of the mmaping with the DRM core code, but | ||
1260 | * relinquish ownership of the pages back to the system. | ||
1261 | * | ||
1262 | * It is vital that we remove the page mapping if we have mapped a tiled | ||
1263 | * object through the GTT and then lose the fence register due to | ||
1264 | * resource pressure. Similarly if the object has been moved out of the | ||
1265 | * aperture, than pages mapped into userspace must be revoked. Removing the | ||
1266 | * mapping will then trigger a page fault on the next user access, allowing | ||
1267 | * fixup by i915_gem_fault(). | ||
1268 | */ | ||
1269 | void | ||
1270 | i915_gem_release_mmap(struct drm_gem_object *obj) | ||
1271 | { | ||
1272 | struct drm_device *dev = obj->dev; | ||
1273 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1274 | |||
1275 | if (dev->dev_mapping) | ||
1276 | unmap_mapping_range(dev->dev_mapping, | ||
1277 | obj_priv->mmap_offset, obj->size, 1); | ||
1278 | } | ||
1279 | |||
1255 | static void | 1280 | static void |
1256 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) | 1281 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) |
1257 | { | 1282 | { |
@@ -1861,7 +1886,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1861 | { | 1886 | { |
1862 | struct drm_device *dev = obj->dev; | 1887 | struct drm_device *dev = obj->dev; |
1863 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1888 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
1864 | loff_t offset; | ||
1865 | int ret = 0; | 1889 | int ret = 0; |
1866 | 1890 | ||
1867 | #if WATCH_BUF | 1891 | #if WATCH_BUF |
@@ -1898,9 +1922,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1898 | BUG_ON(obj_priv->active); | 1922 | BUG_ON(obj_priv->active); |
1899 | 1923 | ||
1900 | /* blow away mappings if mapped through GTT */ | 1924 | /* blow away mappings if mapped through GTT */ |
1901 | offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT; | 1925 | i915_gem_release_mmap(obj); |
1902 | if (dev->dev_mapping) | ||
1903 | unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1); | ||
1904 | 1926 | ||
1905 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1927 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
1906 | i915_gem_clear_fence_reg(obj); | 1928 | i915_gem_clear_fence_reg(obj); |
@@ -2222,7 +2244,6 @@ try_again: | |||
2222 | /* None available, try to steal one or wait for a user to finish */ | 2244 | /* None available, try to steal one or wait for a user to finish */ |
2223 | if (i == dev_priv->num_fence_regs) { | 2245 | if (i == dev_priv->num_fence_regs) { |
2224 | uint32_t seqno = dev_priv->mm.next_gem_seqno; | 2246 | uint32_t seqno = dev_priv->mm.next_gem_seqno; |
2225 | loff_t offset; | ||
2226 | 2247 | ||
2227 | if (avail == 0) | 2248 | if (avail == 0) |
2228 | return -ENOSPC; | 2249 | return -ENOSPC; |
@@ -2274,10 +2295,7 @@ try_again: | |||
2274 | * Zap this virtual mapping so we can set up a fence again | 2295 | * Zap this virtual mapping so we can set up a fence again |
2275 | * for this object next time we need it. | 2296 | * for this object next time we need it. |
2276 | */ | 2297 | */ |
2277 | offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT; | 2298 | i915_gem_release_mmap(reg->obj); |
2278 | if (dev->dev_mapping) | ||
2279 | unmap_mapping_range(dev->dev_mapping, offset, | ||
2280 | reg->obj->size, 1); | ||
2281 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2299 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2282 | } | 2300 | } |
2283 | 2301 | ||
@@ -2423,7 +2441,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2423 | } | 2441 | } |
2424 | 2442 | ||
2425 | #if WATCH_BUF | 2443 | #if WATCH_BUF |
2426 | DRM_INFO("Binding object of size %d at 0x%08x\n", | 2444 | DRM_INFO("Binding object of size %zd at 0x%08x\n", |
2427 | obj->size, obj_priv->gtt_offset); | 2445 | obj->size, obj_priv->gtt_offset); |
2428 | #endif | 2446 | #endif |
2429 | ret = i915_gem_object_get_pages(obj); | 2447 | ret = i915_gem_object_get_pages(obj); |
@@ -4227,6 +4245,7 @@ i915_gem_lastclose(struct drm_device *dev) | |||
4227 | void | 4245 | void |
4228 | i915_gem_load(struct drm_device *dev) | 4246 | i915_gem_load(struct drm_device *dev) |
4229 | { | 4247 | { |
4248 | int i; | ||
4230 | drm_i915_private_t *dev_priv = dev->dev_private; | 4249 | drm_i915_private_t *dev_priv = dev->dev_private; |
4231 | 4250 | ||
4232 | spin_lock_init(&dev_priv->mm.active_list_lock); | 4251 | spin_lock_init(&dev_priv->mm.active_list_lock); |
@@ -4246,6 +4265,18 @@ i915_gem_load(struct drm_device *dev) | |||
4246 | else | 4265 | else |
4247 | dev_priv->num_fence_regs = 8; | 4266 | dev_priv->num_fence_regs = 8; |
4248 | 4267 | ||
4268 | /* Initialize fence registers to zero */ | ||
4269 | if (IS_I965G(dev)) { | ||
4270 | for (i = 0; i < 16; i++) | ||
4271 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0); | ||
4272 | } else { | ||
4273 | for (i = 0; i < 8; i++) | ||
4274 | I915_WRITE(FENCE_REG_830_0 + (i * 4), 0); | ||
4275 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
4276 | for (i = 0; i < 8; i++) | ||
4277 | I915_WRITE(FENCE_REG_945_8 + (i * 4), 0); | ||
4278 | } | ||
4279 | |||
4249 | i915_gem_detect_bit_6_swizzle(dev); | 4280 | i915_gem_detect_bit_6_swizzle(dev); |
4250 | } | 4281 | } |
4251 | 4282 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index 8d0b943e2c5a..e602614bd3f8 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c | |||
@@ -87,7 +87,7 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, | |||
87 | chunk_len = page_len - chunk; | 87 | chunk_len = page_len - chunk; |
88 | if (chunk_len > 128) | 88 | if (chunk_len > 128) |
89 | chunk_len = 128; | 89 | chunk_len = 128; |
90 | i915_gem_dump_page(obj_priv->page_list[page], | 90 | i915_gem_dump_page(obj_priv->pages[page], |
91 | chunk, chunk + chunk_len, | 91 | chunk, chunk + chunk_len, |
92 | obj_priv->gtt_offset + | 92 | obj_priv->gtt_offset + |
93 | page * PAGE_SIZE, | 93 | page * PAGE_SIZE, |
@@ -143,7 +143,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | |||
143 | uint32_t *backing_map = NULL; | 143 | uint32_t *backing_map = NULL; |
144 | int bad_count = 0; | 144 | int bad_count = 0; |
145 | 145 | ||
146 | DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n", | 146 | DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", |
147 | __func__, obj, obj_priv->gtt_offset, handle, | 147 | __func__, obj, obj_priv->gtt_offset, handle, |
148 | obj->size / 1024); | 148 | obj->size / 1024); |
149 | 149 | ||
@@ -157,7 +157,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | |||
157 | for (page = 0; page < obj->size / PAGE_SIZE; page++) { | 157 | for (page = 0; page < obj->size / PAGE_SIZE; page++) { |
158 | int i; | 158 | int i; |
159 | 159 | ||
160 | backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0); | 160 | backing_map = kmap_atomic(obj_priv->pages[page], KM_USER0); |
161 | 161 | ||
162 | if (backing_map == NULL) { | 162 | if (backing_map == NULL) { |
163 | DRM_ERROR("failed to map backing page\n"); | 163 | DRM_ERROR("failed to map backing page\n"); |
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c index 28146e405e87..9a44bfcb8139 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
@@ -75,11 +75,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
75 | case ACTIVE_LIST: | 75 | case ACTIVE_LIST: |
76 | seq_printf(m, "Active:\n"); | 76 | seq_printf(m, "Active:\n"); |
77 | lock = &dev_priv->mm.active_list_lock; | 77 | lock = &dev_priv->mm.active_list_lock; |
78 | spin_lock(lock); | ||
79 | head = &dev_priv->mm.active_list; | 78 | head = &dev_priv->mm.active_list; |
80 | break; | 79 | break; |
81 | case INACTIVE_LIST: | 80 | case INACTIVE_LIST: |
82 | seq_printf(m, "Inctive:\n"); | 81 | seq_printf(m, "Inactive:\n"); |
83 | head = &dev_priv->mm.inactive_list; | 82 | head = &dev_priv->mm.inactive_list; |
84 | break; | 83 | break; |
85 | case FLUSHING_LIST: | 84 | case FLUSHING_LIST: |
@@ -91,6 +90,8 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
91 | return 0; | 90 | return 0; |
92 | } | 91 | } |
93 | 92 | ||
93 | if (lock) | ||
94 | spin_lock(lock); | ||
94 | list_for_each_entry(obj_priv, head, list) | 95 | list_for_each_entry(obj_priv, head, list) |
95 | { | 96 | { |
96 | struct drm_gem_object *obj = obj_priv->obj; | 97 | struct drm_gem_object *obj = obj_priv->obj; |
@@ -104,7 +105,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
104 | if (obj->name) | 105 | if (obj->name) |
105 | seq_printf(m, " (name: %d)", obj->name); | 106 | seq_printf(m, " (name: %d)", obj->name); |
106 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 107 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
107 | seq_printf(m, " (fence: %d)\n", obj_priv->fence_reg); | 108 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); |
109 | if (obj_priv->gtt_space != NULL) | ||
110 | seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); | ||
111 | |||
108 | seq_printf(m, "\n"); | 112 | seq_printf(m, "\n"); |
109 | } | 113 | } |
110 | 114 | ||
@@ -323,6 +327,39 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
323 | return 0; | 327 | return 0; |
324 | } | 328 | } |
325 | 329 | ||
330 | static int i915_error_state(struct seq_file *m, void *unused) | ||
331 | { | ||
332 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
333 | struct drm_device *dev = node->minor->dev; | ||
334 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
335 | struct drm_i915_error_state *error; | ||
336 | unsigned long flags; | ||
337 | |||
338 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
339 | if (!dev_priv->first_error) { | ||
340 | seq_printf(m, "no error state collected\n"); | ||
341 | goto out; | ||
342 | } | ||
343 | |||
344 | error = dev_priv->first_error; | ||
345 | |||
346 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | ||
347 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); | ||
348 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | ||
349 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); | ||
350 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); | ||
351 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); | ||
352 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
353 | if (IS_I965G(dev)) { | ||
354 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
355 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | ||
356 | } | ||
357 | |||
358 | out: | ||
359 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
360 | |||
361 | return 0; | ||
362 | } | ||
326 | 363 | ||
327 | static struct drm_info_list i915_gem_debugfs_list[] = { | 364 | static struct drm_info_list i915_gem_debugfs_list[] = { |
328 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 365 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
@@ -336,6 +373,7 @@ static struct drm_info_list i915_gem_debugfs_list[] = { | |||
336 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, | 373 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, |
337 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, | 374 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, |
338 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | 375 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, |
376 | {"i915_error_state", i915_error_state, 0}, | ||
339 | }; | 377 | }; |
340 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) | 378 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) |
341 | 379 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 5c1ceec49f5b..a2d527b22ec4 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -114,11 +114,13 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
114 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; | 114 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; |
115 | 115 | ||
116 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ | 116 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ |
117 | #ifdef CONFIG_PNP | ||
117 | if (mchbar_addr && | 118 | if (mchbar_addr && |
118 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { | 119 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { |
119 | ret = 0; | 120 | ret = 0; |
120 | goto out_put; | 121 | goto out_put; |
121 | } | 122 | } |
123 | #endif | ||
122 | 124 | ||
123 | /* Get some space for it */ | 125 | /* Get some space for it */ |
124 | ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, | 126 | ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, |
@@ -519,6 +521,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
519 | goto err; | 521 | goto err; |
520 | } | 522 | } |
521 | 523 | ||
524 | /* If we've changed tiling, GTT-mappings of the object | ||
525 | * need to re-fault to ensure that the correct fence register | ||
526 | * setup is in place. | ||
527 | */ | ||
528 | i915_gem_release_mmap(obj); | ||
529 | |||
522 | obj_priv->tiling_mode = args->tiling_mode; | 530 | obj_priv->tiling_mode = args->tiling_mode; |
523 | obj_priv->stride = args->stride; | 531 | obj_priv->stride = args->stride; |
524 | } | 532 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b86b7b7130c6..7ba23a69a0c0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/sysrq.h> | ||
29 | #include "drmP.h" | 30 | #include "drmP.h" |
30 | #include "drm.h" | 31 | #include "drm.h" |
31 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -41,9 +42,10 @@ | |||
41 | * we leave them always unmasked in IMR and then control enabling them through | 42 | * we leave them always unmasked in IMR and then control enabling them through |
42 | * PIPESTAT alone. | 43 | * PIPESTAT alone. |
43 | */ | 44 | */ |
44 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ | 45 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ |
45 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ | 46 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ |
46 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | 47 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \ |
48 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | ||
47 | 49 | ||
48 | /** Interrupts that we mask and unmask at runtime. */ | 50 | /** Interrupts that we mask and unmask at runtime. */ |
49 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) | 51 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) |
@@ -232,7 +234,17 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
232 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | 234 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, |
233 | hotplug_work); | 235 | hotplug_work); |
234 | struct drm_device *dev = dev_priv->dev; | 236 | struct drm_device *dev = dev_priv->dev; |
235 | 237 | struct drm_mode_config *mode_config = &dev->mode_config; | |
238 | struct drm_connector *connector; | ||
239 | |||
240 | if (mode_config->num_connector) { | ||
241 | list_for_each_entry(connector, &mode_config->connector_list, head) { | ||
242 | struct intel_output *intel_output = to_intel_output(connector); | ||
243 | |||
244 | if (intel_output->hot_plug) | ||
245 | (*intel_output->hot_plug) (intel_output); | ||
246 | } | ||
247 | } | ||
236 | /* Just fire off a uevent and let userspace tell us what to do */ | 248 | /* Just fire off a uevent and let userspace tell us what to do */ |
237 | drm_sysfs_hotplug_event(dev); | 249 | drm_sysfs_hotplug_event(dev); |
238 | } | 250 | } |
@@ -278,6 +290,47 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
278 | return ret; | 290 | return ret; |
279 | } | 291 | } |
280 | 292 | ||
293 | static void i915_capture_error_state(struct drm_device *dev) | ||
294 | { | ||
295 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
296 | struct drm_i915_error_state *error; | ||
297 | unsigned long flags; | ||
298 | |||
299 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
300 | if (dev_priv->first_error) | ||
301 | goto out; | ||
302 | |||
303 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
304 | if (!error) { | ||
305 | DRM_DEBUG("out ot memory, not capturing error state\n"); | ||
306 | goto out; | ||
307 | } | ||
308 | |||
309 | error->eir = I915_READ(EIR); | ||
310 | error->pgtbl_er = I915_READ(PGTBL_ER); | ||
311 | error->pipeastat = I915_READ(PIPEASTAT); | ||
312 | error->pipebstat = I915_READ(PIPEBSTAT); | ||
313 | error->instpm = I915_READ(INSTPM); | ||
314 | if (!IS_I965G(dev)) { | ||
315 | error->ipeir = I915_READ(IPEIR); | ||
316 | error->ipehr = I915_READ(IPEHR); | ||
317 | error->instdone = I915_READ(INSTDONE); | ||
318 | error->acthd = I915_READ(ACTHD); | ||
319 | } else { | ||
320 | error->ipeir = I915_READ(IPEIR_I965); | ||
321 | error->ipehr = I915_READ(IPEHR_I965); | ||
322 | error->instdone = I915_READ(INSTDONE_I965); | ||
323 | error->instps = I915_READ(INSTPS); | ||
324 | error->instdone1 = I915_READ(INSTDONE1); | ||
325 | error->acthd = I915_READ(ACTHD_I965); | ||
326 | } | ||
327 | |||
328 | dev_priv->first_error = error; | ||
329 | |||
330 | out: | ||
331 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
332 | } | ||
333 | |||
281 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 334 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
282 | { | 335 | { |
283 | struct drm_device *dev = (struct drm_device *) arg; | 336 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -323,11 +376,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
323 | * Clear the PIPE(A|B)STAT regs before the IIR | 376 | * Clear the PIPE(A|B)STAT regs before the IIR |
324 | */ | 377 | */ |
325 | if (pipea_stats & 0x8000ffff) { | 378 | if (pipea_stats & 0x8000ffff) { |
379 | if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
380 | DRM_DEBUG("pipe a underrun\n"); | ||
326 | I915_WRITE(PIPEASTAT, pipea_stats); | 381 | I915_WRITE(PIPEASTAT, pipea_stats); |
327 | irq_received = 1; | 382 | irq_received = 1; |
328 | } | 383 | } |
329 | 384 | ||
330 | if (pipeb_stats & 0x8000ffff) { | 385 | if (pipeb_stats & 0x8000ffff) { |
386 | if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
387 | DRM_DEBUG("pipe b underrun\n"); | ||
331 | I915_WRITE(PIPEBSTAT, pipeb_stats); | 388 | I915_WRITE(PIPEBSTAT, pipeb_stats); |
332 | irq_received = 1; | 389 | irq_received = 1; |
333 | } | 390 | } |
@@ -352,6 +409,80 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
352 | I915_READ(PORT_HOTPLUG_STAT); | 409 | I915_READ(PORT_HOTPLUG_STAT); |
353 | } | 410 | } |
354 | 411 | ||
412 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) { | ||
413 | u32 eir = I915_READ(EIR); | ||
414 | |||
415 | i915_capture_error_state(dev); | ||
416 | |||
417 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", | ||
418 | eir); | ||
419 | if (eir & I915_ERROR_PAGE_TABLE) { | ||
420 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
421 | printk(KERN_ERR "page table error\n"); | ||
422 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
423 | pgtbl_err); | ||
424 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
425 | (void)I915_READ(PGTBL_ER); | ||
426 | } | ||
427 | if (eir & I915_ERROR_MEMORY_REFRESH) { | ||
428 | printk(KERN_ERR "memory refresh error\n"); | ||
429 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", | ||
430 | pipea_stats); | ||
431 | printk(KERN_ERR "PIPEBSTAT: 0x%08x\n", | ||
432 | pipeb_stats); | ||
433 | /* pipestat has already been acked */ | ||
434 | } | ||
435 | if (eir & I915_ERROR_INSTRUCTION) { | ||
436 | printk(KERN_ERR "instruction error\n"); | ||
437 | printk(KERN_ERR " INSTPM: 0x%08x\n", | ||
438 | I915_READ(INSTPM)); | ||
439 | if (!IS_I965G(dev)) { | ||
440 | u32 ipeir = I915_READ(IPEIR); | ||
441 | |||
442 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
443 | I915_READ(IPEIR)); | ||
444 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
445 | I915_READ(IPEHR)); | ||
446 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
447 | I915_READ(INSTDONE)); | ||
448 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
449 | I915_READ(ACTHD)); | ||
450 | I915_WRITE(IPEIR, ipeir); | ||
451 | (void)I915_READ(IPEIR); | ||
452 | } else { | ||
453 | u32 ipeir = I915_READ(IPEIR_I965); | ||
454 | |||
455 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
456 | I915_READ(IPEIR_I965)); | ||
457 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
458 | I915_READ(IPEHR_I965)); | ||
459 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
460 | I915_READ(INSTDONE_I965)); | ||
461 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
462 | I915_READ(INSTPS)); | ||
463 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
464 | I915_READ(INSTDONE1)); | ||
465 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
466 | I915_READ(ACTHD_I965)); | ||
467 | I915_WRITE(IPEIR_I965, ipeir); | ||
468 | (void)I915_READ(IPEIR_I965); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | I915_WRITE(EIR, eir); | ||
473 | (void)I915_READ(EIR); | ||
474 | eir = I915_READ(EIR); | ||
475 | if (eir) { | ||
476 | /* | ||
477 | * some errors might have become stuck, | ||
478 | * mask them. | ||
479 | */ | ||
480 | DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir); | ||
481 | I915_WRITE(EMR, I915_READ(EMR) | eir); | ||
482 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); | ||
483 | } | ||
484 | } | ||
485 | |||
355 | I915_WRITE(IIR, iir); | 486 | I915_WRITE(IIR, iir); |
356 | new_iir = I915_READ(IIR); /* Flush posted writes */ | 487 | new_iir = I915_READ(IIR); /* Flush posted writes */ |
357 | 488 | ||
@@ -722,6 +853,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
722 | { | 853 | { |
723 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 854 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
724 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 855 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
856 | u32 error_mask; | ||
725 | 857 | ||
726 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 858 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
727 | 859 | ||
@@ -758,6 +890,21 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
758 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); | 890 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); |
759 | } | 891 | } |
760 | 892 | ||
893 | /* | ||
894 | * Enable some error detection, note the instruction error mask | ||
895 | * bit is reserved, so we leave it masked. | ||
896 | */ | ||
897 | if (IS_G4X(dev)) { | ||
898 | error_mask = ~(GM45_ERROR_PAGE_TABLE | | ||
899 | GM45_ERROR_MEM_PRIV | | ||
900 | GM45_ERROR_CP_PRIV | | ||
901 | I915_ERROR_MEMORY_REFRESH); | ||
902 | } else { | ||
903 | error_mask = ~(I915_ERROR_PAGE_TABLE | | ||
904 | I915_ERROR_MEMORY_REFRESH); | ||
905 | } | ||
906 | I915_WRITE(EMR, error_mask); | ||
907 | |||
761 | /* Disable pipe interrupt enables, clear pending pipe status */ | 908 | /* Disable pipe interrupt enables, clear pending pipe status */ |
762 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); | 909 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); |
763 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); | 910 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f6237a0b1133..6c0858484094 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -206,6 +206,7 @@ | |||
206 | /* | 206 | /* |
207 | * Instruction and interrupt control regs | 207 | * Instruction and interrupt control regs |
208 | */ | 208 | */ |
209 | #define PGTBL_ER 0x02024 | ||
209 | #define PRB0_TAIL 0x02030 | 210 | #define PRB0_TAIL 0x02030 |
210 | #define PRB0_HEAD 0x02034 | 211 | #define PRB0_HEAD 0x02034 |
211 | #define PRB0_START 0x02038 | 212 | #define PRB0_START 0x02038 |
@@ -226,11 +227,18 @@ | |||
226 | #define PRB1_HEAD 0x02044 /* 915+ only */ | 227 | #define PRB1_HEAD 0x02044 /* 915+ only */ |
227 | #define PRB1_START 0x02048 /* 915+ only */ | 228 | #define PRB1_START 0x02048 /* 915+ only */ |
228 | #define PRB1_CTL 0x0204c /* 915+ only */ | 229 | #define PRB1_CTL 0x0204c /* 915+ only */ |
230 | #define IPEIR_I965 0x02064 | ||
231 | #define IPEHR_I965 0x02068 | ||
232 | #define INSTDONE_I965 0x0206c | ||
233 | #define INSTPS 0x02070 /* 965+ only */ | ||
234 | #define INSTDONE1 0x0207c /* 965+ only */ | ||
229 | #define ACTHD_I965 0x02074 | 235 | #define ACTHD_I965 0x02074 |
230 | #define HWS_PGA 0x02080 | 236 | #define HWS_PGA 0x02080 |
231 | #define HWS_ADDRESS_MASK 0xfffff000 | 237 | #define HWS_ADDRESS_MASK 0xfffff000 |
232 | #define HWS_START_ADDRESS_SHIFT 4 | 238 | #define HWS_START_ADDRESS_SHIFT 4 |
233 | #define IPEIR 0x02088 | 239 | #define IPEIR 0x02088 |
240 | #define IPEHR 0x0208c | ||
241 | #define INSTDONE 0x02090 | ||
234 | #define NOPID 0x02094 | 242 | #define NOPID 0x02094 |
235 | #define HWSTAM 0x02098 | 243 | #define HWSTAM 0x02098 |
236 | #define SCPD0 0x0209c /* 915+ only */ | 244 | #define SCPD0 0x0209c /* 915+ only */ |
@@ -258,10 +266,22 @@ | |||
258 | #define EIR 0x020b0 | 266 | #define EIR 0x020b0 |
259 | #define EMR 0x020b4 | 267 | #define EMR 0x020b4 |
260 | #define ESR 0x020b8 | 268 | #define ESR 0x020b8 |
269 | #define GM45_ERROR_PAGE_TABLE (1<<5) | ||
270 | #define GM45_ERROR_MEM_PRIV (1<<4) | ||
271 | #define I915_ERROR_PAGE_TABLE (1<<4) | ||
272 | #define GM45_ERROR_CP_PRIV (1<<3) | ||
273 | #define I915_ERROR_MEMORY_REFRESH (1<<1) | ||
274 | #define I915_ERROR_INSTRUCTION (1<<0) | ||
261 | #define INSTPM 0x020c0 | 275 | #define INSTPM 0x020c0 |
262 | #define ACTHD 0x020c8 | 276 | #define ACTHD 0x020c8 |
263 | #define FW_BLC 0x020d8 | 277 | #define FW_BLC 0x020d8 |
278 | #define FW_BLC2 0x020dc | ||
264 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ | 279 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ |
280 | #define FW_BLC_SELF_EN (1<<15) | ||
281 | #define MM_BURST_LENGTH 0x00700000 | ||
282 | #define MM_FIFO_WATERMARK 0x0001F000 | ||
283 | #define LM_BURST_LENGTH 0x00000700 | ||
284 | #define LM_FIFO_WATERMARK 0x0000001F | ||
265 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ | 285 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ |
266 | #define CACHE_MODE_0 0x02120 /* 915+ only */ | 286 | #define CACHE_MODE_0 0x02120 /* 915+ only */ |
267 | #define CM0_MASK_SHIFT 16 | 287 | #define CM0_MASK_SHIFT 16 |
@@ -569,6 +589,23 @@ | |||
569 | #define C0DRB3 0x10206 | 589 | #define C0DRB3 0x10206 |
570 | #define C1DRB3 0x10606 | 590 | #define C1DRB3 0x10606 |
571 | 591 | ||
592 | /* Clocking configuration register */ | ||
593 | #define CLKCFG 0x10c00 | ||
594 | #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ | ||
595 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ | ||
596 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ | ||
597 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ | ||
598 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ | ||
599 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ | ||
600 | /* Note, below two are guess */ | ||
601 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ | ||
602 | #define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */ | ||
603 | #define CLKCFG_FSB_MASK (7 << 0) | ||
604 | #define CLKCFG_MEM_533 (1 << 4) | ||
605 | #define CLKCFG_MEM_667 (2 << 4) | ||
606 | #define CLKCFG_MEM_800 (3 << 4) | ||
607 | #define CLKCFG_MEM_MASK (7 << 4) | ||
608 | |||
572 | /** GM965 GM45 render standby register */ | 609 | /** GM965 GM45 render standby register */ |
573 | #define MCHBAR_RENDER_STANDBY 0x111B8 | 610 | #define MCHBAR_RENDER_STANDBY 0x111B8 |
574 | 611 | ||
@@ -834,9 +871,25 @@ | |||
834 | #define HORIZ_INTERP_MASK (3 << 6) | 871 | #define HORIZ_INTERP_MASK (3 << 6) |
835 | #define HORIZ_AUTO_SCALE (1 << 5) | 872 | #define HORIZ_AUTO_SCALE (1 << 5) |
836 | #define PANEL_8TO6_DITHER_ENABLE (1 << 3) | 873 | #define PANEL_8TO6_DITHER_ENABLE (1 << 3) |
874 | #define PFIT_FILTER_FUZZY (0 << 24) | ||
875 | #define PFIT_SCALING_AUTO (0 << 26) | ||
876 | #define PFIT_SCALING_PROGRAMMED (1 << 26) | ||
877 | #define PFIT_SCALING_PILLAR (2 << 26) | ||
878 | #define PFIT_SCALING_LETTER (3 << 26) | ||
837 | #define PFIT_PGM_RATIOS 0x61234 | 879 | #define PFIT_PGM_RATIOS 0x61234 |
838 | #define PFIT_VERT_SCALE_MASK 0xfff00000 | 880 | #define PFIT_VERT_SCALE_MASK 0xfff00000 |
839 | #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 | 881 | #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 |
882 | /* Pre-965 */ | ||
883 | #define PFIT_VERT_SCALE_SHIFT 20 | ||
884 | #define PFIT_VERT_SCALE_MASK 0xfff00000 | ||
885 | #define PFIT_HORIZ_SCALE_SHIFT 4 | ||
886 | #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 | ||
887 | /* 965+ */ | ||
888 | #define PFIT_VERT_SCALE_SHIFT_965 16 | ||
889 | #define PFIT_VERT_SCALE_MASK_965 0x1fff0000 | ||
890 | #define PFIT_HORIZ_SCALE_SHIFT_965 0 | ||
891 | #define PFIT_HORIZ_SCALE_MASK_965 0x00001fff | ||
892 | |||
840 | #define PFIT_AUTO_RATIOS 0x61238 | 893 | #define PFIT_AUTO_RATIOS 0x61238 |
841 | 894 | ||
842 | /* Backlight control */ | 895 | /* Backlight control */ |
@@ -1552,6 +1605,34 @@ | |||
1552 | #define DSPARB_CSTART_SHIFT 7 | 1605 | #define DSPARB_CSTART_SHIFT 7 |
1553 | #define DSPARB_BSTART_MASK (0x7f) | 1606 | #define DSPARB_BSTART_MASK (0x7f) |
1554 | #define DSPARB_BSTART_SHIFT 0 | 1607 | #define DSPARB_BSTART_SHIFT 0 |
1608 | #define DSPARB_BEND_SHIFT 9 /* on 855 */ | ||
1609 | #define DSPARB_AEND_SHIFT 0 | ||
1610 | |||
1611 | #define DSPFW1 0x70034 | ||
1612 | #define DSPFW2 0x70038 | ||
1613 | #define DSPFW3 0x7003c | ||
1614 | #define IGD_SELF_REFRESH_EN (1<<30) | ||
1615 | |||
1616 | /* FIFO watermark sizes etc */ | ||
1617 | #define I915_FIFO_LINE_SIZE 64 | ||
1618 | #define I830_FIFO_LINE_SIZE 32 | ||
1619 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ | ||
1620 | #define I915_FIFO_SIZE 95 | ||
1621 | #define I855GM_FIFO_SIZE 255 | ||
1622 | #define I830_FIFO_SIZE 95 | ||
1623 | #define I915_MAX_WM 0x3f | ||
1624 | |||
1625 | #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ | ||
1626 | #define IGD_FIFO_LINE_SIZE 64 | ||
1627 | #define IGD_MAX_WM 0x1ff | ||
1628 | #define IGD_DFT_WM 0x3f | ||
1629 | #define IGD_DFT_HPLLOFF_WM 0 | ||
1630 | #define IGD_GUARD_WM 10 | ||
1631 | #define IGD_CURSOR_FIFO 64 | ||
1632 | #define IGD_CURSOR_MAX_WM 0x3f | ||
1633 | #define IGD_CURSOR_DFT_WM 0 | ||
1634 | #define IGD_CURSOR_GUARD_WM 5 | ||
1635 | |||
1555 | /* | 1636 | /* |
1556 | * The two pipe frame counter registers are not synchronized, so | 1637 | * The two pipe frame counter registers are not synchronized, so |
1557 | * reading a stable value is somewhat tricky. The following code | 1638 | * reading a stable value is somewhat tricky. The following code |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index a98e2831ed31..9e1d16e5c3ea 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -222,23 +222,12 @@ static void i915_restore_vga(struct drm_device *dev) | |||
222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); | 222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); |
223 | } | 223 | } |
224 | 224 | ||
225 | int i915_save_state(struct drm_device *dev) | 225 | static void i915_save_modeset_reg(struct drm_device *dev) |
226 | { | 226 | { |
227 | struct drm_i915_private *dev_priv = dev->dev_private; | 227 | struct drm_i915_private *dev_priv = dev->dev_private; |
228 | int i; | ||
229 | |||
230 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
231 | |||
232 | /* Render Standby */ | ||
233 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
234 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
235 | |||
236 | /* Hardware status page */ | ||
237 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
238 | |||
239 | /* Display arbitration control */ | ||
240 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
241 | 228 | ||
229 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
230 | return; | ||
242 | /* Pipe & plane A info */ | 231 | /* Pipe & plane A info */ |
243 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 232 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
244 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 233 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -294,7 +283,122 @@ int i915_save_state(struct drm_device *dev) | |||
294 | } | 283 | } |
295 | i915_save_palette(dev, PIPE_B); | 284 | i915_save_palette(dev, PIPE_B); |
296 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | 285 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); |
286 | return; | ||
287 | } | ||
288 | static void i915_restore_modeset_reg(struct drm_device *dev) | ||
289 | { | ||
290 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
291 | |||
292 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
293 | return; | ||
294 | |||
295 | /* Pipe & plane A info */ | ||
296 | /* Prime the clock */ | ||
297 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
298 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
299 | ~DPLL_VCO_ENABLE); | ||
300 | DRM_UDELAY(150); | ||
301 | } | ||
302 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
303 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
304 | /* Actually enable it */ | ||
305 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
306 | DRM_UDELAY(150); | ||
307 | if (IS_I965G(dev)) | ||
308 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
309 | DRM_UDELAY(150); | ||
310 | |||
311 | /* Restore mode */ | ||
312 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
313 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
314 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
315 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
316 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
317 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
318 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
319 | |||
320 | /* Restore plane info */ | ||
321 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
322 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
323 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
324 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
325 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
326 | if (IS_I965G(dev)) { | ||
327 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
328 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
329 | } | ||
330 | |||
331 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
332 | |||
333 | i915_restore_palette(dev, PIPE_A); | ||
334 | /* Enable the plane */ | ||
335 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
336 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
337 | |||
338 | /* Pipe & plane B info */ | ||
339 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
340 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
341 | ~DPLL_VCO_ENABLE); | ||
342 | DRM_UDELAY(150); | ||
343 | } | ||
344 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
345 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
346 | /* Actually enable it */ | ||
347 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
348 | DRM_UDELAY(150); | ||
349 | if (IS_I965G(dev)) | ||
350 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
351 | DRM_UDELAY(150); | ||
352 | |||
353 | /* Restore mode */ | ||
354 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
355 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
356 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
357 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
358 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
359 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
360 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
361 | |||
362 | /* Restore plane info */ | ||
363 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
364 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
365 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
366 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
367 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
368 | if (IS_I965G(dev)) { | ||
369 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
370 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
371 | } | ||
372 | |||
373 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
374 | |||
375 | i915_restore_palette(dev, PIPE_B); | ||
376 | /* Enable the plane */ | ||
377 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
378 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
297 | 379 | ||
380 | return; | ||
381 | } | ||
382 | int i915_save_state(struct drm_device *dev) | ||
383 | { | ||
384 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
385 | int i; | ||
386 | |||
387 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
388 | |||
389 | /* Render Standby */ | ||
390 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
391 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
392 | |||
393 | /* Hardware status page */ | ||
394 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
395 | |||
396 | /* Display arbitration control */ | ||
397 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
398 | |||
399 | /* This is only meaningful in non-KMS mode */ | ||
400 | /* Don't save them in KMS mode */ | ||
401 | i915_save_modeset_reg(dev); | ||
298 | /* Cursor state */ | 402 | /* Cursor state */ |
299 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); | 403 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); |
300 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); | 404 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); |
@@ -322,6 +426,20 @@ int i915_save_state(struct drm_device *dev) | |||
322 | dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); | 426 | dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); |
323 | dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); | 427 | dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); |
324 | 428 | ||
429 | /* Display Port state */ | ||
430 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
431 | dev_priv->saveDP_B = I915_READ(DP_B); | ||
432 | dev_priv->saveDP_C = I915_READ(DP_C); | ||
433 | dev_priv->saveDP_D = I915_READ(DP_D); | ||
434 | dev_priv->savePIPEA_GMCH_DATA_M = I915_READ(PIPEA_GMCH_DATA_M); | ||
435 | dev_priv->savePIPEB_GMCH_DATA_M = I915_READ(PIPEB_GMCH_DATA_M); | ||
436 | dev_priv->savePIPEA_GMCH_DATA_N = I915_READ(PIPEA_GMCH_DATA_N); | ||
437 | dev_priv->savePIPEB_GMCH_DATA_N = I915_READ(PIPEB_GMCH_DATA_N); | ||
438 | dev_priv->savePIPEA_DP_LINK_M = I915_READ(PIPEA_DP_LINK_M); | ||
439 | dev_priv->savePIPEB_DP_LINK_M = I915_READ(PIPEB_DP_LINK_M); | ||
440 | dev_priv->savePIPEA_DP_LINK_N = I915_READ(PIPEA_DP_LINK_N); | ||
441 | dev_priv->savePIPEB_DP_LINK_N = I915_READ(PIPEB_DP_LINK_N); | ||
442 | } | ||
325 | /* FIXME: save TV & SDVO state */ | 443 | /* FIXME: save TV & SDVO state */ |
326 | 444 | ||
327 | /* FBC state */ | 445 | /* FBC state */ |
@@ -404,92 +522,21 @@ int i915_restore_state(struct drm_device *dev) | |||
404 | for (i = 0; i < 8; i++) | 522 | for (i = 0; i < 8; i++) |
405 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | 523 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); |
406 | } | 524 | } |
407 | 525 | ||
408 | /* Pipe & plane A info */ | 526 | /* Display port ratios (must be done before clock is set) */ |
409 | /* Prime the clock */ | 527 | if (SUPPORTS_INTEGRATED_DP(dev)) { |
410 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 528 | I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); |
411 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | 529 | I915_WRITE(PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); |
412 | ~DPLL_VCO_ENABLE); | 530 | I915_WRITE(PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); |
413 | DRM_UDELAY(150); | 531 | I915_WRITE(PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); |
532 | I915_WRITE(PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); | ||
533 | I915_WRITE(PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); | ||
534 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); | ||
535 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); | ||
414 | } | 536 | } |
415 | I915_WRITE(FPA0, dev_priv->saveFPA0); | 537 | /* This is only meaningful in non-KMS mode */ |
416 | I915_WRITE(FPA1, dev_priv->saveFPA1); | 538 | /* Don't restore them in KMS mode */ |
417 | /* Actually enable it */ | 539 | i915_restore_modeset_reg(dev); |
418 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
419 | DRM_UDELAY(150); | ||
420 | if (IS_I965G(dev)) | ||
421 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
422 | DRM_UDELAY(150); | ||
423 | |||
424 | /* Restore mode */ | ||
425 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
426 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
427 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
428 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
429 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
430 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
431 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
432 | |||
433 | /* Restore plane info */ | ||
434 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
435 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
436 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
437 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
438 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
439 | if (IS_I965G(dev)) { | ||
440 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
441 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
442 | } | ||
443 | |||
444 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
445 | |||
446 | i915_restore_palette(dev, PIPE_A); | ||
447 | /* Enable the plane */ | ||
448 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
449 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
450 | |||
451 | /* Pipe & plane B info */ | ||
452 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
453 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
454 | ~DPLL_VCO_ENABLE); | ||
455 | DRM_UDELAY(150); | ||
456 | } | ||
457 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
458 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
459 | /* Actually enable it */ | ||
460 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
461 | DRM_UDELAY(150); | ||
462 | if (IS_I965G(dev)) | ||
463 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
464 | DRM_UDELAY(150); | ||
465 | |||
466 | /* Restore mode */ | ||
467 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
468 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
469 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
470 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
471 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
472 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
473 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
474 | |||
475 | /* Restore plane info */ | ||
476 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
477 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
478 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
479 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
480 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
481 | if (IS_I965G(dev)) { | ||
482 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
483 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
484 | } | ||
485 | |||
486 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
487 | |||
488 | i915_restore_palette(dev, PIPE_B); | ||
489 | /* Enable the plane */ | ||
490 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
491 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
492 | |||
493 | /* Cursor state */ | 540 | /* Cursor state */ |
494 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); | 541 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); |
495 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); | 542 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); |
@@ -518,6 +565,12 @@ int i915_restore_state(struct drm_device *dev) | |||
518 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); | 565 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); |
519 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); | 566 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); |
520 | 567 | ||
568 | /* Display Port state */ | ||
569 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
570 | I915_WRITE(DP_B, dev_priv->saveDP_B); | ||
571 | I915_WRITE(DP_C, dev_priv->saveDP_C); | ||
572 | I915_WRITE(DP_D, dev_priv->saveDP_D); | ||
573 | } | ||
521 | /* FIXME: restore TV & SDVO state */ | 574 | /* FIXME: restore TV & SDVO state */ |
522 | 575 | ||
523 | /* FBC info */ | 576 | /* FBC info */ |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index cdd126d068a7..7cc447191028 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -97,11 +97,14 @@ static void | |||
97 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, | 97 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, |
98 | struct bdb_header *bdb) | 98 | struct bdb_header *bdb) |
99 | { | 99 | { |
100 | struct drm_device *dev = dev_priv->dev; | ||
100 | struct bdb_lvds_options *lvds_options; | 101 | struct bdb_lvds_options *lvds_options; |
101 | struct bdb_lvds_lfp_data *lvds_lfp_data; | 102 | struct bdb_lvds_lfp_data *lvds_lfp_data; |
103 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; | ||
102 | struct bdb_lvds_lfp_data_entry *entry; | 104 | struct bdb_lvds_lfp_data_entry *entry; |
103 | struct lvds_dvo_timing *dvo_timing; | 105 | struct lvds_dvo_timing *dvo_timing; |
104 | struct drm_display_mode *panel_fixed_mode; | 106 | struct drm_display_mode *panel_fixed_mode; |
107 | int lfp_data_size; | ||
105 | 108 | ||
106 | /* Defaults if we can't find VBT info */ | 109 | /* Defaults if we can't find VBT info */ |
107 | dev_priv->lvds_dither = 0; | 110 | dev_priv->lvds_dither = 0; |
@@ -119,10 +122,25 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
119 | if (!lvds_lfp_data) | 122 | if (!lvds_lfp_data) |
120 | return; | 123 | return; |
121 | 124 | ||
125 | lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); | ||
126 | if (!lvds_lfp_data_ptrs) | ||
127 | return; | ||
128 | |||
122 | dev_priv->lvds_vbt = 1; | 129 | dev_priv->lvds_vbt = 1; |
123 | 130 | ||
124 | entry = &lvds_lfp_data->data[lvds_options->panel_type]; | 131 | lfp_data_size = lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset - |
125 | dvo_timing = &entry->dvo_timing; | 132 | lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset; |
133 | entry = (struct bdb_lvds_lfp_data_entry *) | ||
134 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * | ||
135 | lvds_options->panel_type)); | ||
136 | |||
137 | /* On IGDNG mobile, LVDS data block removes panel fitting registers. | ||
138 | So dec 2 dword from dvo_timing offset */ | ||
139 | if (IS_IGDNG(dev)) | ||
140 | dvo_timing = (struct lvds_dvo_timing *) | ||
141 | ((u8 *)&entry->dvo_timing - 8); | ||
142 | else | ||
143 | dvo_timing = &entry->dvo_timing; | ||
126 | 144 | ||
127 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); | 145 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
128 | 146 | ||
@@ -185,10 +203,12 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
185 | dev_priv->lvds_use_ssc = general->enable_ssc; | 203 | dev_priv->lvds_use_ssc = general->enable_ssc; |
186 | 204 | ||
187 | if (dev_priv->lvds_use_ssc) { | 205 | if (dev_priv->lvds_use_ssc) { |
188 | if (IS_I855(dev_priv->dev)) | 206 | if (IS_I85X(dev_priv->dev)) |
189 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; | 207 | dev_priv->lvds_ssc_freq = |
190 | else | 208 | general->ssc_freq ? 66 : 48; |
191 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; | 209 | else |
210 | dev_priv->lvds_ssc_freq = | ||
211 | general->ssc_freq ? 100 : 96; | ||
192 | } | 212 | } |
193 | } | 213 | } |
194 | } | 214 | } |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 6de97fc66029..d6a1a6e5539a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -46,7 +46,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
46 | 46 | ||
47 | temp = I915_READ(reg); | 47 | temp = I915_READ(reg); |
48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | 48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
49 | temp |= ADPA_DAC_ENABLE; | 49 | temp &= ~ADPA_DAC_ENABLE; |
50 | 50 | ||
51 | switch(mode) { | 51 | switch(mode) { |
52 | case DRM_MODE_DPMS_ON: | 52 | case DRM_MODE_DPMS_ON: |
@@ -428,8 +428,34 @@ static void intel_crt_destroy(struct drm_connector *connector) | |||
428 | 428 | ||
429 | static int intel_crt_get_modes(struct drm_connector *connector) | 429 | static int intel_crt_get_modes(struct drm_connector *connector) |
430 | { | 430 | { |
431 | int ret; | ||
431 | struct intel_output *intel_output = to_intel_output(connector); | 432 | struct intel_output *intel_output = to_intel_output(connector); |
432 | return intel_ddc_get_modes(intel_output); | 433 | struct i2c_adapter *ddcbus; |
434 | struct drm_device *dev = connector->dev; | ||
435 | |||
436 | |||
437 | ret = intel_ddc_get_modes(intel_output); | ||
438 | if (ret || !IS_G4X(dev)) | ||
439 | goto end; | ||
440 | |||
441 | ddcbus = intel_output->ddc_bus; | ||
442 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | ||
443 | intel_output->ddc_bus = | ||
444 | intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); | ||
445 | |||
446 | if (!intel_output->ddc_bus) { | ||
447 | intel_output->ddc_bus = ddcbus; | ||
448 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, | ||
449 | "DDC bus registration failed for CRTDDC_D.\n"); | ||
450 | goto end; | ||
451 | } | ||
452 | /* Try to get modes by GPIOD port */ | ||
453 | ret = intel_ddc_get_modes(intel_output); | ||
454 | intel_i2c_destroy(ddcbus); | ||
455 | |||
456 | end: | ||
457 | return ret; | ||
458 | |||
433 | } | 459 | } |
434 | 460 | ||
435 | static int intel_crt_set_property(struct drm_connector *connector, | 461 | static int intel_crt_set_property(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3e1c78162119..508838ee31e0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -25,14 +25,17 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/kernel.h> | ||
28 | #include "drmP.h" | 29 | #include "drmP.h" |
29 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
30 | #include "i915_drm.h" | 31 | #include "i915_drm.h" |
31 | #include "i915_drv.h" | 32 | #include "i915_drv.h" |
33 | #include "intel_dp.h" | ||
32 | 34 | ||
33 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
34 | 36 | ||
35 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 37 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
38 | static void intel_update_watermarks(struct drm_device *dev); | ||
36 | 39 | ||
37 | typedef struct { | 40 | typedef struct { |
38 | /* given values */ | 41 | /* given values */ |
@@ -127,19 +130,6 @@ struct intel_limit { | |||
127 | #define I9XX_P2_LVDS_FAST 7 | 130 | #define I9XX_P2_LVDS_FAST 7 |
128 | #define I9XX_P2_LVDS_SLOW_LIMIT 112000 | 131 | #define I9XX_P2_LVDS_SLOW_LIMIT 112000 |
129 | 132 | ||
130 | #define INTEL_LIMIT_I8XX_DVO_DAC 0 | ||
131 | #define INTEL_LIMIT_I8XX_LVDS 1 | ||
132 | #define INTEL_LIMIT_I9XX_SDVO_DAC 2 | ||
133 | #define INTEL_LIMIT_I9XX_LVDS 3 | ||
134 | #define INTEL_LIMIT_G4X_SDVO 4 | ||
135 | #define INTEL_LIMIT_G4X_HDMI_DAC 5 | ||
136 | #define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6 | ||
137 | #define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7 | ||
138 | #define INTEL_LIMIT_IGD_SDVO_DAC 8 | ||
139 | #define INTEL_LIMIT_IGD_LVDS 9 | ||
140 | #define INTEL_LIMIT_IGDNG_SDVO_DAC 10 | ||
141 | #define INTEL_LIMIT_IGDNG_LVDS 11 | ||
142 | |||
143 | /*The parameter is for SDVO on G4x platform*/ | 133 | /*The parameter is for SDVO on G4x platform*/ |
144 | #define G4X_DOT_SDVO_MIN 25000 | 134 | #define G4X_DOT_SDVO_MIN 25000 |
145 | #define G4X_DOT_SDVO_MAX 270000 | 135 | #define G4X_DOT_SDVO_MAX 270000 |
@@ -218,6 +208,25 @@ struct intel_limit { | |||
218 | #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 | 208 | #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 |
219 | #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 | 209 | #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 |
220 | 210 | ||
211 | /*The parameter is for DISPLAY PORT on G4x platform*/ | ||
212 | #define G4X_DOT_DISPLAY_PORT_MIN 161670 | ||
213 | #define G4X_DOT_DISPLAY_PORT_MAX 227000 | ||
214 | #define G4X_N_DISPLAY_PORT_MIN 1 | ||
215 | #define G4X_N_DISPLAY_PORT_MAX 2 | ||
216 | #define G4X_M_DISPLAY_PORT_MIN 97 | ||
217 | #define G4X_M_DISPLAY_PORT_MAX 108 | ||
218 | #define G4X_M1_DISPLAY_PORT_MIN 0x10 | ||
219 | #define G4X_M1_DISPLAY_PORT_MAX 0x12 | ||
220 | #define G4X_M2_DISPLAY_PORT_MIN 0x05 | ||
221 | #define G4X_M2_DISPLAY_PORT_MAX 0x06 | ||
222 | #define G4X_P_DISPLAY_PORT_MIN 10 | ||
223 | #define G4X_P_DISPLAY_PORT_MAX 20 | ||
224 | #define G4X_P1_DISPLAY_PORT_MIN 1 | ||
225 | #define G4X_P1_DISPLAY_PORT_MAX 2 | ||
226 | #define G4X_P2_DISPLAY_PORT_SLOW 10 | ||
227 | #define G4X_P2_DISPLAY_PORT_FAST 10 | ||
228 | #define G4X_P2_DISPLAY_PORT_LIMIT 0 | ||
229 | |||
221 | /* IGDNG */ | 230 | /* IGDNG */ |
222 | /* as we calculate clock using (register_value + 2) for | 231 | /* as we calculate clock using (register_value + 2) for |
223 | N/M1/M2, so here the range value for them is (actual_value-2). | 232 | N/M1/M2, so here the range value for them is (actual_value-2). |
@@ -256,8 +265,11 @@ static bool | |||
256 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 265 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
257 | int target, int refclk, intel_clock_t *best_clock); | 266 | int target, int refclk, intel_clock_t *best_clock); |
258 | 267 | ||
259 | static const intel_limit_t intel_limits[] = { | 268 | static bool |
260 | { /* INTEL_LIMIT_I8XX_DVO_DAC */ | 269 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
270 | int target, int refclk, intel_clock_t *best_clock); | ||
271 | |||
272 | static const intel_limit_t intel_limits_i8xx_dvo = { | ||
261 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 273 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
262 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, | 274 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, |
263 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, | 275 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, |
@@ -269,8 +281,9 @@ static const intel_limit_t intel_limits[] = { | |||
269 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 281 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
270 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, | 282 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, |
271 | .find_pll = intel_find_best_PLL, | 283 | .find_pll = intel_find_best_PLL, |
272 | }, | 284 | }; |
273 | { /* INTEL_LIMIT_I8XX_LVDS */ | 285 | |
286 | static const intel_limit_t intel_limits_i8xx_lvds = { | ||
274 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 287 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
275 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, | 288 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, |
276 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, | 289 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, |
@@ -282,8 +295,9 @@ static const intel_limit_t intel_limits[] = { | |||
282 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 295 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
283 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, | 296 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, |
284 | .find_pll = intel_find_best_PLL, | 297 | .find_pll = intel_find_best_PLL, |
285 | }, | 298 | }; |
286 | { /* INTEL_LIMIT_I9XX_SDVO_DAC */ | 299 | |
300 | static const intel_limit_t intel_limits_i9xx_sdvo = { | ||
287 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 301 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
288 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, | 302 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, |
289 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, | 303 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, |
@@ -295,8 +309,9 @@ static const intel_limit_t intel_limits[] = { | |||
295 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 309 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
296 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 310 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
297 | .find_pll = intel_find_best_PLL, | 311 | .find_pll = intel_find_best_PLL, |
298 | }, | 312 | }; |
299 | { /* INTEL_LIMIT_I9XX_LVDS */ | 313 | |
314 | static const intel_limit_t intel_limits_i9xx_lvds = { | ||
300 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 315 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
301 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, | 316 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, |
302 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, | 317 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, |
@@ -311,9 +326,10 @@ static const intel_limit_t intel_limits[] = { | |||
311 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 326 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
312 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, | 327 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, |
313 | .find_pll = intel_find_best_PLL, | 328 | .find_pll = intel_find_best_PLL, |
314 | }, | 329 | }; |
330 | |||
315 | /* below parameter and function is for G4X Chipset Family*/ | 331 | /* below parameter and function is for G4X Chipset Family*/ |
316 | { /* INTEL_LIMIT_G4X_SDVO */ | 332 | static const intel_limit_t intel_limits_g4x_sdvo = { |
317 | .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, | 333 | .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, |
318 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | 334 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, |
319 | .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, | 335 | .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, |
@@ -327,8 +343,9 @@ static const intel_limit_t intel_limits[] = { | |||
327 | .p2_fast = G4X_P2_SDVO_FAST | 343 | .p2_fast = G4X_P2_SDVO_FAST |
328 | }, | 344 | }, |
329 | .find_pll = intel_g4x_find_best_PLL, | 345 | .find_pll = intel_g4x_find_best_PLL, |
330 | }, | 346 | }; |
331 | { /* INTEL_LIMIT_G4X_HDMI_DAC */ | 347 | |
348 | static const intel_limit_t intel_limits_g4x_hdmi = { | ||
332 | .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, | 349 | .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, |
333 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | 350 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, |
334 | .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, | 351 | .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, |
@@ -342,8 +359,9 @@ static const intel_limit_t intel_limits[] = { | |||
342 | .p2_fast = G4X_P2_HDMI_DAC_FAST | 359 | .p2_fast = G4X_P2_HDMI_DAC_FAST |
343 | }, | 360 | }, |
344 | .find_pll = intel_g4x_find_best_PLL, | 361 | .find_pll = intel_g4x_find_best_PLL, |
345 | }, | 362 | }; |
346 | { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */ | 363 | |
364 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | ||
347 | .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, | 365 | .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, |
348 | .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, | 366 | .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, |
349 | .vco = { .min = G4X_VCO_MIN, | 367 | .vco = { .min = G4X_VCO_MIN, |
@@ -365,8 +383,9 @@ static const intel_limit_t intel_limits[] = { | |||
365 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST | 383 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST |
366 | }, | 384 | }, |
367 | .find_pll = intel_g4x_find_best_PLL, | 385 | .find_pll = intel_g4x_find_best_PLL, |
368 | }, | 386 | }; |
369 | { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */ | 387 | |
388 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | ||
370 | .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, | 389 | .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, |
371 | .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, | 390 | .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, |
372 | .vco = { .min = G4X_VCO_MIN, | 391 | .vco = { .min = G4X_VCO_MIN, |
@@ -388,8 +407,32 @@ static const intel_limit_t intel_limits[] = { | |||
388 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST | 407 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST |
389 | }, | 408 | }, |
390 | .find_pll = intel_g4x_find_best_PLL, | 409 | .find_pll = intel_g4x_find_best_PLL, |
391 | }, | 410 | }; |
392 | { /* INTEL_LIMIT_IGD_SDVO */ | 411 | |
412 | static const intel_limit_t intel_limits_g4x_display_port = { | ||
413 | .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN, | ||
414 | .max = G4X_DOT_DISPLAY_PORT_MAX }, | ||
415 | .vco = { .min = G4X_VCO_MIN, | ||
416 | .max = G4X_VCO_MAX}, | ||
417 | .n = { .min = G4X_N_DISPLAY_PORT_MIN, | ||
418 | .max = G4X_N_DISPLAY_PORT_MAX }, | ||
419 | .m = { .min = G4X_M_DISPLAY_PORT_MIN, | ||
420 | .max = G4X_M_DISPLAY_PORT_MAX }, | ||
421 | .m1 = { .min = G4X_M1_DISPLAY_PORT_MIN, | ||
422 | .max = G4X_M1_DISPLAY_PORT_MAX }, | ||
423 | .m2 = { .min = G4X_M2_DISPLAY_PORT_MIN, | ||
424 | .max = G4X_M2_DISPLAY_PORT_MAX }, | ||
425 | .p = { .min = G4X_P_DISPLAY_PORT_MIN, | ||
426 | .max = G4X_P_DISPLAY_PORT_MAX }, | ||
427 | .p1 = { .min = G4X_P1_DISPLAY_PORT_MIN, | ||
428 | .max = G4X_P1_DISPLAY_PORT_MAX}, | ||
429 | .p2 = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT, | ||
430 | .p2_slow = G4X_P2_DISPLAY_PORT_SLOW, | ||
431 | .p2_fast = G4X_P2_DISPLAY_PORT_FAST }, | ||
432 | .find_pll = intel_find_pll_g4x_dp, | ||
433 | }; | ||
434 | |||
435 | static const intel_limit_t intel_limits_igd_sdvo = { | ||
393 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, | 436 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, |
394 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, | 437 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, |
395 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, | 438 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, |
@@ -401,8 +444,9 @@ static const intel_limit_t intel_limits[] = { | |||
401 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 444 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
402 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 445 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
403 | .find_pll = intel_find_best_PLL, | 446 | .find_pll = intel_find_best_PLL, |
404 | }, | 447 | }; |
405 | { /* INTEL_LIMIT_IGD_LVDS */ | 448 | |
449 | static const intel_limit_t intel_limits_igd_lvds = { | ||
406 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 450 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
407 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, | 451 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, |
408 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, | 452 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, |
@@ -415,8 +459,9 @@ static const intel_limit_t intel_limits[] = { | |||
415 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 459 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
416 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, | 460 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, |
417 | .find_pll = intel_find_best_PLL, | 461 | .find_pll = intel_find_best_PLL, |
418 | }, | 462 | }; |
419 | { /* INTEL_LIMIT_IGDNG_SDVO_DAC */ | 463 | |
464 | static const intel_limit_t intel_limits_igdng_sdvo = { | ||
420 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, | 465 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, |
421 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, | 466 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, |
422 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, | 467 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, |
@@ -429,8 +474,9 @@ static const intel_limit_t intel_limits[] = { | |||
429 | .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, | 474 | .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, |
430 | .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, | 475 | .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, |
431 | .find_pll = intel_igdng_find_best_PLL, | 476 | .find_pll = intel_igdng_find_best_PLL, |
432 | }, | 477 | }; |
433 | { /* INTEL_LIMIT_IGDNG_LVDS */ | 478 | |
479 | static const intel_limit_t intel_limits_igdng_lvds = { | ||
434 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, | 480 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, |
435 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, | 481 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, |
436 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, | 482 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, |
@@ -443,16 +489,15 @@ static const intel_limit_t intel_limits[] = { | |||
443 | .p2_slow = IGDNG_P2_LVDS_SLOW, | 489 | .p2_slow = IGDNG_P2_LVDS_SLOW, |
444 | .p2_fast = IGDNG_P2_LVDS_FAST }, | 490 | .p2_fast = IGDNG_P2_LVDS_FAST }, |
445 | .find_pll = intel_igdng_find_best_PLL, | 491 | .find_pll = intel_igdng_find_best_PLL, |
446 | }, | ||
447 | }; | 492 | }; |
448 | 493 | ||
449 | static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) | 494 | static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) |
450 | { | 495 | { |
451 | const intel_limit_t *limit; | 496 | const intel_limit_t *limit; |
452 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 497 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
453 | limit = &intel_limits[INTEL_LIMIT_IGDNG_LVDS]; | 498 | limit = &intel_limits_igdng_lvds; |
454 | else | 499 | else |
455 | limit = &intel_limits[INTEL_LIMIT_IGDNG_SDVO_DAC]; | 500 | limit = &intel_limits_igdng_sdvo; |
456 | 501 | ||
457 | return limit; | 502 | return limit; |
458 | } | 503 | } |
@@ -467,19 +512,19 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) | |||
467 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 512 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
468 | LVDS_CLKB_POWER_UP) | 513 | LVDS_CLKB_POWER_UP) |
469 | /* LVDS with dual channel */ | 514 | /* LVDS with dual channel */ |
470 | limit = &intel_limits | 515 | limit = &intel_limits_g4x_dual_channel_lvds; |
471 | [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS]; | ||
472 | else | 516 | else |
473 | /* LVDS with dual channel */ | 517 | /* LVDS with dual channel */ |
474 | limit = &intel_limits | 518 | limit = &intel_limits_g4x_single_channel_lvds; |
475 | [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS]; | ||
476 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || | 519 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || |
477 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { | 520 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { |
478 | limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; | 521 | limit = &intel_limits_g4x_hdmi; |
479 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { | 522 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { |
480 | limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; | 523 | limit = &intel_limits_g4x_sdvo; |
524 | } else if (intel_pipe_has_type (crtc, INTEL_OUTPUT_DISPLAYPORT)) { | ||
525 | limit = &intel_limits_g4x_display_port; | ||
481 | } else /* The option is for other outputs */ | 526 | } else /* The option is for other outputs */ |
482 | limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; | 527 | limit = &intel_limits_i9xx_sdvo; |
483 | 528 | ||
484 | return limit; | 529 | return limit; |
485 | } | 530 | } |
@@ -495,19 +540,19 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) | |||
495 | limit = intel_g4x_limit(crtc); | 540 | limit = intel_g4x_limit(crtc); |
496 | } else if (IS_I9XX(dev) && !IS_IGD(dev)) { | 541 | } else if (IS_I9XX(dev) && !IS_IGD(dev)) { |
497 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 542 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
498 | limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; | 543 | limit = &intel_limits_i9xx_lvds; |
499 | else | 544 | else |
500 | limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; | 545 | limit = &intel_limits_i9xx_sdvo; |
501 | } else if (IS_IGD(dev)) { | 546 | } else if (IS_IGD(dev)) { |
502 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 547 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
503 | limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; | 548 | limit = &intel_limits_igd_lvds; |
504 | else | 549 | else |
505 | limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; | 550 | limit = &intel_limits_igd_sdvo; |
506 | } else { | 551 | } else { |
507 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 552 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
508 | limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; | 553 | limit = &intel_limits_i8xx_lvds; |
509 | else | 554 | else |
510 | limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; | 555 | limit = &intel_limits_i8xx_dvo; |
511 | } | 556 | } |
512 | return limit; | 557 | return limit; |
513 | } | 558 | } |
@@ -764,6 +809,32 @@ out: | |||
764 | return found; | 809 | return found; |
765 | } | 810 | } |
766 | 811 | ||
812 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | ||
813 | static bool | ||
814 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
815 | int target, int refclk, intel_clock_t *best_clock) | ||
816 | { | ||
817 | intel_clock_t clock; | ||
818 | if (target < 200000) { | ||
819 | clock.p1 = 2; | ||
820 | clock.p2 = 10; | ||
821 | clock.n = 2; | ||
822 | clock.m1 = 23; | ||
823 | clock.m2 = 8; | ||
824 | } else { | ||
825 | clock.p1 = 1; | ||
826 | clock.p2 = 10; | ||
827 | clock.n = 1; | ||
828 | clock.m1 = 14; | ||
829 | clock.m2 = 2; | ||
830 | } | ||
831 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); | ||
832 | clock.p = (clock.p1 * clock.p2); | ||
833 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; | ||
834 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | ||
835 | return true; | ||
836 | } | ||
837 | |||
767 | void | 838 | void |
768 | intel_wait_for_vblank(struct drm_device *dev) | 839 | intel_wait_for_vblank(struct drm_device *dev) |
769 | { | 840 | { |
@@ -933,7 +1004,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
933 | struct drm_i915_private *dev_priv = dev->dev_private; | 1004 | struct drm_i915_private *dev_priv = dev->dev_private; |
934 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1005 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
935 | int pipe = intel_crtc->pipe; | 1006 | int pipe = intel_crtc->pipe; |
936 | int plane = intel_crtc->pipe; | 1007 | int plane = intel_crtc->plane; |
937 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | 1008 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; |
938 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | 1009 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; |
939 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | 1010 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; |
@@ -1263,8 +1334,10 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1263 | 1334 | ||
1264 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 1335 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
1265 | //intel_crtc_dpms_video(crtc, true); TODO | 1336 | //intel_crtc_dpms_video(crtc, true); TODO |
1337 | intel_update_watermarks(dev); | ||
1266 | break; | 1338 | break; |
1267 | case DRM_MODE_DPMS_OFF: | 1339 | case DRM_MODE_DPMS_OFF: |
1340 | intel_update_watermarks(dev); | ||
1268 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1341 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1269 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1342 | //intel_crtc_dpms_video(crtc, FALSE); TODO |
1270 | 1343 | ||
@@ -1443,7 +1516,6 @@ static int intel_get_core_clock_speed(struct drm_device *dev) | |||
1443 | return 0; /* Silence gcc warning */ | 1516 | return 0; /* Silence gcc warning */ |
1444 | } | 1517 | } |
1445 | 1518 | ||
1446 | |||
1447 | /** | 1519 | /** |
1448 | * Return the pipe currently connected to the panel fitter, | 1520 | * Return the pipe currently connected to the panel fitter, |
1449 | * or -1 if the panel fitter is not present or not in use | 1521 | * or -1 if the panel fitter is not present or not in use |
@@ -1502,7 +1574,7 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1502 | 1574 | ||
1503 | temp = (u64) DATA_N * pixel_clock; | 1575 | temp = (u64) DATA_N * pixel_clock; |
1504 | temp = div_u64(temp, link_clock); | 1576 | temp = div_u64(temp, link_clock); |
1505 | m_n->gmch_m = (temp * bytes_per_pixel) / nlanes; | 1577 | m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); |
1506 | m_n->gmch_n = DATA_N; | 1578 | m_n->gmch_n = DATA_N; |
1507 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 1579 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
1508 | 1580 | ||
@@ -1513,6 +1585,420 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1513 | } | 1585 | } |
1514 | 1586 | ||
1515 | 1587 | ||
1588 | struct intel_watermark_params { | ||
1589 | unsigned long fifo_size; | ||
1590 | unsigned long max_wm; | ||
1591 | unsigned long default_wm; | ||
1592 | unsigned long guard_size; | ||
1593 | unsigned long cacheline_size; | ||
1594 | }; | ||
1595 | |||
1596 | /* IGD has different values for various configs */ | ||
1597 | static struct intel_watermark_params igd_display_wm = { | ||
1598 | IGD_DISPLAY_FIFO, | ||
1599 | IGD_MAX_WM, | ||
1600 | IGD_DFT_WM, | ||
1601 | IGD_GUARD_WM, | ||
1602 | IGD_FIFO_LINE_SIZE | ||
1603 | }; | ||
1604 | static struct intel_watermark_params igd_display_hplloff_wm = { | ||
1605 | IGD_DISPLAY_FIFO, | ||
1606 | IGD_MAX_WM, | ||
1607 | IGD_DFT_HPLLOFF_WM, | ||
1608 | IGD_GUARD_WM, | ||
1609 | IGD_FIFO_LINE_SIZE | ||
1610 | }; | ||
1611 | static struct intel_watermark_params igd_cursor_wm = { | ||
1612 | IGD_CURSOR_FIFO, | ||
1613 | IGD_CURSOR_MAX_WM, | ||
1614 | IGD_CURSOR_DFT_WM, | ||
1615 | IGD_CURSOR_GUARD_WM, | ||
1616 | IGD_FIFO_LINE_SIZE, | ||
1617 | }; | ||
1618 | static struct intel_watermark_params igd_cursor_hplloff_wm = { | ||
1619 | IGD_CURSOR_FIFO, | ||
1620 | IGD_CURSOR_MAX_WM, | ||
1621 | IGD_CURSOR_DFT_WM, | ||
1622 | IGD_CURSOR_GUARD_WM, | ||
1623 | IGD_FIFO_LINE_SIZE | ||
1624 | }; | ||
1625 | static struct intel_watermark_params i945_wm_info = { | ||
1626 | I915_FIFO_LINE_SIZE, | ||
1627 | I915_MAX_WM, | ||
1628 | 1, | ||
1629 | 0, | ||
1630 | IGD_FIFO_LINE_SIZE | ||
1631 | }; | ||
1632 | static struct intel_watermark_params i915_wm_info = { | ||
1633 | I945_FIFO_SIZE, | ||
1634 | I915_MAX_WM, | ||
1635 | 1, | ||
1636 | 0, | ||
1637 | I915_FIFO_LINE_SIZE | ||
1638 | }; | ||
1639 | static struct intel_watermark_params i855_wm_info = { | ||
1640 | I855GM_FIFO_SIZE, | ||
1641 | I915_MAX_WM, | ||
1642 | 1, | ||
1643 | 0, | ||
1644 | I830_FIFO_LINE_SIZE | ||
1645 | }; | ||
1646 | static struct intel_watermark_params i830_wm_info = { | ||
1647 | I830_FIFO_SIZE, | ||
1648 | I915_MAX_WM, | ||
1649 | 1, | ||
1650 | 0, | ||
1651 | I830_FIFO_LINE_SIZE | ||
1652 | }; | ||
1653 | |||
1654 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | ||
1655 | struct intel_watermark_params *wm, | ||
1656 | int pixel_size, | ||
1657 | unsigned long latency_ns) | ||
1658 | { | ||
1659 | unsigned long bytes_required, wm_size; | ||
1660 | |||
1661 | bytes_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; | ||
1662 | bytes_required /= wm->cacheline_size; | ||
1663 | wm_size = wm->fifo_size - bytes_required - wm->guard_size; | ||
1664 | |||
1665 | if (wm_size > wm->max_wm) | ||
1666 | wm_size = wm->max_wm; | ||
1667 | if (wm_size == 0) | ||
1668 | wm_size = wm->default_wm; | ||
1669 | return wm_size; | ||
1670 | } | ||
1671 | |||
1672 | struct cxsr_latency { | ||
1673 | int is_desktop; | ||
1674 | unsigned long fsb_freq; | ||
1675 | unsigned long mem_freq; | ||
1676 | unsigned long display_sr; | ||
1677 | unsigned long display_hpll_disable; | ||
1678 | unsigned long cursor_sr; | ||
1679 | unsigned long cursor_hpll_disable; | ||
1680 | }; | ||
1681 | |||
1682 | static struct cxsr_latency cxsr_latency_table[] = { | ||
1683 | {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | ||
1684 | {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | ||
1685 | {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | ||
1686 | |||
1687 | {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | ||
1688 | {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | ||
1689 | {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | ||
1690 | |||
1691 | {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | ||
1692 | {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | ||
1693 | {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | ||
1694 | |||
1695 | {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | ||
1696 | {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | ||
1697 | {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | ||
1698 | |||
1699 | {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
1700 | {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
1701 | {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
1702 | |||
1703 | {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
1704 | {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
1705 | {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
1706 | }; | ||
1707 | |||
1708 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | ||
1709 | int mem) | ||
1710 | { | ||
1711 | int i; | ||
1712 | struct cxsr_latency *latency; | ||
1713 | |||
1714 | if (fsb == 0 || mem == 0) | ||
1715 | return NULL; | ||
1716 | |||
1717 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | ||
1718 | latency = &cxsr_latency_table[i]; | ||
1719 | if (is_desktop == latency->is_desktop && | ||
1720 | fsb == latency->fsb_freq && mem == latency->mem_freq) | ||
1721 | break; | ||
1722 | } | ||
1723 | if (i >= ARRAY_SIZE(cxsr_latency_table)) { | ||
1724 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1725 | return NULL; | ||
1726 | } | ||
1727 | return latency; | ||
1728 | } | ||
1729 | |||
1730 | static void igd_disable_cxsr(struct drm_device *dev) | ||
1731 | { | ||
1732 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1733 | u32 reg; | ||
1734 | |||
1735 | /* deactivate cxsr */ | ||
1736 | reg = I915_READ(DSPFW3); | ||
1737 | reg &= ~(IGD_SELF_REFRESH_EN); | ||
1738 | I915_WRITE(DSPFW3, reg); | ||
1739 | DRM_INFO("Big FIFO is disabled\n"); | ||
1740 | } | ||
1741 | |||
1742 | static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | ||
1743 | int pixel_size) | ||
1744 | { | ||
1745 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1746 | u32 reg; | ||
1747 | unsigned long wm; | ||
1748 | struct cxsr_latency *latency; | ||
1749 | |||
1750 | latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq, | ||
1751 | dev_priv->mem_freq); | ||
1752 | if (!latency) { | ||
1753 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1754 | igd_disable_cxsr(dev); | ||
1755 | return; | ||
1756 | } | ||
1757 | |||
1758 | /* Display SR */ | ||
1759 | wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size, | ||
1760 | latency->display_sr); | ||
1761 | reg = I915_READ(DSPFW1); | ||
1762 | reg &= 0x7fffff; | ||
1763 | reg |= wm << 23; | ||
1764 | I915_WRITE(DSPFW1, reg); | ||
1765 | DRM_DEBUG("DSPFW1 register is %x\n", reg); | ||
1766 | |||
1767 | /* cursor SR */ | ||
1768 | wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size, | ||
1769 | latency->cursor_sr); | ||
1770 | reg = I915_READ(DSPFW3); | ||
1771 | reg &= ~(0x3f << 24); | ||
1772 | reg |= (wm & 0x3f) << 24; | ||
1773 | I915_WRITE(DSPFW3, reg); | ||
1774 | |||
1775 | /* Display HPLL off SR */ | ||
1776 | wm = intel_calculate_wm(clock, &igd_display_hplloff_wm, | ||
1777 | latency->display_hpll_disable, I915_FIFO_LINE_SIZE); | ||
1778 | reg = I915_READ(DSPFW3); | ||
1779 | reg &= 0xfffffe00; | ||
1780 | reg |= wm & 0x1ff; | ||
1781 | I915_WRITE(DSPFW3, reg); | ||
1782 | |||
1783 | /* cursor HPLL off SR */ | ||
1784 | wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size, | ||
1785 | latency->cursor_hpll_disable); | ||
1786 | reg = I915_READ(DSPFW3); | ||
1787 | reg &= ~(0x3f << 16); | ||
1788 | reg |= (wm & 0x3f) << 16; | ||
1789 | I915_WRITE(DSPFW3, reg); | ||
1790 | DRM_DEBUG("DSPFW3 register is %x\n", reg); | ||
1791 | |||
1792 | /* activate cxsr */ | ||
1793 | reg = I915_READ(DSPFW3); | ||
1794 | reg |= IGD_SELF_REFRESH_EN; | ||
1795 | I915_WRITE(DSPFW3, reg); | ||
1796 | |||
1797 | DRM_INFO("Big FIFO is enabled\n"); | ||
1798 | |||
1799 | return; | ||
1800 | } | ||
1801 | |||
1802 | const static int latency_ns = 5000; /* default for non-igd platforms */ | ||
1803 | |||
1804 | |||
1805 | static void i965_update_wm(struct drm_device *dev) | ||
1806 | { | ||
1807 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1808 | |||
1809 | DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n"); | ||
1810 | |||
1811 | /* 965 has limitations... */ | ||
1812 | I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0)); | ||
1813 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | ||
1814 | } | ||
1815 | |||
1816 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | ||
1817 | int planeb_clock, int sr_hdisplay, int pixel_size) | ||
1818 | { | ||
1819 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1820 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | ||
1821 | uint32_t fwater_hi = I915_READ(FW_BLC2) & LM_FIFO_WATERMARK; | ||
1822 | int bsize, asize, cwm, bwm = 1, awm = 1, srwm = 1; | ||
1823 | uint32_t dsparb = I915_READ(DSPARB); | ||
1824 | int planea_entries, planeb_entries; | ||
1825 | struct intel_watermark_params *wm_params; | ||
1826 | unsigned long line_time_us; | ||
1827 | int sr_clock, sr_entries = 0; | ||
1828 | |||
1829 | if (IS_I965GM(dev) || IS_I945GM(dev)) | ||
1830 | wm_params = &i945_wm_info; | ||
1831 | else if (IS_I9XX(dev)) | ||
1832 | wm_params = &i915_wm_info; | ||
1833 | else | ||
1834 | wm_params = &i855_wm_info; | ||
1835 | |||
1836 | planea_entries = intel_calculate_wm(planea_clock, wm_params, | ||
1837 | pixel_size, latency_ns); | ||
1838 | planeb_entries = intel_calculate_wm(planeb_clock, wm_params, | ||
1839 | pixel_size, latency_ns); | ||
1840 | |||
1841 | DRM_DEBUG("FIFO entries - A: %d, B: %d\n", planea_entries, | ||
1842 | planeb_entries); | ||
1843 | |||
1844 | if (IS_I9XX(dev)) { | ||
1845 | asize = dsparb & 0x7f; | ||
1846 | bsize = (dsparb >> DSPARB_CSTART_SHIFT) & 0x7f; | ||
1847 | } else { | ||
1848 | asize = dsparb & 0x1ff; | ||
1849 | bsize = (dsparb >> DSPARB_BEND_SHIFT) & 0x1ff; | ||
1850 | } | ||
1851 | DRM_DEBUG("FIFO size - A: %d, B: %d\n", asize, bsize); | ||
1852 | |||
1853 | /* Two extra entries for padding */ | ||
1854 | awm = asize - (planea_entries + 2); | ||
1855 | bwm = bsize - (planeb_entries + 2); | ||
1856 | |||
1857 | /* Sanity check against potentially bad FIFO allocations */ | ||
1858 | if (awm <= 0) { | ||
1859 | /* pipe is on but has too few FIFO entries */ | ||
1860 | if (planea_entries != 0) | ||
1861 | DRM_DEBUG("plane A needs more FIFO entries\n"); | ||
1862 | awm = 1; | ||
1863 | } | ||
1864 | if (bwm <= 0) { | ||
1865 | if (planeb_entries != 0) | ||
1866 | DRM_DEBUG("plane B needs more FIFO entries\n"); | ||
1867 | bwm = 1; | ||
1868 | } | ||
1869 | |||
1870 | /* | ||
1871 | * Overlay gets an aggressive default since video jitter is bad. | ||
1872 | */ | ||
1873 | cwm = 2; | ||
1874 | |||
1875 | /* Calc sr entries for one pipe configs */ | ||
1876 | if (!planea_clock || !planeb_clock) { | ||
1877 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
1878 | line_time_us = (sr_hdisplay * 1000) / sr_clock; | ||
1879 | sr_entries = (((latency_ns / line_time_us) + 1) * pixel_size * | ||
1880 | sr_hdisplay) / 1000; | ||
1881 | sr_entries = roundup(sr_entries / wm_params->cacheline_size, 1); | ||
1882 | if (sr_entries < wm_params->fifo_size) | ||
1883 | srwm = wm_params->fifo_size - sr_entries; | ||
1884 | } | ||
1885 | |||
1886 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | ||
1887 | awm, bwm, cwm, srwm); | ||
1888 | |||
1889 | fwater_lo = fwater_lo | ((bwm & 0x3f) << 16) | (awm & 0x3f); | ||
1890 | fwater_hi = fwater_hi | (cwm & 0x1f); | ||
1891 | |||
1892 | I915_WRITE(FW_BLC, fwater_lo); | ||
1893 | I915_WRITE(FW_BLC2, fwater_hi); | ||
1894 | if (IS_I9XX(dev)) | ||
1895 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); | ||
1896 | } | ||
1897 | |||
1898 | static void i830_update_wm(struct drm_device *dev, int planea_clock, | ||
1899 | int pixel_size) | ||
1900 | { | ||
1901 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1902 | uint32_t dsparb = I915_READ(DSPARB); | ||
1903 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | ||
1904 | unsigned int asize, awm; | ||
1905 | int planea_entries; | ||
1906 | |||
1907 | planea_entries = intel_calculate_wm(planea_clock, &i830_wm_info, | ||
1908 | pixel_size, latency_ns); | ||
1909 | |||
1910 | asize = dsparb & 0x7f; | ||
1911 | |||
1912 | awm = asize - planea_entries; | ||
1913 | |||
1914 | fwater_lo = fwater_lo | awm; | ||
1915 | |||
1916 | I915_WRITE(FW_BLC, fwater_lo); | ||
1917 | } | ||
1918 | |||
1919 | /** | ||
1920 | * intel_update_watermarks - update FIFO watermark values based on current modes | ||
1921 | * | ||
1922 | * Calculate watermark values for the various WM regs based on current mode | ||
1923 | * and plane configuration. | ||
1924 | * | ||
1925 | * There are several cases to deal with here: | ||
1926 | * - normal (i.e. non-self-refresh) | ||
1927 | * - self-refresh (SR) mode | ||
1928 | * - lines are large relative to FIFO size (buffer can hold up to 2) | ||
1929 | * - lines are small relative to FIFO size (buffer can hold more than 2 | ||
1930 | * lines), so need to account for TLB latency | ||
1931 | * | ||
1932 | * The normal calculation is: | ||
1933 | * watermark = dotclock * bytes per pixel * latency | ||
1934 | * where latency is platform & configuration dependent (we assume pessimal | ||
1935 | * values here). | ||
1936 | * | ||
1937 | * The SR calculation is: | ||
1938 | * watermark = (trunc(latency/line time)+1) * surface width * | ||
1939 | * bytes per pixel | ||
1940 | * where | ||
1941 | * line time = htotal / dotclock | ||
1942 | * and latency is assumed to be high, as above. | ||
1943 | * | ||
1944 | * The final value programmed to the register should always be rounded up, | ||
1945 | * and include an extra 2 entries to account for clock crossings. | ||
1946 | * | ||
1947 | * We don't use the sprite, so we can ignore that. And on Crestline we have | ||
1948 | * to set the non-SR watermarks to 8. | ||
1949 | */ | ||
1950 | static void intel_update_watermarks(struct drm_device *dev) | ||
1951 | { | ||
1952 | struct drm_crtc *crtc; | ||
1953 | struct intel_crtc *intel_crtc; | ||
1954 | int sr_hdisplay = 0; | ||
1955 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | ||
1956 | int enabled = 0, pixel_size = 0; | ||
1957 | |||
1958 | if (DSPARB_HWCONTROL(dev)) | ||
1959 | return; | ||
1960 | |||
1961 | /* Get the clock config from both planes */ | ||
1962 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
1963 | intel_crtc = to_intel_crtc(crtc); | ||
1964 | if (crtc->enabled) { | ||
1965 | enabled++; | ||
1966 | if (intel_crtc->plane == 0) { | ||
1967 | DRM_DEBUG("plane A (pipe %d) clock: %d\n", | ||
1968 | intel_crtc->pipe, crtc->mode.clock); | ||
1969 | planea_clock = crtc->mode.clock; | ||
1970 | } else { | ||
1971 | DRM_DEBUG("plane B (pipe %d) clock: %d\n", | ||
1972 | intel_crtc->pipe, crtc->mode.clock); | ||
1973 | planeb_clock = crtc->mode.clock; | ||
1974 | } | ||
1975 | sr_hdisplay = crtc->mode.hdisplay; | ||
1976 | sr_clock = crtc->mode.clock; | ||
1977 | if (crtc->fb) | ||
1978 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
1979 | else | ||
1980 | pixel_size = 4; /* by default */ | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | if (enabled <= 0) | ||
1985 | return; | ||
1986 | |||
1987 | /* Single pipe configs can enable self refresh */ | ||
1988 | if (enabled == 1 && IS_IGD(dev)) | ||
1989 | igd_enable_cxsr(dev, sr_clock, pixel_size); | ||
1990 | else if (IS_IGD(dev)) | ||
1991 | igd_disable_cxsr(dev); | ||
1992 | |||
1993 | if (IS_I965G(dev)) | ||
1994 | i965_update_wm(dev); | ||
1995 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | ||
1996 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | ||
1997 | pixel_size); | ||
1998 | else | ||
1999 | i830_update_wm(dev, planea_clock, pixel_size); | ||
2000 | } | ||
2001 | |||
1516 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 2002 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
1517 | struct drm_display_mode *mode, | 2003 | struct drm_display_mode *mode, |
1518 | struct drm_display_mode *adjusted_mode, | 2004 | struct drm_display_mode *adjusted_mode, |
@@ -1541,7 +2027,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1541 | intel_clock_t clock; | 2027 | intel_clock_t clock; |
1542 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 2028 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; |
1543 | bool ok, is_sdvo = false, is_dvo = false; | 2029 | bool ok, is_sdvo = false, is_dvo = false; |
1544 | bool is_crt = false, is_lvds = false, is_tv = false; | 2030 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
1545 | struct drm_mode_config *mode_config = &dev->mode_config; | 2031 | struct drm_mode_config *mode_config = &dev->mode_config; |
1546 | struct drm_connector *connector; | 2032 | struct drm_connector *connector; |
1547 | const intel_limit_t *limit; | 2033 | const intel_limit_t *limit; |
@@ -1585,6 +2071,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1585 | case INTEL_OUTPUT_ANALOG: | 2071 | case INTEL_OUTPUT_ANALOG: |
1586 | is_crt = true; | 2072 | is_crt = true; |
1587 | break; | 2073 | break; |
2074 | case INTEL_OUTPUT_DISPLAYPORT: | ||
2075 | is_dp = true; | ||
2076 | break; | ||
1588 | } | 2077 | } |
1589 | 2078 | ||
1590 | num_outputs++; | 2079 | num_outputs++; |
@@ -1600,6 +2089,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1600 | } else { | 2089 | } else { |
1601 | refclk = 48000; | 2090 | refclk = 48000; |
1602 | } | 2091 | } |
2092 | |||
1603 | 2093 | ||
1604 | /* | 2094 | /* |
1605 | * Returns a set of divisors for the desired target clock with the given | 2095 | * Returns a set of divisors for the desired target clock with the given |
@@ -1662,6 +2152,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1662 | else if (IS_IGDNG(dev)) | 2152 | else if (IS_IGDNG(dev)) |
1663 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | 2153 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
1664 | } | 2154 | } |
2155 | if (is_dp) | ||
2156 | dpll |= DPLL_DVO_HIGH_SPEED; | ||
1665 | 2157 | ||
1666 | /* compute bitmask from p1 value */ | 2158 | /* compute bitmask from p1 value */ |
1667 | if (IS_IGD(dev)) | 2159 | if (IS_IGD(dev)) |
@@ -1809,6 +2301,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1809 | I915_WRITE(lvds_reg, lvds); | 2301 | I915_WRITE(lvds_reg, lvds); |
1810 | I915_READ(lvds_reg); | 2302 | I915_READ(lvds_reg); |
1811 | } | 2303 | } |
2304 | if (is_dp) | ||
2305 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | ||
1812 | 2306 | ||
1813 | I915_WRITE(fp_reg, fp); | 2307 | I915_WRITE(fp_reg, fp); |
1814 | I915_WRITE(dpll_reg, dpll); | 2308 | I915_WRITE(dpll_reg, dpll); |
@@ -1871,6 +2365,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1871 | 2365 | ||
1872 | /* Flush the plane changes */ | 2366 | /* Flush the plane changes */ |
1873 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 2367 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
2368 | |||
2369 | intel_update_watermarks(dev); | ||
2370 | |||
1874 | drm_vblank_post_modeset(dev, pipe); | 2371 | drm_vblank_post_modeset(dev, pipe); |
1875 | 2372 | ||
1876 | return ret; | 2373 | return ret; |
@@ -2359,6 +2856,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
2359 | 2856 | ||
2360 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); | 2857 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
2361 | intel_crtc->pipe = pipe; | 2858 | intel_crtc->pipe = pipe; |
2859 | intel_crtc->plane = pipe; | ||
2362 | for (i = 0; i < 256; i++) { | 2860 | for (i = 0; i < 256; i++) { |
2363 | intel_crtc->lut_r[i] = i; | 2861 | intel_crtc->lut_r[i] = i; |
2364 | intel_crtc->lut_g[i] = i; | 2862 | intel_crtc->lut_g[i] = i; |
@@ -2475,6 +2973,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2475 | found = intel_sdvo_init(dev, SDVOB); | 2973 | found = intel_sdvo_init(dev, SDVOB); |
2476 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 2974 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
2477 | intel_hdmi_init(dev, SDVOB); | 2975 | intel_hdmi_init(dev, SDVOB); |
2976 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | ||
2977 | intel_dp_init(dev, DP_B); | ||
2478 | } | 2978 | } |
2479 | 2979 | ||
2480 | /* Before G4X SDVOC doesn't have its own detect register */ | 2980 | /* Before G4X SDVOC doesn't have its own detect register */ |
@@ -2487,7 +2987,11 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2487 | found = intel_sdvo_init(dev, SDVOC); | 2987 | found = intel_sdvo_init(dev, SDVOC); |
2488 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 2988 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
2489 | intel_hdmi_init(dev, SDVOC); | 2989 | intel_hdmi_init(dev, SDVOC); |
2990 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | ||
2991 | intel_dp_init(dev, DP_C); | ||
2490 | } | 2992 | } |
2993 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | ||
2994 | intel_dp_init(dev, DP_D); | ||
2491 | } else | 2995 | } else |
2492 | intel_dvo_init(dev); | 2996 | intel_dvo_init(dev); |
2493 | 2997 | ||
@@ -2530,6 +3034,11 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2530 | (1 << 1)); | 3034 | (1 << 1)); |
2531 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); | 3035 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); |
2532 | break; | 3036 | break; |
3037 | case INTEL_OUTPUT_DISPLAYPORT: | ||
3038 | crtc_mask = ((1 << 0) | | ||
3039 | (1 << 1)); | ||
3040 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | ||
3041 | break; | ||
2533 | } | 3042 | } |
2534 | encoder->possible_crtcs = crtc_mask; | 3043 | encoder->possible_crtcs = crtc_mask; |
2535 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | 3044 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c new file mode 100644 index 000000000000..6770ae88370d --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -0,0 +1,1156 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Keith Packard <keithp@keithp.com> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/i2c.h> | ||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "drm_crtc.h" | ||
32 | #include "drm_crtc_helper.h" | ||
33 | #include "intel_drv.h" | ||
34 | #include "i915_drm.h" | ||
35 | #include "i915_drv.h" | ||
36 | #include "intel_dp.h" | ||
37 | |||
38 | #define DP_LINK_STATUS_SIZE 6 | ||
39 | #define DP_LINK_CHECK_TIMEOUT (10 * 1000) | ||
40 | |||
41 | #define DP_LINK_CONFIGURATION_SIZE 9 | ||
42 | |||
43 | struct intel_dp_priv { | ||
44 | uint32_t output_reg; | ||
45 | uint32_t DP; | ||
46 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
47 | uint32_t save_DP; | ||
48 | uint8_t save_link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
49 | bool has_audio; | ||
50 | int dpms_mode; | ||
51 | uint8_t link_bw; | ||
52 | uint8_t lane_count; | ||
53 | uint8_t dpcd[4]; | ||
54 | struct intel_output *intel_output; | ||
55 | struct i2c_adapter adapter; | ||
56 | struct i2c_algo_dp_aux_data algo; | ||
57 | }; | ||
58 | |||
59 | static void | ||
60 | intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | ||
61 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); | ||
62 | |||
63 | static void | ||
64 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); | ||
65 | |||
66 | static int | ||
67 | intel_dp_max_lane_count(struct intel_output *intel_output) | ||
68 | { | ||
69 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
70 | int max_lane_count = 4; | ||
71 | |||
72 | if (dp_priv->dpcd[0] >= 0x11) { | ||
73 | max_lane_count = dp_priv->dpcd[2] & 0x1f; | ||
74 | switch (max_lane_count) { | ||
75 | case 1: case 2: case 4: | ||
76 | break; | ||
77 | default: | ||
78 | max_lane_count = 4; | ||
79 | } | ||
80 | } | ||
81 | return max_lane_count; | ||
82 | } | ||
83 | |||
84 | static int | ||
85 | intel_dp_max_link_bw(struct intel_output *intel_output) | ||
86 | { | ||
87 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
88 | int max_link_bw = dp_priv->dpcd[1]; | ||
89 | |||
90 | switch (max_link_bw) { | ||
91 | case DP_LINK_BW_1_62: | ||
92 | case DP_LINK_BW_2_7: | ||
93 | break; | ||
94 | default: | ||
95 | max_link_bw = DP_LINK_BW_1_62; | ||
96 | break; | ||
97 | } | ||
98 | return max_link_bw; | ||
99 | } | ||
100 | |||
101 | static int | ||
102 | intel_dp_link_clock(uint8_t link_bw) | ||
103 | { | ||
104 | if (link_bw == DP_LINK_BW_2_7) | ||
105 | return 270000; | ||
106 | else | ||
107 | return 162000; | ||
108 | } | ||
109 | |||
110 | /* I think this is a fiction */ | ||
111 | static int | ||
112 | intel_dp_link_required(int pixel_clock) | ||
113 | { | ||
114 | return pixel_clock * 3; | ||
115 | } | ||
116 | |||
117 | static int | ||
118 | intel_dp_mode_valid(struct drm_connector *connector, | ||
119 | struct drm_display_mode *mode) | ||
120 | { | ||
121 | struct intel_output *intel_output = to_intel_output(connector); | ||
122 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); | ||
123 | int max_lanes = intel_dp_max_lane_count(intel_output); | ||
124 | |||
125 | if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes) | ||
126 | return MODE_CLOCK_HIGH; | ||
127 | |||
128 | if (mode->clock < 10000) | ||
129 | return MODE_CLOCK_LOW; | ||
130 | |||
131 | return MODE_OK; | ||
132 | } | ||
133 | |||
134 | static uint32_t | ||
135 | pack_aux(uint8_t *src, int src_bytes) | ||
136 | { | ||
137 | int i; | ||
138 | uint32_t v = 0; | ||
139 | |||
140 | if (src_bytes > 4) | ||
141 | src_bytes = 4; | ||
142 | for (i = 0; i < src_bytes; i++) | ||
143 | v |= ((uint32_t) src[i]) << ((3-i) * 8); | ||
144 | return v; | ||
145 | } | ||
146 | |||
147 | static void | ||
148 | unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) | ||
149 | { | ||
150 | int i; | ||
151 | if (dst_bytes > 4) | ||
152 | dst_bytes = 4; | ||
153 | for (i = 0; i < dst_bytes; i++) | ||
154 | dst[i] = src >> ((3-i) * 8); | ||
155 | } | ||
156 | |||
157 | /* hrawclock is 1/4 the FSB frequency */ | ||
158 | static int | ||
159 | intel_hrawclk(struct drm_device *dev) | ||
160 | { | ||
161 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
162 | uint32_t clkcfg; | ||
163 | |||
164 | clkcfg = I915_READ(CLKCFG); | ||
165 | switch (clkcfg & CLKCFG_FSB_MASK) { | ||
166 | case CLKCFG_FSB_400: | ||
167 | return 100; | ||
168 | case CLKCFG_FSB_533: | ||
169 | return 133; | ||
170 | case CLKCFG_FSB_667: | ||
171 | return 166; | ||
172 | case CLKCFG_FSB_800: | ||
173 | return 200; | ||
174 | case CLKCFG_FSB_1067: | ||
175 | return 266; | ||
176 | case CLKCFG_FSB_1333: | ||
177 | return 333; | ||
178 | /* these two are just a guess; one of them might be right */ | ||
179 | case CLKCFG_FSB_1600: | ||
180 | case CLKCFG_FSB_1600_ALT: | ||
181 | return 400; | ||
182 | default: | ||
183 | return 133; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static int | ||
188 | intel_dp_aux_ch(struct intel_output *intel_output, | ||
189 | uint8_t *send, int send_bytes, | ||
190 | uint8_t *recv, int recv_size) | ||
191 | { | ||
192 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
193 | uint32_t output_reg = dp_priv->output_reg; | ||
194 | struct drm_device *dev = intel_output->base.dev; | ||
195 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
196 | uint32_t ch_ctl = output_reg + 0x10; | ||
197 | uint32_t ch_data = ch_ctl + 4; | ||
198 | int i; | ||
199 | int recv_bytes; | ||
200 | uint32_t ctl; | ||
201 | uint32_t status; | ||
202 | uint32_t aux_clock_divider; | ||
203 | int try; | ||
204 | |||
205 | /* The clock divider is based off the hrawclk, | ||
206 | * and would like to run at 2MHz. So, take the | ||
207 | * hrawclk value and divide by 2 and use that | ||
208 | */ | ||
209 | aux_clock_divider = intel_hrawclk(dev) / 2; | ||
210 | /* Must try at least 3 times according to DP spec */ | ||
211 | for (try = 0; try < 5; try++) { | ||
212 | /* Load the send data into the aux channel data registers */ | ||
213 | for (i = 0; i < send_bytes; i += 4) { | ||
214 | uint32_t d = pack_aux(send + i, send_bytes - i);; | ||
215 | |||
216 | I915_WRITE(ch_data + i, d); | ||
217 | } | ||
218 | |||
219 | ctl = (DP_AUX_CH_CTL_SEND_BUSY | | ||
220 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
221 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
222 | (5 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
223 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
224 | DP_AUX_CH_CTL_DONE | | ||
225 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
226 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
227 | |||
228 | /* Send the command and wait for it to complete */ | ||
229 | I915_WRITE(ch_ctl, ctl); | ||
230 | (void) I915_READ(ch_ctl); | ||
231 | for (;;) { | ||
232 | udelay(100); | ||
233 | status = I915_READ(ch_ctl); | ||
234 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | /* Clear done status and any errors */ | ||
239 | I915_WRITE(ch_ctl, (ctl | | ||
240 | DP_AUX_CH_CTL_DONE | | ||
241 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
242 | DP_AUX_CH_CTL_RECEIVE_ERROR)); | ||
243 | (void) I915_READ(ch_ctl); | ||
244 | if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { | ||
249 | DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status); | ||
250 | return -EBUSY; | ||
251 | } | ||
252 | |||
253 | /* Check for timeout or receive error. | ||
254 | * Timeouts occur when the sink is not connected | ||
255 | */ | ||
256 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { | ||
257 | DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status); | ||
258 | return -EIO; | ||
259 | } | ||
260 | |||
261 | /* Timeouts occur when the device isn't connected, so they're | ||
262 | * "normal" -- don't fill the kernel log with these */ | ||
263 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { | ||
264 | DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status); | ||
265 | return -ETIMEDOUT; | ||
266 | } | ||
267 | |||
268 | /* Unload any bytes sent back from the other side */ | ||
269 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> | ||
270 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); | ||
271 | |||
272 | if (recv_bytes > recv_size) | ||
273 | recv_bytes = recv_size; | ||
274 | |||
275 | for (i = 0; i < recv_bytes; i += 4) { | ||
276 | uint32_t d = I915_READ(ch_data + i); | ||
277 | |||
278 | unpack_aux(d, recv + i, recv_bytes - i); | ||
279 | } | ||
280 | |||
281 | return recv_bytes; | ||
282 | } | ||
283 | |||
284 | /* Write data to the aux channel in native mode */ | ||
285 | static int | ||
286 | intel_dp_aux_native_write(struct intel_output *intel_output, | ||
287 | uint16_t address, uint8_t *send, int send_bytes) | ||
288 | { | ||
289 | int ret; | ||
290 | uint8_t msg[20]; | ||
291 | int msg_bytes; | ||
292 | uint8_t ack; | ||
293 | |||
294 | if (send_bytes > 16) | ||
295 | return -1; | ||
296 | msg[0] = AUX_NATIVE_WRITE << 4; | ||
297 | msg[1] = address >> 8; | ||
298 | msg[2] = address; | ||
299 | msg[3] = send_bytes - 1; | ||
300 | memcpy(&msg[4], send, send_bytes); | ||
301 | msg_bytes = send_bytes + 4; | ||
302 | for (;;) { | ||
303 | ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); | ||
304 | if (ret < 0) | ||
305 | return ret; | ||
306 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | ||
307 | break; | ||
308 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) | ||
309 | udelay(100); | ||
310 | else | ||
311 | return -EIO; | ||
312 | } | ||
313 | return send_bytes; | ||
314 | } | ||
315 | |||
316 | /* Write a single byte to the aux channel in native mode */ | ||
317 | static int | ||
318 | intel_dp_aux_native_write_1(struct intel_output *intel_output, | ||
319 | uint16_t address, uint8_t byte) | ||
320 | { | ||
321 | return intel_dp_aux_native_write(intel_output, address, &byte, 1); | ||
322 | } | ||
323 | |||
324 | /* read bytes from a native aux channel */ | ||
325 | static int | ||
326 | intel_dp_aux_native_read(struct intel_output *intel_output, | ||
327 | uint16_t address, uint8_t *recv, int recv_bytes) | ||
328 | { | ||
329 | uint8_t msg[4]; | ||
330 | int msg_bytes; | ||
331 | uint8_t reply[20]; | ||
332 | int reply_bytes; | ||
333 | uint8_t ack; | ||
334 | int ret; | ||
335 | |||
336 | msg[0] = AUX_NATIVE_READ << 4; | ||
337 | msg[1] = address >> 8; | ||
338 | msg[2] = address & 0xff; | ||
339 | msg[3] = recv_bytes - 1; | ||
340 | |||
341 | msg_bytes = 4; | ||
342 | reply_bytes = recv_bytes + 1; | ||
343 | |||
344 | for (;;) { | ||
345 | ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, | ||
346 | reply, reply_bytes); | ||
347 | if (ret == 0) | ||
348 | return -EPROTO; | ||
349 | if (ret < 0) | ||
350 | return ret; | ||
351 | ack = reply[0]; | ||
352 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) { | ||
353 | memcpy(recv, reply + 1, ret - 1); | ||
354 | return ret - 1; | ||
355 | } | ||
356 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) | ||
357 | udelay(100); | ||
358 | else | ||
359 | return -EIO; | ||
360 | } | ||
361 | } | ||
362 | |||
363 | static int | ||
364 | intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, | ||
365 | uint8_t *send, int send_bytes, | ||
366 | uint8_t *recv, int recv_bytes) | ||
367 | { | ||
368 | struct intel_dp_priv *dp_priv = container_of(adapter, | ||
369 | struct intel_dp_priv, | ||
370 | adapter); | ||
371 | struct intel_output *intel_output = dp_priv->intel_output; | ||
372 | |||
373 | return intel_dp_aux_ch(intel_output, | ||
374 | send, send_bytes, recv, recv_bytes); | ||
375 | } | ||
376 | |||
377 | static int | ||
378 | intel_dp_i2c_init(struct intel_output *intel_output, const char *name) | ||
379 | { | ||
380 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
381 | |||
382 | DRM_ERROR("i2c_init %s\n", name); | ||
383 | dp_priv->algo.running = false; | ||
384 | dp_priv->algo.address = 0; | ||
385 | dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; | ||
386 | |||
387 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | ||
388 | dp_priv->adapter.owner = THIS_MODULE; | ||
389 | dp_priv->adapter.class = I2C_CLASS_DDC; | ||
390 | strncpy (dp_priv->adapter.name, name, sizeof dp_priv->adapter.name - 1); | ||
391 | dp_priv->adapter.name[sizeof dp_priv->adapter.name - 1] = '\0'; | ||
392 | dp_priv->adapter.algo_data = &dp_priv->algo; | ||
393 | dp_priv->adapter.dev.parent = &intel_output->base.kdev; | ||
394 | |||
395 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | ||
396 | } | ||
397 | |||
398 | static bool | ||
399 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | ||
400 | struct drm_display_mode *adjusted_mode) | ||
401 | { | ||
402 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
403 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
404 | int lane_count, clock; | ||
405 | int max_lane_count = intel_dp_max_lane_count(intel_output); | ||
406 | int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; | ||
407 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | ||
408 | |||
409 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | ||
410 | for (clock = 0; clock <= max_clock; clock++) { | ||
411 | int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; | ||
412 | |||
413 | if (intel_dp_link_required(mode->clock) <= link_avail) { | ||
414 | dp_priv->link_bw = bws[clock]; | ||
415 | dp_priv->lane_count = lane_count; | ||
416 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | ||
417 | DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n", | ||
418 | dp_priv->link_bw, dp_priv->lane_count, | ||
419 | adjusted_mode->clock); | ||
420 | return true; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | return false; | ||
425 | } | ||
426 | |||
427 | struct intel_dp_m_n { | ||
428 | uint32_t tu; | ||
429 | uint32_t gmch_m; | ||
430 | uint32_t gmch_n; | ||
431 | uint32_t link_m; | ||
432 | uint32_t link_n; | ||
433 | }; | ||
434 | |||
435 | static void | ||
436 | intel_reduce_ratio(uint32_t *num, uint32_t *den) | ||
437 | { | ||
438 | while (*num > 0xffffff || *den > 0xffffff) { | ||
439 | *num >>= 1; | ||
440 | *den >>= 1; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | static void | ||
445 | intel_dp_compute_m_n(int bytes_per_pixel, | ||
446 | int nlanes, | ||
447 | int pixel_clock, | ||
448 | int link_clock, | ||
449 | struct intel_dp_m_n *m_n) | ||
450 | { | ||
451 | m_n->tu = 64; | ||
452 | m_n->gmch_m = pixel_clock * bytes_per_pixel; | ||
453 | m_n->gmch_n = link_clock * nlanes; | ||
454 | intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | ||
455 | m_n->link_m = pixel_clock; | ||
456 | m_n->link_n = link_clock; | ||
457 | intel_reduce_ratio(&m_n->link_m, &m_n->link_n); | ||
458 | } | ||
459 | |||
460 | void | ||
461 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | ||
462 | struct drm_display_mode *adjusted_mode) | ||
463 | { | ||
464 | struct drm_device *dev = crtc->dev; | ||
465 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
466 | struct drm_connector *connector; | ||
467 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
468 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
469 | int lane_count = 4; | ||
470 | struct intel_dp_m_n m_n; | ||
471 | |||
472 | /* | ||
473 | * Find the lane count in the intel_output private | ||
474 | */ | ||
475 | list_for_each_entry(connector, &mode_config->connector_list, head) { | ||
476 | struct intel_output *intel_output = to_intel_output(connector); | ||
477 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
478 | |||
479 | if (!connector->encoder || connector->encoder->crtc != crtc) | ||
480 | continue; | ||
481 | |||
482 | if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { | ||
483 | lane_count = dp_priv->lane_count; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * Compute the GMCH and Link ratios. The '3' here is | ||
490 | * the number of bytes_per_pixel post-LUT, which we always | ||
491 | * set up for 8-bits of R/G/B, or 3 bytes total. | ||
492 | */ | ||
493 | intel_dp_compute_m_n(3, lane_count, | ||
494 | mode->clock, adjusted_mode->clock, &m_n); | ||
495 | |||
496 | if (intel_crtc->pipe == 0) { | ||
497 | I915_WRITE(PIPEA_GMCH_DATA_M, | ||
498 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
499 | m_n.gmch_m); | ||
500 | I915_WRITE(PIPEA_GMCH_DATA_N, | ||
501 | m_n.gmch_n); | ||
502 | I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); | ||
503 | I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); | ||
504 | } else { | ||
505 | I915_WRITE(PIPEB_GMCH_DATA_M, | ||
506 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
507 | m_n.gmch_m); | ||
508 | I915_WRITE(PIPEB_GMCH_DATA_N, | ||
509 | m_n.gmch_n); | ||
510 | I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); | ||
511 | I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | static void | ||
516 | intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | ||
517 | struct drm_display_mode *adjusted_mode) | ||
518 | { | ||
519 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
520 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
521 | struct drm_crtc *crtc = intel_output->enc.crtc; | ||
522 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
523 | |||
524 | dp_priv->DP = (DP_LINK_TRAIN_OFF | | ||
525 | DP_VOLTAGE_0_4 | | ||
526 | DP_PRE_EMPHASIS_0 | | ||
527 | DP_SYNC_VS_HIGH | | ||
528 | DP_SYNC_HS_HIGH); | ||
529 | |||
530 | switch (dp_priv->lane_count) { | ||
531 | case 1: | ||
532 | dp_priv->DP |= DP_PORT_WIDTH_1; | ||
533 | break; | ||
534 | case 2: | ||
535 | dp_priv->DP |= DP_PORT_WIDTH_2; | ||
536 | break; | ||
537 | case 4: | ||
538 | dp_priv->DP |= DP_PORT_WIDTH_4; | ||
539 | break; | ||
540 | } | ||
541 | if (dp_priv->has_audio) | ||
542 | dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; | ||
543 | |||
544 | memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | ||
545 | dp_priv->link_configuration[0] = dp_priv->link_bw; | ||
546 | dp_priv->link_configuration[1] = dp_priv->lane_count; | ||
547 | |||
548 | /* | ||
549 | * Check for DPCD version > 1.1, | ||
550 | * enable enahanced frame stuff in that case | ||
551 | */ | ||
552 | if (dp_priv->dpcd[0] >= 0x11) { | ||
553 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | ||
554 | dp_priv->DP |= DP_ENHANCED_FRAMING; | ||
555 | } | ||
556 | |||
557 | if (intel_crtc->pipe == 1) | ||
558 | dp_priv->DP |= DP_PIPEB_SELECT; | ||
559 | } | ||
560 | |||
561 | |||
562 | static void | ||
563 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | ||
564 | { | ||
565 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
566 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
567 | struct drm_device *dev = intel_output->base.dev; | ||
568 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
569 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | ||
570 | |||
571 | if (mode != DRM_MODE_DPMS_ON) { | ||
572 | if (dp_reg & DP_PORT_EN) | ||
573 | intel_dp_link_down(intel_output, dp_priv->DP); | ||
574 | } else { | ||
575 | if (!(dp_reg & DP_PORT_EN)) | ||
576 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | ||
577 | } | ||
578 | dp_priv->dpms_mode = mode; | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * Fetch AUX CH registers 0x202 - 0x207 which contain | ||
583 | * link status information | ||
584 | */ | ||
585 | static bool | ||
586 | intel_dp_get_link_status(struct intel_output *intel_output, | ||
587 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | ||
588 | { | ||
589 | int ret; | ||
590 | |||
591 | ret = intel_dp_aux_native_read(intel_output, | ||
592 | DP_LANE0_1_STATUS, | ||
593 | link_status, DP_LINK_STATUS_SIZE); | ||
594 | if (ret != DP_LINK_STATUS_SIZE) | ||
595 | return false; | ||
596 | return true; | ||
597 | } | ||
598 | |||
599 | static uint8_t | ||
600 | intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
601 | int r) | ||
602 | { | ||
603 | return link_status[r - DP_LANE0_1_STATUS]; | ||
604 | } | ||
605 | |||
606 | static void | ||
607 | intel_dp_save(struct drm_connector *connector) | ||
608 | { | ||
609 | struct intel_output *intel_output = to_intel_output(connector); | ||
610 | struct drm_device *dev = intel_output->base.dev; | ||
611 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
612 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
613 | |||
614 | dp_priv->save_DP = I915_READ(dp_priv->output_reg); | ||
615 | intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, | ||
616 | dp_priv->save_link_configuration, | ||
617 | sizeof (dp_priv->save_link_configuration)); | ||
618 | } | ||
619 | |||
620 | static uint8_t | ||
621 | intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
622 | int lane) | ||
623 | { | ||
624 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
625 | int s = ((lane & 1) ? | ||
626 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | ||
627 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | ||
628 | uint8_t l = intel_dp_link_status(link_status, i); | ||
629 | |||
630 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | ||
631 | } | ||
632 | |||
633 | static uint8_t | ||
634 | intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
635 | int lane) | ||
636 | { | ||
637 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
638 | int s = ((lane & 1) ? | ||
639 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | ||
640 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | ||
641 | uint8_t l = intel_dp_link_status(link_status, i); | ||
642 | |||
643 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
644 | } | ||
645 | |||
646 | |||
647 | #if 0 | ||
648 | static char *voltage_names[] = { | ||
649 | "0.4V", "0.6V", "0.8V", "1.2V" | ||
650 | }; | ||
651 | static char *pre_emph_names[] = { | ||
652 | "0dB", "3.5dB", "6dB", "9.5dB" | ||
653 | }; | ||
654 | static char *link_train_names[] = { | ||
655 | "pattern 1", "pattern 2", "idle", "off" | ||
656 | }; | ||
657 | #endif | ||
658 | |||
659 | /* | ||
660 | * These are source-specific values; current Intel hardware supports | ||
661 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB | ||
662 | */ | ||
663 | #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 | ||
664 | |||
665 | static uint8_t | ||
666 | intel_dp_pre_emphasis_max(uint8_t voltage_swing) | ||
667 | { | ||
668 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
669 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
670 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
671 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
672 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
673 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
674 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
675 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
676 | default: | ||
677 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
678 | } | ||
679 | } | ||
680 | |||
681 | static void | ||
682 | intel_get_adjust_train(struct intel_output *intel_output, | ||
683 | uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
684 | int lane_count, | ||
685 | uint8_t train_set[4]) | ||
686 | { | ||
687 | uint8_t v = 0; | ||
688 | uint8_t p = 0; | ||
689 | int lane; | ||
690 | |||
691 | for (lane = 0; lane < lane_count; lane++) { | ||
692 | uint8_t this_v = intel_get_adjust_request_voltage(link_status, lane); | ||
693 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(link_status, lane); | ||
694 | |||
695 | if (this_v > v) | ||
696 | v = this_v; | ||
697 | if (this_p > p) | ||
698 | p = this_p; | ||
699 | } | ||
700 | |||
701 | if (v >= I830_DP_VOLTAGE_MAX) | ||
702 | v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | ||
703 | |||
704 | if (p >= intel_dp_pre_emphasis_max(v)) | ||
705 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | ||
706 | |||
707 | for (lane = 0; lane < 4; lane++) | ||
708 | train_set[lane] = v | p; | ||
709 | } | ||
710 | |||
711 | static uint32_t | ||
712 | intel_dp_signal_levels(uint8_t train_set, int lane_count) | ||
713 | { | ||
714 | uint32_t signal_levels = 0; | ||
715 | |||
716 | switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
717 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
718 | default: | ||
719 | signal_levels |= DP_VOLTAGE_0_4; | ||
720 | break; | ||
721 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
722 | signal_levels |= DP_VOLTAGE_0_6; | ||
723 | break; | ||
724 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
725 | signal_levels |= DP_VOLTAGE_0_8; | ||
726 | break; | ||
727 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
728 | signal_levels |= DP_VOLTAGE_1_2; | ||
729 | break; | ||
730 | } | ||
731 | switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { | ||
732 | case DP_TRAIN_PRE_EMPHASIS_0: | ||
733 | default: | ||
734 | signal_levels |= DP_PRE_EMPHASIS_0; | ||
735 | break; | ||
736 | case DP_TRAIN_PRE_EMPHASIS_3_5: | ||
737 | signal_levels |= DP_PRE_EMPHASIS_3_5; | ||
738 | break; | ||
739 | case DP_TRAIN_PRE_EMPHASIS_6: | ||
740 | signal_levels |= DP_PRE_EMPHASIS_6; | ||
741 | break; | ||
742 | case DP_TRAIN_PRE_EMPHASIS_9_5: | ||
743 | signal_levels |= DP_PRE_EMPHASIS_9_5; | ||
744 | break; | ||
745 | } | ||
746 | return signal_levels; | ||
747 | } | ||
748 | |||
749 | static uint8_t | ||
750 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
751 | int lane) | ||
752 | { | ||
753 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
754 | int s = (lane & 1) * 4; | ||
755 | uint8_t l = intel_dp_link_status(link_status, i); | ||
756 | |||
757 | return (l >> s) & 0xf; | ||
758 | } | ||
759 | |||
760 | /* Check for clock recovery is done on all channels */ | ||
761 | static bool | ||
762 | intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | ||
763 | { | ||
764 | int lane; | ||
765 | uint8_t lane_status; | ||
766 | |||
767 | for (lane = 0; lane < lane_count; lane++) { | ||
768 | lane_status = intel_get_lane_status(link_status, lane); | ||
769 | if ((lane_status & DP_LANE_CR_DONE) == 0) | ||
770 | return false; | ||
771 | } | ||
772 | return true; | ||
773 | } | ||
774 | |||
775 | /* Check to see if channel eq is done on all channels */ | ||
776 | #define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\ | ||
777 | DP_LANE_CHANNEL_EQ_DONE|\ | ||
778 | DP_LANE_SYMBOL_LOCKED) | ||
779 | static bool | ||
780 | intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | ||
781 | { | ||
782 | uint8_t lane_align; | ||
783 | uint8_t lane_status; | ||
784 | int lane; | ||
785 | |||
786 | lane_align = intel_dp_link_status(link_status, | ||
787 | DP_LANE_ALIGN_STATUS_UPDATED); | ||
788 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | ||
789 | return false; | ||
790 | for (lane = 0; lane < lane_count; lane++) { | ||
791 | lane_status = intel_get_lane_status(link_status, lane); | ||
792 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) | ||
793 | return false; | ||
794 | } | ||
795 | return true; | ||
796 | } | ||
797 | |||
798 | static bool | ||
799 | intel_dp_set_link_train(struct intel_output *intel_output, | ||
800 | uint32_t dp_reg_value, | ||
801 | uint8_t dp_train_pat, | ||
802 | uint8_t train_set[4], | ||
803 | bool first) | ||
804 | { | ||
805 | struct drm_device *dev = intel_output->base.dev; | ||
806 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
807 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
808 | int ret; | ||
809 | |||
810 | I915_WRITE(dp_priv->output_reg, dp_reg_value); | ||
811 | POSTING_READ(dp_priv->output_reg); | ||
812 | if (first) | ||
813 | intel_wait_for_vblank(dev); | ||
814 | |||
815 | intel_dp_aux_native_write_1(intel_output, | ||
816 | DP_TRAINING_PATTERN_SET, | ||
817 | dp_train_pat); | ||
818 | |||
819 | ret = intel_dp_aux_native_write(intel_output, | ||
820 | DP_TRAINING_LANE0_SET, train_set, 4); | ||
821 | if (ret != 4) | ||
822 | return false; | ||
823 | |||
824 | return true; | ||
825 | } | ||
826 | |||
827 | static void | ||
828 | intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | ||
829 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
830 | { | ||
831 | struct drm_device *dev = intel_output->base.dev; | ||
832 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
833 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
834 | uint8_t train_set[4]; | ||
835 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
836 | int i; | ||
837 | uint8_t voltage; | ||
838 | bool clock_recovery = false; | ||
839 | bool channel_eq = false; | ||
840 | bool first = true; | ||
841 | int tries; | ||
842 | |||
843 | /* Write the link configuration data */ | ||
844 | intel_dp_aux_native_write(intel_output, 0x100, | ||
845 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | ||
846 | |||
847 | DP |= DP_PORT_EN; | ||
848 | DP &= ~DP_LINK_TRAIN_MASK; | ||
849 | memset(train_set, 0, 4); | ||
850 | voltage = 0xff; | ||
851 | tries = 0; | ||
852 | clock_recovery = false; | ||
853 | for (;;) { | ||
854 | /* Use train_set[0] to set the voltage and pre emphasis values */ | ||
855 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | ||
856 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | ||
857 | |||
858 | if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, | ||
859 | DP_TRAINING_PATTERN_1, train_set, first)) | ||
860 | break; | ||
861 | first = false; | ||
862 | /* Set training pattern 1 */ | ||
863 | |||
864 | udelay(100); | ||
865 | if (!intel_dp_get_link_status(intel_output, link_status)) | ||
866 | break; | ||
867 | |||
868 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { | ||
869 | clock_recovery = true; | ||
870 | break; | ||
871 | } | ||
872 | |||
873 | /* Check to see if we've tried the max voltage */ | ||
874 | for (i = 0; i < dp_priv->lane_count; i++) | ||
875 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | ||
876 | break; | ||
877 | if (i == dp_priv->lane_count) | ||
878 | break; | ||
879 | |||
880 | /* Check to see if we've tried the same voltage 5 times */ | ||
881 | if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | ||
882 | ++tries; | ||
883 | if (tries == 5) | ||
884 | break; | ||
885 | } else | ||
886 | tries = 0; | ||
887 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
888 | |||
889 | /* Compute new train_set as requested by target */ | ||
890 | intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); | ||
891 | } | ||
892 | |||
893 | /* channel equalization */ | ||
894 | tries = 0; | ||
895 | channel_eq = false; | ||
896 | for (;;) { | ||
897 | /* Use train_set[0] to set the voltage and pre emphasis values */ | ||
898 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | ||
899 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | ||
900 | |||
901 | /* channel eq pattern */ | ||
902 | if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, | ||
903 | DP_TRAINING_PATTERN_2, train_set, | ||
904 | false)) | ||
905 | break; | ||
906 | |||
907 | udelay(400); | ||
908 | if (!intel_dp_get_link_status(intel_output, link_status)) | ||
909 | break; | ||
910 | |||
911 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { | ||
912 | channel_eq = true; | ||
913 | break; | ||
914 | } | ||
915 | |||
916 | /* Try 5 times */ | ||
917 | if (tries > 5) | ||
918 | break; | ||
919 | |||
920 | /* Compute new train_set as requested by target */ | ||
921 | intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); | ||
922 | ++tries; | ||
923 | } | ||
924 | |||
925 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); | ||
926 | POSTING_READ(dp_priv->output_reg); | ||
927 | intel_dp_aux_native_write_1(intel_output, | ||
928 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | ||
929 | } | ||
930 | |||
931 | static void | ||
932 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | ||
933 | { | ||
934 | struct drm_device *dev = intel_output->base.dev; | ||
935 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
936 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
937 | |||
938 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | ||
939 | POSTING_READ(dp_priv->output_reg); | ||
940 | } | ||
941 | |||
942 | static void | ||
943 | intel_dp_restore(struct drm_connector *connector) | ||
944 | { | ||
945 | struct intel_output *intel_output = to_intel_output(connector); | ||
946 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
947 | |||
948 | if (dp_priv->save_DP & DP_PORT_EN) | ||
949 | intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); | ||
950 | else | ||
951 | intel_dp_link_down(intel_output, dp_priv->save_DP); | ||
952 | } | ||
953 | |||
954 | /* | ||
955 | * According to DP spec | ||
956 | * 5.1.2: | ||
957 | * 1. Read DPCD | ||
958 | * 2. Configure link according to Receiver Capabilities | ||
959 | * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 | ||
960 | * 4. Check link status on receipt of hot-plug interrupt | ||
961 | */ | ||
962 | |||
963 | static void | ||
964 | intel_dp_check_link_status(struct intel_output *intel_output) | ||
965 | { | ||
966 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
967 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
968 | |||
969 | if (!intel_output->enc.crtc) | ||
970 | return; | ||
971 | |||
972 | if (!intel_dp_get_link_status(intel_output, link_status)) { | ||
973 | intel_dp_link_down(intel_output, dp_priv->DP); | ||
974 | return; | ||
975 | } | ||
976 | |||
977 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) | ||
978 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | ||
979 | } | ||
980 | |||
981 | /** | ||
982 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. | ||
983 | * | ||
984 | * \return true if DP port is connected. | ||
985 | * \return false if DP port is disconnected. | ||
986 | */ | ||
987 | static enum drm_connector_status | ||
988 | intel_dp_detect(struct drm_connector *connector) | ||
989 | { | ||
990 | struct intel_output *intel_output = to_intel_output(connector); | ||
991 | struct drm_device *dev = intel_output->base.dev; | ||
992 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
993 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
994 | uint32_t temp, bit; | ||
995 | enum drm_connector_status status; | ||
996 | |||
997 | dp_priv->has_audio = false; | ||
998 | |||
999 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
1000 | |||
1001 | I915_WRITE(PORT_HOTPLUG_EN, | ||
1002 | temp | | ||
1003 | DPB_HOTPLUG_INT_EN | | ||
1004 | DPC_HOTPLUG_INT_EN | | ||
1005 | DPD_HOTPLUG_INT_EN); | ||
1006 | |||
1007 | POSTING_READ(PORT_HOTPLUG_EN); | ||
1008 | |||
1009 | switch (dp_priv->output_reg) { | ||
1010 | case DP_B: | ||
1011 | bit = DPB_HOTPLUG_INT_STATUS; | ||
1012 | break; | ||
1013 | case DP_C: | ||
1014 | bit = DPC_HOTPLUG_INT_STATUS; | ||
1015 | break; | ||
1016 | case DP_D: | ||
1017 | bit = DPD_HOTPLUG_INT_STATUS; | ||
1018 | break; | ||
1019 | default: | ||
1020 | return connector_status_unknown; | ||
1021 | } | ||
1022 | |||
1023 | temp = I915_READ(PORT_HOTPLUG_STAT); | ||
1024 | |||
1025 | if ((temp & bit) == 0) | ||
1026 | return connector_status_disconnected; | ||
1027 | |||
1028 | status = connector_status_disconnected; | ||
1029 | if (intel_dp_aux_native_read(intel_output, | ||
1030 | 0x000, dp_priv->dpcd, | ||
1031 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | ||
1032 | { | ||
1033 | if (dp_priv->dpcd[0] != 0) | ||
1034 | status = connector_status_connected; | ||
1035 | } | ||
1036 | return status; | ||
1037 | } | ||
1038 | |||
1039 | static int intel_dp_get_modes(struct drm_connector *connector) | ||
1040 | { | ||
1041 | struct intel_output *intel_output = to_intel_output(connector); | ||
1042 | |||
1043 | /* We should parse the EDID data and find out if it has an audio sink | ||
1044 | */ | ||
1045 | |||
1046 | return intel_ddc_get_modes(intel_output); | ||
1047 | } | ||
1048 | |||
1049 | static void | ||
1050 | intel_dp_destroy (struct drm_connector *connector) | ||
1051 | { | ||
1052 | struct intel_output *intel_output = to_intel_output(connector); | ||
1053 | |||
1054 | if (intel_output->i2c_bus) | ||
1055 | intel_i2c_destroy(intel_output->i2c_bus); | ||
1056 | drm_sysfs_connector_remove(connector); | ||
1057 | drm_connector_cleanup(connector); | ||
1058 | kfree(intel_output); | ||
1059 | } | ||
1060 | |||
1061 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | ||
1062 | .dpms = intel_dp_dpms, | ||
1063 | .mode_fixup = intel_dp_mode_fixup, | ||
1064 | .prepare = intel_encoder_prepare, | ||
1065 | .mode_set = intel_dp_mode_set, | ||
1066 | .commit = intel_encoder_commit, | ||
1067 | }; | ||
1068 | |||
1069 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | ||
1070 | .dpms = drm_helper_connector_dpms, | ||
1071 | .save = intel_dp_save, | ||
1072 | .restore = intel_dp_restore, | ||
1073 | .detect = intel_dp_detect, | ||
1074 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
1075 | .destroy = intel_dp_destroy, | ||
1076 | }; | ||
1077 | |||
1078 | static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { | ||
1079 | .get_modes = intel_dp_get_modes, | ||
1080 | .mode_valid = intel_dp_mode_valid, | ||
1081 | .best_encoder = intel_best_encoder, | ||
1082 | }; | ||
1083 | |||
1084 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) | ||
1085 | { | ||
1086 | drm_encoder_cleanup(encoder); | ||
1087 | } | ||
1088 | |||
1089 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | ||
1090 | .destroy = intel_dp_enc_destroy, | ||
1091 | }; | ||
1092 | |||
1093 | void | ||
1094 | intel_dp_hot_plug(struct intel_output *intel_output) | ||
1095 | { | ||
1096 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
1097 | |||
1098 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | ||
1099 | intel_dp_check_link_status(intel_output); | ||
1100 | } | ||
1101 | |||
1102 | void | ||
1103 | intel_dp_init(struct drm_device *dev, int output_reg) | ||
1104 | { | ||
1105 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1106 | struct drm_connector *connector; | ||
1107 | struct intel_output *intel_output; | ||
1108 | struct intel_dp_priv *dp_priv; | ||
1109 | |||
1110 | intel_output = kcalloc(sizeof(struct intel_output) + | ||
1111 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | ||
1112 | if (!intel_output) | ||
1113 | return; | ||
1114 | |||
1115 | dp_priv = (struct intel_dp_priv *)(intel_output + 1); | ||
1116 | |||
1117 | connector = &intel_output->base; | ||
1118 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, | ||
1119 | DRM_MODE_CONNECTOR_DisplayPort); | ||
1120 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | ||
1121 | |||
1122 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1123 | |||
1124 | connector->interlace_allowed = true; | ||
1125 | connector->doublescan_allowed = 0; | ||
1126 | |||
1127 | dp_priv->intel_output = intel_output; | ||
1128 | dp_priv->output_reg = output_reg; | ||
1129 | dp_priv->has_audio = false; | ||
1130 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; | ||
1131 | intel_output->dev_priv = dp_priv; | ||
1132 | |||
1133 | drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, | ||
1134 | DRM_MODE_ENCODER_TMDS); | ||
1135 | drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); | ||
1136 | |||
1137 | drm_mode_connector_attach_encoder(&intel_output->base, | ||
1138 | &intel_output->enc); | ||
1139 | drm_sysfs_connector_add(connector); | ||
1140 | |||
1141 | /* Set up the DDC bus. */ | ||
1142 | intel_dp_i2c_init(intel_output, | ||
1143 | (output_reg == DP_B) ? "DPDDC-B" : | ||
1144 | (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); | ||
1145 | intel_output->ddc_bus = &dp_priv->adapter; | ||
1146 | intel_output->hot_plug = intel_dp_hot_plug; | ||
1147 | |||
1148 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written | ||
1149 | * 0xd. Failure to do so will result in spurious interrupts being | ||
1150 | * generated on the port when a cable is not attached. | ||
1151 | */ | ||
1152 | if (IS_G4X(dev) && !IS_GM45(dev)) { | ||
1153 | u32 temp = I915_READ(PEG_BAND_GAP_DATA); | ||
1154 | I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); | ||
1155 | } | ||
1156 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.h b/drivers/gpu/drm/i915/intel_dp.h new file mode 100644 index 000000000000..2b38054d3b6d --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dp.h | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Keith Packard | ||
3 | * | ||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | ||
5 | * documentation for any purpose is hereby granted without fee, provided that | ||
6 | * the above copyright notice appear in all copies and that both that copyright | ||
7 | * notice and this permission notice appear in supporting documentation, and | ||
8 | * that the name of the copyright holders not be used in advertising or | ||
9 | * publicity pertaining to distribution of the software without specific, | ||
10 | * written prior permission. The copyright holders make no representations | ||
11 | * about the suitability of this software for any purpose. It is provided "as | ||
12 | * is" without express or implied warranty. | ||
13 | * | ||
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||
20 | * OF THIS SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #ifndef _INTEL_DP_H_ | ||
24 | #define _INTEL_DP_H_ | ||
25 | |||
26 | /* From the VESA DisplayPort spec */ | ||
27 | |||
28 | #define AUX_NATIVE_WRITE 0x8 | ||
29 | #define AUX_NATIVE_READ 0x9 | ||
30 | #define AUX_I2C_WRITE 0x0 | ||
31 | #define AUX_I2C_READ 0x1 | ||
32 | #define AUX_I2C_STATUS 0x2 | ||
33 | #define AUX_I2C_MOT 0x4 | ||
34 | |||
35 | #define AUX_NATIVE_REPLY_ACK (0x0 << 4) | ||
36 | #define AUX_NATIVE_REPLY_NACK (0x1 << 4) | ||
37 | #define AUX_NATIVE_REPLY_DEFER (0x2 << 4) | ||
38 | #define AUX_NATIVE_REPLY_MASK (0x3 << 4) | ||
39 | |||
40 | #define AUX_I2C_REPLY_ACK (0x0 << 6) | ||
41 | #define AUX_I2C_REPLY_NACK (0x1 << 6) | ||
42 | #define AUX_I2C_REPLY_DEFER (0x2 << 6) | ||
43 | #define AUX_I2C_REPLY_MASK (0x3 << 6) | ||
44 | |||
45 | /* AUX CH addresses */ | ||
46 | #define DP_LINK_BW_SET 0x100 | ||
47 | # define DP_LINK_BW_1_62 0x06 | ||
48 | # define DP_LINK_BW_2_7 0x0a | ||
49 | |||
50 | #define DP_LANE_COUNT_SET 0x101 | ||
51 | # define DP_LANE_COUNT_MASK 0x0f | ||
52 | # define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) | ||
53 | |||
54 | #define DP_TRAINING_PATTERN_SET 0x102 | ||
55 | |||
56 | # define DP_TRAINING_PATTERN_DISABLE 0 | ||
57 | # define DP_TRAINING_PATTERN_1 1 | ||
58 | # define DP_TRAINING_PATTERN_2 2 | ||
59 | # define DP_TRAINING_PATTERN_MASK 0x3 | ||
60 | |||
61 | # define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2) | ||
62 | # define DP_LINK_QUAL_PATTERN_D10_2 (1 << 2) | ||
63 | # define DP_LINK_QUAL_PATTERN_ERROR_RATE (2 << 2) | ||
64 | # define DP_LINK_QUAL_PATTERN_PRBS7 (3 << 2) | ||
65 | # define DP_LINK_QUAL_PATTERN_MASK (3 << 2) | ||
66 | |||
67 | # define DP_RECOVERED_CLOCK_OUT_EN (1 << 4) | ||
68 | # define DP_LINK_SCRAMBLING_DISABLE (1 << 5) | ||
69 | |||
70 | # define DP_SYMBOL_ERROR_COUNT_BOTH (0 << 6) | ||
71 | # define DP_SYMBOL_ERROR_COUNT_DISPARITY (1 << 6) | ||
72 | # define DP_SYMBOL_ERROR_COUNT_SYMBOL (2 << 6) | ||
73 | # define DP_SYMBOL_ERROR_COUNT_MASK (3 << 6) | ||
74 | |||
75 | #define DP_TRAINING_LANE0_SET 0x103 | ||
76 | #define DP_TRAINING_LANE1_SET 0x104 | ||
77 | #define DP_TRAINING_LANE2_SET 0x105 | ||
78 | #define DP_TRAINING_LANE3_SET 0x106 | ||
79 | |||
80 | # define DP_TRAIN_VOLTAGE_SWING_MASK 0x3 | ||
81 | # define DP_TRAIN_VOLTAGE_SWING_SHIFT 0 | ||
82 | # define DP_TRAIN_MAX_SWING_REACHED (1 << 2) | ||
83 | # define DP_TRAIN_VOLTAGE_SWING_400 (0 << 0) | ||
84 | # define DP_TRAIN_VOLTAGE_SWING_600 (1 << 0) | ||
85 | # define DP_TRAIN_VOLTAGE_SWING_800 (2 << 0) | ||
86 | # define DP_TRAIN_VOLTAGE_SWING_1200 (3 << 0) | ||
87 | |||
88 | # define DP_TRAIN_PRE_EMPHASIS_MASK (3 << 3) | ||
89 | # define DP_TRAIN_PRE_EMPHASIS_0 (0 << 3) | ||
90 | # define DP_TRAIN_PRE_EMPHASIS_3_5 (1 << 3) | ||
91 | # define DP_TRAIN_PRE_EMPHASIS_6 (2 << 3) | ||
92 | # define DP_TRAIN_PRE_EMPHASIS_9_5 (3 << 3) | ||
93 | |||
94 | # define DP_TRAIN_PRE_EMPHASIS_SHIFT 3 | ||
95 | # define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED (1 << 5) | ||
96 | |||
97 | #define DP_DOWNSPREAD_CTRL 0x107 | ||
98 | # define DP_SPREAD_AMP_0_5 (1 << 4) | ||
99 | |||
100 | #define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 | ||
101 | # define DP_SET_ANSI_8B10B (1 << 0) | ||
102 | |||
103 | #define DP_LANE0_1_STATUS 0x202 | ||
104 | #define DP_LANE2_3_STATUS 0x203 | ||
105 | |||
106 | # define DP_LANE_CR_DONE (1 << 0) | ||
107 | # define DP_LANE_CHANNEL_EQ_DONE (1 << 1) | ||
108 | # define DP_LANE_SYMBOL_LOCKED (1 << 2) | ||
109 | |||
110 | #define DP_LANE_ALIGN_STATUS_UPDATED 0x204 | ||
111 | |||
112 | #define DP_INTERLANE_ALIGN_DONE (1 << 0) | ||
113 | #define DP_DOWNSTREAM_PORT_STATUS_CHANGED (1 << 6) | ||
114 | #define DP_LINK_STATUS_UPDATED (1 << 7) | ||
115 | |||
116 | #define DP_SINK_STATUS 0x205 | ||
117 | |||
118 | #define DP_RECEIVE_PORT_0_STATUS (1 << 0) | ||
119 | #define DP_RECEIVE_PORT_1_STATUS (1 << 1) | ||
120 | |||
121 | #define DP_ADJUST_REQUEST_LANE0_1 0x206 | ||
122 | #define DP_ADJUST_REQUEST_LANE2_3 0x207 | ||
123 | |||
124 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 | ||
125 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 | ||
126 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c | ||
127 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 | ||
128 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 | ||
129 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 | ||
130 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 | ||
131 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 | ||
132 | |||
133 | struct i2c_algo_dp_aux_data { | ||
134 | bool running; | ||
135 | u16 address; | ||
136 | int (*aux_ch) (struct i2c_adapter *adapter, | ||
137 | uint8_t *send, int send_bytes, | ||
138 | uint8_t *recv, int recv_bytes); | ||
139 | }; | ||
140 | |||
141 | int | ||
142 | i2c_dp_aux_add_bus(struct i2c_adapter *adapter); | ||
143 | |||
144 | #endif /* _INTEL_DP_H_ */ | ||
diff --git a/drivers/gpu/drm/i915/intel_dp_i2c.c b/drivers/gpu/drm/i915/intel_dp_i2c.c new file mode 100644 index 000000000000..a63b6f57d2d4 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dp_i2c.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * Copyright © 2009 Keith Packard | ||
3 | * | ||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | ||
5 | * documentation for any purpose is hereby granted without fee, provided that | ||
6 | * the above copyright notice appear in all copies and that both that copyright | ||
7 | * notice and this permission notice appear in supporting documentation, and | ||
8 | * that the name of the copyright holders not be used in advertising or | ||
9 | * publicity pertaining to distribution of the software without specific, | ||
10 | * written prior permission. The copyright holders make no representations | ||
11 | * about the suitability of this software for any purpose. It is provided "as | ||
12 | * is" without express or implied warranty. | ||
13 | * | ||
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||
20 | * OF THIS SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include "intel_dp.h" | ||
32 | #include "drmP.h" | ||
33 | |||
34 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ | ||
35 | |||
36 | #define MODE_I2C_START 1 | ||
37 | #define MODE_I2C_WRITE 2 | ||
38 | #define MODE_I2C_READ 4 | ||
39 | #define MODE_I2C_STOP 8 | ||
40 | |||
41 | static int | ||
42 | i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | ||
43 | uint8_t write_byte, uint8_t *read_byte) | ||
44 | { | ||
45 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
46 | uint16_t address = algo_data->address; | ||
47 | uint8_t msg[5]; | ||
48 | uint8_t reply[2]; | ||
49 | int msg_bytes; | ||
50 | int reply_bytes; | ||
51 | int ret; | ||
52 | |||
53 | /* Set up the command byte */ | ||
54 | if (mode & MODE_I2C_READ) | ||
55 | msg[0] = AUX_I2C_READ << 4; | ||
56 | else | ||
57 | msg[0] = AUX_I2C_WRITE << 4; | ||
58 | |||
59 | if (!(mode & MODE_I2C_STOP)) | ||
60 | msg[0] |= AUX_I2C_MOT << 4; | ||
61 | |||
62 | msg[1] = address >> 8; | ||
63 | msg[2] = address; | ||
64 | |||
65 | switch (mode) { | ||
66 | case MODE_I2C_WRITE: | ||
67 | msg[3] = 0; | ||
68 | msg[4] = write_byte; | ||
69 | msg_bytes = 5; | ||
70 | reply_bytes = 1; | ||
71 | break; | ||
72 | case MODE_I2C_READ: | ||
73 | msg[3] = 0; | ||
74 | msg_bytes = 4; | ||
75 | reply_bytes = 2; | ||
76 | break; | ||
77 | default: | ||
78 | msg_bytes = 3; | ||
79 | reply_bytes = 1; | ||
80 | break; | ||
81 | } | ||
82 | |||
83 | for (;;) { | ||
84 | ret = (*algo_data->aux_ch)(adapter, | ||
85 | msg, msg_bytes, | ||
86 | reply, reply_bytes); | ||
87 | if (ret < 0) { | ||
88 | DRM_DEBUG("aux_ch failed %d\n", ret); | ||
89 | return ret; | ||
90 | } | ||
91 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | ||
92 | case AUX_I2C_REPLY_ACK: | ||
93 | if (mode == MODE_I2C_READ) { | ||
94 | *read_byte = reply[1]; | ||
95 | } | ||
96 | return reply_bytes - 1; | ||
97 | case AUX_I2C_REPLY_NACK: | ||
98 | DRM_DEBUG("aux_ch nack\n"); | ||
99 | return -EREMOTEIO; | ||
100 | case AUX_I2C_REPLY_DEFER: | ||
101 | DRM_DEBUG("aux_ch defer\n"); | ||
102 | udelay(100); | ||
103 | break; | ||
104 | default: | ||
105 | DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); | ||
106 | return -EREMOTEIO; | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * I2C over AUX CH | ||
113 | */ | ||
114 | |||
115 | /* | ||
116 | * Send the address. If the I2C link is running, this 'restarts' | ||
117 | * the connection with the new address, this is used for doing | ||
118 | * a write followed by a read (as needed for DDC) | ||
119 | */ | ||
120 | static int | ||
121 | i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) | ||
122 | { | ||
123 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
124 | int mode = MODE_I2C_START; | ||
125 | int ret; | ||
126 | |||
127 | if (reading) | ||
128 | mode |= MODE_I2C_READ; | ||
129 | else | ||
130 | mode |= MODE_I2C_WRITE; | ||
131 | algo_data->address = address; | ||
132 | algo_data->running = true; | ||
133 | ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); | ||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Stop the I2C transaction. This closes out the link, sending | ||
139 | * a bare address packet with the MOT bit turned off | ||
140 | */ | ||
141 | static void | ||
142 | i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) | ||
143 | { | ||
144 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
145 | int mode = MODE_I2C_STOP; | ||
146 | |||
147 | if (reading) | ||
148 | mode |= MODE_I2C_READ; | ||
149 | else | ||
150 | mode |= MODE_I2C_WRITE; | ||
151 | if (algo_data->running) { | ||
152 | (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); | ||
153 | algo_data->running = false; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Write a single byte to the current I2C address, the | ||
159 | * the I2C link must be running or this returns -EIO | ||
160 | */ | ||
161 | static int | ||
162 | i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) | ||
163 | { | ||
164 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
165 | int ret; | ||
166 | |||
167 | if (!algo_data->running) | ||
168 | return -EIO; | ||
169 | |||
170 | ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * Read a single byte from the current I2C address, the | ||
176 | * I2C link must be running or this returns -EIO | ||
177 | */ | ||
178 | static int | ||
179 | i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) | ||
180 | { | ||
181 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
182 | int ret; | ||
183 | |||
184 | if (!algo_data->running) | ||
185 | return -EIO; | ||
186 | |||
187 | ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); | ||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static int | ||
192 | i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, | ||
193 | struct i2c_msg *msgs, | ||
194 | int num) | ||
195 | { | ||
196 | int ret = 0; | ||
197 | bool reading = false; | ||
198 | int m; | ||
199 | int b; | ||
200 | |||
201 | for (m = 0; m < num; m++) { | ||
202 | u16 len = msgs[m].len; | ||
203 | u8 *buf = msgs[m].buf; | ||
204 | reading = (msgs[m].flags & I2C_M_RD) != 0; | ||
205 | ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); | ||
206 | if (ret < 0) | ||
207 | break; | ||
208 | if (reading) { | ||
209 | for (b = 0; b < len; b++) { | ||
210 | ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); | ||
211 | if (ret < 0) | ||
212 | break; | ||
213 | } | ||
214 | } else { | ||
215 | for (b = 0; b < len; b++) { | ||
216 | ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); | ||
217 | if (ret < 0) | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | if (ret < 0) | ||
222 | break; | ||
223 | } | ||
224 | if (ret >= 0) | ||
225 | ret = num; | ||
226 | i2c_algo_dp_aux_stop(adapter, reading); | ||
227 | DRM_DEBUG("dp_aux_xfer return %d\n", ret); | ||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | static u32 | ||
232 | i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) | ||
233 | { | ||
234 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | ||
235 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | ||
236 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | | ||
237 | I2C_FUNC_10BIT_ADDR; | ||
238 | } | ||
239 | |||
240 | static const struct i2c_algorithm i2c_dp_aux_algo = { | ||
241 | .master_xfer = i2c_algo_dp_aux_xfer, | ||
242 | .functionality = i2c_algo_dp_aux_functionality, | ||
243 | }; | ||
244 | |||
245 | static void | ||
246 | i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) | ||
247 | { | ||
248 | (void) i2c_algo_dp_aux_address(adapter, 0, false); | ||
249 | (void) i2c_algo_dp_aux_stop(adapter, false); | ||
250 | |||
251 | } | ||
252 | |||
253 | static int | ||
254 | i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) | ||
255 | { | ||
256 | adapter->algo = &i2c_dp_aux_algo; | ||
257 | adapter->retries = 3; | ||
258 | i2c_dp_aux_reset_bus(adapter); | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | int | ||
263 | i2c_dp_aux_add_bus(struct i2c_adapter *adapter) | ||
264 | { | ||
265 | int error; | ||
266 | |||
267 | error = i2c_dp_aux_prepare_bus(adapter); | ||
268 | if (error) | ||
269 | return error; | ||
270 | error = i2c_add_adapter(adapter); | ||
271 | return error; | ||
272 | } | ||
273 | EXPORT_SYMBOL(i2c_dp_aux_add_bus); | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cd4b9c5f715e..004541c935a8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #define INTEL_OUTPUT_LVDS 4 | 54 | #define INTEL_OUTPUT_LVDS 4 |
55 | #define INTEL_OUTPUT_TVOUT 5 | 55 | #define INTEL_OUTPUT_TVOUT 5 |
56 | #define INTEL_OUTPUT_HDMI 6 | 56 | #define INTEL_OUTPUT_HDMI 6 |
57 | #define INTEL_OUTPUT_DISPLAYPORT 7 | ||
57 | 58 | ||
58 | #define INTEL_DVO_CHIP_NONE 0 | 59 | #define INTEL_DVO_CHIP_NONE 0 |
59 | #define INTEL_DVO_CHIP_LVDS 1 | 60 | #define INTEL_DVO_CHIP_LVDS 1 |
@@ -65,7 +66,6 @@ struct intel_i2c_chan { | |||
65 | u32 reg; /* GPIO reg */ | 66 | u32 reg; /* GPIO reg */ |
66 | struct i2c_adapter adapter; | 67 | struct i2c_adapter adapter; |
67 | struct i2c_algo_bit_data algo; | 68 | struct i2c_algo_bit_data algo; |
68 | u8 slave_addr; | ||
69 | }; | 69 | }; |
70 | 70 | ||
71 | struct intel_framebuffer { | 71 | struct intel_framebuffer { |
@@ -79,11 +79,12 @@ struct intel_output { | |||
79 | 79 | ||
80 | struct drm_encoder enc; | 80 | struct drm_encoder enc; |
81 | int type; | 81 | int type; |
82 | struct intel_i2c_chan *i2c_bus; /* for control functions */ | 82 | struct i2c_adapter *i2c_bus; |
83 | struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */ | 83 | struct i2c_adapter *ddc_bus; |
84 | bool load_detect_temp; | 84 | bool load_detect_temp; |
85 | bool needs_tv_clock; | 85 | bool needs_tv_clock; |
86 | void *dev_priv; | 86 | void *dev_priv; |
87 | void (*hot_plug)(struct intel_output *); | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | struct intel_crtc { | 90 | struct intel_crtc { |
@@ -104,9 +105,9 @@ struct intel_crtc { | |||
104 | #define enc_to_intel_output(x) container_of(x, struct intel_output, enc) | 105 | #define enc_to_intel_output(x) container_of(x, struct intel_output, enc) |
105 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 106 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
106 | 107 | ||
107 | struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, | 108 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
108 | const char *name); | 109 | const char *name); |
109 | void intel_i2c_destroy(struct intel_i2c_chan *chan); | 110 | void intel_i2c_destroy(struct i2c_adapter *adapter); |
110 | int intel_ddc_get_modes(struct intel_output *intel_output); | 111 | int intel_ddc_get_modes(struct intel_output *intel_output); |
111 | extern bool intel_ddc_probe(struct intel_output *intel_output); | 112 | extern bool intel_ddc_probe(struct intel_output *intel_output); |
112 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); | 113 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); |
@@ -116,6 +117,10 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device); | |||
116 | extern void intel_dvo_init(struct drm_device *dev); | 117 | extern void intel_dvo_init(struct drm_device *dev); |
117 | extern void intel_tv_init(struct drm_device *dev); | 118 | extern void intel_tv_init(struct drm_device *dev); |
118 | extern void intel_lvds_init(struct drm_device *dev); | 119 | extern void intel_lvds_init(struct drm_device *dev); |
120 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); | ||
121 | void | ||
122 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | ||
123 | struct drm_display_mode *adjusted_mode); | ||
119 | 124 | ||
120 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 125 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
121 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 126 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 1ee3007d6ec0..13bff20930e8 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -384,10 +384,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
384 | { | 384 | { |
385 | struct intel_output *intel_output; | 385 | struct intel_output *intel_output; |
386 | struct intel_dvo_device *dvo; | 386 | struct intel_dvo_device *dvo; |
387 | struct intel_i2c_chan *i2cbus = NULL; | 387 | struct i2c_adapter *i2cbus = NULL; |
388 | int ret = 0; | 388 | int ret = 0; |
389 | int i; | 389 | int i; |
390 | int gpio_inited = 0; | ||
391 | int encoder_type = DRM_MODE_ENCODER_NONE; | 390 | int encoder_type = DRM_MODE_ENCODER_NONE; |
392 | intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); | 391 | intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); |
393 | if (!intel_output) | 392 | if (!intel_output) |
@@ -420,14 +419,11 @@ void intel_dvo_init(struct drm_device *dev) | |||
420 | * It appears that everything is on GPIOE except for panels | 419 | * It appears that everything is on GPIOE except for panels |
421 | * on i830 laptops, which are on GPIOB (DVOA). | 420 | * on i830 laptops, which are on GPIOB (DVOA). |
422 | */ | 421 | */ |
423 | if (gpio_inited != gpio) { | 422 | if (i2cbus != NULL) |
424 | if (i2cbus != NULL) | 423 | intel_i2c_destroy(i2cbus); |
425 | intel_i2c_destroy(i2cbus); | 424 | if (!(i2cbus = intel_i2c_create(dev, gpio, |
426 | if (!(i2cbus = intel_i2c_create(dev, gpio, | 425 | gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { |
427 | gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { | 426 | continue; |
428 | continue; | ||
429 | } | ||
430 | gpio_inited = gpio; | ||
431 | } | 427 | } |
432 | 428 | ||
433 | if (dvo->dev_ops!= NULL) | 429 | if (dvo->dev_ops!= NULL) |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 1af7d68e3807..1d30802e773e 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -453,7 +453,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
453 | size = ALIGN(size, PAGE_SIZE); | 453 | size = ALIGN(size, PAGE_SIZE); |
454 | fbo = drm_gem_object_alloc(dev, size); | 454 | fbo = drm_gem_object_alloc(dev, size); |
455 | if (!fbo) { | 455 | if (!fbo) { |
456 | printk(KERN_ERR "failed to allocate framebuffer\n"); | 456 | DRM_ERROR("failed to allocate framebuffer\n"); |
457 | ret = -ENOMEM; | 457 | ret = -ENOMEM; |
458 | goto out; | 458 | goto out; |
459 | } | 459 | } |
@@ -610,8 +610,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
610 | par->dev = dev; | 610 | par->dev = dev; |
611 | 611 | ||
612 | /* To allow resizeing without swapping buffers */ | 612 | /* To allow resizeing without swapping buffers */ |
613 | printk("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, | 613 | DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, |
614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); | 614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); |
615 | 615 | ||
616 | mutex_unlock(&dev->struct_mutex); | 616 | mutex_unlock(&dev->struct_mutex); |
617 | return 0; | 617 | return 0; |
@@ -698,13 +698,13 @@ static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc * | |||
698 | } else | 698 | } else |
699 | intelfb_set_par(info); | 699 | intelfb_set_par(info); |
700 | 700 | ||
701 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 701 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
702 | info->fix.id); | 702 | info->fix.id); |
703 | 703 | ||
704 | /* Switch back to kernel console on panic */ | 704 | /* Switch back to kernel console on panic */ |
705 | kernelfb_mode = *modeset; | 705 | kernelfb_mode = *modeset; |
706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
707 | printk(KERN_INFO "registered panic notifier\n"); | 707 | DRM_DEBUG("registered panic notifier\n"); |
708 | 708 | ||
709 | return 0; | 709 | return 0; |
710 | } | 710 | } |
@@ -852,13 +852,13 @@ static int intelfb_single_fb_probe(struct drm_device *dev) | |||
852 | } else | 852 | } else |
853 | intelfb_set_par(info); | 853 | intelfb_set_par(info); |
854 | 854 | ||
855 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 855 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
856 | info->fix.id); | 856 | info->fix.id); |
857 | 857 | ||
858 | /* Switch back to kernel console on panic */ | 858 | /* Switch back to kernel console on panic */ |
859 | kernelfb_mode = *modeset; | 859 | kernelfb_mode = *modeset; |
860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
861 | printk(KERN_INFO "registered panic notifier\n"); | 861 | DRM_DEBUG("registered panic notifier\n"); |
862 | 862 | ||
863 | return 0; | 863 | return 0; |
864 | } | 864 | } |
@@ -872,8 +872,8 @@ void intelfb_restore(void) | |||
872 | { | 872 | { |
873 | int ret; | 873 | int ret; |
874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { | 874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { |
875 | printk(KERN_ERR "Failed to restore crtc configuration: %d\n", | 875 | DRM_ERROR("Failed to restore crtc configuration: %d\n", |
876 | ret); | 876 | ret); |
877 | } | 877 | } |
878 | } | 878 | } |
879 | 879 | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 4ea2a651b92c..9e30daae37dc 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "drmP.h" | 31 | #include "drmP.h" |
32 | #include "drm.h" | 32 | #include "drm.h" |
33 | #include "drm_crtc.h" | 33 | #include "drm_crtc.h" |
34 | #include "drm_edid.h" | ||
34 | #include "intel_drv.h" | 35 | #include "intel_drv.h" |
35 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
36 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
@@ -56,8 +57,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
56 | sdvox = SDVO_ENCODING_HDMI | | 57 | sdvox = SDVO_ENCODING_HDMI | |
57 | SDVO_BORDER_ENABLE | | 58 | SDVO_BORDER_ENABLE | |
58 | SDVO_VSYNC_ACTIVE_HIGH | | 59 | SDVO_VSYNC_ACTIVE_HIGH | |
59 | SDVO_HSYNC_ACTIVE_HIGH | | 60 | SDVO_HSYNC_ACTIVE_HIGH; |
60 | SDVO_NULL_PACKETS_DURING_VSYNC; | ||
61 | 61 | ||
62 | if (hdmi_priv->has_hdmi_sink) | 62 | if (hdmi_priv->has_hdmi_sink) |
63 | sdvox |= SDVO_AUDIO_ENABLE; | 63 | sdvox |= SDVO_AUDIO_ENABLE; |
@@ -129,20 +129,26 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
129 | return true; | 129 | return true; |
130 | } | 130 | } |
131 | 131 | ||
132 | static void | 132 | static enum drm_connector_status |
133 | intel_hdmi_sink_detect(struct drm_connector *connector) | 133 | intel_hdmi_edid_detect(struct drm_connector *connector) |
134 | { | 134 | { |
135 | struct intel_output *intel_output = to_intel_output(connector); | 135 | struct intel_output *intel_output = to_intel_output(connector); |
136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; |
137 | struct edid *edid = NULL; | 137 | struct edid *edid = NULL; |
138 | enum drm_connector_status status = connector_status_disconnected; | ||
138 | 139 | ||
139 | edid = drm_get_edid(&intel_output->base, | 140 | edid = drm_get_edid(&intel_output->base, |
140 | &intel_output->ddc_bus->adapter); | 141 | intel_output->ddc_bus); |
141 | if (edid != NULL) { | 142 | hdmi_priv->has_hdmi_sink = false; |
142 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 143 | if (edid) { |
143 | kfree(edid); | 144 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
145 | status = connector_status_connected; | ||
146 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | ||
147 | } | ||
144 | intel_output->base.display_info.raw_edid = NULL; | 148 | intel_output->base.display_info.raw_edid = NULL; |
149 | kfree(edid); | ||
145 | } | 150 | } |
151 | return status; | ||
146 | } | 152 | } |
147 | 153 | ||
148 | static enum drm_connector_status | 154 | static enum drm_connector_status |
@@ -154,11 +160,7 @@ igdng_hdmi_detect(struct drm_connector *connector) | |||
154 | /* FIXME hotplug detect */ | 160 | /* FIXME hotplug detect */ |
155 | 161 | ||
156 | hdmi_priv->has_hdmi_sink = false; | 162 | hdmi_priv->has_hdmi_sink = false; |
157 | intel_hdmi_sink_detect(connector); | 163 | return intel_hdmi_edid_detect(connector); |
158 | if (hdmi_priv->has_hdmi_sink) | ||
159 | return connector_status_connected; | ||
160 | else | ||
161 | return connector_status_disconnected; | ||
162 | } | 164 | } |
163 | 165 | ||
164 | static enum drm_connector_status | 166 | static enum drm_connector_status |
@@ -201,10 +203,9 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
201 | return connector_status_unknown; | 203 | return connector_status_unknown; |
202 | } | 204 | } |
203 | 205 | ||
204 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) { | 206 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) |
205 | intel_hdmi_sink_detect(connector); | 207 | return intel_hdmi_edid_detect(connector); |
206 | return connector_status_connected; | 208 | else |
207 | } else | ||
208 | return connector_status_disconnected; | 209 | return connector_status_disconnected; |
209 | } | 210 | } |
210 | 211 | ||
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index f7061f68d050..62b8bead7652 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -124,6 +124,7 @@ static void set_data(void *data, int state_high) | |||
124 | * @output: driver specific output device | 124 | * @output: driver specific output device |
125 | * @reg: GPIO reg to use | 125 | * @reg: GPIO reg to use |
126 | * @name: name for this bus | 126 | * @name: name for this bus |
127 | * @slave_addr: slave address (if fixed) | ||
127 | * | 128 | * |
128 | * Creates and registers a new i2c bus with the Linux i2c layer, for use | 129 | * Creates and registers a new i2c bus with the Linux i2c layer, for use |
129 | * in output probing and control (e.g. DDC or SDVO control functions). | 130 | * in output probing and control (e.g. DDC or SDVO control functions). |
@@ -139,8 +140,8 @@ static void set_data(void *data, int state_high) | |||
139 | * %GPIOH | 140 | * %GPIOH |
140 | * see PRM for details on how these different busses are used. | 141 | * see PRM for details on how these different busses are used. |
141 | */ | 142 | */ |
142 | struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, | 143 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
143 | const char *name) | 144 | const char *name) |
144 | { | 145 | { |
145 | struct intel_i2c_chan *chan; | 146 | struct intel_i2c_chan *chan; |
146 | 147 | ||
@@ -174,7 +175,7 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, | |||
174 | intel_i2c_quirk_set(dev, false); | 175 | intel_i2c_quirk_set(dev, false); |
175 | udelay(20); | 176 | udelay(20); |
176 | 177 | ||
177 | return chan; | 178 | return &chan->adapter; |
178 | 179 | ||
179 | out_free: | 180 | out_free: |
180 | kfree(chan); | 181 | kfree(chan); |
@@ -187,11 +188,16 @@ out_free: | |||
187 | * | 188 | * |
188 | * Unregister the adapter from the i2c layer, then free the structure. | 189 | * Unregister the adapter from the i2c layer, then free the structure. |
189 | */ | 190 | */ |
190 | void intel_i2c_destroy(struct intel_i2c_chan *chan) | 191 | void intel_i2c_destroy(struct i2c_adapter *adapter) |
191 | { | 192 | { |
192 | if (!chan) | 193 | struct intel_i2c_chan *chan; |
194 | |||
195 | if (!adapter) | ||
193 | return; | 196 | return; |
194 | 197 | ||
198 | chan = container_of(adapter, | ||
199 | struct intel_i2c_chan, | ||
200 | adapter); | ||
195 | i2c_del_adapter(&chan->adapter); | 201 | i2c_del_adapter(&chan->adapter); |
196 | kfree(chan); | 202 | kfree(chan); |
197 | } | 203 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f073ed8432e8..9ab38efffecf 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -36,9 +36,25 @@ | |||
36 | #include "intel_drv.h" | 36 | #include "intel_drv.h" |
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | #include <linux/acpi.h> | ||
39 | 40 | ||
40 | #define I915_LVDS "i915_lvds" | 41 | #define I915_LVDS "i915_lvds" |
41 | 42 | ||
43 | /* | ||
44 | * the following four scaling options are defined. | ||
45 | * #define DRM_MODE_SCALE_NON_GPU 0 | ||
46 | * #define DRM_MODE_SCALE_FULLSCREEN 1 | ||
47 | * #define DRM_MODE_SCALE_NO_SCALE 2 | ||
48 | * #define DRM_MODE_SCALE_ASPECT 3 | ||
49 | */ | ||
50 | |||
51 | /* Private structure for the integrated LVDS support */ | ||
52 | struct intel_lvds_priv { | ||
53 | int fitting_mode; | ||
54 | u32 pfit_control; | ||
55 | u32 pfit_pgm_ratios; | ||
56 | }; | ||
57 | |||
42 | /** | 58 | /** |
43 | * Sets the backlight level. | 59 | * Sets the backlight level. |
44 | * | 60 | * |
@@ -213,26 +229,45 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
213 | struct drm_display_mode *mode, | 229 | struct drm_display_mode *mode, |
214 | struct drm_display_mode *adjusted_mode) | 230 | struct drm_display_mode *adjusted_mode) |
215 | { | 231 | { |
232 | /* | ||
233 | * float point operation is not supported . So the PANEL_RATIO_FACTOR | ||
234 | * is defined, which can avoid the float point computation when | ||
235 | * calculating the panel ratio. | ||
236 | */ | ||
237 | #define PANEL_RATIO_FACTOR 8192 | ||
216 | struct drm_device *dev = encoder->dev; | 238 | struct drm_device *dev = encoder->dev; |
217 | struct drm_i915_private *dev_priv = dev->dev_private; | 239 | struct drm_i915_private *dev_priv = dev->dev_private; |
218 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 240 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
219 | struct drm_encoder *tmp_encoder; | 241 | struct drm_encoder *tmp_encoder; |
242 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
243 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; | ||
244 | u32 pfit_control = 0, pfit_pgm_ratios = 0; | ||
245 | int left_border = 0, right_border = 0, top_border = 0; | ||
246 | int bottom_border = 0; | ||
247 | bool border = 0; | ||
248 | int panel_ratio, desired_ratio, vert_scale, horiz_scale; | ||
249 | int horiz_ratio, vert_ratio; | ||
250 | u32 hsync_width, vsync_width; | ||
251 | u32 hblank_width, vblank_width; | ||
252 | u32 hsync_pos, vsync_pos; | ||
220 | 253 | ||
221 | /* Should never happen!! */ | 254 | /* Should never happen!! */ |
222 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 255 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
223 | printk(KERN_ERR "Can't support LVDS on pipe A\n"); | 256 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
224 | return false; | 257 | return false; |
225 | } | 258 | } |
226 | 259 | ||
227 | /* Should never happen!! */ | 260 | /* Should never happen!! */ |
228 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { | 261 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { |
229 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { | 262 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { |
230 | printk(KERN_ERR "Can't enable LVDS and another " | 263 | DRM_ERROR("Can't enable LVDS and another " |
231 | "encoder on the same pipe\n"); | 264 | "encoder on the same pipe\n"); |
232 | return false; | 265 | return false; |
233 | } | 266 | } |
234 | } | 267 | } |
235 | 268 | /* If we don't have a panel mode, there is nothing we can do */ | |
269 | if (dev_priv->panel_fixed_mode == NULL) | ||
270 | return true; | ||
236 | /* | 271 | /* |
237 | * If we have timings from the BIOS for the panel, put them in | 272 | * If we have timings from the BIOS for the panel, put them in |
238 | * to the adjusted mode. The CRTC will be set up for this mode, | 273 | * to the adjusted mode. The CRTC will be set up for this mode, |
@@ -256,6 +291,243 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
256 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | 291 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); |
257 | } | 292 | } |
258 | 293 | ||
294 | /* Make sure pre-965s set dither correctly */ | ||
295 | if (!IS_I965G(dev)) { | ||
296 | if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) | ||
297 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; | ||
298 | } | ||
299 | |||
300 | /* Native modes don't need fitting */ | ||
301 | if (adjusted_mode->hdisplay == mode->hdisplay && | ||
302 | adjusted_mode->vdisplay == mode->vdisplay) { | ||
303 | pfit_pgm_ratios = 0; | ||
304 | border = 0; | ||
305 | goto out; | ||
306 | } | ||
307 | |||
308 | /* 965+ wants fuzzy fitting */ | ||
309 | if (IS_I965G(dev)) | ||
310 | pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | | ||
311 | PFIT_FILTER_FUZZY; | ||
312 | |||
313 | hsync_width = adjusted_mode->crtc_hsync_end - | ||
314 | adjusted_mode->crtc_hsync_start; | ||
315 | vsync_width = adjusted_mode->crtc_vsync_end - | ||
316 | adjusted_mode->crtc_vsync_start; | ||
317 | hblank_width = adjusted_mode->crtc_hblank_end - | ||
318 | adjusted_mode->crtc_hblank_start; | ||
319 | vblank_width = adjusted_mode->crtc_vblank_end - | ||
320 | adjusted_mode->crtc_vblank_start; | ||
321 | /* | ||
322 | * Deal with panel fitting options. Figure out how to stretch the | ||
323 | * image based on its aspect ratio & the current panel fitting mode. | ||
324 | */ | ||
325 | panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR / | ||
326 | adjusted_mode->vdisplay; | ||
327 | desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR / | ||
328 | mode->vdisplay; | ||
329 | /* | ||
330 | * Enable automatic panel scaling for non-native modes so that they fill | ||
331 | * the screen. Should be enabled before the pipe is enabled, according | ||
332 | * to register description and PRM. | ||
333 | * Change the value here to see the borders for debugging | ||
334 | */ | ||
335 | I915_WRITE(BCLRPAT_A, 0); | ||
336 | I915_WRITE(BCLRPAT_B, 0); | ||
337 | |||
338 | switch (lvds_priv->fitting_mode) { | ||
339 | case DRM_MODE_SCALE_NO_SCALE: | ||
340 | /* | ||
341 | * For centered modes, we have to calculate border widths & | ||
342 | * heights and modify the values programmed into the CRTC. | ||
343 | */ | ||
344 | left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2; | ||
345 | right_border = left_border; | ||
346 | if (mode->hdisplay & 1) | ||
347 | right_border++; | ||
348 | top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2; | ||
349 | bottom_border = top_border; | ||
350 | if (mode->vdisplay & 1) | ||
351 | bottom_border++; | ||
352 | /* Set active & border values */ | ||
353 | adjusted_mode->crtc_hdisplay = mode->hdisplay; | ||
354 | /* Keep the boder be even */ | ||
355 | if (right_border & 1) | ||
356 | right_border++; | ||
357 | /* use the border directly instead of border minuse one */ | ||
358 | adjusted_mode->crtc_hblank_start = mode->hdisplay + | ||
359 | right_border; | ||
360 | /* keep the blank width constant */ | ||
361 | adjusted_mode->crtc_hblank_end = | ||
362 | adjusted_mode->crtc_hblank_start + hblank_width; | ||
363 | /* get the hsync pos relative to hblank start */ | ||
364 | hsync_pos = (hblank_width - hsync_width) / 2; | ||
365 | /* keep the hsync pos be even */ | ||
366 | if (hsync_pos & 1) | ||
367 | hsync_pos++; | ||
368 | adjusted_mode->crtc_hsync_start = | ||
369 | adjusted_mode->crtc_hblank_start + hsync_pos; | ||
370 | /* keep the hsync width constant */ | ||
371 | adjusted_mode->crtc_hsync_end = | ||
372 | adjusted_mode->crtc_hsync_start + hsync_width; | ||
373 | adjusted_mode->crtc_vdisplay = mode->vdisplay; | ||
374 | /* use the border instead of border minus one */ | ||
375 | adjusted_mode->crtc_vblank_start = mode->vdisplay + | ||
376 | bottom_border; | ||
377 | /* keep the vblank width constant */ | ||
378 | adjusted_mode->crtc_vblank_end = | ||
379 | adjusted_mode->crtc_vblank_start + vblank_width; | ||
380 | /* get the vsync start postion relative to vblank start */ | ||
381 | vsync_pos = (vblank_width - vsync_width) / 2; | ||
382 | adjusted_mode->crtc_vsync_start = | ||
383 | adjusted_mode->crtc_vblank_start + vsync_pos; | ||
384 | /* keep the vsync width constant */ | ||
385 | adjusted_mode->crtc_vsync_end = | ||
386 | adjusted_mode->crtc_vblank_start + vsync_width; | ||
387 | border = 1; | ||
388 | break; | ||
389 | case DRM_MODE_SCALE_ASPECT: | ||
390 | /* Scale but preserve the spect ratio */ | ||
391 | pfit_control |= PFIT_ENABLE; | ||
392 | if (IS_I965G(dev)) { | ||
393 | /* 965+ is easy, it does everything in hw */ | ||
394 | if (panel_ratio > desired_ratio) | ||
395 | pfit_control |= PFIT_SCALING_PILLAR; | ||
396 | else if (panel_ratio < desired_ratio) | ||
397 | pfit_control |= PFIT_SCALING_LETTER; | ||
398 | else | ||
399 | pfit_control |= PFIT_SCALING_AUTO; | ||
400 | } else { | ||
401 | /* | ||
402 | * For earlier chips we have to calculate the scaling | ||
403 | * ratio by hand and program it into the | ||
404 | * PFIT_PGM_RATIO register | ||
405 | */ | ||
406 | u32 horiz_bits, vert_bits, bits = 12; | ||
407 | horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/ | ||
408 | adjusted_mode->hdisplay; | ||
409 | vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/ | ||
410 | adjusted_mode->vdisplay; | ||
411 | horiz_scale = adjusted_mode->hdisplay * | ||
412 | PANEL_RATIO_FACTOR / mode->hdisplay; | ||
413 | vert_scale = adjusted_mode->vdisplay * | ||
414 | PANEL_RATIO_FACTOR / mode->vdisplay; | ||
415 | |||
416 | /* retain aspect ratio */ | ||
417 | if (panel_ratio > desired_ratio) { /* Pillar */ | ||
418 | u32 scaled_width; | ||
419 | scaled_width = mode->hdisplay * vert_scale / | ||
420 | PANEL_RATIO_FACTOR; | ||
421 | horiz_ratio = vert_ratio; | ||
422 | pfit_control |= (VERT_AUTO_SCALE | | ||
423 | VERT_INTERP_BILINEAR | | ||
424 | HORIZ_INTERP_BILINEAR); | ||
425 | /* Pillar will have left/right borders */ | ||
426 | left_border = (adjusted_mode->hdisplay - | ||
427 | scaled_width) / 2; | ||
428 | right_border = left_border; | ||
429 | if (mode->hdisplay & 1) /* odd resolutions */ | ||
430 | right_border++; | ||
431 | /* keep the border be even */ | ||
432 | if (right_border & 1) | ||
433 | right_border++; | ||
434 | adjusted_mode->crtc_hdisplay = scaled_width; | ||
435 | /* use border instead of border minus one */ | ||
436 | adjusted_mode->crtc_hblank_start = | ||
437 | scaled_width + right_border; | ||
438 | /* keep the hblank width constant */ | ||
439 | adjusted_mode->crtc_hblank_end = | ||
440 | adjusted_mode->crtc_hblank_start + | ||
441 | hblank_width; | ||
442 | /* | ||
443 | * get the hsync start pos relative to | ||
444 | * hblank start | ||
445 | */ | ||
446 | hsync_pos = (hblank_width - hsync_width) / 2; | ||
447 | /* keep the hsync_pos be even */ | ||
448 | if (hsync_pos & 1) | ||
449 | hsync_pos++; | ||
450 | adjusted_mode->crtc_hsync_start = | ||
451 | adjusted_mode->crtc_hblank_start + | ||
452 | hsync_pos; | ||
453 | /* keept hsync width constant */ | ||
454 | adjusted_mode->crtc_hsync_end = | ||
455 | adjusted_mode->crtc_hsync_start + | ||
456 | hsync_width; | ||
457 | border = 1; | ||
458 | } else if (panel_ratio < desired_ratio) { /* letter */ | ||
459 | u32 scaled_height = mode->vdisplay * | ||
460 | horiz_scale / PANEL_RATIO_FACTOR; | ||
461 | vert_ratio = horiz_ratio; | ||
462 | pfit_control |= (HORIZ_AUTO_SCALE | | ||
463 | VERT_INTERP_BILINEAR | | ||
464 | HORIZ_INTERP_BILINEAR); | ||
465 | /* Letterbox will have top/bottom border */ | ||
466 | top_border = (adjusted_mode->vdisplay - | ||
467 | scaled_height) / 2; | ||
468 | bottom_border = top_border; | ||
469 | if (mode->vdisplay & 1) | ||
470 | bottom_border++; | ||
471 | adjusted_mode->crtc_vdisplay = scaled_height; | ||
472 | /* use border instead of border minus one */ | ||
473 | adjusted_mode->crtc_vblank_start = | ||
474 | scaled_height + bottom_border; | ||
475 | /* keep the vblank width constant */ | ||
476 | adjusted_mode->crtc_vblank_end = | ||
477 | adjusted_mode->crtc_vblank_start + | ||
478 | vblank_width; | ||
479 | /* | ||
480 | * get the vsync start pos relative to | ||
481 | * vblank start | ||
482 | */ | ||
483 | vsync_pos = (vblank_width - vsync_width) / 2; | ||
484 | adjusted_mode->crtc_vsync_start = | ||
485 | adjusted_mode->crtc_vblank_start + | ||
486 | vsync_pos; | ||
487 | /* keep the vsync width constant */ | ||
488 | adjusted_mode->crtc_vsync_end = | ||
489 | adjusted_mode->crtc_vsync_start + | ||
490 | vsync_width; | ||
491 | border = 1; | ||
492 | } else { | ||
493 | /* Aspects match, Let hw scale both directions */ | ||
494 | pfit_control |= (VERT_AUTO_SCALE | | ||
495 | HORIZ_AUTO_SCALE | | ||
496 | VERT_INTERP_BILINEAR | | ||
497 | HORIZ_INTERP_BILINEAR); | ||
498 | } | ||
499 | horiz_bits = (1 << bits) * horiz_ratio / | ||
500 | PANEL_RATIO_FACTOR; | ||
501 | vert_bits = (1 << bits) * vert_ratio / | ||
502 | PANEL_RATIO_FACTOR; | ||
503 | pfit_pgm_ratios = | ||
504 | ((vert_bits << PFIT_VERT_SCALE_SHIFT) & | ||
505 | PFIT_VERT_SCALE_MASK) | | ||
506 | ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & | ||
507 | PFIT_HORIZ_SCALE_MASK); | ||
508 | } | ||
509 | break; | ||
510 | |||
511 | case DRM_MODE_SCALE_FULLSCREEN: | ||
512 | /* | ||
513 | * Full scaling, even if it changes the aspect ratio. | ||
514 | * Fortunately this is all done for us in hw. | ||
515 | */ | ||
516 | pfit_control |= PFIT_ENABLE; | ||
517 | if (IS_I965G(dev)) | ||
518 | pfit_control |= PFIT_SCALING_AUTO; | ||
519 | else | ||
520 | pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | | ||
521 | VERT_INTERP_BILINEAR | | ||
522 | HORIZ_INTERP_BILINEAR); | ||
523 | break; | ||
524 | default: | ||
525 | break; | ||
526 | } | ||
527 | |||
528 | out: | ||
529 | lvds_priv->pfit_control = pfit_control; | ||
530 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; | ||
259 | /* | 531 | /* |
260 | * XXX: It would be nice to support lower refresh rates on the | 532 | * XXX: It would be nice to support lower refresh rates on the |
261 | * panels to reduce power consumption, and perhaps match the | 533 | * panels to reduce power consumption, and perhaps match the |
@@ -301,8 +573,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
301 | { | 573 | { |
302 | struct drm_device *dev = encoder->dev; | 574 | struct drm_device *dev = encoder->dev; |
303 | struct drm_i915_private *dev_priv = dev->dev_private; | 575 | struct drm_i915_private *dev_priv = dev->dev_private; |
304 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 576 | struct intel_output *intel_output = enc_to_intel_output(encoder); |
305 | u32 pfit_control; | 577 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; |
306 | 578 | ||
307 | /* | 579 | /* |
308 | * The LVDS pin pair will already have been turned on in the | 580 | * The LVDS pin pair will already have been turned on in the |
@@ -319,22 +591,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
319 | * screen. Should be enabled before the pipe is enabled, according to | 591 | * screen. Should be enabled before the pipe is enabled, according to |
320 | * register description and PRM. | 592 | * register description and PRM. |
321 | */ | 593 | */ |
322 | if (mode->hdisplay != adjusted_mode->hdisplay || | 594 | I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); |
323 | mode->vdisplay != adjusted_mode->vdisplay) | 595 | I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); |
324 | pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | | ||
325 | HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | | ||
326 | HORIZ_INTERP_BILINEAR); | ||
327 | else | ||
328 | pfit_control = 0; | ||
329 | |||
330 | if (!IS_I965G(dev)) { | ||
331 | if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) | ||
332 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; | ||
333 | } | ||
334 | else | ||
335 | pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT; | ||
336 | |||
337 | I915_WRITE(PFIT_CONTROL, pfit_control); | ||
338 | } | 596 | } |
339 | 597 | ||
340 | /** | 598 | /** |
@@ -406,6 +664,34 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
406 | struct drm_property *property, | 664 | struct drm_property *property, |
407 | uint64_t value) | 665 | uint64_t value) |
408 | { | 666 | { |
667 | struct drm_device *dev = connector->dev; | ||
668 | struct intel_output *intel_output = | ||
669 | to_intel_output(connector); | ||
670 | |||
671 | if (property == dev->mode_config.scaling_mode_property && | ||
672 | connector->encoder) { | ||
673 | struct drm_crtc *crtc = connector->encoder->crtc; | ||
674 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; | ||
675 | if (value == DRM_MODE_SCALE_NON_GPU) { | ||
676 | DRM_DEBUG_KMS(I915_LVDS, | ||
677 | "non_GPU property is unsupported\n"); | ||
678 | return 0; | ||
679 | } | ||
680 | if (lvds_priv->fitting_mode == value) { | ||
681 | /* the LVDS scaling property is not changed */ | ||
682 | return 0; | ||
683 | } | ||
684 | lvds_priv->fitting_mode = value; | ||
685 | if (crtc && crtc->enabled) { | ||
686 | /* | ||
687 | * If the CRTC is enabled, the display will be changed | ||
688 | * according to the new panel fitting mode. | ||
689 | */ | ||
690 | drm_crtc_helper_set_mode(crtc, &crtc->mode, | ||
691 | crtc->x, crtc->y, crtc->fb); | ||
692 | } | ||
693 | } | ||
694 | |||
409 | return 0; | 695 | return 0; |
410 | } | 696 | } |
411 | 697 | ||
@@ -456,7 +742,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
456 | .callback = intel_no_lvds_dmi_callback, | 742 | .callback = intel_no_lvds_dmi_callback, |
457 | .ident = "Apple Mac Mini (Core series)", | 743 | .ident = "Apple Mac Mini (Core series)", |
458 | .matches = { | 744 | .matches = { |
459 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 745 | DMI_MATCH(DMI_SYS_VENDOR, "Apple"), |
460 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), | 746 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), |
461 | }, | 747 | }, |
462 | }, | 748 | }, |
@@ -464,7 +750,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
464 | .callback = intel_no_lvds_dmi_callback, | 750 | .callback = intel_no_lvds_dmi_callback, |
465 | .ident = "Apple Mac Mini (Core 2 series)", | 751 | .ident = "Apple Mac Mini (Core 2 series)", |
466 | .matches = { | 752 | .matches = { |
467 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 753 | DMI_MATCH(DMI_SYS_VENDOR, "Apple"), |
468 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), | 754 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), |
469 | }, | 755 | }, |
470 | }, | 756 | }, |
@@ -503,6 +789,65 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
503 | { } /* terminating entry */ | 789 | { } /* terminating entry */ |
504 | }; | 790 | }; |
505 | 791 | ||
792 | #ifdef CONFIG_ACPI | ||
793 | /* | ||
794 | * check_lid_device -- check whether @handle is an ACPI LID device. | ||
795 | * @handle: ACPI device handle | ||
796 | * @level : depth in the ACPI namespace tree | ||
797 | * @context: the number of LID device when we find the device | ||
798 | * @rv: a return value to fill if desired (Not use) | ||
799 | */ | ||
800 | static acpi_status | ||
801 | check_lid_device(acpi_handle handle, u32 level, void *context, | ||
802 | void **return_value) | ||
803 | { | ||
804 | struct acpi_device *acpi_dev; | ||
805 | int *lid_present = context; | ||
806 | |||
807 | acpi_dev = NULL; | ||
808 | /* Get the acpi device for device handle */ | ||
809 | if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { | ||
810 | /* If there is no ACPI device for handle, return */ | ||
811 | return AE_OK; | ||
812 | } | ||
813 | |||
814 | if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) | ||
815 | *lid_present = 1; | ||
816 | |||
817 | return AE_OK; | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * check whether there exists the ACPI LID device by enumerating the ACPI | ||
822 | * device tree. | ||
823 | */ | ||
824 | static int intel_lid_present(void) | ||
825 | { | ||
826 | int lid_present = 0; | ||
827 | |||
828 | if (acpi_disabled) { | ||
829 | /* If ACPI is disabled, there is no ACPI device tree to | ||
830 | * check, so assume the LID device would have been present. | ||
831 | */ | ||
832 | return 1; | ||
833 | } | ||
834 | |||
835 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
836 | ACPI_UINT32_MAX, | ||
837 | check_lid_device, &lid_present, NULL); | ||
838 | |||
839 | return lid_present; | ||
840 | } | ||
841 | #else | ||
842 | static int intel_lid_present(void) | ||
843 | { | ||
844 | /* In the absence of ACPI built in, assume that the LID device would | ||
845 | * have been present. | ||
846 | */ | ||
847 | return 1; | ||
848 | } | ||
849 | #endif | ||
850 | |||
506 | /** | 851 | /** |
507 | * intel_lvds_init - setup LVDS connectors on this device | 852 | * intel_lvds_init - setup LVDS connectors on this device |
508 | * @dev: drm device | 853 | * @dev: drm device |
@@ -518,6 +863,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
518 | struct drm_encoder *encoder; | 863 | struct drm_encoder *encoder; |
519 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 864 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
520 | struct drm_crtc *crtc; | 865 | struct drm_crtc *crtc; |
866 | struct intel_lvds_priv *lvds_priv; | ||
521 | u32 lvds; | 867 | u32 lvds; |
522 | int pipe, gpio = GPIOC; | 868 | int pipe, gpio = GPIOC; |
523 | 869 | ||
@@ -525,13 +871,24 @@ void intel_lvds_init(struct drm_device *dev) | |||
525 | if (dmi_check_system(intel_no_lvds)) | 871 | if (dmi_check_system(intel_no_lvds)) |
526 | return; | 872 | return; |
527 | 873 | ||
874 | /* Assume that any device without an ACPI LID device also doesn't | ||
875 | * have an integrated LVDS. We would be better off parsing the BIOS | ||
876 | * to get a reliable indicator, but that code isn't written yet. | ||
877 | * | ||
878 | * In the case of all-in-one desktops using LVDS that we've seen, | ||
879 | * they're using SDVO LVDS. | ||
880 | */ | ||
881 | if (!intel_lid_present()) | ||
882 | return; | ||
883 | |||
528 | if (IS_IGDNG(dev)) { | 884 | if (IS_IGDNG(dev)) { |
529 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 885 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
530 | return; | 886 | return; |
531 | gpio = PCH_GPIOC; | 887 | gpio = PCH_GPIOC; |
532 | } | 888 | } |
533 | 889 | ||
534 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); | 890 | intel_output = kzalloc(sizeof(struct intel_output) + |
891 | sizeof(struct intel_lvds_priv), GFP_KERNEL); | ||
535 | if (!intel_output) { | 892 | if (!intel_output) { |
536 | return; | 893 | return; |
537 | } | 894 | } |
@@ -553,7 +910,18 @@ void intel_lvds_init(struct drm_device *dev) | |||
553 | connector->interlace_allowed = false; | 910 | connector->interlace_allowed = false; |
554 | connector->doublescan_allowed = false; | 911 | connector->doublescan_allowed = false; |
555 | 912 | ||
913 | lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); | ||
914 | intel_output->dev_priv = lvds_priv; | ||
915 | /* create the scaling mode property */ | ||
916 | drm_mode_create_scaling_mode_property(dev); | ||
917 | /* | ||
918 | * the initial panel fitting mode will be FULL_SCREEN. | ||
919 | */ | ||
556 | 920 | ||
921 | drm_connector_attach_property(&intel_output->base, | ||
922 | dev->mode_config.scaling_mode_property, | ||
923 | DRM_MODE_SCALE_FULLSCREEN); | ||
924 | lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; | ||
557 | /* | 925 | /* |
558 | * LVDS discovery: | 926 | * LVDS discovery: |
559 | * 1) check for EDID on DDC | 927 | * 1) check for EDID on DDC |
@@ -649,5 +1017,5 @@ failed: | |||
649 | if (intel_output->ddc_bus) | 1017 | if (intel_output->ddc_bus) |
650 | intel_i2c_destroy(intel_output->ddc_bus); | 1018 | intel_i2c_destroy(intel_output->ddc_bus); |
651 | drm_connector_cleanup(connector); | 1019 | drm_connector_cleanup(connector); |
652 | kfree(connector); | 1020 | kfree(intel_output); |
653 | } | 1021 | } |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index e0910fefce87..67e2f4632a24 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -53,10 +53,9 @@ bool intel_ddc_probe(struct intel_output *intel_output) | |||
53 | } | 53 | } |
54 | }; | 54 | }; |
55 | 55 | ||
56 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); | 56 | intel_i2c_quirk_set(intel_output->base.dev, true); |
57 | ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2); | 57 | ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); |
58 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); | 58 | intel_i2c_quirk_set(intel_output->base.dev, false); |
59 | |||
60 | if (ret == 2) | 59 | if (ret == 2) |
61 | return true; | 60 | return true; |
62 | 61 | ||
@@ -74,10 +73,9 @@ int intel_ddc_get_modes(struct intel_output *intel_output) | |||
74 | struct edid *edid; | 73 | struct edid *edid; |
75 | int ret = 0; | 74 | int ret = 0; |
76 | 75 | ||
77 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); | 76 | intel_i2c_quirk_set(intel_output->base.dev, true); |
78 | edid = drm_get_edid(&intel_output->base, | 77 | edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); |
79 | &intel_output->ddc_bus->adapter); | 78 | intel_i2c_quirk_set(intel_output->base.dev, false); |
80 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); | ||
81 | if (edid) { | 79 | if (edid) { |
82 | drm_mode_connector_update_edid_property(&intel_output->base, | 80 | drm_mode_connector_update_edid_property(&intel_output->base, |
83 | edid); | 81 | edid); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9a00adb3a508..4f0c30948bc4 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -38,8 +38,7 @@ | |||
38 | #undef SDVO_DEBUG | 38 | #undef SDVO_DEBUG |
39 | #define I915_SDVO "i915_sdvo" | 39 | #define I915_SDVO "i915_sdvo" |
40 | struct intel_sdvo_priv { | 40 | struct intel_sdvo_priv { |
41 | struct intel_i2c_chan *i2c_bus; | 41 | u8 slave_addr; |
42 | int slaveaddr; | ||
43 | 42 | ||
44 | /* Register for the SDVO device: SDVOB or SDVOC */ | 43 | /* Register for the SDVO device: SDVOB or SDVOC */ |
45 | int output_device; | 44 | int output_device; |
@@ -69,12 +68,23 @@ struct intel_sdvo_priv { | |||
69 | * This is set if we treat the device as HDMI, instead of DVI. | 68 | * This is set if we treat the device as HDMI, instead of DVI. |
70 | */ | 69 | */ |
71 | bool is_hdmi; | 70 | bool is_hdmi; |
71 | |||
72 | /** | 72 | /** |
73 | * This is set if we detect output of sdvo device as LVDS. | 73 | * This is set if we detect output of sdvo device as LVDS. |
74 | */ | 74 | */ |
75 | bool is_lvds; | 75 | bool is_lvds; |
76 | 76 | ||
77 | /** | 77 | /** |
78 | * This is sdvo flags for input timing. | ||
79 | */ | ||
80 | uint8_t sdvo_flags; | ||
81 | |||
82 | /** | ||
83 | * This is sdvo fixed pannel mode pointer | ||
84 | */ | ||
85 | struct drm_display_mode *sdvo_lvds_fixed_mode; | ||
86 | |||
87 | /** | ||
78 | * Returned SDTV resolutions allowed for the current format, if the | 88 | * Returned SDTV resolutions allowed for the current format, if the |
79 | * device reported it. | 89 | * device reported it. |
80 | */ | 90 | */ |
@@ -146,13 +156,13 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
146 | 156 | ||
147 | struct i2c_msg msgs[] = { | 157 | struct i2c_msg msgs[] = { |
148 | { | 158 | { |
149 | .addr = sdvo_priv->i2c_bus->slave_addr, | 159 | .addr = sdvo_priv->slave_addr >> 1, |
150 | .flags = 0, | 160 | .flags = 0, |
151 | .len = 1, | 161 | .len = 1, |
152 | .buf = out_buf, | 162 | .buf = out_buf, |
153 | }, | 163 | }, |
154 | { | 164 | { |
155 | .addr = sdvo_priv->i2c_bus->slave_addr, | 165 | .addr = sdvo_priv->slave_addr >> 1, |
156 | .flags = I2C_M_RD, | 166 | .flags = I2C_M_RD, |
157 | .len = 1, | 167 | .len = 1, |
158 | .buf = buf, | 168 | .buf = buf, |
@@ -162,7 +172,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
162 | out_buf[0] = addr; | 172 | out_buf[0] = addr; |
163 | out_buf[1] = 0; | 173 | out_buf[1] = 0; |
164 | 174 | ||
165 | if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2) | 175 | if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) |
166 | { | 176 | { |
167 | *ch = buf[0]; | 177 | *ch = buf[0]; |
168 | return true; | 178 | return true; |
@@ -175,10 +185,11 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
175 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | 185 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, |
176 | u8 ch) | 186 | u8 ch) |
177 | { | 187 | { |
188 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
178 | u8 out_buf[2]; | 189 | u8 out_buf[2]; |
179 | struct i2c_msg msgs[] = { | 190 | struct i2c_msg msgs[] = { |
180 | { | 191 | { |
181 | .addr = intel_output->i2c_bus->slave_addr, | 192 | .addr = sdvo_priv->slave_addr >> 1, |
182 | .flags = 0, | 193 | .flags = 0, |
183 | .len = 2, | 194 | .len = 2, |
184 | .buf = out_buf, | 195 | .buf = out_buf, |
@@ -188,7 +199,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | |||
188 | out_buf[0] = addr; | 199 | out_buf[0] = addr; |
189 | out_buf[1] = ch; | 200 | out_buf[1] = ch; |
190 | 201 | ||
191 | if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1) | 202 | if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) |
192 | { | 203 | { |
193 | return true; | 204 | return true; |
194 | } | 205 | } |
@@ -592,6 +603,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
592 | uint16_t height) | 603 | uint16_t height) |
593 | { | 604 | { |
594 | struct intel_sdvo_preferred_input_timing_args args; | 605 | struct intel_sdvo_preferred_input_timing_args args; |
606 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | ||
595 | uint8_t status; | 607 | uint8_t status; |
596 | 608 | ||
597 | memset(&args, 0, sizeof(args)); | 609 | memset(&args, 0, sizeof(args)); |
@@ -599,7 +611,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
599 | args.width = width; | 611 | args.width = width; |
600 | args.height = height; | 612 | args.height = height; |
601 | args.interlace = 0; | 613 | args.interlace = 0; |
602 | args.scaled = 0; | 614 | |
615 | if (sdvo_priv->is_lvds && | ||
616 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | ||
617 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | ||
618 | args.scaled = 1; | ||
619 | |||
603 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 620 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
604 | &args, sizeof(args)); | 621 | &args, sizeof(args)); |
605 | status = intel_sdvo_read_response(output, NULL, 0); | 622 | status = intel_sdvo_read_response(output, NULL, 0); |
@@ -944,12 +961,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
944 | struct intel_output *output = enc_to_intel_output(encoder); | 961 | struct intel_output *output = enc_to_intel_output(encoder); |
945 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | 962 | struct intel_sdvo_priv *dev_priv = output->dev_priv; |
946 | 963 | ||
947 | if (!dev_priv->is_tv) { | 964 | if (dev_priv->is_tv) { |
948 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
949 | * SDVO device will be told of the multiplier during mode_set. | ||
950 | */ | ||
951 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
952 | } else { | ||
953 | struct intel_sdvo_dtd output_dtd; | 965 | struct intel_sdvo_dtd output_dtd; |
954 | bool success; | 966 | bool success; |
955 | 967 | ||
@@ -980,6 +992,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
980 | intel_sdvo_get_preferred_input_timing(output, | 992 | intel_sdvo_get_preferred_input_timing(output, |
981 | &input_dtd); | 993 | &input_dtd); |
982 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 994 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
995 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
983 | 996 | ||
984 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 997 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
985 | 998 | ||
@@ -990,6 +1003,52 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
990 | } else { | 1003 | } else { |
991 | return false; | 1004 | return false; |
992 | } | 1005 | } |
1006 | } else if (dev_priv->is_lvds) { | ||
1007 | struct intel_sdvo_dtd output_dtd; | ||
1008 | bool success; | ||
1009 | |||
1010 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1011 | /* Set output timings */ | ||
1012 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1013 | dev_priv->sdvo_lvds_fixed_mode); | ||
1014 | |||
1015 | intel_sdvo_set_target_output(output, | ||
1016 | dev_priv->controlled_output); | ||
1017 | intel_sdvo_set_output_timing(output, &output_dtd); | ||
1018 | |||
1019 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1020 | intel_sdvo_set_target_input(output, true, false); | ||
1021 | |||
1022 | |||
1023 | success = intel_sdvo_create_preferred_input_timing( | ||
1024 | output, | ||
1025 | mode->clock / 10, | ||
1026 | mode->hdisplay, | ||
1027 | mode->vdisplay); | ||
1028 | |||
1029 | if (success) { | ||
1030 | struct intel_sdvo_dtd input_dtd; | ||
1031 | |||
1032 | intel_sdvo_get_preferred_input_timing(output, | ||
1033 | &input_dtd); | ||
1034 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1035 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1036 | |||
1037 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
1038 | |||
1039 | mode->clock = adjusted_mode->clock; | ||
1040 | |||
1041 | adjusted_mode->clock *= | ||
1042 | intel_sdvo_get_pixel_multiplier(mode); | ||
1043 | } else { | ||
1044 | return false; | ||
1045 | } | ||
1046 | |||
1047 | } else { | ||
1048 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1049 | * SDVO device will be told of the multiplier during mode_set. | ||
1050 | */ | ||
1051 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
993 | } | 1052 | } |
994 | return true; | 1053 | return true; |
995 | } | 1054 | } |
@@ -1033,15 +1092,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1033 | 1092 | ||
1034 | /* We have tried to get input timing in mode_fixup, and filled into | 1093 | /* We have tried to get input timing in mode_fixup, and filled into |
1035 | adjusted_mode */ | 1094 | adjusted_mode */ |
1036 | if (sdvo_priv->is_tv) | 1095 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { |
1037 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1096 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1038 | else | 1097 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; |
1098 | } else | ||
1039 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1099 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
1040 | 1100 | ||
1041 | /* If it's a TV, we already set the output timing in mode_fixup. | 1101 | /* If it's a TV, we already set the output timing in mode_fixup. |
1042 | * Otherwise, the output timing is equal to the input timing. | 1102 | * Otherwise, the output timing is equal to the input timing. |
1043 | */ | 1103 | */ |
1044 | if (!sdvo_priv->is_tv) { | 1104 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1045 | /* Set the output timing to the screen */ | 1105 | /* Set the output timing to the screen */ |
1046 | intel_sdvo_set_target_output(output, | 1106 | intel_sdvo_set_target_output(output, |
1047 | sdvo_priv->controlled_output); | 1107 | sdvo_priv->controlled_output); |
@@ -1116,6 +1176,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1116 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1176 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1117 | } | 1177 | } |
1118 | 1178 | ||
1179 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | ||
1180 | sdvox |= SDVO_STALL_SELECT; | ||
1119 | intel_sdvo_write_sdvox(output, sdvox); | 1181 | intel_sdvo_write_sdvox(output, sdvox); |
1120 | } | 1182 | } |
1121 | 1183 | ||
@@ -1276,6 +1338,17 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1276 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1338 | if (sdvo_priv->pixel_clock_max < mode->clock) |
1277 | return MODE_CLOCK_HIGH; | 1339 | return MODE_CLOCK_HIGH; |
1278 | 1340 | ||
1341 | if (sdvo_priv->is_lvds == true) { | ||
1342 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | ||
1343 | return MODE_PANEL; | ||
1344 | |||
1345 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | ||
1346 | return MODE_PANEL; | ||
1347 | |||
1348 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1349 | return MODE_PANEL; | ||
1350 | } | ||
1351 | |||
1279 | return MODE_OK; | 1352 | return MODE_OK; |
1280 | } | 1353 | } |
1281 | 1354 | ||
@@ -1369,9 +1442,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1442 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1370 | struct edid *edid = NULL; | 1443 | struct edid *edid = NULL; |
1371 | 1444 | ||
1372 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1373 | edid = drm_get_edid(&intel_output->base, | 1445 | edid = drm_get_edid(&intel_output->base, |
1374 | &intel_output->ddc_bus->adapter); | 1446 | intel_output->ddc_bus); |
1375 | if (edid != NULL) { | 1447 | if (edid != NULL) { |
1376 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1448 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); |
1377 | kfree(edid); | 1449 | kfree(edid); |
@@ -1549,23 +1621,21 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1549 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1621 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1550 | { | 1622 | { |
1551 | struct intel_output *intel_output = to_intel_output(connector); | 1623 | struct intel_output *intel_output = to_intel_output(connector); |
1552 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1553 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1624 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1625 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1626 | struct drm_display_mode *newmode; | ||
1554 | 1627 | ||
1555 | /* | 1628 | /* |
1556 | * Attempt to get the mode list from DDC. | 1629 | * Attempt to get the mode list from DDC. |
1557 | * Assume that the preferred modes are | 1630 | * Assume that the preferred modes are |
1558 | * arranged in priority order. | 1631 | * arranged in priority order. |
1559 | */ | 1632 | */ |
1560 | /* set the bus switch and get the modes */ | ||
1561 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1562 | intel_ddc_get_modes(intel_output); | 1633 | intel_ddc_get_modes(intel_output); |
1563 | if (list_empty(&connector->probed_modes) == false) | 1634 | if (list_empty(&connector->probed_modes) == false) |
1564 | return; | 1635 | goto end; |
1565 | 1636 | ||
1566 | /* Fetch modes from VBT */ | 1637 | /* Fetch modes from VBT */ |
1567 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { | 1638 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
1568 | struct drm_display_mode *newmode; | ||
1569 | newmode = drm_mode_duplicate(connector->dev, | 1639 | newmode = drm_mode_duplicate(connector->dev, |
1570 | dev_priv->sdvo_lvds_vbt_mode); | 1640 | dev_priv->sdvo_lvds_vbt_mode); |
1571 | if (newmode != NULL) { | 1641 | if (newmode != NULL) { |
@@ -1575,6 +1645,16 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1575 | drm_mode_probed_add(connector, newmode); | 1645 | drm_mode_probed_add(connector, newmode); |
1576 | } | 1646 | } |
1577 | } | 1647 | } |
1648 | |||
1649 | end: | ||
1650 | list_for_each_entry(newmode, &connector->probed_modes, head) { | ||
1651 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1652 | sdvo_priv->sdvo_lvds_fixed_mode = | ||
1653 | drm_mode_duplicate(connector->dev, newmode); | ||
1654 | break; | ||
1655 | } | ||
1656 | } | ||
1657 | |||
1578 | } | 1658 | } |
1579 | 1659 | ||
1580 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1660 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
@@ -1597,14 +1677,20 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1597 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1677 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1598 | { | 1678 | { |
1599 | struct intel_output *intel_output = to_intel_output(connector); | 1679 | struct intel_output *intel_output = to_intel_output(connector); |
1680 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1600 | 1681 | ||
1601 | if (intel_output->i2c_bus) | 1682 | if (intel_output->i2c_bus) |
1602 | intel_i2c_destroy(intel_output->i2c_bus); | 1683 | intel_i2c_destroy(intel_output->i2c_bus); |
1603 | if (intel_output->ddc_bus) | 1684 | if (intel_output->ddc_bus) |
1604 | intel_i2c_destroy(intel_output->ddc_bus); | 1685 | intel_i2c_destroy(intel_output->ddc_bus); |
1605 | 1686 | ||
1687 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1688 | drm_mode_destroy(connector->dev, | ||
1689 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1690 | |||
1606 | drm_sysfs_connector_remove(connector); | 1691 | drm_sysfs_connector_remove(connector); |
1607 | drm_connector_cleanup(connector); | 1692 | drm_connector_cleanup(connector); |
1693 | |||
1608 | kfree(intel_output); | 1694 | kfree(intel_output); |
1609 | } | 1695 | } |
1610 | 1696 | ||
@@ -1709,7 +1795,7 @@ intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) | |||
1709 | 1795 | ||
1710 | list_for_each_entry(connector, | 1796 | list_for_each_entry(connector, |
1711 | &dev->mode_config.connector_list, head) { | 1797 | &dev->mode_config.connector_list, head) { |
1712 | if (to_intel_output(connector)->ddc_bus == chan) { | 1798 | if (to_intel_output(connector)->ddc_bus == &chan->adapter) { |
1713 | intel_output = to_intel_output(connector); | 1799 | intel_output = to_intel_output(connector); |
1714 | break; | 1800 | break; |
1715 | } | 1801 | } |
@@ -1723,7 +1809,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1723 | struct intel_output *intel_output; | 1809 | struct intel_output *intel_output; |
1724 | struct intel_sdvo_priv *sdvo_priv; | 1810 | struct intel_sdvo_priv *sdvo_priv; |
1725 | struct i2c_algo_bit_data *algo_data; | 1811 | struct i2c_algo_bit_data *algo_data; |
1726 | struct i2c_algorithm *algo; | 1812 | const struct i2c_algorithm *algo; |
1727 | 1813 | ||
1728 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 1814 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
1729 | intel_output = | 1815 | intel_output = |
@@ -1733,7 +1819,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1733 | return -EINVAL; | 1819 | return -EINVAL; |
1734 | 1820 | ||
1735 | sdvo_priv = intel_output->dev_priv; | 1821 | sdvo_priv = intel_output->dev_priv; |
1736 | algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; | 1822 | algo = intel_output->i2c_bus->algo; |
1737 | 1823 | ||
1738 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | 1824 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); |
1739 | return algo->master_xfer(i2c_adap, msgs, num); | 1825 | return algo->master_xfer(i2c_adap, msgs, num); |
@@ -1785,13 +1871,11 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1785 | struct drm_connector *connector; | 1871 | struct drm_connector *connector; |
1786 | struct intel_output *intel_output; | 1872 | struct intel_output *intel_output; |
1787 | struct intel_sdvo_priv *sdvo_priv; | 1873 | struct intel_sdvo_priv *sdvo_priv; |
1788 | struct intel_i2c_chan *i2cbus = NULL; | 1874 | |
1789 | struct intel_i2c_chan *ddcbus = NULL; | ||
1790 | int connector_type; | 1875 | int connector_type; |
1791 | u8 ch[0x40]; | 1876 | u8 ch[0x40]; |
1792 | int i; | 1877 | int i; |
1793 | int encoder_type, output_id; | 1878 | int encoder_type; |
1794 | u8 slave_addr; | ||
1795 | 1879 | ||
1796 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 1880 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
1797 | if (!intel_output) { | 1881 | if (!intel_output) { |
@@ -1799,29 +1883,24 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1799 | } | 1883 | } |
1800 | 1884 | ||
1801 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); | 1885 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); |
1886 | sdvo_priv->output_device = output_device; | ||
1887 | |||
1888 | intel_output->dev_priv = sdvo_priv; | ||
1802 | intel_output->type = INTEL_OUTPUT_SDVO; | 1889 | intel_output->type = INTEL_OUTPUT_SDVO; |
1803 | 1890 | ||
1804 | /* setup the DDC bus. */ | 1891 | /* setup the DDC bus. */ |
1805 | if (output_device == SDVOB) | 1892 | if (output_device == SDVOB) |
1806 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 1893 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); |
1807 | else | 1894 | else |
1808 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 1895 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); |
1809 | 1896 | ||
1810 | if (!i2cbus) | 1897 | if (!intel_output->i2c_bus) |
1811 | goto err_inteloutput; | 1898 | goto err_inteloutput; |
1812 | 1899 | ||
1813 | slave_addr = intel_sdvo_get_slave_addr(dev, output_device); | 1900 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); |
1814 | sdvo_priv->i2c_bus = i2cbus; | ||
1815 | 1901 | ||
1816 | if (output_device == SDVOB) { | 1902 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
1817 | output_id = 1; | 1903 | intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; |
1818 | } else { | ||
1819 | output_id = 2; | ||
1820 | } | ||
1821 | sdvo_priv->i2c_bus->slave_addr = slave_addr >> 1; | ||
1822 | sdvo_priv->output_device = output_device; | ||
1823 | intel_output->i2c_bus = i2cbus; | ||
1824 | intel_output->dev_priv = sdvo_priv; | ||
1825 | 1904 | ||
1826 | /* Read the regs to test if we can talk to the device */ | 1905 | /* Read the regs to test if we can talk to the device */ |
1827 | for (i = 0; i < 0x40; i++) { | 1906 | for (i = 0; i < 0x40; i++) { |
@@ -1835,17 +1914,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1835 | 1914 | ||
1836 | /* setup the DDC bus. */ | 1915 | /* setup the DDC bus. */ |
1837 | if (output_device == SDVOB) | 1916 | if (output_device == SDVOB) |
1838 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 1917 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
1839 | else | 1918 | else |
1840 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 1919 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
1841 | 1920 | ||
1842 | if (ddcbus == NULL) | 1921 | if (intel_output->ddc_bus == NULL) |
1843 | goto err_i2c; | 1922 | goto err_i2c; |
1844 | 1923 | ||
1845 | intel_sdvo_i2c_bit_algo.functionality = | 1924 | /* Wrap with our custom algo which switches to DDC mode */ |
1846 | intel_output->i2c_bus->adapter.algo->functionality; | 1925 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
1847 | ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; | ||
1848 | intel_output->ddc_bus = ddcbus; | ||
1849 | 1926 | ||
1850 | /* In defaut case sdvo lvds is false */ | 1927 | /* In defaut case sdvo lvds is false */ |
1851 | sdvo_priv->is_lvds = false; | 1928 | sdvo_priv->is_lvds = false; |
@@ -1965,9 +2042,10 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1965 | return true; | 2042 | return true; |
1966 | 2043 | ||
1967 | err_i2c: | 2044 | err_i2c: |
1968 | if (ddcbus != NULL) | 2045 | if (intel_output->ddc_bus != NULL) |
1969 | intel_i2c_destroy(intel_output->ddc_bus); | 2046 | intel_i2c_destroy(intel_output->ddc_bus); |
1970 | intel_i2c_destroy(intel_output->i2c_bus); | 2047 | if (intel_output->i2c_bus != NULL) |
2048 | intel_i2c_destroy(intel_output->i2c_bus); | ||
1971 | err_inteloutput: | 2049 | err_inteloutput: |
1972 | kfree(intel_output); | 2050 | kfree(intel_output); |
1973 | 2051 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 193938b7d7f9..ba5cdf8ae40b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
@@ -715,6 +715,7 @@ struct intel_sdvo_enhancements_arg { | |||
715 | #define SDVO_HBUF_TX_ONCE (2 << 6) | 715 | #define SDVO_HBUF_TX_ONCE (2 << 6) |
716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) | 716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) |
717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c | 717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c |
718 | #define SDVO_NEED_TO_STALL (1 << 7) | ||
718 | 719 | ||
719 | struct intel_sdvo_encode{ | 720 | struct intel_sdvo_encode{ |
720 | u8 dvi_rev; | 721 | u8 dvi_rev; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index ea68992e4416..a43c98e3f077 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1383,34 +1383,31 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) | |||
1383 | /* | 1383 | /* |
1384 | * Detect TV by polling) | 1384 | * Detect TV by polling) |
1385 | */ | 1385 | */ |
1386 | if (intel_output->load_detect_temp) { | 1386 | save_tv_dac = tv_dac; |
1387 | /* TV not currently running, prod it with destructive detect */ | 1387 | tv_ctl = I915_READ(TV_CTL); |
1388 | save_tv_dac = tv_dac; | 1388 | save_tv_ctl = tv_ctl; |
1389 | tv_ctl = I915_READ(TV_CTL); | 1389 | tv_ctl &= ~TV_ENC_ENABLE; |
1390 | save_tv_ctl = tv_ctl; | 1390 | tv_ctl &= ~TV_TEST_MODE_MASK; |
1391 | tv_ctl &= ~TV_ENC_ENABLE; | 1391 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; |
1392 | tv_ctl &= ~TV_TEST_MODE_MASK; | 1392 | tv_dac &= ~TVDAC_SENSE_MASK; |
1393 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; | 1393 | tv_dac &= ~DAC_A_MASK; |
1394 | tv_dac &= ~TVDAC_SENSE_MASK; | 1394 | tv_dac &= ~DAC_B_MASK; |
1395 | tv_dac &= ~DAC_A_MASK; | 1395 | tv_dac &= ~DAC_C_MASK; |
1396 | tv_dac &= ~DAC_B_MASK; | 1396 | tv_dac |= (TVDAC_STATE_CHG_EN | |
1397 | tv_dac &= ~DAC_C_MASK; | 1397 | TVDAC_A_SENSE_CTL | |
1398 | tv_dac |= (TVDAC_STATE_CHG_EN | | 1398 | TVDAC_B_SENSE_CTL | |
1399 | TVDAC_A_SENSE_CTL | | 1399 | TVDAC_C_SENSE_CTL | |
1400 | TVDAC_B_SENSE_CTL | | 1400 | DAC_CTL_OVERRIDE | |
1401 | TVDAC_C_SENSE_CTL | | 1401 | DAC_A_0_7_V | |
1402 | DAC_CTL_OVERRIDE | | 1402 | DAC_B_0_7_V | |
1403 | DAC_A_0_7_V | | 1403 | DAC_C_0_7_V); |
1404 | DAC_B_0_7_V | | 1404 | I915_WRITE(TV_CTL, tv_ctl); |
1405 | DAC_C_0_7_V); | 1405 | I915_WRITE(TV_DAC, tv_dac); |
1406 | I915_WRITE(TV_CTL, tv_ctl); | 1406 | intel_wait_for_vblank(dev); |
1407 | I915_WRITE(TV_DAC, tv_dac); | 1407 | tv_dac = I915_READ(TV_DAC); |
1408 | intel_wait_for_vblank(dev); | 1408 | I915_WRITE(TV_DAC, save_tv_dac); |
1409 | tv_dac = I915_READ(TV_DAC); | 1409 | I915_WRITE(TV_CTL, save_tv_ctl); |
1410 | I915_WRITE(TV_DAC, save_tv_dac); | 1410 | intel_wait_for_vblank(dev); |
1411 | I915_WRITE(TV_CTL, save_tv_ctl); | ||
1412 | intel_wait_for_vblank(dev); | ||
1413 | } | ||
1414 | /* | 1411 | /* |
1415 | * A B C | 1412 | * A B C |
1416 | * 0 1 1 Composite | 1413 | * 0 1 1 Composite |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index f30aa7274a54..f97563db4e59 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -35,6 +35,23 @@ | |||
35 | #include "atom.h" | 35 | #include "atom.h" |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Clear GPU surface registers. | ||
39 | */ | ||
40 | static void radeon_surface_init(struct radeon_device *rdev) | ||
41 | { | ||
42 | /* FIXME: check this out */ | ||
43 | if (rdev->family < CHIP_R600) { | ||
44 | int i; | ||
45 | |||
46 | for (i = 0; i < 8; i++) { | ||
47 | WREG32(RADEON_SURFACE0_INFO + | ||
48 | i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO), | ||
49 | 0); | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /* | ||
38 | * GPU scratch registers helpers function. | 55 | * GPU scratch registers helpers function. |
39 | */ | 56 | */ |
40 | static void radeon_scratch_init(struct radeon_device *rdev) | 57 | static void radeon_scratch_init(struct radeon_device *rdev) |
@@ -496,6 +513,8 @@ int radeon_device_init(struct radeon_device *rdev, | |||
496 | radeon_errata(rdev); | 513 | radeon_errata(rdev); |
497 | /* Initialize scratch registers */ | 514 | /* Initialize scratch registers */ |
498 | radeon_scratch_init(rdev); | 515 | radeon_scratch_init(rdev); |
516 | /* Initialize surface registers */ | ||
517 | radeon_surface_init(rdev); | ||
499 | 518 | ||
500 | /* TODO: disable VGA need to use VGA request */ | 519 | /* TODO: disable VGA need to use VGA request */ |
501 | /* BIOS*/ | 520 | /* BIOS*/ |
@@ -604,9 +623,6 @@ int radeon_device_init(struct radeon_device *rdev, | |||
604 | if (r) { | 623 | if (r) { |
605 | return r; | 624 | return r; |
606 | } | 625 | } |
607 | if (rdev->fbdev_rfb && rdev->fbdev_rfb->obj) { | ||
608 | rdev->fbdev_robj = rdev->fbdev_rfb->obj->driver_private; | ||
609 | } | ||
610 | if (!ret) { | 626 | if (!ret) { |
611 | DRM_INFO("radeon: kernel modesetting successfully initialized.\n"); | 627 | DRM_INFO("radeon: kernel modesetting successfully initialized.\n"); |
612 | } | 628 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 09c9fb9f6210..84ba69f48784 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -345,7 +345,7 @@ static void __exit radeon_exit(void) | |||
345 | drm_exit(driver); | 345 | drm_exit(driver); |
346 | } | 346 | } |
347 | 347 | ||
348 | late_initcall(radeon_init); | 348 | module_init(radeon_init); |
349 | module_exit(radeon_exit); | 349 | module_exit(radeon_exit); |
350 | 350 | ||
351 | MODULE_AUTHOR(DRIVER_AUTHOR); | 351 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index fa86d398945e..9e8f191eb64a 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -478,14 +478,16 @@ int radeonfb_create(struct radeon_device *rdev, | |||
478 | { | 478 | { |
479 | struct fb_info *info; | 479 | struct fb_info *info; |
480 | struct radeon_fb_device *rfbdev; | 480 | struct radeon_fb_device *rfbdev; |
481 | struct drm_framebuffer *fb; | 481 | struct drm_framebuffer *fb = NULL; |
482 | struct radeon_framebuffer *rfb; | 482 | struct radeon_framebuffer *rfb; |
483 | struct drm_mode_fb_cmd mode_cmd; | 483 | struct drm_mode_fb_cmd mode_cmd; |
484 | struct drm_gem_object *gobj = NULL; | 484 | struct drm_gem_object *gobj = NULL; |
485 | struct radeon_object *robj = NULL; | 485 | struct radeon_object *robj = NULL; |
486 | struct device *device = &rdev->pdev->dev; | 486 | struct device *device = &rdev->pdev->dev; |
487 | int size, aligned_size, ret; | 487 | int size, aligned_size, ret; |
488 | u64 fb_gpuaddr; | ||
488 | void *fbptr = NULL; | 489 | void *fbptr = NULL; |
490 | unsigned long tmp; | ||
489 | 491 | ||
490 | mode_cmd.width = surface_width; | 492 | mode_cmd.width = surface_width; |
491 | mode_cmd.height = surface_height; | 493 | mode_cmd.height = surface_height; |
@@ -498,11 +500,12 @@ int radeonfb_create(struct radeon_device *rdev, | |||
498 | aligned_size = ALIGN(size, PAGE_SIZE); | 500 | aligned_size = ALIGN(size, PAGE_SIZE); |
499 | 501 | ||
500 | ret = radeon_gem_object_create(rdev, aligned_size, 0, | 502 | ret = radeon_gem_object_create(rdev, aligned_size, 0, |
501 | RADEON_GEM_DOMAIN_VRAM, | 503 | RADEON_GEM_DOMAIN_VRAM, |
502 | false, ttm_bo_type_kernel, | 504 | false, ttm_bo_type_kernel, |
503 | false, &gobj); | 505 | false, &gobj); |
504 | if (ret) { | 506 | if (ret) { |
505 | printk(KERN_ERR "failed to allocate framebuffer\n"); | 507 | printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", |
508 | surface_width, surface_height); | ||
506 | ret = -ENOMEM; | 509 | ret = -ENOMEM; |
507 | goto out; | 510 | goto out; |
508 | } | 511 | } |
@@ -515,12 +518,19 @@ int radeonfb_create(struct radeon_device *rdev, | |||
515 | ret = -ENOMEM; | 518 | ret = -ENOMEM; |
516 | goto out_unref; | 519 | goto out_unref; |
517 | } | 520 | } |
521 | ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); | ||
522 | if (ret) { | ||
523 | printk(KERN_ERR "failed to pin framebuffer\n"); | ||
524 | ret = -ENOMEM; | ||
525 | goto out_unref; | ||
526 | } | ||
518 | 527 | ||
519 | list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); | 528 | list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); |
520 | 529 | ||
521 | rfb = to_radeon_framebuffer(fb); | 530 | rfb = to_radeon_framebuffer(fb); |
522 | *rfb_p = rfb; | 531 | *rfb_p = rfb; |
523 | rdev->fbdev_rfb = rfb; | 532 | rdev->fbdev_rfb = rfb; |
533 | rdev->fbdev_robj = robj; | ||
524 | 534 | ||
525 | info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); | 535 | info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); |
526 | if (info == NULL) { | 536 | if (info == NULL) { |
@@ -541,13 +551,13 @@ int radeonfb_create(struct radeon_device *rdev, | |||
541 | info->fix.xpanstep = 1; /* doing it in hw */ | 551 | info->fix.xpanstep = 1; /* doing it in hw */ |
542 | info->fix.ypanstep = 1; /* doing it in hw */ | 552 | info->fix.ypanstep = 1; /* doing it in hw */ |
543 | info->fix.ywrapstep = 0; | 553 | info->fix.ywrapstep = 0; |
544 | info->fix.accel = FB_ACCEL_I830; | 554 | info->fix.accel = FB_ACCEL_NONE; |
545 | info->fix.type_aux = 0; | 555 | info->fix.type_aux = 0; |
546 | info->flags = FBINFO_DEFAULT; | 556 | info->flags = FBINFO_DEFAULT; |
547 | info->fbops = &radeonfb_ops; | 557 | info->fbops = &radeonfb_ops; |
548 | info->fix.line_length = fb->pitch; | 558 | info->fix.line_length = fb->pitch; |
549 | info->screen_base = fbptr; | 559 | tmp = fb_gpuaddr - rdev->mc.vram_location; |
550 | info->fix.smem_start = (unsigned long)fbptr; | 560 | info->fix.smem_start = rdev->mc.aper_base + tmp; |
551 | info->fix.smem_len = size; | 561 | info->fix.smem_len = size; |
552 | info->screen_base = fbptr; | 562 | info->screen_base = fbptr; |
553 | info->screen_size = size; | 563 | info->screen_size = size; |
@@ -562,8 +572,8 @@ int radeonfb_create(struct radeon_device *rdev, | |||
562 | info->var.width = -1; | 572 | info->var.width = -1; |
563 | info->var.xres = fb_width; | 573 | info->var.xres = fb_width; |
564 | info->var.yres = fb_height; | 574 | info->var.yres = fb_height; |
565 | info->fix.mmio_start = pci_resource_start(rdev->pdev, 2); | 575 | info->fix.mmio_start = 0; |
566 | info->fix.mmio_len = pci_resource_len(rdev->pdev, 2); | 576 | info->fix.mmio_len = 0; |
567 | info->pixmap.size = 64*1024; | 577 | info->pixmap.size = 64*1024; |
568 | info->pixmap.buf_align = 8; | 578 | info->pixmap.buf_align = 8; |
569 | info->pixmap.access_align = 32; | 579 | info->pixmap.access_align = 32; |
@@ -644,7 +654,7 @@ out_unref: | |||
644 | if (robj) { | 654 | if (robj) { |
645 | radeon_object_kunmap(robj); | 655 | radeon_object_kunmap(robj); |
646 | } | 656 | } |
647 | if (ret) { | 657 | if (fb && ret) { |
648 | list_del(&fb->filp_head); | 658 | list_del(&fb->filp_head); |
649 | drm_gem_object_unreference(gobj); | 659 | drm_gem_object_unreference(gobj); |
650 | drm_framebuffer_cleanup(fb); | 660 | drm_framebuffer_cleanup(fb); |
@@ -813,6 +823,7 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) | |||
813 | robj = rfb->obj->driver_private; | 823 | robj = rfb->obj->driver_private; |
814 | unregister_framebuffer(info); | 824 | unregister_framebuffer(info); |
815 | radeon_object_kunmap(robj); | 825 | radeon_object_kunmap(robj); |
826 | radeon_object_unpin(robj); | ||
816 | framebuffer_release(info); | 827 | framebuffer_release(info); |
817 | } | 828 | } |
818 | 829 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 983e8df5e000..bac0d06c52ac 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -223,7 +223,6 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
223 | { | 223 | { |
224 | uint32_t flags; | 224 | uint32_t flags; |
225 | uint32_t tmp; | 225 | uint32_t tmp; |
226 | void *fbptr; | ||
227 | int r; | 226 | int r; |
228 | 227 | ||
229 | flags = radeon_object_flags_from_domain(domain); | 228 | flags = radeon_object_flags_from_domain(domain); |
@@ -242,10 +241,6 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
242 | DRM_ERROR("radeon: failed to reserve object for pinning it.\n"); | 241 | DRM_ERROR("radeon: failed to reserve object for pinning it.\n"); |
243 | return r; | 242 | return r; |
244 | } | 243 | } |
245 | if (robj->rdev->fbdev_robj == robj) { | ||
246 | mutex_lock(&robj->rdev->fbdev_info->lock); | ||
247 | radeon_object_kunmap(robj); | ||
248 | } | ||
249 | tmp = robj->tobj.mem.placement; | 244 | tmp = robj->tobj.mem.placement; |
250 | ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM); | 245 | ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM); |
251 | robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING; | 246 | robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING; |
@@ -261,23 +256,12 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
261 | DRM_ERROR("radeon: failed to pin object.\n"); | 256 | DRM_ERROR("radeon: failed to pin object.\n"); |
262 | } | 257 | } |
263 | radeon_object_unreserve(robj); | 258 | radeon_object_unreserve(robj); |
264 | if (robj->rdev->fbdev_robj == robj) { | ||
265 | if (!r) { | ||
266 | r = radeon_object_kmap(robj, &fbptr); | ||
267 | } | ||
268 | if (!r) { | ||
269 | robj->rdev->fbdev_info->screen_base = fbptr; | ||
270 | robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; | ||
271 | } | ||
272 | mutex_unlock(&robj->rdev->fbdev_info->lock); | ||
273 | } | ||
274 | return r; | 259 | return r; |
275 | } | 260 | } |
276 | 261 | ||
277 | void radeon_object_unpin(struct radeon_object *robj) | 262 | void radeon_object_unpin(struct radeon_object *robj) |
278 | { | 263 | { |
279 | uint32_t flags; | 264 | uint32_t flags; |
280 | void *fbptr; | ||
281 | int r; | 265 | int r; |
282 | 266 | ||
283 | spin_lock(&robj->tobj.lock); | 267 | spin_lock(&robj->tobj.lock); |
@@ -297,10 +281,6 @@ void radeon_object_unpin(struct radeon_object *robj) | |||
297 | DRM_ERROR("radeon: failed to reserve object for unpinning it.\n"); | 281 | DRM_ERROR("radeon: failed to reserve object for unpinning it.\n"); |
298 | return; | 282 | return; |
299 | } | 283 | } |
300 | if (robj->rdev->fbdev_robj == robj) { | ||
301 | mutex_lock(&robj->rdev->fbdev_info->lock); | ||
302 | radeon_object_kunmap(robj); | ||
303 | } | ||
304 | flags = robj->tobj.mem.placement; | 284 | flags = robj->tobj.mem.placement; |
305 | robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT; | 285 | robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT; |
306 | r = ttm_buffer_object_validate(&robj->tobj, | 286 | r = ttm_buffer_object_validate(&robj->tobj, |
@@ -310,16 +290,6 @@ void radeon_object_unpin(struct radeon_object *robj) | |||
310 | DRM_ERROR("radeon: failed to unpin buffer.\n"); | 290 | DRM_ERROR("radeon: failed to unpin buffer.\n"); |
311 | } | 291 | } |
312 | radeon_object_unreserve(robj); | 292 | radeon_object_unreserve(robj); |
313 | if (robj->rdev->fbdev_robj == robj) { | ||
314 | if (!r) { | ||
315 | r = radeon_object_kmap(robj, &fbptr); | ||
316 | } | ||
317 | if (!r) { | ||
318 | robj->rdev->fbdev_info->screen_base = fbptr; | ||
319 | robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; | ||
320 | } | ||
321 | mutex_unlock(&robj->rdev->fbdev_info->lock); | ||
322 | } | ||
323 | } | 293 | } |
324 | 294 | ||
325 | int radeon_object_wait(struct radeon_object *robj) | 295 | int radeon_object_wait(struct radeon_object *robj) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 517c84559633..bdec583901eb 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/wait.h> | 35 | #include <linux/wait.h> |
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/version.h> | ||
38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
39 | 38 | ||
40 | void ttm_bo_free_old_node(struct ttm_buffer_object *bo) | 39 | void ttm_bo_free_old_node(struct ttm_buffer_object *bo) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 27b146c54fbc..40b75032ea47 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <ttm/ttm_bo_driver.h> | 32 | #include <ttm/ttm_bo_driver.h> |
33 | #include <ttm/ttm_placement.h> | 33 | #include <ttm/ttm_placement.h> |
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/version.h> | ||
36 | #include <linux/rbtree.h> | 35 | #include <linux/rbtree.h> |
37 | #include <linux/module.h> | 36 | #include <linux/module.h> |
38 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 0331fa74cd3f..75dc8bd24592 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -28,7 +28,6 @@ | |||
28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/version.h> | ||
32 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
33 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
34 | #include <linux/highmem.h> | 33 | #include <linux/highmem.h> |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index aa87b6a3bbef..8206442fbabd 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -328,6 +328,7 @@ config I2C_DAVINCI | |||
328 | 328 | ||
329 | config I2C_DESIGNWARE | 329 | config I2C_DESIGNWARE |
330 | tristate "Synopsys DesignWare" | 330 | tristate "Synopsys DesignWare" |
331 | depends on HAVE_CLK | ||
331 | help | 332 | help |
332 | If you say yes to this option, support will be included for the | 333 | If you say yes to this option, support will be included for the |
333 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 334 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index e4476743f203..b1bc6e277d2a 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -85,10 +85,11 @@ static void dump_iic_regs(const char* header, struct ibm_iic_private* dev) | |||
85 | { | 85 | { |
86 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 86 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
87 | printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header); | 87 | printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header); |
88 | printk(KERN_DEBUG " cntl = 0x%02x, mdcntl = 0x%02x\n" | 88 | printk(KERN_DEBUG |
89 | KERN_DEBUG " sts = 0x%02x, extsts = 0x%02x\n" | 89 | " cntl = 0x%02x, mdcntl = 0x%02x\n" |
90 | KERN_DEBUG " clkdiv = 0x%02x, xfrcnt = 0x%02x\n" | 90 | " sts = 0x%02x, extsts = 0x%02x\n" |
91 | KERN_DEBUG " xtcntlss = 0x%02x, directcntl = 0x%02x\n", | 91 | " clkdiv = 0x%02x, xfrcnt = 0x%02x\n" |
92 | " xtcntlss = 0x%02x, directcntl = 0x%02x\n", | ||
92 | in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), | 93 | in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), |
93 | in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), | 94 | in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), |
94 | in_8(&iic->xtcntlss), in_8(&iic->directcntl)); | 95 | in_8(&iic->xtcntlss), in_8(&iic->directcntl)); |
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c index bd066bb9d611..09f98ed0731f 100644 --- a/drivers/ide/cs5520.c +++ b/drivers/ide/cs5520.c | |||
@@ -135,6 +135,7 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic | |||
135 | 135 | ||
136 | ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); | 136 | ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); |
137 | hw[0].irq = 14; | 137 | hw[0].irq = 14; |
138 | hw[1].irq = 15; | ||
138 | 139 | ||
139 | return ide_host_add(d, hws, 2, NULL); | 140 | return ide_host_add(d, hws, 2, NULL); |
140 | } | 141 | } |
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 77f79d26b264..c509c9916464 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -92,6 +92,11 @@ int ide_acpi_init(void) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | bool ide_port_acpi(ide_hwif_t *hwif) | ||
96 | { | ||
97 | return ide_noacpi == 0 && hwif->acpidata; | ||
98 | } | ||
99 | |||
95 | /** | 100 | /** |
96 | * ide_get_dev_handle - finds acpi_handle and PCI device.function | 101 | * ide_get_dev_handle - finds acpi_handle and PCI device.function |
97 | * @dev: device to locate | 102 | * @dev: device to locate |
@@ -352,9 +357,6 @@ int ide_acpi_exec_tfs(ide_drive_t *drive) | |||
352 | unsigned long gtf_address; | 357 | unsigned long gtf_address; |
353 | unsigned long obj_loc; | 358 | unsigned long obj_loc; |
354 | 359 | ||
355 | if (ide_noacpi) | ||
356 | return 0; | ||
357 | |||
358 | DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn); | 360 | DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn); |
359 | 361 | ||
360 | ret = do_drive_get_GTF(drive, >f_length, >f_address, &obj_loc); | 362 | ret = do_drive_get_GTF(drive, >f_length, >f_address, &obj_loc); |
@@ -389,16 +391,6 @@ void ide_acpi_get_timing(ide_hwif_t *hwif) | |||
389 | struct acpi_buffer output; | 391 | struct acpi_buffer output; |
390 | union acpi_object *out_obj; | 392 | union acpi_object *out_obj; |
391 | 393 | ||
392 | if (ide_noacpi) | ||
393 | return; | ||
394 | |||
395 | DEBPRINT("ENTER:\n"); | ||
396 | |||
397 | if (!hwif->acpidata) { | ||
398 | DEBPRINT("no ACPI data for %s\n", hwif->name); | ||
399 | return; | ||
400 | } | ||
401 | |||
402 | /* Setting up output buffer for _GTM */ | 394 | /* Setting up output buffer for _GTM */ |
403 | output.length = ACPI_ALLOCATE_BUFFER; | 395 | output.length = ACPI_ALLOCATE_BUFFER; |
404 | output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ | 396 | output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ |
@@ -479,16 +471,6 @@ void ide_acpi_push_timing(ide_hwif_t *hwif) | |||
479 | struct ide_acpi_drive_link *master = &hwif->acpidata->master; | 471 | struct ide_acpi_drive_link *master = &hwif->acpidata->master; |
480 | struct ide_acpi_drive_link *slave = &hwif->acpidata->slave; | 472 | struct ide_acpi_drive_link *slave = &hwif->acpidata->slave; |
481 | 473 | ||
482 | if (ide_noacpi) | ||
483 | return; | ||
484 | |||
485 | DEBPRINT("ENTER:\n"); | ||
486 | |||
487 | if (!hwif->acpidata) { | ||
488 | DEBPRINT("no ACPI data for %s\n", hwif->name); | ||
489 | return; | ||
490 | } | ||
491 | |||
492 | /* Give the GTM buffer + drive Identify data to the channel via the | 474 | /* Give the GTM buffer + drive Identify data to the channel via the |
493 | * _STM method: */ | 475 | * _STM method: */ |
494 | /* setup input parameters buffer for _STM */ | 476 | /* setup input parameters buffer for _STM */ |
@@ -527,16 +509,11 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) | |||
527 | ide_drive_t *drive; | 509 | ide_drive_t *drive; |
528 | int i; | 510 | int i; |
529 | 511 | ||
530 | if (ide_noacpi || ide_noacpi_psx) | 512 | if (ide_noacpi_psx) |
531 | return; | 513 | return; |
532 | 514 | ||
533 | DEBPRINT("ENTER:\n"); | 515 | DEBPRINT("ENTER:\n"); |
534 | 516 | ||
535 | if (!hwif->acpidata) { | ||
536 | DEBPRINT("no ACPI data for %s\n", hwif->name); | ||
537 | return; | ||
538 | } | ||
539 | |||
540 | /* channel first and then drives for power on and verse versa for power off */ | 517 | /* channel first and then drives for power on and verse versa for power off */ |
541 | if (on) | 518 | if (on) |
542 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); | 519 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); |
@@ -616,7 +593,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) | |||
616 | drive->name, err); | 593 | drive->name, err); |
617 | } | 594 | } |
618 | 595 | ||
619 | if (!ide_acpionboot) { | 596 | if (ide_noacpi || ide_acpionboot == 0) { |
620 | DEBPRINT("ACPI methods disabled on boot\n"); | 597 | DEBPRINT("ACPI methods disabled on boot\n"); |
621 | return; | 598 | return; |
622 | } | 599 | } |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4a19686fcfe9..6a9a769bffc1 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -592,9 +592,19 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
592 | } | 592 | } |
593 | } else if (!blk_pc_request(rq)) { | 593 | } else if (!blk_pc_request(rq)) { |
594 | ide_cd_request_sense_fixup(drive, cmd); | 594 | ide_cd_request_sense_fixup(drive, cmd); |
595 | /* complain if we still have data left to transfer */ | 595 | |
596 | uptodate = cmd->nleft ? 0 : 1; | 596 | uptodate = cmd->nleft ? 0 : 1; |
597 | if (uptodate == 0) | 597 | |
598 | /* | ||
599 | * suck out the remaining bytes from the drive in an | ||
600 | * attempt to complete the data xfer. (see BZ#13399) | ||
601 | */ | ||
602 | if (!(stat & ATA_ERR) && !uptodate && thislen) { | ||
603 | ide_pio_bytes(drive, cmd, write, thislen); | ||
604 | uptodate = cmd->nleft ? 0 : 1; | ||
605 | } | ||
606 | |||
607 | if (!uptodate) | ||
598 | rq->cmd_flags |= REQ_FAILED; | 608 | rq->cmd_flags |= REQ_FAILED; |
599 | } | 609 | } |
600 | goto out_end; | 610 | goto out_end; |
@@ -876,9 +886,12 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
876 | return stat; | 886 | return stat; |
877 | 887 | ||
878 | /* | 888 | /* |
879 | * Sanity check the given block size | 889 | * Sanity check the given block size, in so far as making |
890 | * sure the sectors_per_frame we give to the caller won't | ||
891 | * end up being bogus. | ||
880 | */ | 892 | */ |
881 | blocklen = be32_to_cpu(capbuf.blocklen); | 893 | blocklen = be32_to_cpu(capbuf.blocklen); |
894 | blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS; | ||
882 | switch (blocklen) { | 895 | switch (blocklen) { |
883 | case 512: | 896 | case 512: |
884 | case 1024: | 897 | case 1024: |
@@ -886,10 +899,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
886 | case 4096: | 899 | case 4096: |
887 | break; | 900 | break; |
888 | default: | 901 | default: |
889 | printk(KERN_ERR PFX "%s: weird block size %u\n", | 902 | printk_once(KERN_ERR PFX "%s: weird block size %u; " |
903 | "setting default block size to 2048\n", | ||
890 | drive->name, blocklen); | 904 | drive->name, blocklen); |
891 | printk(KERN_ERR PFX "%s: default to 2kb block size\n", | ||
892 | drive->name); | ||
893 | blocklen = 2048; | 905 | blocklen = 2048; |
894 | break; | 906 | break; |
895 | } | 907 | } |
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c index 5bf958e5b1d5..1099bf7cf968 100644 --- a/drivers/ide/ide-devsets.c +++ b/drivers/ide/ide-devsets.c | |||
@@ -183,6 +183,6 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq) | |||
183 | err = setfunc(drive, *(int *)&rq->cmd[1]); | 183 | err = setfunc(drive, *(int *)&rq->cmd[1]); |
184 | if (err) | 184 | if (err) |
185 | rq->errors = err; | 185 | rq->errors = err; |
186 | ide_complete_rq(drive, err, ide_rq_bytes(rq)); | 186 | ide_complete_rq(drive, err, blk_rq_bytes(rq)); |
187 | return ide_stopped; | 187 | return ide_stopped; |
188 | } | 188 | } |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 219e6fb78dc6..ee58c88dee5a 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -361,9 +361,6 @@ static int ide_tune_dma(ide_drive_t *drive) | |||
361 | if (__ide_dma_bad_drive(drive)) | 361 | if (__ide_dma_bad_drive(drive)) |
362 | return 0; | 362 | return 0; |
363 | 363 | ||
364 | if (ide_id_dma_bug(drive)) | ||
365 | return 0; | ||
366 | |||
367 | if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) | 364 | if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) |
368 | return config_drive_for_dma(drive); | 365 | return config_drive_for_dma(drive); |
369 | 366 | ||
@@ -394,24 +391,6 @@ static int ide_dma_check(ide_drive_t *drive) | |||
394 | return -1; | 391 | return -1; |
395 | } | 392 | } |
396 | 393 | ||
397 | int ide_id_dma_bug(ide_drive_t *drive) | ||
398 | { | ||
399 | u16 *id = drive->id; | ||
400 | |||
401 | if (id[ATA_ID_FIELD_VALID] & 4) { | ||
402 | if ((id[ATA_ID_UDMA_MODES] >> 8) && | ||
403 | (id[ATA_ID_MWDMA_MODES] >> 8)) | ||
404 | goto err_out; | ||
405 | } else if ((id[ATA_ID_MWDMA_MODES] >> 8) && | ||
406 | (id[ATA_ID_SWDMA_MODES] >> 8)) | ||
407 | goto err_out; | ||
408 | |||
409 | return 0; | ||
410 | err_out: | ||
411 | printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name); | ||
412 | return 1; | ||
413 | } | ||
414 | |||
415 | int ide_set_dma(ide_drive_t *drive) | 394 | int ide_set_dma(ide_drive_t *drive) |
416 | { | 395 | { |
417 | int rc; | 396 | int rc; |
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c index 2b9141979613..e9abf2c3c335 100644 --- a/drivers/ide/ide-eh.c +++ b/drivers/ide/ide-eh.c | |||
@@ -149,7 +149,7 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) | |||
149 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) { | 149 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) { |
150 | if (err <= 0 && rq->errors == 0) | 150 | if (err <= 0 && rq->errors == 0) |
151 | rq->errors = -EIO; | 151 | rq->errors = -EIO; |
152 | ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq)); | 152 | ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq)); |
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 8b3f204f7d73..fefbdfc8db06 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -293,7 +293,7 @@ out_end: | |||
293 | drive->failed_pc = NULL; | 293 | drive->failed_pc = NULL; |
294 | if (blk_fs_request(rq) == 0 && rq->errors == 0) | 294 | if (blk_fs_request(rq) == 0 && rq->errors == 0) |
295 | rq->errors = -EIO; | 295 | rq->errors = -EIO; |
296 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); | 296 | ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); |
297 | return ide_stopped; | 297 | return ide_stopped; |
298 | } | 298 | } |
299 | 299 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1059f809b809..db96138fefcd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -112,16 +112,6 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | /* obsolete, blk_rq_bytes() should be used instead */ | ||
116 | unsigned int ide_rq_bytes(struct request *rq) | ||
117 | { | ||
118 | if (blk_pc_request(rq)) | ||
119 | return blk_rq_bytes(rq); | ||
120 | else | ||
121 | return blk_rq_cur_sectors(rq) << 9; | ||
122 | } | ||
123 | EXPORT_SYMBOL_GPL(ide_rq_bytes); | ||
124 | |||
125 | int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) | 115 | int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) |
126 | { | 116 | { |
127 | ide_hwif_t *hwif = drive->hwif; | 117 | ide_hwif_t *hwif = drive->hwif; |
@@ -152,14 +142,14 @@ void ide_kill_rq(ide_drive_t *drive, struct request *rq) | |||
152 | 142 | ||
153 | if ((media == ide_floppy || media == ide_tape) && drv_req) { | 143 | if ((media == ide_floppy || media == ide_tape) && drv_req) { |
154 | rq->errors = 0; | 144 | rq->errors = 0; |
155 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); | ||
156 | } else { | 145 | } else { |
157 | if (media == ide_tape) | 146 | if (media == ide_tape) |
158 | rq->errors = IDE_DRV_ERROR_GENERAL; | 147 | rq->errors = IDE_DRV_ERROR_GENERAL; |
159 | else if (blk_fs_request(rq) == 0 && rq->errors == 0) | 148 | else if (blk_fs_request(rq) == 0 && rq->errors == 0) |
160 | rq->errors = -EIO; | 149 | rq->errors = -EIO; |
161 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); | ||
162 | } | 150 | } |
151 | |||
152 | ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); | ||
163 | } | 153 | } |
164 | 154 | ||
165 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 155 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index 82f252c3ee6e..e246d3d3fbcc 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c | |||
@@ -64,7 +64,8 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, | |||
64 | goto out; | 64 | goto out; |
65 | } | 65 | } |
66 | 66 | ||
67 | id = kmalloc(size, GFP_KERNEL); | 67 | /* ata_id_to_hd_driveid() relies on 'id' to be fully allocated. */ |
68 | id = kmalloc(ATA_ID_WORDS * 2, GFP_KERNEL); | ||
68 | if (id == NULL) { | 69 | if (id == NULL) { |
69 | rc = -ENOMEM; | 70 | rc = -ENOMEM; |
70 | goto out; | 71 | goto out; |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index fa047150a1c6..2892b242bbe1 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -210,6 +210,7 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list); | |||
210 | */ | 210 | */ |
211 | static const struct drive_list_entry ivb_list[] = { | 211 | static const struct drive_list_entry ivb_list[] = { |
212 | { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, | 212 | { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, |
213 | { "QUANTUM FIREBALLlct20 30" , "APL.0900" }, | ||
213 | { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, | 214 | { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, |
214 | { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, | 215 | { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, |
215 | { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, | 216 | { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, |
@@ -329,9 +330,6 @@ int ide_driveid_update(ide_drive_t *drive) | |||
329 | 330 | ||
330 | kfree(id); | 331 | kfree(id); |
331 | 332 | ||
332 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive)) | ||
333 | ide_dma_off(drive); | ||
334 | |||
335 | return 1; | 333 | return 1; |
336 | out_err: | 334 | out_err: |
337 | if (rc == 2) | 335 | if (rc == 2) |
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index c14ca144cffe..ad7be2669dcb 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c | |||
@@ -10,9 +10,11 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) | |||
10 | struct request_pm_state rqpm; | 10 | struct request_pm_state rqpm; |
11 | int ret; | 11 | int ret; |
12 | 12 | ||
13 | /* call ACPI _GTM only once */ | 13 | if (ide_port_acpi(hwif)) { |
14 | if ((drive->dn & 1) == 0 || pair == NULL) | 14 | /* call ACPI _GTM only once */ |
15 | ide_acpi_get_timing(hwif); | 15 | if ((drive->dn & 1) == 0 || pair == NULL) |
16 | ide_acpi_get_timing(hwif); | ||
17 | } | ||
16 | 18 | ||
17 | memset(&rqpm, 0, sizeof(rqpm)); | 19 | memset(&rqpm, 0, sizeof(rqpm)); |
18 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 20 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
@@ -26,9 +28,11 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) | |||
26 | ret = blk_execute_rq(drive->queue, NULL, rq, 0); | 28 | ret = blk_execute_rq(drive->queue, NULL, rq, 0); |
27 | blk_put_request(rq); | 29 | blk_put_request(rq); |
28 | 30 | ||
29 | /* call ACPI _PS3 only after both devices are suspended */ | 31 | if (ret == 0 && ide_port_acpi(hwif)) { |
30 | if (ret == 0 && ((drive->dn & 1) || pair == NULL)) | 32 | /* call ACPI _PS3 only after both devices are suspended */ |
31 | ide_acpi_set_state(hwif, 0); | 33 | if ((drive->dn & 1) || pair == NULL) |
34 | ide_acpi_set_state(hwif, 0); | ||
35 | } | ||
32 | 36 | ||
33 | return ret; | 37 | return ret; |
34 | } | 38 | } |
@@ -42,13 +46,15 @@ int generic_ide_resume(struct device *dev) | |||
42 | struct request_pm_state rqpm; | 46 | struct request_pm_state rqpm; |
43 | int err; | 47 | int err; |
44 | 48 | ||
45 | /* call ACPI _PS0 / _STM only once */ | 49 | if (ide_port_acpi(hwif)) { |
46 | if ((drive->dn & 1) == 0 || pair == NULL) { | 50 | /* call ACPI _PS0 / _STM only once */ |
47 | ide_acpi_set_state(hwif, 1); | 51 | if ((drive->dn & 1) == 0 || pair == NULL) { |
48 | ide_acpi_push_timing(hwif); | 52 | ide_acpi_set_state(hwif, 1); |
49 | } | 53 | ide_acpi_push_timing(hwif); |
54 | } | ||
50 | 55 | ||
51 | ide_acpi_exec_tfs(drive); | 56 | ide_acpi_exec_tfs(drive); |
57 | } | ||
52 | 58 | ||
53 | memset(&rqpm, 0, sizeof(rqpm)); | 59 | memset(&rqpm, 0, sizeof(rqpm)); |
54 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 60 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 51af4eea0d36..1bb106f6221a 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -818,6 +818,24 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) | |||
818 | return j; | 818 | return j; |
819 | } | 819 | } |
820 | 820 | ||
821 | static void ide_host_enable_irqs(struct ide_host *host) | ||
822 | { | ||
823 | ide_hwif_t *hwif; | ||
824 | int i; | ||
825 | |||
826 | ide_host_for_each_port(i, hwif, host) { | ||
827 | if (hwif == NULL) | ||
828 | continue; | ||
829 | |||
830 | /* clear any pending IRQs */ | ||
831 | hwif->tp_ops->read_status(hwif); | ||
832 | |||
833 | /* unmask IRQs */ | ||
834 | if (hwif->io_ports.ctl_addr) | ||
835 | hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); | ||
836 | } | ||
837 | } | ||
838 | |||
821 | /* | 839 | /* |
822 | * This routine sets up the IRQ for an IDE interface. | 840 | * This routine sets up the IRQ for an IDE interface. |
823 | */ | 841 | */ |
@@ -831,9 +849,6 @@ static int init_irq (ide_hwif_t *hwif) | |||
831 | if (irq_handler == NULL) | 849 | if (irq_handler == NULL) |
832 | irq_handler = ide_intr; | 850 | irq_handler = ide_intr; |
833 | 851 | ||
834 | if (io_ports->ctl_addr) | ||
835 | hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); | ||
836 | |||
837 | if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) | 852 | if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) |
838 | goto out_up; | 853 | goto out_up; |
839 | 854 | ||
@@ -1404,6 +1419,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1404 | ide_port_tune_devices(hwif); | 1419 | ide_port_tune_devices(hwif); |
1405 | } | 1420 | } |
1406 | 1421 | ||
1422 | ide_host_enable_irqs(host); | ||
1423 | |||
1407 | ide_host_for_each_port(i, hwif, host) { | 1424 | ide_host_for_each_port(i, hwif, host) { |
1408 | if (hwif == NULL) | 1425 | if (hwif == NULL) |
1409 | continue; | 1426 | continue; |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 83b734aec923..52b25f8b111d 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -880,6 +880,7 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud) | |||
880 | } | 880 | } |
881 | 881 | ||
882 | shost->hostdata[0] = (unsigned long)lu; | 882 | shost->hostdata[0] = (unsigned long)lu; |
883 | shost->max_cmd_len = SBP2_MAX_CDB_SIZE; | ||
883 | 884 | ||
884 | if (!scsi_add_host(shost, &ud->device)) { | 885 | if (!scsi_add_host(shost, &ud->device)) { |
885 | lu->shost = shost; | 886 | lu->shost = shost; |
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index c5036f1cc5b0..64a3a66a8a39 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
@@ -25,6 +25,12 @@ | |||
25 | #define SBP2_DEVICE_NAME "sbp2" | 25 | #define SBP2_DEVICE_NAME "sbp2" |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * There is no transport protocol limit to the CDB length, but we implement | ||
29 | * a fixed length only. 16 bytes is enough for disks larger than 2 TB. | ||
30 | */ | ||
31 | #define SBP2_MAX_CDB_SIZE 16 | ||
32 | |||
33 | /* | ||
28 | * SBP-2 specific definitions | 34 | * SBP-2 specific definitions |
29 | */ | 35 | */ |
30 | 36 | ||
@@ -51,7 +57,7 @@ struct sbp2_command_orb { | |||
51 | u32 data_descriptor_hi; | 57 | u32 data_descriptor_hi; |
52 | u32 data_descriptor_lo; | 58 | u32 data_descriptor_lo; |
53 | u32 misc; | 59 | u32 misc; |
54 | u8 cdb[12]; | 60 | u8 cdb[SBP2_MAX_CDB_SIZE]; |
55 | } __attribute__((packed)); | 61 | } __attribute__((packed)); |
56 | 62 | ||
57 | #define SBP2_LOGIN_REQUEST 0x0 | 63 | #define SBP2_LOGIN_REQUEST 0x0 |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 9d8f796c6745..a6b989a9dc07 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -12,6 +12,42 @@ menuconfig INPUT_KEYBOARD | |||
12 | 12 | ||
13 | if INPUT_KEYBOARD | 13 | if INPUT_KEYBOARD |
14 | 14 | ||
15 | config KEYBOARD_AAED2000 | ||
16 | tristate "AAED-2000 keyboard" | ||
17 | depends on MACH_AAED2000 | ||
18 | select INPUT_POLLDEV | ||
19 | default y | ||
20 | help | ||
21 | Say Y here to enable the keyboard on the Agilent AAED-2000 | ||
22 | development board. | ||
23 | |||
24 | To compile this driver as a module, choose M here: the | ||
25 | module will be called aaed2000_kbd. | ||
26 | |||
27 | config KEYBOARD_AMIGA | ||
28 | tristate "Amiga keyboard" | ||
29 | depends on AMIGA | ||
30 | help | ||
31 | Say Y here if you are running Linux on any AMIGA and have a keyboard | ||
32 | attached. | ||
33 | |||
34 | To compile this driver as a module, choose M here: the | ||
35 | module will be called amikbd. | ||
36 | |||
37 | config ATARI_KBD_CORE | ||
38 | bool | ||
39 | |||
40 | config KEYBOARD_ATARI | ||
41 | tristate "Atari keyboard" | ||
42 | depends on ATARI | ||
43 | select ATARI_KBD_CORE | ||
44 | help | ||
45 | Say Y here if you are running Linux on any Atari and have a keyboard | ||
46 | attached. | ||
47 | |||
48 | To compile this driver as a module, choose M here: the | ||
49 | module will be called atakbd. | ||
50 | |||
15 | config KEYBOARD_ATKBD | 51 | config KEYBOARD_ATKBD |
16 | tristate "AT keyboard" if EMBEDDED || !X86 | 52 | tristate "AT keyboard" if EMBEDDED || !X86 |
17 | default y | 53 | default y |
@@ -68,69 +104,14 @@ config KEYBOARD_ATKBD_RDI_KEYCODES | |||
68 | right-hand column will be interpreted as the key shown in the | 104 | right-hand column will be interpreted as the key shown in the |
69 | left-hand column. | 105 | left-hand column. |
70 | 106 | ||
71 | config KEYBOARD_SUNKBD | 107 | config KEYBOARD_BFIN |
72 | tristate "Sun Type 4 and Type 5 keyboard" | 108 | tristate "Blackfin BF54x keypad support" |
73 | select SERIO | 109 | depends on (BF54x && !BF544) |
74 | help | ||
75 | Say Y here if you want to use a Sun Type 4 or Type 5 keyboard, | ||
76 | connected either to the Sun keyboard connector or to an serial | ||
77 | (RS-232) port via a simple adapter. | ||
78 | |||
79 | To compile this driver as a module, choose M here: the | ||
80 | module will be called sunkbd. | ||
81 | |||
82 | config KEYBOARD_LKKBD | ||
83 | tristate "DECstation/VAXstation LK201/LK401 keyboard" | ||
84 | select SERIO | ||
85 | help | ||
86 | Say Y here if you want to use a LK201 or LK401 style serial | ||
87 | keyboard. This keyboard is also useable on PCs if you attach | ||
88 | it with the inputattach program. The connector pinout is | ||
89 | described within lkkbd.c. | ||
90 | |||
91 | To compile this driver as a module, choose M here: the | ||
92 | module will be called lkkbd. | ||
93 | |||
94 | config KEYBOARD_LOCOMO | ||
95 | tristate "LoCoMo Keyboard Support" | ||
96 | depends on SHARP_LOCOMO && INPUT_KEYBOARD | ||
97 | help | ||
98 | Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA | ||
99 | |||
100 | To compile this driver as a module, choose M here: the | ||
101 | module will be called locomokbd. | ||
102 | |||
103 | config KEYBOARD_XTKBD | ||
104 | tristate "XT keyboard" | ||
105 | select SERIO | ||
106 | help | ||
107 | Say Y here if you want to use the old IBM PC/XT keyboard (or | ||
108 | compatible) on your system. This is only possible with a | ||
109 | parallel port keyboard adapter, you cannot connect it to the | ||
110 | keyboard port on a PC that runs Linux. | ||
111 | |||
112 | To compile this driver as a module, choose M here: the | ||
113 | module will be called xtkbd. | ||
114 | |||
115 | config KEYBOARD_NEWTON | ||
116 | tristate "Newton keyboard" | ||
117 | select SERIO | ||
118 | help | ||
119 | Say Y here if you have a Newton keyboard on a serial port. | ||
120 | |||
121 | To compile this driver as a module, choose M here: the | ||
122 | module will be called newtonkbd. | ||
123 | |||
124 | config KEYBOARD_STOWAWAY | ||
125 | tristate "Stowaway keyboard" | ||
126 | select SERIO | ||
127 | help | 110 | help |
128 | Say Y here if you have a Stowaway keyboard on a serial port. | 111 | Say Y here if you want to use the BF54x keypad. |
129 | Stowaway compatible keyboards like Dicota Input-PDA keyboard | ||
130 | are also supported by this driver. | ||
131 | 112 | ||
132 | To compile this driver as a module, choose M here: the | 113 | To compile this driver as a module, choose M here: the |
133 | module will be called stowaway. | 114 | module will be called bf54x-keys. |
134 | 115 | ||
135 | config KEYBOARD_CORGI | 116 | config KEYBOARD_CORGI |
136 | tristate "Corgi keyboard" | 117 | tristate "Corgi keyboard" |
@@ -143,61 +124,50 @@ config KEYBOARD_CORGI | |||
143 | To compile this driver as a module, choose M here: the | 124 | To compile this driver as a module, choose M here: the |
144 | module will be called corgikbd. | 125 | module will be called corgikbd. |
145 | 126 | ||
146 | config KEYBOARD_SPITZ | 127 | config KEYBOARD_LKKBD |
147 | tristate "Spitz keyboard" | 128 | tristate "DECstation/VAXstation LK201/LK401 keyboard" |
148 | depends on PXA_SHARPSL | 129 | select SERIO |
149 | default y | ||
150 | help | 130 | help |
151 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, | 131 | Say Y here if you want to use a LK201 or LK401 style serial |
152 | SL-C3000 and Sl-C3100 series of PDAs. | 132 | keyboard. This keyboard is also useable on PCs if you attach |
133 | it with the inputattach program. The connector pinout is | ||
134 | described within lkkbd.c. | ||
153 | 135 | ||
154 | To compile this driver as a module, choose M here: the | 136 | To compile this driver as a module, choose M here: the |
155 | module will be called spitzkbd. | 137 | module will be called lkkbd. |
156 | 138 | ||
157 | config KEYBOARD_TOSA | 139 | config KEYBOARD_EP93XX |
158 | tristate "Tosa keyboard" | 140 | tristate "EP93xx Matrix Keypad support" |
159 | depends on MACH_TOSA | 141 | depends on ARCH_EP93XX |
160 | default y | ||
161 | help | 142 | help |
162 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) | 143 | Say Y here to enable the matrix keypad on the Cirrus EP93XX. |
163 | 144 | ||
164 | To compile this driver as a module, choose M here: the | 145 | To compile this driver as a module, choose M here: the |
165 | module will be called tosakbd. | 146 | module will be called ep93xx_keypad. |
166 | 147 | ||
167 | config KEYBOARD_TOSA_USE_EXT_KEYCODES | 148 | config KEYBOARD_GPIO |
168 | bool "Tosa keyboard: use extended keycodes" | 149 | tristate "GPIO Buttons" |
169 | depends on KEYBOARD_TOSA | 150 | depends on GENERIC_GPIO |
170 | default n | ||
171 | help | 151 | help |
172 | Say Y here to enable the tosa keyboard driver to generate extended | 152 | This driver implements support for buttons connected |
173 | (>= 127) keycodes. Be aware, that they can't be correctly interpreted | 153 | to GPIO pins of various CPUs (and some other chips). |
174 | by either console keyboard driver or by Kdrive keybd driver. | ||
175 | |||
176 | Say Y only if you know, what you are doing! | ||
177 | 154 | ||
178 | config KEYBOARD_AMIGA | 155 | Say Y here if your device has buttons connected |
179 | tristate "Amiga keyboard" | 156 | directly to such GPIO pins. Your board-specific |
180 | depends on AMIGA | 157 | setup logic must also provide a platform device, |
181 | help | 158 | with configuration data saying which GPIOs are used. |
182 | Say Y here if you are running Linux on any AMIGA and have a keyboard | ||
183 | attached. | ||
184 | 159 | ||
185 | To compile this driver as a module, choose M here: the | 160 | To compile this driver as a module, choose M here: the |
186 | module will be called amikbd. | 161 | module will be called gpio_keys. |
187 | 162 | ||
188 | config ATARI_KBD_CORE | 163 | config KEYBOARD_MATRIX |
189 | bool | 164 | tristate "GPIO driven matrix keypad support" |
190 | 165 | depends on GENERIC_GPIO | |
191 | config KEYBOARD_ATARI | ||
192 | tristate "Atari keyboard" | ||
193 | depends on ATARI | ||
194 | select ATARI_KBD_CORE | ||
195 | help | 166 | help |
196 | Say Y here if you are running Linux on any Atari and have a keyboard | 167 | Enable support for GPIO driven matrix keypad. |
197 | attached. | ||
198 | 168 | ||
199 | To compile this driver as a module, choose M here: the | 169 | To compile this driver as a module, choose M here: the |
200 | module will be called atakbd. | 170 | module will be called matrix_keypad. |
201 | 171 | ||
202 | config KEYBOARD_HIL_OLD | 172 | config KEYBOARD_HIL_OLD |
203 | tristate "HP HIL keyboard support (simple driver)" | 173 | tristate "HP HIL keyboard support (simple driver)" |
@@ -261,20 +231,39 @@ config KEYBOARD_LM8323 | |||
261 | To compile this driver as a module, choose M here: the | 231 | To compile this driver as a module, choose M here: the |
262 | module will be called lm8323. | 232 | module will be called lm8323. |
263 | 233 | ||
264 | config KEYBOARD_OMAP | 234 | config KEYBOARD_LOCOMO |
265 | tristate "TI OMAP keypad support" | 235 | tristate "LoCoMo Keyboard Support" |
266 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 236 | depends on SHARP_LOCOMO |
267 | help | 237 | help |
268 | Say Y here if you want to use the OMAP keypad. | 238 | Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA |
269 | 239 | ||
270 | To compile this driver as a module, choose M here: the | 240 | To compile this driver as a module, choose M here: the |
271 | module will be called omap-keypad. | 241 | module will be called locomokbd. |
242 | |||
243 | config KEYBOARD_MAPLE | ||
244 | tristate "Maple bus keyboard" | ||
245 | depends on SH_DREAMCAST && MAPLE | ||
246 | help | ||
247 | Say Y here if you have a Dreamcast console running Linux and have | ||
248 | a keyboard attached to its Maple bus. | ||
249 | |||
250 | To compile this driver as a module, choose M here: the | ||
251 | module will be called maple_keyb. | ||
252 | |||
253 | config KEYBOARD_NEWTON | ||
254 | tristate "Newton keyboard" | ||
255 | select SERIO | ||
256 | help | ||
257 | Say Y here if you have a Newton keyboard on a serial port. | ||
258 | |||
259 | To compile this driver as a module, choose M here: the | ||
260 | module will be called newtonkbd. | ||
272 | 261 | ||
273 | config KEYBOARD_PXA27x | 262 | config KEYBOARD_PXA27x |
274 | tristate "PXA27x/PXA3xx keypad support" | 263 | tristate "PXA27x/PXA3xx keypad support" |
275 | depends on PXA27x || PXA3xx | 264 | depends on PXA27x || PXA3xx |
276 | help | 265 | help |
277 | Enable support for PXA27x/PXA3xx keypad controller | 266 | Enable support for PXA27x/PXA3xx keypad controller. |
278 | 267 | ||
279 | To compile this driver as a module, choose M here: the | 268 | To compile this driver as a module, choose M here: the |
280 | module will be called pxa27x_keypad. | 269 | module will be called pxa27x_keypad. |
@@ -288,51 +277,38 @@ config KEYBOARD_PXA930_ROTARY | |||
288 | To compile this driver as a module, choose M here: the | 277 | To compile this driver as a module, choose M here: the |
289 | module will be called pxa930_rotary. | 278 | module will be called pxa930_rotary. |
290 | 279 | ||
291 | config KEYBOARD_AAED2000 | 280 | config KEYBOARD_SPITZ |
292 | tristate "AAED-2000 keyboard" | 281 | tristate "Spitz keyboard" |
293 | depends on MACH_AAED2000 | 282 | depends on PXA_SHARPSL |
294 | select INPUT_POLLDEV | ||
295 | default y | 283 | default y |
296 | help | 284 | help |
297 | Say Y here to enable the keyboard on the Agilent AAED-2000 | 285 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, |
298 | development board. | 286 | SL-C3000 and Sl-C3100 series of PDAs. |
299 | |||
300 | To compile this driver as a module, choose M here: the | ||
301 | module will be called aaed2000_kbd. | ||
302 | |||
303 | config KEYBOARD_GPIO | ||
304 | tristate "GPIO Buttons" | ||
305 | depends on GENERIC_GPIO | ||
306 | help | ||
307 | This driver implements support for buttons connected | ||
308 | to GPIO pins of various CPUs (and some other chips). | ||
309 | |||
310 | Say Y here if your device has buttons connected | ||
311 | directly to such GPIO pins. Your board-specific | ||
312 | setup logic must also provide a platform device, | ||
313 | with configuration data saying which GPIOs are used. | ||
314 | 287 | ||
315 | To compile this driver as a module, choose M here: the | 288 | To compile this driver as a module, choose M here: the |
316 | module will be called gpio-keys. | 289 | module will be called spitzkbd. |
317 | 290 | ||
318 | config KEYBOARD_MAPLE | 291 | config KEYBOARD_STOWAWAY |
319 | tristate "Maple bus keyboard" | 292 | tristate "Stowaway keyboard" |
320 | depends on SH_DREAMCAST && MAPLE | 293 | select SERIO |
321 | help | 294 | help |
322 | Say Y here if you have a Dreamcast console running Linux and have | 295 | Say Y here if you have a Stowaway keyboard on a serial port. |
323 | a keyboard attached to its Maple bus. | 296 | Stowaway compatible keyboards like Dicota Input-PDA keyboard |
297 | are also supported by this driver. | ||
324 | 298 | ||
325 | To compile this driver as a module, choose M here: the | 299 | To compile this driver as a module, choose M here: the |
326 | module will be called maple_keyb. | 300 | module will be called stowaway. |
327 | 301 | ||
328 | config KEYBOARD_BFIN | 302 | config KEYBOARD_SUNKBD |
329 | tristate "Blackfin BF54x keypad support" | 303 | tristate "Sun Type 4 and Type 5 keyboard" |
330 | depends on (BF54x && !BF544) | 304 | select SERIO |
331 | help | 305 | help |
332 | Say Y here if you want to use the BF54x keypad. | 306 | Say Y here if you want to use a Sun Type 4 or Type 5 keyboard, |
307 | connected either to the Sun keyboard connector or to an serial | ||
308 | (RS-232) port via a simple adapter. | ||
333 | 309 | ||
334 | To compile this driver as a module, choose M here: the | 310 | To compile this driver as a module, choose M here: the |
335 | module will be called bf54x-keys. | 311 | module will be called sunkbd. |
336 | 312 | ||
337 | config KEYBOARD_SH_KEYSC | 313 | config KEYBOARD_SH_KEYSC |
338 | tristate "SuperH KEYSC keypad support" | 314 | tristate "SuperH KEYSC keypad support" |
@@ -344,13 +320,45 @@ config KEYBOARD_SH_KEYSC | |||
344 | To compile this driver as a module, choose M here: the | 320 | To compile this driver as a module, choose M here: the |
345 | module will be called sh_keysc. | 321 | module will be called sh_keysc. |
346 | 322 | ||
347 | config KEYBOARD_EP93XX | 323 | config KEYBOARD_OMAP |
348 | tristate "EP93xx Matrix Keypad support" | 324 | tristate "TI OMAP keypad support" |
349 | depends on ARCH_EP93XX | 325 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
350 | help | 326 | help |
351 | Say Y here to enable the matrix keypad on the Cirrus EP93XX. | 327 | Say Y here if you want to use the OMAP keypad. |
352 | 328 | ||
353 | To compile this driver as a module, choose M here: the | 329 | To compile this driver as a module, choose M here: the |
354 | module will be called ep93xx_keypad. | 330 | module will be called omap-keypad. |
331 | |||
332 | config KEYBOARD_TOSA | ||
333 | tristate "Tosa keyboard" | ||
334 | depends on MACH_TOSA | ||
335 | default y | ||
336 | help | ||
337 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) | ||
338 | |||
339 | To compile this driver as a module, choose M here: the | ||
340 | module will be called tosakbd. | ||
341 | |||
342 | config KEYBOARD_TOSA_USE_EXT_KEYCODES | ||
343 | bool "Tosa keyboard: use extended keycodes" | ||
344 | depends on KEYBOARD_TOSA | ||
345 | help | ||
346 | Say Y here to enable the tosa keyboard driver to generate extended | ||
347 | (>= 127) keycodes. Be aware, that they can't be correctly interpreted | ||
348 | by either console keyboard driver or by Kdrive keybd driver. | ||
349 | |||
350 | Say Y only if you know, what you are doing! | ||
351 | |||
352 | config KEYBOARD_XTKBD | ||
353 | tristate "XT keyboard" | ||
354 | select SERIO | ||
355 | help | ||
356 | Say Y here if you want to use the old IBM PC/XT keyboard (or | ||
357 | compatible) on your system. This is only possible with a | ||
358 | parallel port keyboard adapter, you cannot connect it to the | ||
359 | keyboard port on a PC that runs Linux. | ||
360 | |||
361 | To compile this driver as a module, choose M here: the | ||
362 | module will be called xtkbd. | ||
355 | 363 | ||
356 | endif | 364 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 156b647a259b..b5b5eae9724f 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -4,29 +4,30 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o |
8 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | ||
9 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | ||
10 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | ||
11 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 8 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
12 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 9 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
13 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | 10 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
14 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 11 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
15 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | ||
16 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | 12 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o |
17 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | 13 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
18 | obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o | 14 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
19 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 15 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
20 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 16 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
17 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | ||
18 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | ||
19 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | ||
21 | obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o | 20 | obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o |
21 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | ||
22 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | ||
23 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | ||
24 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | ||
22 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 25 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
23 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o | 26 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o |
24 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | 27 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o |
25 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | ||
26 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | ||
27 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | ||
28 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | ||
29 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | ||
30 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | ||
31 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | 28 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o |
32 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 29 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o |
30 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | ||
31 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | ||
32 | obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o | ||
33 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 2157cd7de00c..efed0c9e242e 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -29,7 +29,8 @@ | |||
29 | struct gpio_button_data { | 29 | struct gpio_button_data { |
30 | struct gpio_keys_button *button; | 30 | struct gpio_keys_button *button; |
31 | struct input_dev *input; | 31 | struct input_dev *input; |
32 | struct delayed_work work; | 32 | struct timer_list timer; |
33 | struct work_struct work; | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct gpio_keys_drvdata { | 36 | struct gpio_keys_drvdata { |
@@ -40,7 +41,7 @@ struct gpio_keys_drvdata { | |||
40 | static void gpio_keys_report_event(struct work_struct *work) | 41 | static void gpio_keys_report_event(struct work_struct *work) |
41 | { | 42 | { |
42 | struct gpio_button_data *bdata = | 43 | struct gpio_button_data *bdata = |
43 | container_of(work, struct gpio_button_data, work.work); | 44 | container_of(work, struct gpio_button_data, work); |
44 | struct gpio_keys_button *button = bdata->button; | 45 | struct gpio_keys_button *button = bdata->button; |
45 | struct input_dev *input = bdata->input; | 46 | struct input_dev *input = bdata->input; |
46 | unsigned int type = button->type ?: EV_KEY; | 47 | unsigned int type = button->type ?: EV_KEY; |
@@ -50,17 +51,25 @@ static void gpio_keys_report_event(struct work_struct *work) | |||
50 | input_sync(input); | 51 | input_sync(input); |
51 | } | 52 | } |
52 | 53 | ||
54 | static void gpio_keys_timer(unsigned long _data) | ||
55 | { | ||
56 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | ||
57 | |||
58 | schedule_work(&data->work); | ||
59 | } | ||
60 | |||
53 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | 61 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) |
54 | { | 62 | { |
55 | struct gpio_button_data *bdata = dev_id; | 63 | struct gpio_button_data *bdata = dev_id; |
56 | struct gpio_keys_button *button = bdata->button; | 64 | struct gpio_keys_button *button = bdata->button; |
57 | unsigned long delay; | ||
58 | 65 | ||
59 | BUG_ON(irq != gpio_to_irq(button->gpio)); | 66 | BUG_ON(irq != gpio_to_irq(button->gpio)); |
60 | 67 | ||
61 | delay = button->debounce_interval ? | 68 | if (button->debounce_interval) |
62 | msecs_to_jiffies(button->debounce_interval) : 0; | 69 | mod_timer(&bdata->timer, |
63 | schedule_delayed_work(&bdata->work, delay); | 70 | jiffies + msecs_to_jiffies(button->debounce_interval)); |
71 | else | ||
72 | schedule_work(&bdata->work); | ||
64 | 73 | ||
65 | return IRQ_HANDLED; | 74 | return IRQ_HANDLED; |
66 | } | 75 | } |
@@ -107,7 +116,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
107 | 116 | ||
108 | bdata->input = input; | 117 | bdata->input = input; |
109 | bdata->button = button; | 118 | bdata->button = button; |
110 | INIT_DELAYED_WORK(&bdata->work, gpio_keys_report_event); | 119 | setup_timer(&bdata->timer, |
120 | gpio_keys_timer, (unsigned long)bdata); | ||
121 | INIT_WORK(&bdata->work, gpio_keys_report_event); | ||
111 | 122 | ||
112 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); | 123 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); |
113 | if (error < 0) { | 124 | if (error < 0) { |
@@ -166,7 +177,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
166 | fail2: | 177 | fail2: |
167 | while (--i >= 0) { | 178 | while (--i >= 0) { |
168 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 179 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
169 | cancel_delayed_work_sync(&ddata->data[i].work); | 180 | if (pdata->buttons[i].debounce_interval) |
181 | del_timer_sync(&ddata->data[i].timer); | ||
182 | cancel_work_sync(&ddata->data[i].work); | ||
170 | gpio_free(pdata->buttons[i].gpio); | 183 | gpio_free(pdata->buttons[i].gpio); |
171 | } | 184 | } |
172 | 185 | ||
@@ -190,7 +203,9 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
190 | for (i = 0; i < pdata->nbuttons; i++) { | 203 | for (i = 0; i < pdata->nbuttons; i++) { |
191 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 204 | int irq = gpio_to_irq(pdata->buttons[i].gpio); |
192 | free_irq(irq, &ddata->data[i]); | 205 | free_irq(irq, &ddata->data[i]); |
193 | cancel_delayed_work_sync(&ddata->data[i].work); | 206 | if (pdata->buttons[i].debounce_interval) |
207 | del_timer_sync(&ddata->data[i].timer); | ||
208 | cancel_work_sync(&ddata->data[i].work); | ||
194 | gpio_free(pdata->buttons[i].gpio); | 209 | gpio_free(pdata->buttons[i].gpio); |
195 | } | 210 | } |
196 | 211 | ||
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c new file mode 100644 index 000000000000..e9b2e7cb05be --- /dev/null +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -0,0 +1,453 @@ | |||
1 | /* | ||
2 | * GPIO driven matrix keyboard driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com> | ||
5 | * | ||
6 | * Based on corgikbd.c | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/jiffies.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/input/matrix_keypad.h> | ||
25 | |||
26 | struct matrix_keypad { | ||
27 | const struct matrix_keypad_platform_data *pdata; | ||
28 | struct input_dev *input_dev; | ||
29 | unsigned short *keycodes; | ||
30 | |||
31 | uint32_t last_key_state[MATRIX_MAX_COLS]; | ||
32 | struct delayed_work work; | ||
33 | bool scan_pending; | ||
34 | bool stopped; | ||
35 | spinlock_t lock; | ||
36 | }; | ||
37 | |||
38 | /* | ||
39 | * NOTE: normally the GPIO has to be put into HiZ when de-activated to cause | ||
40 | * minmal side effect when scanning other columns, here it is configured to | ||
41 | * be input, and it should work on most platforms. | ||
42 | */ | ||
43 | static void __activate_col(const struct matrix_keypad_platform_data *pdata, | ||
44 | int col, bool on) | ||
45 | { | ||
46 | bool level_on = !pdata->active_low; | ||
47 | |||
48 | if (on) { | ||
49 | gpio_direction_output(pdata->col_gpios[col], level_on); | ||
50 | } else { | ||
51 | gpio_set_value_cansleep(pdata->col_gpios[col], !level_on); | ||
52 | gpio_direction_input(pdata->col_gpios[col]); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | static void activate_col(const struct matrix_keypad_platform_data *pdata, | ||
57 | int col, bool on) | ||
58 | { | ||
59 | __activate_col(pdata, col, on); | ||
60 | |||
61 | if (on && pdata->col_scan_delay_us) | ||
62 | udelay(pdata->col_scan_delay_us); | ||
63 | } | ||
64 | |||
65 | static void activate_all_cols(const struct matrix_keypad_platform_data *pdata, | ||
66 | bool on) | ||
67 | { | ||
68 | int col; | ||
69 | |||
70 | for (col = 0; col < pdata->num_col_gpios; col++) | ||
71 | __activate_col(pdata, col, on); | ||
72 | } | ||
73 | |||
74 | static bool row_asserted(const struct matrix_keypad_platform_data *pdata, | ||
75 | int row) | ||
76 | { | ||
77 | return gpio_get_value_cansleep(pdata->row_gpios[row]) ? | ||
78 | !pdata->active_low : pdata->active_low; | ||
79 | } | ||
80 | |||
81 | static void enable_row_irqs(struct matrix_keypad *keypad) | ||
82 | { | ||
83 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
84 | int i; | ||
85 | |||
86 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
87 | enable_irq(gpio_to_irq(pdata->row_gpios[i])); | ||
88 | } | ||
89 | |||
90 | static void disable_row_irqs(struct matrix_keypad *keypad) | ||
91 | { | ||
92 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
93 | int i; | ||
94 | |||
95 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
96 | disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i])); | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * This gets the keys from keyboard and reports it to input subsystem | ||
101 | */ | ||
102 | static void matrix_keypad_scan(struct work_struct *work) | ||
103 | { | ||
104 | struct matrix_keypad *keypad = | ||
105 | container_of(work, struct matrix_keypad, work.work); | ||
106 | struct input_dev *input_dev = keypad->input_dev; | ||
107 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
108 | uint32_t new_state[MATRIX_MAX_COLS]; | ||
109 | int row, col, code; | ||
110 | |||
111 | /* de-activate all columns for scanning */ | ||
112 | activate_all_cols(pdata, false); | ||
113 | |||
114 | memset(new_state, 0, sizeof(new_state)); | ||
115 | |||
116 | /* assert each column and read the row status out */ | ||
117 | for (col = 0; col < pdata->num_col_gpios; col++) { | ||
118 | |||
119 | activate_col(pdata, col, true); | ||
120 | |||
121 | for (row = 0; row < pdata->num_row_gpios; row++) | ||
122 | new_state[col] |= | ||
123 | row_asserted(pdata, row) ? (1 << row) : 0; | ||
124 | |||
125 | activate_col(pdata, col, false); | ||
126 | } | ||
127 | |||
128 | for (col = 0; col < pdata->num_col_gpios; col++) { | ||
129 | uint32_t bits_changed; | ||
130 | |||
131 | bits_changed = keypad->last_key_state[col] ^ new_state[col]; | ||
132 | if (bits_changed == 0) | ||
133 | continue; | ||
134 | |||
135 | for (row = 0; row < pdata->num_row_gpios; row++) { | ||
136 | if ((bits_changed & (1 << row)) == 0) | ||
137 | continue; | ||
138 | |||
139 | code = (row << 4) + col; | ||
140 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
141 | input_report_key(input_dev, | ||
142 | keypad->keycodes[code], | ||
143 | new_state[col] & (1 << row)); | ||
144 | } | ||
145 | } | ||
146 | input_sync(input_dev); | ||
147 | |||
148 | memcpy(keypad->last_key_state, new_state, sizeof(new_state)); | ||
149 | |||
150 | activate_all_cols(pdata, true); | ||
151 | |||
152 | /* Enable IRQs again */ | ||
153 | spin_lock_irq(&keypad->lock); | ||
154 | keypad->scan_pending = false; | ||
155 | enable_row_irqs(keypad); | ||
156 | spin_unlock_irq(&keypad->lock); | ||
157 | } | ||
158 | |||
159 | static irqreturn_t matrix_keypad_interrupt(int irq, void *id) | ||
160 | { | ||
161 | struct matrix_keypad *keypad = id; | ||
162 | unsigned long flags; | ||
163 | |||
164 | spin_lock_irqsave(&keypad->lock, flags); | ||
165 | |||
166 | /* | ||
167 | * See if another IRQ beaten us to it and scheduled the | ||
168 | * scan already. In that case we should not try to | ||
169 | * disable IRQs again. | ||
170 | */ | ||
171 | if (unlikely(keypad->scan_pending || keypad->stopped)) | ||
172 | goto out; | ||
173 | |||
174 | disable_row_irqs(keypad); | ||
175 | keypad->scan_pending = true; | ||
176 | schedule_delayed_work(&keypad->work, | ||
177 | msecs_to_jiffies(keypad->pdata->debounce_ms)); | ||
178 | |||
179 | out: | ||
180 | spin_unlock_irqrestore(&keypad->lock, flags); | ||
181 | return IRQ_HANDLED; | ||
182 | } | ||
183 | |||
184 | static int matrix_keypad_start(struct input_dev *dev) | ||
185 | { | ||
186 | struct matrix_keypad *keypad = input_get_drvdata(dev); | ||
187 | |||
188 | keypad->stopped = false; | ||
189 | mb(); | ||
190 | |||
191 | /* | ||
192 | * Schedule an immediate key scan to capture current key state; | ||
193 | * columns will be activated and IRQs be enabled after the scan. | ||
194 | */ | ||
195 | schedule_delayed_work(&keypad->work, 0); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static void matrix_keypad_stop(struct input_dev *dev) | ||
201 | { | ||
202 | struct matrix_keypad *keypad = input_get_drvdata(dev); | ||
203 | |||
204 | keypad->stopped = true; | ||
205 | mb(); | ||
206 | flush_work(&keypad->work.work); | ||
207 | /* | ||
208 | * matrix_keypad_scan() will leave IRQs enabled; | ||
209 | * we should disable them now. | ||
210 | */ | ||
211 | disable_row_irqs(keypad); | ||
212 | } | ||
213 | |||
214 | #ifdef CONFIG_PM | ||
215 | static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state) | ||
216 | { | ||
217 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | ||
218 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
219 | int i; | ||
220 | |||
221 | matrix_keypad_stop(keypad->input_dev); | ||
222 | |||
223 | if (device_may_wakeup(&pdev->dev)) | ||
224 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
225 | enable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int matrix_keypad_resume(struct platform_device *pdev) | ||
231 | { | ||
232 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | ||
233 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
234 | int i; | ||
235 | |||
236 | if (device_may_wakeup(&pdev->dev)) | ||
237 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
238 | disable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); | ||
239 | |||
240 | matrix_keypad_start(keypad->input_dev); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | #else | ||
245 | #define matrix_keypad_suspend NULL | ||
246 | #define matrix_keypad_resume NULL | ||
247 | #endif | ||
248 | |||
249 | static int __devinit init_matrix_gpio(struct platform_device *pdev, | ||
250 | struct matrix_keypad *keypad) | ||
251 | { | ||
252 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
253 | int i, err = -EINVAL; | ||
254 | |||
255 | /* initialized strobe lines as outputs, activated */ | ||
256 | for (i = 0; i < pdata->num_col_gpios; i++) { | ||
257 | err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col"); | ||
258 | if (err) { | ||
259 | dev_err(&pdev->dev, | ||
260 | "failed to request GPIO%d for COL%d\n", | ||
261 | pdata->col_gpios[i], i); | ||
262 | goto err_free_cols; | ||
263 | } | ||
264 | |||
265 | gpio_direction_output(pdata->col_gpios[i], !pdata->active_low); | ||
266 | } | ||
267 | |||
268 | for (i = 0; i < pdata->num_row_gpios; i++) { | ||
269 | err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row"); | ||
270 | if (err) { | ||
271 | dev_err(&pdev->dev, | ||
272 | "failed to request GPIO%d for ROW%d\n", | ||
273 | pdata->row_gpios[i], i); | ||
274 | goto err_free_rows; | ||
275 | } | ||
276 | |||
277 | gpio_direction_input(pdata->row_gpios[i]); | ||
278 | } | ||
279 | |||
280 | for (i = 0; i < pdata->num_row_gpios; i++) { | ||
281 | err = request_irq(gpio_to_irq(pdata->row_gpios[i]), | ||
282 | matrix_keypad_interrupt, | ||
283 | IRQF_DISABLED | | ||
284 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
285 | "matrix-keypad", keypad); | ||
286 | if (err) { | ||
287 | dev_err(&pdev->dev, | ||
288 | "Unable to acquire interrupt for GPIO line %i\n", | ||
289 | pdata->row_gpios[i]); | ||
290 | goto err_free_irqs; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | /* initialized as disabled - enabled by input->open */ | ||
295 | disable_row_irqs(keypad); | ||
296 | return 0; | ||
297 | |||
298 | err_free_irqs: | ||
299 | while (--i >= 0) | ||
300 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | ||
301 | i = pdata->num_row_gpios; | ||
302 | err_free_rows: | ||
303 | while (--i >= 0) | ||
304 | gpio_free(pdata->row_gpios[i]); | ||
305 | i = pdata->num_col_gpios; | ||
306 | err_free_cols: | ||
307 | while (--i >= 0) | ||
308 | gpio_free(pdata->col_gpios[i]); | ||
309 | |||
310 | return err; | ||
311 | } | ||
312 | |||
313 | static int __devinit matrix_keypad_probe(struct platform_device *pdev) | ||
314 | { | ||
315 | const struct matrix_keypad_platform_data *pdata; | ||
316 | const struct matrix_keymap_data *keymap_data; | ||
317 | struct matrix_keypad *keypad; | ||
318 | struct input_dev *input_dev; | ||
319 | unsigned short *keycodes; | ||
320 | int i; | ||
321 | int err; | ||
322 | |||
323 | pdata = pdev->dev.platform_data; | ||
324 | if (!pdata) { | ||
325 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
326 | return -EINVAL; | ||
327 | } | ||
328 | |||
329 | keymap_data = pdata->keymap_data; | ||
330 | if (!keymap_data) { | ||
331 | dev_err(&pdev->dev, "no keymap data defined\n"); | ||
332 | return -EINVAL; | ||
333 | } | ||
334 | |||
335 | if (!keymap_data->max_keymap_size) { | ||
336 | dev_err(&pdev->dev, "invalid keymap data supplied\n"); | ||
337 | return -EINVAL; | ||
338 | } | ||
339 | |||
340 | keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); | ||
341 | keycodes = kzalloc(keymap_data->max_keymap_size * | ||
342 | sizeof(keypad->keycodes), | ||
343 | GFP_KERNEL); | ||
344 | input_dev = input_allocate_device(); | ||
345 | if (!keypad || !keycodes || !input_dev) { | ||
346 | err = -ENOMEM; | ||
347 | goto err_free_mem; | ||
348 | } | ||
349 | |||
350 | keypad->input_dev = input_dev; | ||
351 | keypad->pdata = pdata; | ||
352 | keypad->keycodes = keycodes; | ||
353 | keypad->stopped = true; | ||
354 | INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); | ||
355 | spin_lock_init(&keypad->lock); | ||
356 | |||
357 | input_dev->name = pdev->name; | ||
358 | input_dev->id.bustype = BUS_HOST; | ||
359 | input_dev->dev.parent = &pdev->dev; | ||
360 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
361 | input_dev->open = matrix_keypad_start; | ||
362 | input_dev->close = matrix_keypad_stop; | ||
363 | |||
364 | input_dev->keycode = keycodes; | ||
365 | input_dev->keycodesize = sizeof(*keycodes); | ||
366 | input_dev->keycodemax = keymap_data->max_keymap_size; | ||
367 | |||
368 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
369 | unsigned int key = keymap_data->keymap[i]; | ||
370 | unsigned int row = KEY_ROW(key); | ||
371 | unsigned int col = KEY_COL(key); | ||
372 | unsigned short code = KEY_VAL(key); | ||
373 | |||
374 | keycodes[(row << 4) + col] = code; | ||
375 | __set_bit(code, input_dev->keybit); | ||
376 | } | ||
377 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
378 | |||
379 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
380 | input_set_drvdata(input_dev, keypad); | ||
381 | |||
382 | err = init_matrix_gpio(pdev, keypad); | ||
383 | if (err) | ||
384 | goto err_free_mem; | ||
385 | |||
386 | err = input_register_device(keypad->input_dev); | ||
387 | if (err) | ||
388 | goto err_free_mem; | ||
389 | |||
390 | device_init_wakeup(&pdev->dev, pdata->wakeup); | ||
391 | platform_set_drvdata(pdev, keypad); | ||
392 | |||
393 | return 0; | ||
394 | |||
395 | err_free_mem: | ||
396 | input_free_device(input_dev); | ||
397 | kfree(keycodes); | ||
398 | kfree(keypad); | ||
399 | return err; | ||
400 | } | ||
401 | |||
402 | static int __devexit matrix_keypad_remove(struct platform_device *pdev) | ||
403 | { | ||
404 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | ||
405 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
406 | int i; | ||
407 | |||
408 | device_init_wakeup(&pdev->dev, 0); | ||
409 | |||
410 | for (i = 0; i < pdata->num_row_gpios; i++) { | ||
411 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | ||
412 | gpio_free(pdata->row_gpios[i]); | ||
413 | } | ||
414 | |||
415 | for (i = 0; i < pdata->num_col_gpios; i++) | ||
416 | gpio_free(pdata->col_gpios[i]); | ||
417 | |||
418 | input_unregister_device(keypad->input_dev); | ||
419 | platform_set_drvdata(pdev, NULL); | ||
420 | kfree(keypad->keycodes); | ||
421 | kfree(keypad); | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static struct platform_driver matrix_keypad_driver = { | ||
427 | .probe = matrix_keypad_probe, | ||
428 | .remove = __devexit_p(matrix_keypad_remove), | ||
429 | .suspend = matrix_keypad_suspend, | ||
430 | .resume = matrix_keypad_resume, | ||
431 | .driver = { | ||
432 | .name = "matrix-keypad", | ||
433 | .owner = THIS_MODULE, | ||
434 | }, | ||
435 | }; | ||
436 | |||
437 | static int __init matrix_keypad_init(void) | ||
438 | { | ||
439 | return platform_driver_register(&matrix_keypad_driver); | ||
440 | } | ||
441 | |||
442 | static void __exit matrix_keypad_exit(void) | ||
443 | { | ||
444 | platform_driver_unregister(&matrix_keypad_driver); | ||
445 | } | ||
446 | |||
447 | module_init(matrix_keypad_init); | ||
448 | module_exit(matrix_keypad_exit); | ||
449 | |||
450 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); | ||
451 | MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver"); | ||
452 | MODULE_LICENSE("GPL v2"); | ||
453 | MODULE_ALIAS("platform:matrix-keypad"); | ||
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 2adf9cb265da..d114d3a9e1e9 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Cobalt button interface driver. | 2 | * Cobalt button interface driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2007-2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -148,7 +148,7 @@ static int __devexit cobalt_buttons_remove(struct platform_device *pdev) | |||
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | 150 | ||
151 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | 151 | MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); |
152 | MODULE_DESCRIPTION("Cobalt button interface driver"); | 152 | MODULE_DESCRIPTION("Cobalt button interface driver"); |
153 | MODULE_LICENSE("GPL"); | 153 | MODULE_LICENSE("GPL"); |
154 | /* work with hotplug and coldplug */ | 154 | /* work with hotplug and coldplug */ |
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 5e5eb88d8d1e..7b6ce178f1b6 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c | |||
@@ -46,7 +46,7 @@ static void gpio_mouse_scan(struct input_polled_dev *dev) | |||
46 | input_sync(input); | 46 | input_sync(input); |
47 | } | 47 | } |
48 | 48 | ||
49 | static int __init gpio_mouse_probe(struct platform_device *pdev) | 49 | static int __devinit gpio_mouse_probe(struct platform_device *pdev) |
50 | { | 50 | { |
51 | struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; | 51 | struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; |
52 | struct input_polled_dev *input_poll; | 52 | struct input_polled_dev *input_poll; |
@@ -170,10 +170,8 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev) | |||
170 | return 0; | 170 | return 0; |
171 | } | 171 | } |
172 | 172 | ||
173 | /* work with hotplug and coldplug */ | ||
174 | MODULE_ALIAS("platform:gpio_mouse"); | ||
175 | |||
176 | static struct platform_driver gpio_mouse_device_driver = { | 173 | static struct platform_driver gpio_mouse_device_driver = { |
174 | .probe = gpio_mouse_probe, | ||
177 | .remove = __devexit_p(gpio_mouse_remove), | 175 | .remove = __devexit_p(gpio_mouse_remove), |
178 | .driver = { | 176 | .driver = { |
179 | .name = "gpio_mouse", | 177 | .name = "gpio_mouse", |
@@ -183,8 +181,7 @@ static struct platform_driver gpio_mouse_device_driver = { | |||
183 | 181 | ||
184 | static int __init gpio_mouse_init(void) | 182 | static int __init gpio_mouse_init(void) |
185 | { | 183 | { |
186 | return platform_driver_probe(&gpio_mouse_device_driver, | 184 | return platform_driver_register(&gpio_mouse_device_driver); |
187 | gpio_mouse_probe); | ||
188 | } | 185 | } |
189 | module_init(gpio_mouse_init); | 186 | module_init(gpio_mouse_init); |
190 | 187 | ||
@@ -197,3 +194,5 @@ module_exit(gpio_mouse_exit); | |||
197 | MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); | 194 | MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); |
198 | MODULE_DESCRIPTION("GPIO mouse driver"); | 195 | MODULE_DESCRIPTION("GPIO mouse driver"); |
199 | MODULE_LICENSE("GPL"); | 196 | MODULE_LICENSE("GPL"); |
197 | MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */ | ||
198 | |||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index fb8a3cd3ffd0..924e8ed7f2cf 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -392,6 +392,34 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { | |||
392 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), | 392 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), |
393 | }, | 393 | }, |
394 | }, | 394 | }, |
395 | { | ||
396 | .ident = "Acer Aspire One 150", | ||
397 | .matches = { | ||
398 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
399 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), | ||
400 | }, | ||
401 | }, | ||
402 | { | ||
403 | .ident = "Advent 4211", | ||
404 | .matches = { | ||
405 | DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), | ||
406 | DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), | ||
407 | }, | ||
408 | }, | ||
409 | { | ||
410 | .ident = "Medion Akoya Mini E1210", | ||
411 | .matches = { | ||
412 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), | ||
413 | DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), | ||
414 | }, | ||
415 | }, | ||
416 | { | ||
417 | .ident = "Mivvy M310", | ||
418 | .matches = { | ||
419 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), | ||
420 | DMI_MATCH(DMI_PRODUCT_NAME, "N10"), | ||
421 | }, | ||
422 | }, | ||
395 | { } | 423 | { } |
396 | }; | 424 | }; |
397 | 425 | ||
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index f919bf57293c..582245c497eb 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -934,10 +934,11 @@ static bool i8042_suspended; | |||
934 | 934 | ||
935 | static int i8042_suspend(struct platform_device *dev, pm_message_t state) | 935 | static int i8042_suspend(struct platform_device *dev, pm_message_t state) |
936 | { | 936 | { |
937 | if (!i8042_suspended && state.event == PM_EVENT_SUSPEND) { | 937 | if (!i8042_suspended && state.event == PM_EVENT_SUSPEND) |
938 | i8042_controller_reset(); | 938 | i8042_controller_reset(); |
939 | i8042_suspended = true; | 939 | |
940 | } | 940 | i8042_suspended = state.event == PM_EVENT_SUSPEND || |
941 | state.event == PM_EVENT_FREEZE; | ||
941 | 942 | ||
942 | return 0; | 943 | return 0; |
943 | } | 944 | } |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index fb17573f8f2d..d66f4944f2a0 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -935,10 +935,11 @@ static int serio_suspend(struct device *dev, pm_message_t state) | |||
935 | { | 935 | { |
936 | struct serio *serio = to_serio_port(dev); | 936 | struct serio *serio = to_serio_port(dev); |
937 | 937 | ||
938 | if (!serio->suspended && state.event == PM_EVENT_SUSPEND) { | 938 | if (!serio->suspended && state.event == PM_EVENT_SUSPEND) |
939 | serio_cleanup(serio); | 939 | serio_cleanup(serio); |
940 | serio->suspended = true; | 940 | |
941 | } | 941 | serio->suspended = state.event == PM_EVENT_SUSPEND || |
942 | state.event == PM_EVENT_FREEZE; | ||
942 | 943 | ||
943 | return 0; | 944 | return 0; |
944 | } | 945 | } |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 38bf86384aeb..c896d6a21b7e 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -384,6 +384,8 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
384 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 384 | wacom_report_key(wcombo, BTN_STYLUS2, 0); |
385 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 385 | wacom_report_key(wcombo, BTN_TOUCH, 0); |
386 | wacom_report_abs(wcombo, ABS_WHEEL, 0); | 386 | wacom_report_abs(wcombo, ABS_WHEEL, 0); |
387 | if (wacom->features->type >= INTUOS3S) | ||
388 | wacom_report_abs(wcombo, ABS_Z, 0); | ||
387 | } | 389 | } |
388 | wacom_report_key(wcombo, wacom->tool[idx], 0); | 390 | wacom_report_key(wcombo, wacom->tool[idx], 0); |
389 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 391 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ |
@@ -836,6 +838,7 @@ static struct wacom_features wacom_features[] = { | |||
836 | { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, | 838 | { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, |
837 | { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, | 839 | { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, |
838 | { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, | 840 | { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, |
841 | { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL }, | ||
839 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU }, | 842 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU }, |
840 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, | 843 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, |
841 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 844 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, |
@@ -897,8 +900,9 @@ static struct usb_device_id wacom_ids[] = { | |||
897 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, | 900 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, |
898 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, | 901 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, |
899 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, | 902 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, |
900 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, | ||
901 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, | 903 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, |
904 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, | ||
905 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, | ||
902 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, | 906 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, |
903 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, | 907 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, |
904 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, | 908 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, |
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c index 6071f5882572..937dfe4e9b12 100644 --- a/drivers/input/touchscreen/w90p910_ts.c +++ b/drivers/input/touchscreen/w90p910_ts.c | |||
@@ -326,7 +326,7 @@ static struct platform_driver w90x900ts_driver = { | |||
326 | .probe = w90x900ts_probe, | 326 | .probe = w90x900ts_probe, |
327 | .remove = __devexit_p(w90x900ts_remove), | 327 | .remove = __devexit_p(w90x900ts_remove), |
328 | .driver = { | 328 | .driver = { |
329 | .name = "w90x900-ts", | 329 | .name = "nuc900-ts", |
330 | .owner = THIS_MODULE, | 330 | .owner = THIS_MODULE, |
331 | }, | 331 | }, |
332 | }; | 332 | }; |
@@ -347,4 +347,4 @@ module_exit(w90x900ts_exit); | |||
347 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | 347 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); |
348 | MODULE_DESCRIPTION("w90p910 touch screen driver!"); | 348 | MODULE_DESCRIPTION("w90p910 touch screen driver!"); |
349 | MODULE_LICENSE("GPL"); | 349 | MODULE_LICENSE("GPL"); |
350 | MODULE_ALIAS("platform:w90p910-ts"); | 350 | MODULE_ALIAS("platform:nuc900-ts"); |
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index ec5169604a6a..2d91049571a4 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -294,32 +294,33 @@ struct reply_t gigaset_tab_cid[] = | |||
294 | {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}}, | 294 | {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}}, |
295 | {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, | 295 | {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, |
296 | {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, | 296 | {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, |
297 | {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, /* set "Endgeraetemodus" */ | 297 | {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, |
298 | {RSP_OK, 607,607, -1, 608,-1}, | 298 | {RSP_OK, 607,607, -1, 608,-1}, |
299 | //{RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 608, 0, {ACT_ERROR}},//DELETE | ||
300 | {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}}, | 299 | {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}}, |
301 | {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}}, | 300 | {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}}, |
302 | 301 | ||
303 | {RSP_ZVLS, 608,608, 17, -1,-1, {ACT_DEBUG}}, | ||
304 | {RSP_ZCTP, 609,609, -1, -1,-1, {ACT_DEBUG}}, | ||
305 | {RSP_ZCPN, 609,609, -1, -1,-1, {ACT_DEBUG}}, | ||
306 | {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, | 302 | {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, |
307 | {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, | 303 | {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, |
308 | 304 | ||
309 | /* dialing */ | 305 | /* optional dialing responses */ |
310 | {RSP_ZCTP, 650,650, -1, -1,-1, {ACT_DEBUG}}, | 306 | {EV_BC_OPEN, 650,650, -1, 651,-1}, |
311 | {RSP_ZCPN, 650,650, -1, -1,-1, {ACT_DEBUG}}, | 307 | {RSP_ZVLS, 608,651, 17, -1,-1, {ACT_DEBUG}}, |
312 | {RSP_ZSAU, 650,650,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* some devices don't send this */ | 308 | {RSP_ZCTP, 609,651, -1, -1,-1, {ACT_DEBUG}}, |
313 | 309 | {RSP_ZCPN, 609,651, -1, -1,-1, {ACT_DEBUG}}, | |
314 | /* connection established */ | 310 | {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, |
315 | {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1 | 311 | |
316 | {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1 | 312 | /* connect */ |
317 | 313 | {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, | |
318 | {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}}, //FIXME new constate + timeout | 314 | {RSP_ZSAU, 651,651,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT, |
315 | ACT_NOTIFY_BC_UP}}, | ||
316 | {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, | ||
317 | {RSP_ZSAU, 751,751,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT, | ||
318 | ACT_NOTIFY_BC_UP}}, | ||
319 | {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}}, | ||
319 | 320 | ||
320 | /* remote hangup */ | 321 | /* remote hangup */ |
321 | {RSP_ZSAU, 650,650,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}}, | 322 | {RSP_ZSAU, 650,651,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}}, |
322 | {RSP_ZSAU, 750,750,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, | 323 | {RSP_ZSAU, 750,751,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, |
323 | {RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, | 324 | {RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, |
324 | 325 | ||
325 | /* hangup */ | 326 | /* hangup */ |
@@ -358,7 +359,8 @@ struct reply_t gigaset_tab_cid[] = | |||
358 | {RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}}, | 359 | {RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}}, |
359 | {RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}}, | 360 | {RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}}, |
360 | 361 | ||
361 | {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, | 362 | {EV_BC_OPEN, 750,750, -1, 751,-1}, |
363 | {EV_TIMEOUT, 750,751, -1, 0, 0, {ACT_CONNTIMEOUT}}, | ||
362 | 364 | ||
363 | /* B channel closed (general case) */ | 365 | /* B channel closed (general case) */ |
364 | {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME | 366 | {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME |
@@ -876,12 +878,6 @@ static void bchannel_down(struct bc_state *bcs) | |||
876 | 878 | ||
877 | static void bchannel_up(struct bc_state *bcs) | 879 | static void bchannel_up(struct bc_state *bcs) |
878 | { | 880 | { |
879 | if (!(bcs->chstate & CHS_D_UP)) { | ||
880 | dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__); | ||
881 | bcs->chstate |= CHS_D_UP; | ||
882 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | ||
883 | } | ||
884 | |||
885 | if (bcs->chstate & CHS_B_UP) { | 881 | if (bcs->chstate & CHS_B_UP) { |
886 | dev_notice(bcs->cs->dev, "%s: B channel already up\n", | 882 | dev_notice(bcs->cs->dev, "%s: B channel already up\n", |
887 | __func__); | 883 | __func__); |
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index db3a1e4cd489..bed38fcc432b 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -174,12 +174,6 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
174 | pr_err("invalid size %d\n", size); | 174 | pr_err("invalid size %d\n", size); |
175 | return -EINVAL; | 175 | return -EINVAL; |
176 | } | 176 | } |
177 | src = iwb->read; | ||
178 | if (unlikely(limit >= BAS_OUTBUFSIZE + BAS_OUTBUFPAD || | ||
179 | (read < src && limit >= src))) { | ||
180 | pr_err("isoc write buffer frame reservation violated\n"); | ||
181 | return -EFAULT; | ||
182 | } | ||
183 | #endif | 177 | #endif |
184 | 178 | ||
185 | if (read < write) { | 179 | if (read < write) { |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 9b60b6b684d9..7c8e7122aaa9 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -75,6 +75,7 @@ config LEDS_ALIX2 | |||
75 | depends on LEDS_CLASS && X86 && EXPERIMENTAL | 75 | depends on LEDS_CLASS && X86 && EXPERIMENTAL |
76 | help | 76 | help |
77 | This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. | 77 | This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. |
78 | You have to set leds-alix2.force=1 for boards with Award BIOS. | ||
78 | 79 | ||
79 | config LEDS_H1940 | 80 | config LEDS_H1940 |
80 | tristate "LED Support for iPAQ H1940 device" | 81 | tristate "LED Support for iPAQ H1940 device" |
@@ -145,15 +146,16 @@ config LEDS_GPIO_OF | |||
145 | of_platform devices. For instance, LEDs which are listed in a "dts" | 146 | of_platform devices. For instance, LEDs which are listed in a "dts" |
146 | file. | 147 | file. |
147 | 148 | ||
148 | config LEDS_LP5521 | 149 | config LEDS_LP3944 |
149 | tristate "LED Support for the LP5521 LEDs" | 150 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" |
150 | depends on LEDS_CLASS && I2C | 151 | depends on LEDS_CLASS && I2C |
151 | help | 152 | help |
152 | If you say 'Y' here you get support for the National Semiconductor | 153 | This option enables support for LEDs connected to the National |
153 | LP5521 LED driver used in n8x0 boards. | 154 | Semiconductor LP3944 Lighting Management Unit (LMU) also known as |
155 | Fun Light Chip. | ||
154 | 156 | ||
155 | This driver can be built as a module by choosing 'M'. The module | 157 | To compile this driver as a module, choose M here: the |
156 | will be called leds-lp5521. | 158 | module will be called leds-lp3944. |
157 | 159 | ||
158 | config LEDS_CLEVO_MAIL | 160 | config LEDS_CLEVO_MAIL |
159 | tristate "Mail LED on Clevo notebook" | 161 | tristate "Mail LED on Clevo notebook" |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 2d41c4dcf92f..e8cdcf77a4c3 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o | |||
20 | obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o | 20 | obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o |
21 | obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o | 21 | obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o |
22 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o | 22 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o |
23 | obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o | ||
23 | obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o | 24 | obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o |
24 | obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o | 25 | obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o |
25 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o | 26 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o |
diff --git a/drivers/leds/leds-alix2.c b/drivers/leds/leds-alix2.c index ddbd7730dfc8..731d4eef3425 100644 --- a/drivers/leds/leds-alix2.c +++ b/drivers/leds/leds-alix2.c | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | static int force = 0; | 15 | static int force = 0; |
16 | module_param(force, bool, 0444); | 16 | module_param(force, bool, 0444); |
17 | MODULE_PARM_DESC(force, "Assume system has ALIX.2 style LEDs"); | 17 | MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs"); |
18 | 18 | ||
19 | struct alix_led { | 19 | struct alix_led { |
20 | struct led_classdev cdev; | 20 | struct led_classdev cdev; |
@@ -155,6 +155,11 @@ static int __init alix_led_init(void) | |||
155 | goto out; | 155 | goto out; |
156 | } | 156 | } |
157 | 157 | ||
158 | /* enable output on GPIO for LED 1,2,3 */ | ||
159 | outl(1 << 6, 0x6104); | ||
160 | outl(1 << 9, 0x6184); | ||
161 | outl(1 << 11, 0x6184); | ||
162 | |||
158 | pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); | 163 | pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); |
159 | if (!IS_ERR(pdev)) { | 164 | if (!IS_ERR(pdev)) { |
160 | ret = platform_driver_probe(&alix_led_driver, alix_led_probe); | 165 | ret = platform_driver_probe(&alix_led_driver, alix_led_probe); |
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c index 4149ecb3a9b2..779d7f262c04 100644 --- a/drivers/leds/leds-bd2802.c +++ b/drivers/leds/leds-bd2802.c | |||
@@ -97,6 +97,10 @@ struct bd2802_led { | |||
97 | enum led_ids led_id; | 97 | enum led_ids led_id; |
98 | enum led_colors color; | 98 | enum led_colors color; |
99 | enum led_bits state; | 99 | enum led_bits state; |
100 | |||
101 | /* General attributes of RGB LEDs */ | ||
102 | int wave_pattern; | ||
103 | int rgb_current; | ||
100 | }; | 104 | }; |
101 | 105 | ||
102 | 106 | ||
@@ -254,7 +258,7 @@ static void bd2802_set_on(struct bd2802_led *led, enum led_ids id, | |||
254 | bd2802_reset_cancel(led); | 258 | bd2802_reset_cancel(led); |
255 | 259 | ||
256 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); | 260 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); |
257 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); | 261 | bd2802_write_byte(led->client, reg, led->rgb_current); |
258 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); | 262 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); |
259 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); | 263 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); |
260 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); | 264 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); |
@@ -275,9 +279,9 @@ static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id, | |||
275 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); | 279 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); |
276 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); | 280 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); |
277 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); | 281 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); |
278 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); | 282 | bd2802_write_byte(led->client, reg, led->rgb_current); |
279 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); | 283 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); |
280 | bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF); | 284 | bd2802_write_byte(led->client, reg, led->wave_pattern); |
281 | 285 | ||
282 | bd2802_enable(led, id); | 286 | bd2802_enable(led, id); |
283 | bd2802_update_state(led, id, color, BD2802_BLINK); | 287 | bd2802_update_state(led, id, color, BD2802_BLINK); |
@@ -406,7 +410,7 @@ static void bd2802_enable_adv_conf(struct bd2802_led *led) | |||
406 | ret = device_create_file(&led->client->dev, | 410 | ret = device_create_file(&led->client->dev, |
407 | bd2802_addr_attributes[i]); | 411 | bd2802_addr_attributes[i]); |
408 | if (ret) { | 412 | if (ret) { |
409 | dev_err(&led->client->dev, "failed to sysfs file %s\n", | 413 | dev_err(&led->client->dev, "failed: sysfs file %s\n", |
410 | bd2802_addr_attributes[i]->attr.name); | 414 | bd2802_addr_attributes[i]->attr.name); |
411 | goto failed_remove_files; | 415 | goto failed_remove_files; |
412 | } | 416 | } |
@@ -483,6 +487,52 @@ static struct device_attribute bd2802_adv_conf_attr = { | |||
483 | .store = bd2802_store_adv_conf, | 487 | .store = bd2802_store_adv_conf, |
484 | }; | 488 | }; |
485 | 489 | ||
490 | #define BD2802_CONTROL_ATTR(attr_name, name_str) \ | ||
491 | static ssize_t bd2802_show_##attr_name(struct device *dev, \ | ||
492 | struct device_attribute *attr, char *buf) \ | ||
493 | { \ | ||
494 | struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ | ||
495 | ssize_t ret; \ | ||
496 | down_read(&led->rwsem); \ | ||
497 | ret = sprintf(buf, "0x%02x\n", led->attr_name); \ | ||
498 | up_read(&led->rwsem); \ | ||
499 | return ret; \ | ||
500 | } \ | ||
501 | static ssize_t bd2802_store_##attr_name(struct device *dev, \ | ||
502 | struct device_attribute *attr, const char *buf, size_t count) \ | ||
503 | { \ | ||
504 | struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ | ||
505 | unsigned long val; \ | ||
506 | int ret; \ | ||
507 | if (!count) \ | ||
508 | return -EINVAL; \ | ||
509 | ret = strict_strtoul(buf, 16, &val); \ | ||
510 | if (ret) \ | ||
511 | return ret; \ | ||
512 | down_write(&led->rwsem); \ | ||
513 | led->attr_name = val; \ | ||
514 | up_write(&led->rwsem); \ | ||
515 | return count; \ | ||
516 | } \ | ||
517 | static struct device_attribute bd2802_##attr_name##_attr = { \ | ||
518 | .attr = { \ | ||
519 | .name = name_str, \ | ||
520 | .mode = 0644, \ | ||
521 | .owner = THIS_MODULE \ | ||
522 | }, \ | ||
523 | .show = bd2802_show_##attr_name, \ | ||
524 | .store = bd2802_store_##attr_name, \ | ||
525 | }; | ||
526 | |||
527 | BD2802_CONTROL_ATTR(wave_pattern, "wave_pattern"); | ||
528 | BD2802_CONTROL_ATTR(rgb_current, "rgb_current"); | ||
529 | |||
530 | static struct device_attribute *bd2802_attributes[] = { | ||
531 | &bd2802_adv_conf_attr, | ||
532 | &bd2802_wave_pattern_attr, | ||
533 | &bd2802_rgb_current_attr, | ||
534 | }; | ||
535 | |||
486 | static void bd2802_led_work(struct work_struct *work) | 536 | static void bd2802_led_work(struct work_struct *work) |
487 | { | 537 | { |
488 | struct bd2802_led *led = container_of(work, struct bd2802_led, work); | 538 | struct bd2802_led *led = container_of(work, struct bd2802_led, work); |
@@ -538,7 +588,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
538 | led->cdev_led1r.brightness = LED_OFF; | 588 | led->cdev_led1r.brightness = LED_OFF; |
539 | led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; | 589 | led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; |
540 | led->cdev_led1r.blink_set = bd2802_set_led1r_blink; | 590 | led->cdev_led1r.blink_set = bd2802_set_led1r_blink; |
541 | led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME; | ||
542 | 591 | ||
543 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); | 592 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); |
544 | if (ret < 0) { | 593 | if (ret < 0) { |
@@ -551,7 +600,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
551 | led->cdev_led1g.brightness = LED_OFF; | 600 | led->cdev_led1g.brightness = LED_OFF; |
552 | led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; | 601 | led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; |
553 | led->cdev_led1g.blink_set = bd2802_set_led1g_blink; | 602 | led->cdev_led1g.blink_set = bd2802_set_led1g_blink; |
554 | led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME; | ||
555 | 603 | ||
556 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); | 604 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); |
557 | if (ret < 0) { | 605 | if (ret < 0) { |
@@ -564,7 +612,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
564 | led->cdev_led1b.brightness = LED_OFF; | 612 | led->cdev_led1b.brightness = LED_OFF; |
565 | led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; | 613 | led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; |
566 | led->cdev_led1b.blink_set = bd2802_set_led1b_blink; | 614 | led->cdev_led1b.blink_set = bd2802_set_led1b_blink; |
567 | led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME; | ||
568 | 615 | ||
569 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); | 616 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); |
570 | if (ret < 0) { | 617 | if (ret < 0) { |
@@ -577,7 +624,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
577 | led->cdev_led2r.brightness = LED_OFF; | 624 | led->cdev_led2r.brightness = LED_OFF; |
578 | led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; | 625 | led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; |
579 | led->cdev_led2r.blink_set = bd2802_set_led2r_blink; | 626 | led->cdev_led2r.blink_set = bd2802_set_led2r_blink; |
580 | led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME; | ||
581 | 627 | ||
582 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); | 628 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); |
583 | if (ret < 0) { | 629 | if (ret < 0) { |
@@ -590,7 +636,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
590 | led->cdev_led2g.brightness = LED_OFF; | 636 | led->cdev_led2g.brightness = LED_OFF; |
591 | led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; | 637 | led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; |
592 | led->cdev_led2g.blink_set = bd2802_set_led2g_blink; | 638 | led->cdev_led2g.blink_set = bd2802_set_led2g_blink; |
593 | led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME; | ||
594 | 639 | ||
595 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); | 640 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); |
596 | if (ret < 0) { | 641 | if (ret < 0) { |
@@ -640,7 +685,7 @@ static int __devinit bd2802_probe(struct i2c_client *client, | |||
640 | { | 685 | { |
641 | struct bd2802_led *led; | 686 | struct bd2802_led *led; |
642 | struct bd2802_led_platform_data *pdata; | 687 | struct bd2802_led_platform_data *pdata; |
643 | int ret; | 688 | int ret, i; |
644 | 689 | ||
645 | led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL); | 690 | led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL); |
646 | if (!led) { | 691 | if (!led) { |
@@ -670,13 +715,20 @@ static int __devinit bd2802_probe(struct i2c_client *client, | |||
670 | /* To save the power, reset BD2802 after detecting */ | 715 | /* To save the power, reset BD2802 after detecting */ |
671 | gpio_set_value(led->pdata->reset_gpio, 0); | 716 | gpio_set_value(led->pdata->reset_gpio, 0); |
672 | 717 | ||
718 | /* Default attributes */ | ||
719 | led->wave_pattern = BD2802_PATTERN_HALF; | ||
720 | led->rgb_current = BD2802_CURRENT_032; | ||
721 | |||
673 | init_rwsem(&led->rwsem); | 722 | init_rwsem(&led->rwsem); |
674 | 723 | ||
675 | ret = device_create_file(&client->dev, &bd2802_adv_conf_attr); | 724 | for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) { |
676 | if (ret) { | 725 | ret = device_create_file(&led->client->dev, |
677 | dev_err(&client->dev, "failed to create sysfs file %s\n", | 726 | bd2802_attributes[i]); |
678 | bd2802_adv_conf_attr.attr.name); | 727 | if (ret) { |
679 | goto failed_free; | 728 | dev_err(&led->client->dev, "failed: sysfs file %s\n", |
729 | bd2802_attributes[i]->attr.name); | ||
730 | goto failed_unregister_dev_file; | ||
731 | } | ||
680 | } | 732 | } |
681 | 733 | ||
682 | ret = bd2802_register_led_classdev(led); | 734 | ret = bd2802_register_led_classdev(led); |
@@ -686,7 +738,8 @@ static int __devinit bd2802_probe(struct i2c_client *client, | |||
686 | return 0; | 738 | return 0; |
687 | 739 | ||
688 | failed_unregister_dev_file: | 740 | failed_unregister_dev_file: |
689 | device_remove_file(&client->dev, &bd2802_adv_conf_attr); | 741 | for (i--; i >= 0; i--) |
742 | device_remove_file(&led->client->dev, bd2802_attributes[i]); | ||
690 | failed_free: | 743 | failed_free: |
691 | i2c_set_clientdata(client, NULL); | 744 | i2c_set_clientdata(client, NULL); |
692 | kfree(led); | 745 | kfree(led); |
@@ -697,12 +750,14 @@ failed_free: | |||
697 | static int __exit bd2802_remove(struct i2c_client *client) | 750 | static int __exit bd2802_remove(struct i2c_client *client) |
698 | { | 751 | { |
699 | struct bd2802_led *led = i2c_get_clientdata(client); | 752 | struct bd2802_led *led = i2c_get_clientdata(client); |
753 | int i; | ||
700 | 754 | ||
701 | bd2802_unregister_led_classdev(led); | ||
702 | gpio_set_value(led->pdata->reset_gpio, 0); | 755 | gpio_set_value(led->pdata->reset_gpio, 0); |
756 | bd2802_unregister_led_classdev(led); | ||
703 | if (led->adf_on) | 757 | if (led->adf_on) |
704 | bd2802_disable_adv_conf(led); | 758 | bd2802_disable_adv_conf(led); |
705 | device_remove_file(&client->dev, &bd2802_adv_conf_attr); | 759 | for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) |
760 | device_remove_file(&led->client->dev, bd2802_attributes[i]); | ||
706 | i2c_set_clientdata(client, NULL); | 761 | i2c_set_clientdata(client, NULL); |
707 | kfree(led); | 762 | kfree(led); |
708 | 763 | ||
@@ -723,8 +778,7 @@ static int bd2802_resume(struct i2c_client *client) | |||
723 | struct bd2802_led *led = i2c_get_clientdata(client); | 778 | struct bd2802_led *led = i2c_get_clientdata(client); |
724 | 779 | ||
725 | if (!bd2802_is_all_off(led) || led->adf_on) { | 780 | if (!bd2802_is_all_off(led) || led->adf_on) { |
726 | gpio_set_value(led->pdata->reset_gpio, 1); | 781 | bd2802_reset_cancel(led); |
727 | udelay(100); | ||
728 | bd2802_restore_state(led); | 782 | bd2802_restore_state(led); |
729 | } | 783 | } |
730 | 784 | ||
@@ -762,4 +816,4 @@ module_exit(bd2802_exit); | |||
762 | 816 | ||
763 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); | 817 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); |
764 | MODULE_DESCRIPTION("BD2802 LED driver"); | 818 | MODULE_DESCRIPTION("BD2802 LED driver"); |
765 | MODULE_LICENSE("GPL"); | 819 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c index ff0e8c3fbf9b..5f1ce810815f 100644 --- a/drivers/leds/leds-cobalt-raq.c +++ b/drivers/leds/leds-cobalt-raq.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * LEDs driver for the Cobalt Raq series. | 2 | * LEDs driver for the Cobalt Raq series. |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index d2109054de85..6b06638eb5b4 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -76,7 +76,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
76 | struct gpio_led_data *led_dat, struct device *parent, | 76 | struct gpio_led_data *led_dat, struct device *parent, |
77 | int (*blink_set)(unsigned, unsigned long *, unsigned long *)) | 77 | int (*blink_set)(unsigned, unsigned long *, unsigned long *)) |
78 | { | 78 | { |
79 | int ret; | 79 | int ret, state; |
80 | 80 | ||
81 | /* skip leds that aren't available */ | 81 | /* skip leds that aren't available */ |
82 | if (!gpio_is_valid(template->gpio)) { | 82 | if (!gpio_is_valid(template->gpio)) { |
@@ -99,11 +99,15 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
99 | led_dat->cdev.blink_set = gpio_blink_set; | 99 | led_dat->cdev.blink_set = gpio_blink_set; |
100 | } | 100 | } |
101 | led_dat->cdev.brightness_set = gpio_led_set; | 101 | led_dat->cdev.brightness_set = gpio_led_set; |
102 | led_dat->cdev.brightness = LED_OFF; | 102 | if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) |
103 | state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low; | ||
104 | else | ||
105 | state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); | ||
106 | led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; | ||
103 | if (!template->retain_state_suspended) | 107 | if (!template->retain_state_suspended) |
104 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | 108 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; |
105 | 109 | ||
106 | ret = gpio_direction_output(led_dat->gpio, led_dat->active_low); | 110 | ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); |
107 | if (ret < 0) | 111 | if (ret < 0) |
108 | goto err; | 112 | goto err; |
109 | 113 | ||
@@ -129,7 +133,7 @@ static void delete_gpio_led(struct gpio_led_data *led) | |||
129 | } | 133 | } |
130 | 134 | ||
131 | #ifdef CONFIG_LEDS_GPIO_PLATFORM | 135 | #ifdef CONFIG_LEDS_GPIO_PLATFORM |
132 | static int gpio_led_probe(struct platform_device *pdev) | 136 | static int __devinit gpio_led_probe(struct platform_device *pdev) |
133 | { | 137 | { |
134 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; | 138 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; |
135 | struct gpio_led_data *leds_data; | 139 | struct gpio_led_data *leds_data; |
@@ -223,12 +227,22 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, | |||
223 | memset(&led, 0, sizeof(led)); | 227 | memset(&led, 0, sizeof(led)); |
224 | for_each_child_of_node(np, child) { | 228 | for_each_child_of_node(np, child) { |
225 | enum of_gpio_flags flags; | 229 | enum of_gpio_flags flags; |
230 | const char *state; | ||
226 | 231 | ||
227 | led.gpio = of_get_gpio_flags(child, 0, &flags); | 232 | led.gpio = of_get_gpio_flags(child, 0, &flags); |
228 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; | 233 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; |
229 | led.name = of_get_property(child, "label", NULL) ? : child->name; | 234 | led.name = of_get_property(child, "label", NULL) ? : child->name; |
230 | led.default_trigger = | 235 | led.default_trigger = |
231 | of_get_property(child, "linux,default-trigger", NULL); | 236 | of_get_property(child, "linux,default-trigger", NULL); |
237 | state = of_get_property(child, "default-state", NULL); | ||
238 | if (state) { | ||
239 | if (!strcmp(state, "keep")) | ||
240 | led.default_state = LEDS_GPIO_DEFSTATE_KEEP; | ||
241 | else if(!strcmp(state, "on")) | ||
242 | led.default_state = LEDS_GPIO_DEFSTATE_ON; | ||
243 | else | ||
244 | led.default_state = LEDS_GPIO_DEFSTATE_OFF; | ||
245 | } | ||
232 | 246 | ||
233 | ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++], | 247 | ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++], |
234 | &ofdev->dev, NULL); | 248 | &ofdev->dev, NULL); |
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c new file mode 100644 index 000000000000..5946208ba26e --- /dev/null +++ b/drivers/leds/leds-lp3944.c | |||
@@ -0,0 +1,466 @@ | |||
1 | /* | ||
2 | * leds-lp3944.c - driver for National Semiconductor LP3944 Funlight Chip | ||
3 | * | ||
4 | * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * I2C driver for National Semiconductor LP3944 Funlight Chip | ||
14 | * http://www.national.com/pf/LP/LP3944.html | ||
15 | * | ||
16 | * This helper chip can drive up to 8 leds, with two programmable DIM modes; | ||
17 | * it could even be used as a gpio expander but this driver assumes it is used | ||
18 | * as a led controller. | ||
19 | * | ||
20 | * The DIM modes are used to set _blink_ patterns for leds, the pattern is | ||
21 | * specified supplying two parameters: | ||
22 | * - period: from 0s to 1.6s | ||
23 | * - duty cycle: percentage of the period the led is on, from 0 to 100 | ||
24 | * | ||
25 | * LP3944 can be found on Motorola A910 smartphone, where it drives the rgb | ||
26 | * leds, the camera flash light and the displays backlights. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <linux/leds.h> | ||
32 | #include <linux/mutex.h> | ||
33 | #include <linux/workqueue.h> | ||
34 | #include <linux/leds-lp3944.h> | ||
35 | |||
36 | /* Read Only Registers */ | ||
37 | #define LP3944_REG_INPUT1 0x00 /* LEDs 0-7 InputRegister (Read Only) */ | ||
38 | #define LP3944_REG_REGISTER1 0x01 /* None (Read Only) */ | ||
39 | |||
40 | #define LP3944_REG_PSC0 0x02 /* Frequency Prescaler 0 (R/W) */ | ||
41 | #define LP3944_REG_PWM0 0x03 /* PWM Register 0 (R/W) */ | ||
42 | #define LP3944_REG_PSC1 0x04 /* Frequency Prescaler 1 (R/W) */ | ||
43 | #define LP3944_REG_PWM1 0x05 /* PWM Register 1 (R/W) */ | ||
44 | #define LP3944_REG_LS0 0x06 /* LEDs 0-3 Selector (R/W) */ | ||
45 | #define LP3944_REG_LS1 0x07 /* LEDs 4-7 Selector (R/W) */ | ||
46 | |||
47 | /* These registers are not used to control leds in LP3944, they can store | ||
48 | * arbitrary values which the chip will ignore. | ||
49 | */ | ||
50 | #define LP3944_REG_REGISTER8 0x08 | ||
51 | #define LP3944_REG_REGISTER9 0x09 | ||
52 | |||
53 | #define LP3944_DIM0 0 | ||
54 | #define LP3944_DIM1 1 | ||
55 | |||
56 | /* period in ms */ | ||
57 | #define LP3944_PERIOD_MIN 0 | ||
58 | #define LP3944_PERIOD_MAX 1600 | ||
59 | |||
60 | /* duty cycle is a percentage */ | ||
61 | #define LP3944_DUTY_CYCLE_MIN 0 | ||
62 | #define LP3944_DUTY_CYCLE_MAX 100 | ||
63 | |||
64 | #define ldev_to_led(c) container_of(c, struct lp3944_led_data, ldev) | ||
65 | |||
66 | /* Saved data */ | ||
67 | struct lp3944_led_data { | ||
68 | u8 id; | ||
69 | enum lp3944_type type; | ||
70 | enum lp3944_status status; | ||
71 | struct led_classdev ldev; | ||
72 | struct i2c_client *client; | ||
73 | struct work_struct work; | ||
74 | }; | ||
75 | |||
76 | struct lp3944_data { | ||
77 | struct mutex lock; | ||
78 | struct i2c_client *client; | ||
79 | struct lp3944_led_data leds[LP3944_LEDS_MAX]; | ||
80 | }; | ||
81 | |||
82 | static int lp3944_reg_read(struct i2c_client *client, u8 reg, u8 *value) | ||
83 | { | ||
84 | int tmp; | ||
85 | |||
86 | tmp = i2c_smbus_read_byte_data(client, reg); | ||
87 | if (tmp < 0) | ||
88 | return -EINVAL; | ||
89 | |||
90 | *value = tmp; | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int lp3944_reg_write(struct i2c_client *client, u8 reg, u8 value) | ||
96 | { | ||
97 | return i2c_smbus_write_byte_data(client, reg, value); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * Set the period for DIM status | ||
102 | * | ||
103 | * @client: the i2c client | ||
104 | * @dim: either LP3944_DIM0 or LP3944_DIM1 | ||
105 | * @period: period of a blink, that is a on/off cycle, expressed in ms. | ||
106 | */ | ||
107 | static int lp3944_dim_set_period(struct i2c_client *client, u8 dim, u16 period) | ||
108 | { | ||
109 | u8 psc_reg; | ||
110 | u8 psc_value; | ||
111 | int err; | ||
112 | |||
113 | if (dim == LP3944_DIM0) | ||
114 | psc_reg = LP3944_REG_PSC0; | ||
115 | else if (dim == LP3944_DIM1) | ||
116 | psc_reg = LP3944_REG_PSC1; | ||
117 | else | ||
118 | return -EINVAL; | ||
119 | |||
120 | /* Convert period to Prescaler value */ | ||
121 | if (period > LP3944_PERIOD_MAX) | ||
122 | return -EINVAL; | ||
123 | |||
124 | psc_value = (period * 255) / LP3944_PERIOD_MAX; | ||
125 | |||
126 | err = lp3944_reg_write(client, psc_reg, psc_value); | ||
127 | |||
128 | return err; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Set the duty cycle for DIM status | ||
133 | * | ||
134 | * @client: the i2c client | ||
135 | * @dim: either LP3944_DIM0 or LP3944_DIM1 | ||
136 | * @duty_cycle: percentage of a period during which a led is ON | ||
137 | */ | ||
138 | static int lp3944_dim_set_dutycycle(struct i2c_client *client, u8 dim, | ||
139 | u8 duty_cycle) | ||
140 | { | ||
141 | u8 pwm_reg; | ||
142 | u8 pwm_value; | ||
143 | int err; | ||
144 | |||
145 | if (dim == LP3944_DIM0) | ||
146 | pwm_reg = LP3944_REG_PWM0; | ||
147 | else if (dim == LP3944_DIM1) | ||
148 | pwm_reg = LP3944_REG_PWM1; | ||
149 | else | ||
150 | return -EINVAL; | ||
151 | |||
152 | /* Convert duty cycle to PWM value */ | ||
153 | if (duty_cycle > LP3944_DUTY_CYCLE_MAX) | ||
154 | return -EINVAL; | ||
155 | |||
156 | pwm_value = (duty_cycle * 255) / LP3944_DUTY_CYCLE_MAX; | ||
157 | |||
158 | err = lp3944_reg_write(client, pwm_reg, pwm_value); | ||
159 | |||
160 | return err; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Set the led status | ||
165 | * | ||
166 | * @led: a lp3944_led_data structure | ||
167 | * @status: one of LP3944_LED_STATUS_OFF | ||
168 | * LP3944_LED_STATUS_ON | ||
169 | * LP3944_LED_STATUS_DIM0 | ||
170 | * LP3944_LED_STATUS_DIM1 | ||
171 | */ | ||
172 | static int lp3944_led_set(struct lp3944_led_data *led, u8 status) | ||
173 | { | ||
174 | struct lp3944_data *data = i2c_get_clientdata(led->client); | ||
175 | u8 id = led->id; | ||
176 | u8 reg; | ||
177 | u8 val = 0; | ||
178 | int err; | ||
179 | |||
180 | dev_dbg(&led->client->dev, "%s: %s, status before normalization:%d\n", | ||
181 | __func__, led->ldev.name, status); | ||
182 | |||
183 | switch (id) { | ||
184 | case LP3944_LED0: | ||
185 | case LP3944_LED1: | ||
186 | case LP3944_LED2: | ||
187 | case LP3944_LED3: | ||
188 | reg = LP3944_REG_LS0; | ||
189 | break; | ||
190 | case LP3944_LED4: | ||
191 | case LP3944_LED5: | ||
192 | case LP3944_LED6: | ||
193 | case LP3944_LED7: | ||
194 | id -= LP3944_LED4; | ||
195 | reg = LP3944_REG_LS1; | ||
196 | break; | ||
197 | default: | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | if (status > LP3944_LED_STATUS_DIM1) | ||
202 | return -EINVAL; | ||
203 | |||
204 | /* invert only 0 and 1, leave unchanged the other values, | ||
205 | * remember we are abusing status to set blink patterns | ||
206 | */ | ||
207 | if (led->type == LP3944_LED_TYPE_LED_INVERTED && status < 2) | ||
208 | status = 1 - status; | ||
209 | |||
210 | mutex_lock(&data->lock); | ||
211 | lp3944_reg_read(led->client, reg, &val); | ||
212 | |||
213 | val &= ~(LP3944_LED_STATUS_MASK << (id << 1)); | ||
214 | val |= (status << (id << 1)); | ||
215 | |||
216 | dev_dbg(&led->client->dev, "%s: %s, reg:%d id:%d status:%d val:%#x\n", | ||
217 | __func__, led->ldev.name, reg, id, status, val); | ||
218 | |||
219 | /* set led status */ | ||
220 | err = lp3944_reg_write(led->client, reg, val); | ||
221 | mutex_unlock(&data->lock); | ||
222 | |||
223 | return err; | ||
224 | } | ||
225 | |||
226 | static int lp3944_led_set_blink(struct led_classdev *led_cdev, | ||
227 | unsigned long *delay_on, | ||
228 | unsigned long *delay_off) | ||
229 | { | ||
230 | struct lp3944_led_data *led = ldev_to_led(led_cdev); | ||
231 | u16 period; | ||
232 | u8 duty_cycle; | ||
233 | int err; | ||
234 | |||
235 | /* units are in ms */ | ||
236 | if (*delay_on + *delay_off > LP3944_PERIOD_MAX) | ||
237 | return -EINVAL; | ||
238 | |||
239 | if (*delay_on == 0 && *delay_off == 0) { | ||
240 | /* Special case: the leds subsystem requires a default user | ||
241 | * friendly blink pattern for the LED. Let's blink the led | ||
242 | * slowly (1Hz). | ||
243 | */ | ||
244 | *delay_on = 500; | ||
245 | *delay_off = 500; | ||
246 | } | ||
247 | |||
248 | period = (*delay_on) + (*delay_off); | ||
249 | |||
250 | /* duty_cycle is the percentage of period during which the led is ON */ | ||
251 | duty_cycle = 100 * (*delay_on) / period; | ||
252 | |||
253 | /* invert duty cycle for inverted leds, this has the same effect of | ||
254 | * swapping delay_on and delay_off | ||
255 | */ | ||
256 | if (led->type == LP3944_LED_TYPE_LED_INVERTED) | ||
257 | duty_cycle = 100 - duty_cycle; | ||
258 | |||
259 | /* NOTE: using always the first DIM mode, this means that all leds | ||
260 | * will have the same blinking pattern. | ||
261 | * | ||
262 | * We could find a way later to have two leds blinking in hardware | ||
263 | * with different patterns at the same time, falling back to software | ||
264 | * control for the other ones. | ||
265 | */ | ||
266 | err = lp3944_dim_set_period(led->client, LP3944_DIM0, period); | ||
267 | if (err) | ||
268 | return err; | ||
269 | |||
270 | err = lp3944_dim_set_dutycycle(led->client, LP3944_DIM0, duty_cycle); | ||
271 | if (err) | ||
272 | return err; | ||
273 | |||
274 | dev_dbg(&led->client->dev, "%s: OK hardware accelerated blink!\n", | ||
275 | __func__); | ||
276 | |||
277 | led->status = LP3944_LED_STATUS_DIM0; | ||
278 | schedule_work(&led->work); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static void lp3944_led_set_brightness(struct led_classdev *led_cdev, | ||
284 | enum led_brightness brightness) | ||
285 | { | ||
286 | struct lp3944_led_data *led = ldev_to_led(led_cdev); | ||
287 | |||
288 | dev_dbg(&led->client->dev, "%s: %s, %d\n", | ||
289 | __func__, led_cdev->name, brightness); | ||
290 | |||
291 | led->status = brightness; | ||
292 | schedule_work(&led->work); | ||
293 | } | ||
294 | |||
295 | static void lp3944_led_work(struct work_struct *work) | ||
296 | { | ||
297 | struct lp3944_led_data *led; | ||
298 | |||
299 | led = container_of(work, struct lp3944_led_data, work); | ||
300 | lp3944_led_set(led, led->status); | ||
301 | } | ||
302 | |||
303 | static int lp3944_configure(struct i2c_client *client, | ||
304 | struct lp3944_data *data, | ||
305 | struct lp3944_platform_data *pdata) | ||
306 | { | ||
307 | int i, err = 0; | ||
308 | |||
309 | for (i = 0; i < pdata->leds_size; i++) { | ||
310 | struct lp3944_led *pled = &pdata->leds[i]; | ||
311 | struct lp3944_led_data *led = &data->leds[i]; | ||
312 | led->client = client; | ||
313 | led->id = i; | ||
314 | |||
315 | switch (pled->type) { | ||
316 | |||
317 | case LP3944_LED_TYPE_LED: | ||
318 | case LP3944_LED_TYPE_LED_INVERTED: | ||
319 | led->type = pled->type; | ||
320 | led->status = pled->status; | ||
321 | led->ldev.name = pled->name; | ||
322 | led->ldev.max_brightness = 1; | ||
323 | led->ldev.brightness_set = lp3944_led_set_brightness; | ||
324 | led->ldev.blink_set = lp3944_led_set_blink; | ||
325 | led->ldev.flags = LED_CORE_SUSPENDRESUME; | ||
326 | |||
327 | INIT_WORK(&led->work, lp3944_led_work); | ||
328 | err = led_classdev_register(&client->dev, &led->ldev); | ||
329 | if (err < 0) { | ||
330 | dev_err(&client->dev, | ||
331 | "couldn't register LED %s\n", | ||
332 | led->ldev.name); | ||
333 | goto exit; | ||
334 | } | ||
335 | |||
336 | /* to expose the default value to userspace */ | ||
337 | led->ldev.brightness = led->status; | ||
338 | |||
339 | /* Set the default led status */ | ||
340 | err = lp3944_led_set(led, led->status); | ||
341 | if (err < 0) { | ||
342 | dev_err(&client->dev, | ||
343 | "%s couldn't set STATUS %d\n", | ||
344 | led->ldev.name, led->status); | ||
345 | goto exit; | ||
346 | } | ||
347 | break; | ||
348 | |||
349 | case LP3944_LED_TYPE_NONE: | ||
350 | default: | ||
351 | break; | ||
352 | |||
353 | } | ||
354 | } | ||
355 | return 0; | ||
356 | |||
357 | exit: | ||
358 | if (i > 0) | ||
359 | for (i = i - 1; i >= 0; i--) | ||
360 | switch (pdata->leds[i].type) { | ||
361 | |||
362 | case LP3944_LED_TYPE_LED: | ||
363 | case LP3944_LED_TYPE_LED_INVERTED: | ||
364 | led_classdev_unregister(&data->leds[i].ldev); | ||
365 | cancel_work_sync(&data->leds[i].work); | ||
366 | break; | ||
367 | |||
368 | case LP3944_LED_TYPE_NONE: | ||
369 | default: | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | return err; | ||
374 | } | ||
375 | |||
376 | static int __devinit lp3944_probe(struct i2c_client *client, | ||
377 | const struct i2c_device_id *id) | ||
378 | { | ||
379 | struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; | ||
380 | struct lp3944_data *data; | ||
381 | |||
382 | if (lp3944_pdata == NULL) { | ||
383 | dev_err(&client->dev, "no platform data\n"); | ||
384 | return -EINVAL; | ||
385 | } | ||
386 | |||
387 | /* Let's see whether this adapter can support what we need. */ | ||
388 | if (!i2c_check_functionality(client->adapter, | ||
389 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
390 | dev_err(&client->dev, "insufficient functionality!\n"); | ||
391 | return -ENODEV; | ||
392 | } | ||
393 | |||
394 | data = kzalloc(sizeof(struct lp3944_data), GFP_KERNEL); | ||
395 | if (!data) | ||
396 | return -ENOMEM; | ||
397 | |||
398 | data->client = client; | ||
399 | i2c_set_clientdata(client, data); | ||
400 | |||
401 | mutex_init(&data->lock); | ||
402 | |||
403 | dev_info(&client->dev, "lp3944 enabled\n"); | ||
404 | |||
405 | lp3944_configure(client, data, lp3944_pdata); | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static int __devexit lp3944_remove(struct i2c_client *client) | ||
410 | { | ||
411 | struct lp3944_platform_data *pdata = client->dev.platform_data; | ||
412 | struct lp3944_data *data = i2c_get_clientdata(client); | ||
413 | int i; | ||
414 | |||
415 | for (i = 0; i < pdata->leds_size; i++) | ||
416 | switch (data->leds[i].type) { | ||
417 | case LP3944_LED_TYPE_LED: | ||
418 | case LP3944_LED_TYPE_LED_INVERTED: | ||
419 | led_classdev_unregister(&data->leds[i].ldev); | ||
420 | cancel_work_sync(&data->leds[i].work); | ||
421 | break; | ||
422 | |||
423 | case LP3944_LED_TYPE_NONE: | ||
424 | default: | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | kfree(data); | ||
429 | i2c_set_clientdata(client, NULL); | ||
430 | |||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | /* lp3944 i2c driver struct */ | ||
435 | static const struct i2c_device_id lp3944_id[] = { | ||
436 | {"lp3944", 0}, | ||
437 | {} | ||
438 | }; | ||
439 | |||
440 | MODULE_DEVICE_TABLE(i2c, lp3944_id); | ||
441 | |||
442 | static struct i2c_driver lp3944_driver = { | ||
443 | .driver = { | ||
444 | .name = "lp3944", | ||
445 | }, | ||
446 | .probe = lp3944_probe, | ||
447 | .remove = __devexit_p(lp3944_remove), | ||
448 | .id_table = lp3944_id, | ||
449 | }; | ||
450 | |||
451 | static int __init lp3944_module_init(void) | ||
452 | { | ||
453 | return i2c_add_driver(&lp3944_driver); | ||
454 | } | ||
455 | |||
456 | static void __exit lp3944_module_exit(void) | ||
457 | { | ||
458 | i2c_del_driver(&lp3944_driver); | ||
459 | } | ||
460 | |||
461 | module_init(lp3944_module_init); | ||
462 | module_exit(lp3944_module_exit); | ||
463 | |||
464 | MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); | ||
465 | MODULE_DESCRIPTION("LP3944 Fun Light Chip"); | ||
466 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 3937244fdcab..dba8921240f2 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
@@ -35,7 +35,7 @@ struct pca9532_data { | |||
35 | struct pca9532_led leds[16]; | 35 | struct pca9532_led leds[16]; |
36 | struct mutex update_lock; | 36 | struct mutex update_lock; |
37 | struct input_dev *idev; | 37 | struct input_dev *idev; |
38 | struct work_struct work; | 38 | struct work_struct work; |
39 | u8 pwm[2]; | 39 | u8 pwm[2]; |
40 | u8 psc[2]; | 40 | u8 psc[2]; |
41 | }; | 41 | }; |
@@ -87,14 +87,14 @@ static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink, | |||
87 | if (b > 0xFF) | 87 | if (b > 0xFF) |
88 | return -EINVAL; | 88 | return -EINVAL; |
89 | data->pwm[pwm] = b; | 89 | data->pwm[pwm] = b; |
90 | data->psc[pwm] = blink; | 90 | data->psc[pwm] = blink; |
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
94 | static int pca9532_setpwm(struct i2c_client *client, int pwm) | 94 | static int pca9532_setpwm(struct i2c_client *client, int pwm) |
95 | { | 95 | { |
96 | struct pca9532_data *data = i2c_get_clientdata(client); | 96 | struct pca9532_data *data = i2c_get_clientdata(client); |
97 | mutex_lock(&data->update_lock); | 97 | mutex_lock(&data->update_lock); |
98 | i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm), | 98 | i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm), |
99 | data->pwm[pwm]); | 99 | data->pwm[pwm]); |
100 | i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm), | 100 | i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm), |
@@ -132,11 +132,11 @@ static void pca9532_set_brightness(struct led_classdev *led_cdev, | |||
132 | led->state = PCA9532_ON; | 132 | led->state = PCA9532_ON; |
133 | else { | 133 | else { |
134 | led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ | 134 | led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ |
135 | err = pca9532_calcpwm(led->client, 0, 0, value); | 135 | err = pca9532_calcpwm(led->client, 0, 0, value); |
136 | if (err) | 136 | if (err) |
137 | return; /* XXX: led api doesn't allow error code? */ | 137 | return; /* XXX: led api doesn't allow error code? */ |
138 | } | 138 | } |
139 | schedule_work(&led->work); | 139 | schedule_work(&led->work); |
140 | } | 140 | } |
141 | 141 | ||
142 | static int pca9532_set_blink(struct led_classdev *led_cdev, | 142 | static int pca9532_set_blink(struct led_classdev *led_cdev, |
@@ -145,7 +145,7 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, | |||
145 | struct pca9532_led *led = ldev_to_led(led_cdev); | 145 | struct pca9532_led *led = ldev_to_led(led_cdev); |
146 | struct i2c_client *client = led->client; | 146 | struct i2c_client *client = led->client; |
147 | int psc; | 147 | int psc; |
148 | int err = 0; | 148 | int err = 0; |
149 | 149 | ||
150 | if (*delay_on == 0 && *delay_off == 0) { | 150 | if (*delay_on == 0 && *delay_off == 0) { |
151 | /* led subsystem ask us for a blink rate */ | 151 | /* led subsystem ask us for a blink rate */ |
@@ -157,11 +157,11 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, | |||
157 | 157 | ||
158 | /* Thecus specific: only use PSC/PWM 0 */ | 158 | /* Thecus specific: only use PSC/PWM 0 */ |
159 | psc = (*delay_on * 152-1)/1000; | 159 | psc = (*delay_on * 152-1)/1000; |
160 | err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); | 160 | err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); |
161 | if (err) | 161 | if (err) |
162 | return err; | 162 | return err; |
163 | schedule_work(&led->work); | 163 | schedule_work(&led->work); |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | static int pca9532_event(struct input_dev *dev, unsigned int type, | 167 | static int pca9532_event(struct input_dev *dev, unsigned int type, |
@@ -178,15 +178,15 @@ static int pca9532_event(struct input_dev *dev, unsigned int type, | |||
178 | else | 178 | else |
179 | data->pwm[1] = 0; | 179 | data->pwm[1] = 0; |
180 | 180 | ||
181 | schedule_work(&data->work); | 181 | schedule_work(&data->work); |
182 | 182 | ||
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | static void pca9532_input_work(struct work_struct *work) | 186 | static void pca9532_input_work(struct work_struct *work) |
187 | { | 187 | { |
188 | struct pca9532_data *data; | 188 | struct pca9532_data *data; |
189 | data = container_of(work, struct pca9532_data, work); | 189 | data = container_of(work, struct pca9532_data, work); |
190 | mutex_lock(&data->update_lock); | 190 | mutex_lock(&data->update_lock); |
191 | i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1), | 191 | i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1), |
192 | data->pwm[1]); | 192 | data->pwm[1]); |
@@ -195,11 +195,11 @@ static void pca9532_input_work(struct work_struct *work) | |||
195 | 195 | ||
196 | static void pca9532_led_work(struct work_struct *work) | 196 | static void pca9532_led_work(struct work_struct *work) |
197 | { | 197 | { |
198 | struct pca9532_led *led; | 198 | struct pca9532_led *led; |
199 | led = container_of(work, struct pca9532_led, work); | 199 | led = container_of(work, struct pca9532_led, work); |
200 | if (led->state == PCA9532_PWM0) | 200 | if (led->state == PCA9532_PWM0) |
201 | pca9532_setpwm(led->client, 0); | 201 | pca9532_setpwm(led->client, 0); |
202 | pca9532_setled(led); | 202 | pca9532_setled(led); |
203 | } | 203 | } |
204 | 204 | ||
205 | static int pca9532_configure(struct i2c_client *client, | 205 | static int pca9532_configure(struct i2c_client *client, |
@@ -232,7 +232,7 @@ static int pca9532_configure(struct i2c_client *client, | |||
232 | led->ldev.brightness = LED_OFF; | 232 | led->ldev.brightness = LED_OFF; |
233 | led->ldev.brightness_set = pca9532_set_brightness; | 233 | led->ldev.brightness_set = pca9532_set_brightness; |
234 | led->ldev.blink_set = pca9532_set_blink; | 234 | led->ldev.blink_set = pca9532_set_blink; |
235 | INIT_WORK(&led->work, pca9532_led_work); | 235 | INIT_WORK(&led->work, pca9532_led_work); |
236 | err = led_classdev_register(&client->dev, &led->ldev); | 236 | err = led_classdev_register(&client->dev, &led->ldev); |
237 | if (err < 0) { | 237 | if (err < 0) { |
238 | dev_err(&client->dev, | 238 | dev_err(&client->dev, |
@@ -262,11 +262,11 @@ static int pca9532_configure(struct i2c_client *client, | |||
262 | BIT_MASK(SND_TONE); | 262 | BIT_MASK(SND_TONE); |
263 | data->idev->event = pca9532_event; | 263 | data->idev->event = pca9532_event; |
264 | input_set_drvdata(data->idev, data); | 264 | input_set_drvdata(data->idev, data); |
265 | INIT_WORK(&data->work, pca9532_input_work); | 265 | INIT_WORK(&data->work, pca9532_input_work); |
266 | err = input_register_device(data->idev); | 266 | err = input_register_device(data->idev); |
267 | if (err) { | 267 | if (err) { |
268 | input_free_device(data->idev); | 268 | input_free_device(data->idev); |
269 | cancel_work_sync(&data->work); | 269 | cancel_work_sync(&data->work); |
270 | data->idev = NULL; | 270 | data->idev = NULL; |
271 | goto exit; | 271 | goto exit; |
272 | } | 272 | } |
@@ -283,13 +283,13 @@ exit: | |||
283 | break; | 283 | break; |
284 | case PCA9532_TYPE_LED: | 284 | case PCA9532_TYPE_LED: |
285 | led_classdev_unregister(&data->leds[i].ldev); | 285 | led_classdev_unregister(&data->leds[i].ldev); |
286 | cancel_work_sync(&data->leds[i].work); | 286 | cancel_work_sync(&data->leds[i].work); |
287 | break; | 287 | break; |
288 | case PCA9532_TYPE_N2100_BEEP: | 288 | case PCA9532_TYPE_N2100_BEEP: |
289 | if (data->idev != NULL) { | 289 | if (data->idev != NULL) { |
290 | input_unregister_device(data->idev); | 290 | input_unregister_device(data->idev); |
291 | input_free_device(data->idev); | 291 | input_free_device(data->idev); |
292 | cancel_work_sync(&data->work); | 292 | cancel_work_sync(&data->work); |
293 | data->idev = NULL; | 293 | data->idev = NULL; |
294 | } | 294 | } |
295 | break; | 295 | break; |
@@ -340,13 +340,13 @@ static int pca9532_remove(struct i2c_client *client) | |||
340 | break; | 340 | break; |
341 | case PCA9532_TYPE_LED: | 341 | case PCA9532_TYPE_LED: |
342 | led_classdev_unregister(&data->leds[i].ldev); | 342 | led_classdev_unregister(&data->leds[i].ldev); |
343 | cancel_work_sync(&data->leds[i].work); | 343 | cancel_work_sync(&data->leds[i].work); |
344 | break; | 344 | break; |
345 | case PCA9532_TYPE_N2100_BEEP: | 345 | case PCA9532_TYPE_N2100_BEEP: |
346 | if (data->idev != NULL) { | 346 | if (data->idev != NULL) { |
347 | input_unregister_device(data->idev); | 347 | input_unregister_device(data->idev); |
348 | input_free_device(data->idev); | 348 | input_free_device(data->idev); |
349 | cancel_work_sync(&data->work); | 349 | cancel_work_sync(&data->work); |
350 | data->idev = NULL; | 350 | data->idev = NULL; |
351 | } | 351 | } |
352 | break; | 352 | break; |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index d4e8979735cb..9c3138265f8e 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -82,7 +82,7 @@ struct lg_cpu { | |||
82 | 82 | ||
83 | struct lg_eventfd { | 83 | struct lg_eventfd { |
84 | unsigned long addr; | 84 | unsigned long addr; |
85 | struct file *event; | 85 | struct eventfd_ctx *event; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | struct lg_eventfd_map { | 88 | struct lg_eventfd_map { |
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index 32e297121058..9f9a2953b383 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c | |||
@@ -50,7 +50,7 @@ static int add_eventfd(struct lguest *lg, unsigned long addr, int fd) | |||
50 | 50 | ||
51 | /* Now append new entry. */ | 51 | /* Now append new entry. */ |
52 | new->map[new->num].addr = addr; | 52 | new->map[new->num].addr = addr; |
53 | new->map[new->num].event = eventfd_fget(fd); | 53 | new->map[new->num].event = eventfd_ctx_fdget(fd); |
54 | if (IS_ERR(new->map[new->num].event)) { | 54 | if (IS_ERR(new->map[new->num].event)) { |
55 | kfree(new); | 55 | kfree(new); |
56 | return PTR_ERR(new->map[new->num].event); | 56 | return PTR_ERR(new->map[new->num].event); |
@@ -357,7 +357,7 @@ static int close(struct inode *inode, struct file *file) | |||
357 | 357 | ||
358 | /* Release any eventfds they registered. */ | 358 | /* Release any eventfds they registered. */ |
359 | for (i = 0; i < lg->eventfds->num; i++) | 359 | for (i = 0; i < lg->eventfds->num; i++) |
360 | fput(lg->eventfds->map[i].event); | 360 | eventfd_ctx_put(lg->eventfds->map[i].event); |
361 | kfree(lg->eventfds); | 361 | kfree(lg->eventfds); |
362 | 362 | ||
363 | /* If lg->dead doesn't contain an error code it will be NULL or a | 363 | /* If lg->dead doesn't contain an error code it will be NULL or a |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 6e149f4a1fff..a0f68386c12f 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -378,6 +378,17 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, | |||
378 | dev->ofdev.dev.bus = &macio_bus_type; | 378 | dev->ofdev.dev.bus = &macio_bus_type; |
379 | dev->ofdev.dev.release = macio_release_dev; | 379 | dev->ofdev.dev.release = macio_release_dev; |
380 | 380 | ||
381 | #ifdef CONFIG_PCI | ||
382 | /* Set the DMA ops to the ones from the PCI device, this could be | ||
383 | * fishy if we didn't know that on PowerMac it's always direct ops | ||
384 | * or iommu ops that will work fine | ||
385 | */ | ||
386 | dev->ofdev.dev.archdata.dma_ops = | ||
387 | chip->lbus.pdev->dev.archdata.dma_ops; | ||
388 | dev->ofdev.dev.archdata.dma_data = | ||
389 | chip->lbus.pdev->dev.archdata.dma_data; | ||
390 | #endif /* CONFIG_PCI */ | ||
391 | |||
381 | #ifdef DEBUG | 392 | #ifdef DEBUG |
382 | printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n", | 393 | printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n", |
383 | dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj); | 394 | dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj); |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 9933eb861c71..529e2ba505c3 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -776,7 +776,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) | |||
776 | * But don't wait if split was due to the io size restriction | 776 | * But don't wait if split was due to the io size restriction |
777 | */ | 777 | */ |
778 | if (unlikely(out_of_pages)) | 778 | if (unlikely(out_of_pages)) |
779 | congestion_wait(WRITE, HZ/100); | 779 | congestion_wait(BLK_RW_ASYNC, HZ/100); |
780 | 780 | ||
781 | /* | 781 | /* |
782 | * With async crypto it is unsafe to share the crypto context | 782 | * With async crypto it is unsafe to share the crypto context |
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index c3ae51584b12..3710ff88fc10 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c | |||
@@ -195,7 +195,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | |||
195 | struct dm_exception_store **store) | 195 | struct dm_exception_store **store) |
196 | { | 196 | { |
197 | int r = 0; | 197 | int r = 0; |
198 | struct dm_exception_store_type *type; | 198 | struct dm_exception_store_type *type = NULL; |
199 | struct dm_exception_store *tmp_store; | 199 | struct dm_exception_store *tmp_store; |
200 | char persistent; | 200 | char persistent; |
201 | 201 | ||
@@ -211,12 +211,15 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | |||
211 | } | 211 | } |
212 | 212 | ||
213 | persistent = toupper(*argv[1]); | 213 | persistent = toupper(*argv[1]); |
214 | if (persistent != 'P' && persistent != 'N') { | 214 | if (persistent == 'P') |
215 | type = get_type("P"); | ||
216 | else if (persistent == 'N') | ||
217 | type = get_type("N"); | ||
218 | else { | ||
215 | ti->error = "Persistent flag is not P or N"; | 219 | ti->error = "Persistent flag is not P or N"; |
216 | return -EINVAL; | 220 | return -EINVAL; |
217 | } | 221 | } |
218 | 222 | ||
219 | type = get_type(&persistent); | ||
220 | if (!type) { | 223 | if (!type) { |
221 | ti->error = "Exception store type not recognised"; | 224 | ti->error = "Exception store type not recognised"; |
222 | r = -EINVAL; | 225 | r = -EINVAL; |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 4899ebe767c8..2cba557d9e61 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -495,7 +495,7 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | |||
495 | return 0; | 495 | return 0; |
496 | } | 496 | } |
497 | 497 | ||
498 | if (blk_stack_limits(limits, &q->limits, start) < 0) | 498 | if (blk_stack_limits(limits, &q->limits, start << 9) < 0) |
499 | DMWARN("%s: target device %s is misaligned", | 499 | DMWARN("%s: target device %s is misaligned", |
500 | dm_device_name(ti->table->md), bdevname(bdev, b)); | 500 | dm_device_name(ti->table->md), bdevname(bdev, b)); |
501 | 501 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3c6d4ee8921d..9acd54a5cffb 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1017,7 +1017,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector, | |||
1017 | clone->bi_flags |= 1 << BIO_CLONED; | 1017 | clone->bi_flags |= 1 << BIO_CLONED; |
1018 | 1018 | ||
1019 | if (bio_integrity(bio)) { | 1019 | if (bio_integrity(bio)) { |
1020 | bio_integrity_clone(clone, bio, GFP_NOIO); | 1020 | bio_integrity_clone(clone, bio, GFP_NOIO, bs); |
1021 | bio_integrity_trim(clone, | 1021 | bio_integrity_trim(clone, |
1022 | bio_sector_offset(bio, idx, offset), len); | 1022 | bio_sector_offset(bio, idx, offset), len); |
1023 | } | 1023 | } |
@@ -1045,7 +1045,7 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector, | |||
1045 | clone->bi_flags &= ~(1 << BIO_SEG_VALID); | 1045 | clone->bi_flags &= ~(1 << BIO_SEG_VALID); |
1046 | 1046 | ||
1047 | if (bio_integrity(bio)) { | 1047 | if (bio_integrity(bio)) { |
1048 | bio_integrity_clone(clone, bio, GFP_NOIO); | 1048 | bio_integrity_clone(clone, bio, GFP_NOIO, bs); |
1049 | 1049 | ||
1050 | if (idx != bio->bi_idx || clone->bi_size < bio->bi_size) | 1050 | if (idx != bio->bi_idx || clone->bi_size < bio->bi_size) |
1051 | bio_integrity_trim(clone, | 1051 | bio_integrity_trim(clone, |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 15c8b7b25a9b..5810fa906af0 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -166,8 +166,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
166 | rdev->sectors = sectors * mddev->chunk_sectors; | 166 | rdev->sectors = sectors * mddev->chunk_sectors; |
167 | } | 167 | } |
168 | 168 | ||
169 | blk_queue_stack_limits(mddev->queue, | 169 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
170 | rdev->bdev->bd_disk->queue); | 170 | rdev->data_offset << 9); |
171 | /* as we don't honour merge_bvec_fn, we must never risk | 171 | /* as we don't honour merge_bvec_fn, we must never risk |
172 | * violating it, so limit ->max_sector to one PAGE, as | 172 | * violating it, so limit ->max_sector to one PAGE, as |
173 | * a one page request is never in violation. | 173 | * a one page request is never in violation. |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 09be637d52cb..d4351ff0849f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1756,9 +1756,10 @@ static void print_sb_1(struct mdp_superblock_1 *sb) | |||
1756 | __u8 *uuid; | 1756 | __u8 *uuid; |
1757 | 1757 | ||
1758 | uuid = sb->set_uuid; | 1758 | uuid = sb->set_uuid; |
1759 | printk(KERN_INFO "md: SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x" | 1759 | printk(KERN_INFO |
1760 | ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n" | 1760 | "md: SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x" |
1761 | KERN_INFO "md: Name: \"%s\" CT:%llu\n", | 1761 | ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n" |
1762 | "md: Name: \"%s\" CT:%llu\n", | ||
1762 | le32_to_cpu(sb->major_version), | 1763 | le32_to_cpu(sb->major_version), |
1763 | le32_to_cpu(sb->feature_map), | 1764 | le32_to_cpu(sb->feature_map), |
1764 | uuid[0], uuid[1], uuid[2], uuid[3], | 1765 | uuid[0], uuid[1], uuid[2], uuid[3], |
@@ -1770,12 +1771,13 @@ static void print_sb_1(struct mdp_superblock_1 *sb) | |||
1770 | & MD_SUPERBLOCK_1_TIME_SEC_MASK); | 1771 | & MD_SUPERBLOCK_1_TIME_SEC_MASK); |
1771 | 1772 | ||
1772 | uuid = sb->device_uuid; | 1773 | uuid = sb->device_uuid; |
1773 | printk(KERN_INFO "md: L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu" | 1774 | printk(KERN_INFO |
1775 | "md: L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu" | ||
1774 | " RO:%llu\n" | 1776 | " RO:%llu\n" |
1775 | KERN_INFO "md: Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x" | 1777 | "md: Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x" |
1776 | ":%02x%02x%02x%02x%02x%02x\n" | 1778 | ":%02x%02x%02x%02x%02x%02x\n" |
1777 | KERN_INFO "md: (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n" | 1779 | "md: (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n" |
1778 | KERN_INFO "md: (MaxDev:%u) \n", | 1780 | "md: (MaxDev:%u) \n", |
1779 | le32_to_cpu(sb->level), | 1781 | le32_to_cpu(sb->level), |
1780 | (unsigned long long)le64_to_cpu(sb->size), | 1782 | (unsigned long long)le64_to_cpu(sb->size), |
1781 | le32_to_cpu(sb->raid_disks), | 1783 | le32_to_cpu(sb->raid_disks), |
@@ -3573,7 +3575,8 @@ suspend_lo_store(mddev_t *mddev, const char *buf, size_t len) | |||
3573 | char *e; | 3575 | char *e; |
3574 | unsigned long long new = simple_strtoull(buf, &e, 10); | 3576 | unsigned long long new = simple_strtoull(buf, &e, 10); |
3575 | 3577 | ||
3576 | if (mddev->pers->quiesce == NULL) | 3578 | if (mddev->pers == NULL || |
3579 | mddev->pers->quiesce == NULL) | ||
3577 | return -EINVAL; | 3580 | return -EINVAL; |
3578 | if (buf == e || (*e && *e != '\n')) | 3581 | if (buf == e || (*e && *e != '\n')) |
3579 | return -EINVAL; | 3582 | return -EINVAL; |
@@ -3601,7 +3604,8 @@ suspend_hi_store(mddev_t *mddev, const char *buf, size_t len) | |||
3601 | char *e; | 3604 | char *e; |
3602 | unsigned long long new = simple_strtoull(buf, &e, 10); | 3605 | unsigned long long new = simple_strtoull(buf, &e, 10); |
3603 | 3606 | ||
3604 | if (mddev->pers->quiesce == NULL) | 3607 | if (mddev->pers == NULL || |
3608 | mddev->pers->quiesce == NULL) | ||
3605 | return -EINVAL; | 3609 | return -EINVAL; |
3606 | if (buf == e || (*e && *e != '\n')) | 3610 | if (buf == e || (*e && *e != '\n')) |
3607 | return -EINVAL; | 3611 | return -EINVAL; |
@@ -3844,11 +3848,9 @@ static int md_alloc(dev_t dev, char *name) | |||
3844 | flush_scheduled_work(); | 3848 | flush_scheduled_work(); |
3845 | 3849 | ||
3846 | mutex_lock(&disks_mutex); | 3850 | mutex_lock(&disks_mutex); |
3847 | if (mddev->gendisk) { | 3851 | error = -EEXIST; |
3848 | mutex_unlock(&disks_mutex); | 3852 | if (mddev->gendisk) |
3849 | mddev_put(mddev); | 3853 | goto abort; |
3850 | return -EEXIST; | ||
3851 | } | ||
3852 | 3854 | ||
3853 | if (name) { | 3855 | if (name) { |
3854 | /* Need to ensure that 'name' is not a duplicate. | 3856 | /* Need to ensure that 'name' is not a duplicate. |
@@ -3860,17 +3862,15 @@ static int md_alloc(dev_t dev, char *name) | |||
3860 | if (mddev2->gendisk && | 3862 | if (mddev2->gendisk && |
3861 | strcmp(mddev2->gendisk->disk_name, name) == 0) { | 3863 | strcmp(mddev2->gendisk->disk_name, name) == 0) { |
3862 | spin_unlock(&all_mddevs_lock); | 3864 | spin_unlock(&all_mddevs_lock); |
3863 | return -EEXIST; | 3865 | goto abort; |
3864 | } | 3866 | } |
3865 | spin_unlock(&all_mddevs_lock); | 3867 | spin_unlock(&all_mddevs_lock); |
3866 | } | 3868 | } |
3867 | 3869 | ||
3870 | error = -ENOMEM; | ||
3868 | mddev->queue = blk_alloc_queue(GFP_KERNEL); | 3871 | mddev->queue = blk_alloc_queue(GFP_KERNEL); |
3869 | if (!mddev->queue) { | 3872 | if (!mddev->queue) |
3870 | mutex_unlock(&disks_mutex); | 3873 | goto abort; |
3871 | mddev_put(mddev); | ||
3872 | return -ENOMEM; | ||
3873 | } | ||
3874 | mddev->queue->queuedata = mddev; | 3874 | mddev->queue->queuedata = mddev; |
3875 | 3875 | ||
3876 | /* Can be unlocked because the queue is new: no concurrency */ | 3876 | /* Can be unlocked because the queue is new: no concurrency */ |
@@ -3880,11 +3880,9 @@ static int md_alloc(dev_t dev, char *name) | |||
3880 | 3880 | ||
3881 | disk = alloc_disk(1 << shift); | 3881 | disk = alloc_disk(1 << shift); |
3882 | if (!disk) { | 3882 | if (!disk) { |
3883 | mutex_unlock(&disks_mutex); | ||
3884 | blk_cleanup_queue(mddev->queue); | 3883 | blk_cleanup_queue(mddev->queue); |
3885 | mddev->queue = NULL; | 3884 | mddev->queue = NULL; |
3886 | mddev_put(mddev); | 3885 | goto abort; |
3887 | return -ENOMEM; | ||
3888 | } | 3886 | } |
3889 | disk->major = MAJOR(mddev->unit); | 3887 | disk->major = MAJOR(mddev->unit); |
3890 | disk->first_minor = unit << shift; | 3888 | disk->first_minor = unit << shift; |
@@ -3906,16 +3904,22 @@ static int md_alloc(dev_t dev, char *name) | |||
3906 | mddev->gendisk = disk; | 3904 | mddev->gendisk = disk; |
3907 | error = kobject_init_and_add(&mddev->kobj, &md_ktype, | 3905 | error = kobject_init_and_add(&mddev->kobj, &md_ktype, |
3908 | &disk_to_dev(disk)->kobj, "%s", "md"); | 3906 | &disk_to_dev(disk)->kobj, "%s", "md"); |
3909 | mutex_unlock(&disks_mutex); | 3907 | if (error) { |
3910 | if (error) | 3908 | /* This isn't possible, but as kobject_init_and_add is marked |
3909 | * __must_check, we must do something with the result | ||
3910 | */ | ||
3911 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", | 3911 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", |
3912 | disk->disk_name); | 3912 | disk->disk_name); |
3913 | else { | 3913 | error = 0; |
3914 | } | ||
3915 | abort: | ||
3916 | mutex_unlock(&disks_mutex); | ||
3917 | if (!error) { | ||
3914 | kobject_uevent(&mddev->kobj, KOBJ_ADD); | 3918 | kobject_uevent(&mddev->kobj, KOBJ_ADD); |
3915 | mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); | 3919 | mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); |
3916 | } | 3920 | } |
3917 | mddev_put(mddev); | 3921 | mddev_put(mddev); |
3918 | return 0; | 3922 | return error; |
3919 | } | 3923 | } |
3920 | 3924 | ||
3921 | static struct kobject *md_probe(dev_t dev, int *part, void *data) | 3925 | static struct kobject *md_probe(dev_t dev, int *part, void *data) |
@@ -6334,10 +6338,16 @@ void md_do_sync(mddev_t *mddev) | |||
6334 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 6338 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
6335 | } | 6339 | } |
6336 | 6340 | ||
6337 | if (j >= mddev->resync_max) | 6341 | while (j >= mddev->resync_max && !kthread_should_stop()) { |
6338 | wait_event(mddev->recovery_wait, | 6342 | /* As this condition is controlled by user-space, |
6339 | mddev->resync_max > j | 6343 | * we can block indefinitely, so use '_interruptible' |
6340 | || kthread_should_stop()); | 6344 | * to avoid triggering warnings. |
6345 | */ | ||
6346 | flush_signals(current); /* just in case */ | ||
6347 | wait_event_interruptible(mddev->recovery_wait, | ||
6348 | mddev->resync_max > j | ||
6349 | || kthread_should_stop()); | ||
6350 | } | ||
6341 | 6351 | ||
6342 | if (kthread_should_stop()) | 6352 | if (kthread_should_stop()) |
6343 | goto interrupted; | 6353 | goto interrupted; |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index cbe368fa6598..237fe3fd235c 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -294,7 +294,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
294 | for (path = first; path <= last; path++) | 294 | for (path = first; path <= last; path++) |
295 | if ((p=conf->multipaths+path)->rdev == NULL) { | 295 | if ((p=conf->multipaths+path)->rdev == NULL) { |
296 | q = rdev->bdev->bd_disk->queue; | 296 | q = rdev->bdev->bd_disk->queue; |
297 | blk_queue_stack_limits(mddev->queue, q); | 297 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
298 | rdev->data_offset << 9); | ||
298 | 299 | ||
299 | /* as we don't honour merge_bvec_fn, we must never risk | 300 | /* as we don't honour merge_bvec_fn, we must never risk |
300 | * violating it, so limit ->max_sector to one PAGE, as | 301 | * violating it, so limit ->max_sector to one PAGE, as |
@@ -463,9 +464,9 @@ static int multipath_run (mddev_t *mddev) | |||
463 | 464 | ||
464 | disk = conf->multipaths + disk_idx; | 465 | disk = conf->multipaths + disk_idx; |
465 | disk->rdev = rdev; | 466 | disk->rdev = rdev; |
467 | disk_stack_limits(mddev->gendisk, rdev->bdev, | ||
468 | rdev->data_offset << 9); | ||
466 | 469 | ||
467 | blk_queue_stack_limits(mddev->queue, | ||
468 | rdev->bdev->bd_disk->queue); | ||
469 | /* as we don't honour merge_bvec_fn, we must never risk | 470 | /* as we don't honour merge_bvec_fn, we must never risk |
470 | * violating it, not that we ever expect a device with | 471 | * violating it, not that we ever expect a device with |
471 | * a merge_bvec_fn to be involved in multipath */ | 472 | * a merge_bvec_fn to be involved in multipath */ |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index ab4a489d8695..335f490dcad6 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -170,8 +170,8 @@ static int create_strip_zones(mddev_t *mddev) | |||
170 | } | 170 | } |
171 | dev[j] = rdev1; | 171 | dev[j] = rdev1; |
172 | 172 | ||
173 | blk_queue_stack_limits(mddev->queue, | 173 | disk_stack_limits(mddev->gendisk, rdev1->bdev, |
174 | rdev1->bdev->bd_disk->queue); | 174 | rdev1->data_offset << 9); |
175 | /* as we don't honour merge_bvec_fn, we must never risk | 175 | /* as we don't honour merge_bvec_fn, we must never risk |
176 | * violating it, so limit ->max_sector to one PAGE, as | 176 | * violating it, so limit ->max_sector to one PAGE, as |
177 | * a one page request is never in violation. | 177 | * a one page request is never in violation. |
@@ -250,6 +250,11 @@ static int create_strip_zones(mddev_t *mddev) | |||
250 | mddev->chunk_sectors << 9); | 250 | mddev->chunk_sectors << 9); |
251 | goto abort; | 251 | goto abort; |
252 | } | 252 | } |
253 | |||
254 | blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); | ||
255 | blk_queue_io_opt(mddev->queue, | ||
256 | (mddev->chunk_sectors << 9) * mddev->raid_disks); | ||
257 | |||
253 | printk(KERN_INFO "raid0: done.\n"); | 258 | printk(KERN_INFO "raid0: done.\n"); |
254 | mddev->private = conf; | 259 | mddev->private = conf; |
255 | return 0; | 260 | return 0; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 89939a7aef57..0569efba0c02 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1123,8 +1123,8 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1123 | for (mirror = first; mirror <= last; mirror++) | 1123 | for (mirror = first; mirror <= last; mirror++) |
1124 | if ( !(p=conf->mirrors+mirror)->rdev) { | 1124 | if ( !(p=conf->mirrors+mirror)->rdev) { |
1125 | 1125 | ||
1126 | blk_queue_stack_limits(mddev->queue, | 1126 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
1127 | rdev->bdev->bd_disk->queue); | 1127 | rdev->data_offset << 9); |
1128 | /* as we don't honour merge_bvec_fn, we must never risk | 1128 | /* as we don't honour merge_bvec_fn, we must never risk |
1129 | * violating it, so limit ->max_sector to one PAGE, as | 1129 | * violating it, so limit ->max_sector to one PAGE, as |
1130 | * a one page request is never in violation. | 1130 | * a one page request is never in violation. |
@@ -1988,9 +1988,8 @@ static int run(mddev_t *mddev) | |||
1988 | disk = conf->mirrors + disk_idx; | 1988 | disk = conf->mirrors + disk_idx; |
1989 | 1989 | ||
1990 | disk->rdev = rdev; | 1990 | disk->rdev = rdev; |
1991 | 1991 | disk_stack_limits(mddev->gendisk, rdev->bdev, | |
1992 | blk_queue_stack_limits(mddev->queue, | 1992 | rdev->data_offset << 9); |
1993 | rdev->bdev->bd_disk->queue); | ||
1994 | /* as we don't honour merge_bvec_fn, we must never risk | 1993 | /* as we don't honour merge_bvec_fn, we must never risk |
1995 | * violating it, so limit ->max_sector to one PAGE, as | 1994 | * violating it, so limit ->max_sector to one PAGE, as |
1996 | * a one page request is never in violation. | 1995 | * a one page request is never in violation. |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index ae12ceafe10c..7298a5e5a183 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1151,8 +1151,8 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1151 | for ( ; mirror <= last ; mirror++) | 1151 | for ( ; mirror <= last ; mirror++) |
1152 | if ( !(p=conf->mirrors+mirror)->rdev) { | 1152 | if ( !(p=conf->mirrors+mirror)->rdev) { |
1153 | 1153 | ||
1154 | blk_queue_stack_limits(mddev->queue, | 1154 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
1155 | rdev->bdev->bd_disk->queue); | 1155 | rdev->data_offset << 9); |
1156 | /* as we don't honour merge_bvec_fn, we must never risk | 1156 | /* as we don't honour merge_bvec_fn, we must never risk |
1157 | * violating it, so limit ->max_sector to one PAGE, as | 1157 | * violating it, so limit ->max_sector to one PAGE, as |
1158 | * a one page request is never in violation. | 1158 | * a one page request is never in violation. |
@@ -2044,7 +2044,7 @@ raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks) | |||
2044 | static int run(mddev_t *mddev) | 2044 | static int run(mddev_t *mddev) |
2045 | { | 2045 | { |
2046 | conf_t *conf; | 2046 | conf_t *conf; |
2047 | int i, disk_idx; | 2047 | int i, disk_idx, chunk_size; |
2048 | mirror_info_t *disk; | 2048 | mirror_info_t *disk; |
2049 | mdk_rdev_t *rdev; | 2049 | mdk_rdev_t *rdev; |
2050 | int nc, fc, fo; | 2050 | int nc, fc, fo; |
@@ -2130,6 +2130,14 @@ static int run(mddev_t *mddev) | |||
2130 | spin_lock_init(&conf->device_lock); | 2130 | spin_lock_init(&conf->device_lock); |
2131 | mddev->queue->queue_lock = &conf->device_lock; | 2131 | mddev->queue->queue_lock = &conf->device_lock; |
2132 | 2132 | ||
2133 | chunk_size = mddev->chunk_sectors << 9; | ||
2134 | blk_queue_io_min(mddev->queue, chunk_size); | ||
2135 | if (conf->raid_disks % conf->near_copies) | ||
2136 | blk_queue_io_opt(mddev->queue, chunk_size * conf->raid_disks); | ||
2137 | else | ||
2138 | blk_queue_io_opt(mddev->queue, chunk_size * | ||
2139 | (conf->raid_disks / conf->near_copies)); | ||
2140 | |||
2133 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 2141 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
2134 | disk_idx = rdev->raid_disk; | 2142 | disk_idx = rdev->raid_disk; |
2135 | if (disk_idx >= mddev->raid_disks | 2143 | if (disk_idx >= mddev->raid_disks |
@@ -2138,9 +2146,8 @@ static int run(mddev_t *mddev) | |||
2138 | disk = conf->mirrors + disk_idx; | 2146 | disk = conf->mirrors + disk_idx; |
2139 | 2147 | ||
2140 | disk->rdev = rdev; | 2148 | disk->rdev = rdev; |
2141 | 2149 | disk_stack_limits(mddev->gendisk, rdev->bdev, | |
2142 | blk_queue_stack_limits(mddev->queue, | 2150 | rdev->data_offset << 9); |
2143 | rdev->bdev->bd_disk->queue); | ||
2144 | /* as we don't honour merge_bvec_fn, we must never risk | 2151 | /* as we don't honour merge_bvec_fn, we must never risk |
2145 | * violating it, so limit ->max_sector to one PAGE, as | 2152 | * violating it, so limit ->max_sector to one PAGE, as |
2146 | * a one page request is never in violation. | 2153 | * a one page request is never in violation. |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index f9f991e6e138..37835538b58e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3699,13 +3699,21 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3699 | goto retry; | 3699 | goto retry; |
3700 | } | 3700 | } |
3701 | } | 3701 | } |
3702 | /* FIXME what if we get a false positive because these | 3702 | |
3703 | * are being updated. | 3703 | if (bio_data_dir(bi) == WRITE && |
3704 | */ | 3704 | logical_sector >= mddev->suspend_lo && |
3705 | if (logical_sector >= mddev->suspend_lo && | ||
3706 | logical_sector < mddev->suspend_hi) { | 3705 | logical_sector < mddev->suspend_hi) { |
3707 | release_stripe(sh); | 3706 | release_stripe(sh); |
3708 | schedule(); | 3707 | /* As the suspend_* range is controlled by |
3708 | * userspace, we want an interruptible | ||
3709 | * wait. | ||
3710 | */ | ||
3711 | flush_signals(current); | ||
3712 | prepare_to_wait(&conf->wait_for_overlap, | ||
3713 | &w, TASK_INTERRUPTIBLE); | ||
3714 | if (logical_sector >= mddev->suspend_lo && | ||
3715 | logical_sector < mddev->suspend_hi) | ||
3716 | schedule(); | ||
3709 | goto retry; | 3717 | goto retry; |
3710 | } | 3718 | } |
3711 | 3719 | ||
@@ -4452,7 +4460,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) | |||
4452 | static int run(mddev_t *mddev) | 4460 | static int run(mddev_t *mddev) |
4453 | { | 4461 | { |
4454 | raid5_conf_t *conf; | 4462 | raid5_conf_t *conf; |
4455 | int working_disks = 0; | 4463 | int working_disks = 0, chunk_size; |
4456 | mdk_rdev_t *rdev; | 4464 | mdk_rdev_t *rdev; |
4457 | 4465 | ||
4458 | if (mddev->recovery_cp != MaxSector) | 4466 | if (mddev->recovery_cp != MaxSector) |
@@ -4607,6 +4615,14 @@ static int run(mddev_t *mddev) | |||
4607 | md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); | 4615 | md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); |
4608 | 4616 | ||
4609 | blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); | 4617 | blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); |
4618 | chunk_size = mddev->chunk_sectors << 9; | ||
4619 | blk_queue_io_min(mddev->queue, chunk_size); | ||
4620 | blk_queue_io_opt(mddev->queue, chunk_size * | ||
4621 | (conf->raid_disks - conf->max_degraded)); | ||
4622 | |||
4623 | list_for_each_entry(rdev, &mddev->disks, same_set) | ||
4624 | disk_stack_limits(mddev->gendisk, rdev->bdev, | ||
4625 | rdev->data_offset << 9); | ||
4610 | 4626 | ||
4611 | return 0; | 4627 | return 0; |
4612 | abort: | 4628 | abort: |
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index b6da9c3873fe..aa20ce8cc668 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -1096,8 +1096,19 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | /* All S-code tables need a 200kHz shift */ | 1098 | /* All S-code tables need a 200kHz shift */ |
1099 | if (priv->ctrl.demod) | 1099 | if (priv->ctrl.demod) { |
1100 | demod = priv->ctrl.demod + 200; | 1100 | demod = priv->ctrl.demod + 200; |
1101 | /* | ||
1102 | * The DTV7 S-code table needs a 700 kHz shift. | ||
1103 | * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this | ||
1104 | * | ||
1105 | * DTV7 is only used in Australia. Germany or Italy may also | ||
1106 | * use this firmware after initialization, but a tune to a UHF | ||
1107 | * channel should then cause DTV78 to be used. | ||
1108 | */ | ||
1109 | if (type & DTV7) | ||
1110 | demod += 500; | ||
1111 | } | ||
1101 | 1112 | ||
1102 | return generic_set_freq(fe, p->frequency, | 1113 | return generic_set_freq(fe, p->frequency, |
1103 | T_DIGITAL_TV, type, 0, demod); | 1114 | T_DIGITAL_TV, type, 0, demod); |
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index 68eb4493f991..d8d4214fd65f 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config TTPCI_EEPROM | 1 | config TTPCI_EEPROM |
2 | tristate | 2 | tristate |
3 | depends on I2C | ||
3 | default n | 4 | default n |
4 | 5 | ||
5 | config DVB_AV7110 | 6 | config DVB_AV7110 |
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 640421ceb24a..46d216329611 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -1200,7 +1200,7 @@ static int si470x_fops_release(struct file *file) | |||
1200 | video_unregister_device(radio->videodev); | 1200 | video_unregister_device(radio->videodev); |
1201 | kfree(radio->buffer); | 1201 | kfree(radio->buffer); |
1202 | kfree(radio); | 1202 | kfree(radio); |
1203 | goto done; | 1203 | goto unlock; |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | /* stop rds reception */ | 1206 | /* stop rds reception */ |
@@ -1213,9 +1213,8 @@ static int si470x_fops_release(struct file *file) | |||
1213 | retval = si470x_stop(radio); | 1213 | retval = si470x_stop(radio); |
1214 | usb_autopm_put_interface(radio->intf); | 1214 | usb_autopm_put_interface(radio->intf); |
1215 | } | 1215 | } |
1216 | 1216 | unlock: | |
1217 | mutex_unlock(&radio->disconnect_lock); | 1217 | mutex_unlock(&radio->disconnect_lock); |
1218 | |||
1219 | done: | 1218 | done: |
1220 | return retval; | 1219 | return retval; |
1221 | } | 1220 | } |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 061e147f6f26..84b6fc15519d 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -312,6 +312,14 @@ config VIDEO_OV7670 | |||
312 | OV7670 VGA camera. It currently only works with the M88ALP01 | 312 | OV7670 VGA camera. It currently only works with the M88ALP01 |
313 | controller. | 313 | controller. |
314 | 314 | ||
315 | config VIDEO_MT9V011 | ||
316 | tristate "Micron mt9v011 sensor support" | ||
317 | depends on I2C && VIDEO_V4L2 | ||
318 | ---help--- | ||
319 | This is a Video4Linux2 sensor-level driver for the Micron | ||
320 | mt0v011 1.3 Mpixel camera. It currently only works with the | ||
321 | em28xx driver. | ||
322 | |||
315 | config VIDEO_TCM825X | 323 | config VIDEO_TCM825X |
316 | tristate "TCM825x camera sensor support" | 324 | tristate "TCM825x camera sensor support" |
317 | depends on I2C && VIDEO_V4L2 | 325 | depends on I2C && VIDEO_V4L2 |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 7fb3add1b387..9f2e3214a482 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -69,6 +69,7 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o | |||
69 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | 69 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o |
70 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | 70 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o |
71 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | 71 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o |
72 | obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o | ||
72 | 73 | ||
73 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | 74 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o |
74 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | 75 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o |
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index c92a25036f0e..36f2d76006fd 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -198,11 +198,14 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = { | |||
198 | 198 | ||
199 | static const struct cx18_card cx18_card_mpc718 = { | 199 | static const struct cx18_card cx18_card_mpc718 = { |
200 | .type = CX18_CARD_YUAN_MPC718, | 200 | .type = CX18_CARD_YUAN_MPC718, |
201 | .name = "Yuan MPC718", | 201 | .name = "Yuan MPC718 MiniPCI DVB-T/Analog", |
202 | .comment = "Analog video capture works; some audio line in may not.\n", | 202 | .comment = "Experimenters needed for device to work well.\n" |
203 | "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", | ||
203 | .v4l2_capabilities = CX18_CAP_ENCODER, | 204 | .v4l2_capabilities = CX18_CAP_ENCODER, |
204 | .hw_audio_ctrl = CX18_HW_418_AV, | 205 | .hw_audio_ctrl = CX18_HW_418_AV, |
205 | .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL, | 206 | .hw_muxer = CX18_HW_GPIO_MUX, |
207 | .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | | ||
208 | CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, | ||
206 | .video_inputs = { | 209 | .video_inputs = { |
207 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, | 210 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, |
208 | { CX18_CARD_INPUT_SVIDEO1, 1, | 211 | { CX18_CARD_INPUT_SVIDEO1, 1, |
@@ -211,27 +214,34 @@ static const struct cx18_card cx18_card_mpc718 = { | |||
211 | { CX18_CARD_INPUT_SVIDEO2, 2, | 214 | { CX18_CARD_INPUT_SVIDEO2, 2, |
212 | CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, | 215 | CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, |
213 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, | 216 | { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, |
214 | { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 }, | ||
215 | }, | 217 | }, |
216 | .audio_inputs = { | 218 | .audio_inputs = { |
217 | { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, | 219 | { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, |
218 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 0 }, | 220 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, |
219 | { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL1, 0 }, | 221 | { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 }, |
220 | }, | 222 | }, |
221 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 0 }, | ||
222 | .tuners = { | 223 | .tuners = { |
223 | /* XC3028 tuner */ | 224 | /* XC3028 tuner */ |
224 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | 225 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, |
225 | }, | 226 | }, |
227 | /* FIXME - the FM radio is just a guess and driver doesn't use SIF */ | ||
228 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, | ||
226 | .ddr = { | 229 | .ddr = { |
227 | /* Probably Samsung K4D263238G-VC33 memory */ | 230 | /* Hynix HY5DU283222B DDR RAM */ |
228 | .chip_config = 0x003, | 231 | .chip_config = 0x303, |
229 | .refresh = 0x30c, | 232 | .refresh = 0x3bd, |
230 | .timing1 = 0x23230b73, | 233 | .timing1 = 0x36320966, |
231 | .timing2 = 0x08, | 234 | .timing2 = 0x1f, |
232 | .tune_lane = 0, | 235 | .tune_lane = 0, |
233 | .initial_emrs = 2, | 236 | .initial_emrs = 2, |
234 | }, | 237 | }, |
238 | .gpio_init.initial_value = 0x1, | ||
239 | .gpio_init.direction = 0x3, | ||
240 | /* FIXME - these GPIO's are just guesses */ | ||
241 | .gpio_audio_input = { .mask = 0x3, | ||
242 | .tuner = 0x1, | ||
243 | .linein = 0x3, | ||
244 | .radio = 0x1 }, | ||
235 | .xceive_pin = 0, | 245 | .xceive_pin = 0, |
236 | .pci_list = cx18_pci_mpc718, | 246 | .pci_list = cx18_pci_mpc718, |
237 | .i2c = &cx18_i2c_std, | 247 | .i2c = &cx18_i2c_std, |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 6ea3fe623ef4..51a0c33b25b7 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
@@ -30,6 +30,10 @@ | |||
30 | #include "s5h1409.h" | 30 | #include "s5h1409.h" |
31 | #include "mxl5005s.h" | 31 | #include "mxl5005s.h" |
32 | #include "zl10353.h" | 32 | #include "zl10353.h" |
33 | |||
34 | #include <linux/firmware.h> | ||
35 | #include "mt352.h" | ||
36 | #include "mt352_priv.h" | ||
33 | #include "tuner-xc2028.h" | 37 | #include "tuner-xc2028.h" |
34 | 38 | ||
35 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 39 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
@@ -38,6 +42,11 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
38 | #define CX18_CLOCK_ENABLE2 0xc71024 | 42 | #define CX18_CLOCK_ENABLE2 0xc71024 |
39 | #define CX18_DMUX_CLK_MASK 0x0080 | 43 | #define CX18_DMUX_CLK_MASK 0x0080 |
40 | 44 | ||
45 | /* | ||
46 | * CX18_CARD_HVR_1600_ESMT | ||
47 | * CX18_CARD_HVR_1600_SAMSUNG | ||
48 | */ | ||
49 | |||
41 | static struct mxl5005s_config hauppauge_hvr1600_tuner = { | 50 | static struct mxl5005s_config hauppauge_hvr1600_tuner = { |
42 | .i2c_address = 0xC6 >> 1, | 51 | .i2c_address = 0xC6 >> 1, |
43 | .if_freq = IF_FREQ_5380000HZ, | 52 | .if_freq = IF_FREQ_5380000HZ, |
@@ -65,6 +74,9 @@ static struct s5h1409_config hauppauge_hvr1600_config = { | |||
65 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 74 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK |
66 | }; | 75 | }; |
67 | 76 | ||
77 | /* | ||
78 | * CX18_CARD_LEADTEK_DVR3100H | ||
79 | */ | ||
68 | /* Information/confirmation of proper config values provided by Terry Wu */ | 80 | /* Information/confirmation of proper config values provided by Terry Wu */ |
69 | static struct zl10353_config leadtek_dvr3100h_demod = { | 81 | static struct zl10353_config leadtek_dvr3100h_demod = { |
70 | .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ | 82 | .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ |
@@ -74,6 +86,121 @@ static struct zl10353_config leadtek_dvr3100h_demod = { | |||
74 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ | 86 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ |
75 | }; | 87 | }; |
76 | 88 | ||
89 | /* | ||
90 | * CX18_CARD_YUAN_MPC718 | ||
91 | */ | ||
92 | /* | ||
93 | * Due to | ||
94 | * | ||
95 | * 1. an absence of information on how to prgram the MT352 | ||
96 | * 2. the Linux mt352 module pushing MT352 initialzation off onto us here | ||
97 | * | ||
98 | * We have to use an init sequence that *you* must extract from the Windows | ||
99 | * driver (yuanrap.sys) and which we load as a firmware. | ||
100 | * | ||
101 | * If someone can provide me with a Zarlink MT352 (Intel CE6352?) Design Manual | ||
102 | * with chip programming details, then I can remove this annoyance. | ||
103 | */ | ||
104 | static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream, | ||
105 | const struct firmware **fw) | ||
106 | { | ||
107 | struct cx18 *cx = stream->cx; | ||
108 | const char *fn = "dvb-cx18-mpc718-mt352.fw"; | ||
109 | int ret; | ||
110 | |||
111 | ret = request_firmware(fw, fn, &cx->pci_dev->dev); | ||
112 | if (ret) | ||
113 | CX18_ERR("Unable to open firmware file %s\n", fn); | ||
114 | else { | ||
115 | size_t sz = (*fw)->size; | ||
116 | if (sz < 2 || sz > 64 || (sz % 2) != 0) { | ||
117 | CX18_ERR("Firmware %s has a bad size: %lu bytes\n", | ||
118 | fn, (unsigned long) sz); | ||
119 | ret = -EILSEQ; | ||
120 | release_firmware(*fw); | ||
121 | *fw = NULL; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | if (ret) { | ||
126 | CX18_ERR("The MPC718 board variant with the MT352 DVB-T" | ||
127 | "demodualtor will not work without it\n"); | ||
128 | CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware " | ||
129 | "mpc718' if you need the firmware\n"); | ||
130 | } | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static int yuan_mpc718_mt352_init(struct dvb_frontend *fe) | ||
135 | { | ||
136 | struct cx18_dvb *dvb = container_of(fe->dvb, | ||
137 | struct cx18_dvb, dvb_adapter); | ||
138 | struct cx18_stream *stream = container_of(dvb, struct cx18_stream, dvb); | ||
139 | const struct firmware *fw = NULL; | ||
140 | int ret; | ||
141 | int i; | ||
142 | u8 buf[3]; | ||
143 | |||
144 | ret = yuan_mpc718_mt352_reqfw(stream, &fw); | ||
145 | if (ret) | ||
146 | return ret; | ||
147 | |||
148 | /* Loop through all the register-value pairs in the firmware file */ | ||
149 | for (i = 0; i < fw->size; i += 2) { | ||
150 | buf[0] = fw->data[i]; | ||
151 | /* Intercept a few registers we want to set ourselves */ | ||
152 | switch (buf[0]) { | ||
153 | case TRL_NOMINAL_RATE_0: | ||
154 | /* Set our custom OFDM bandwidth in the case below */ | ||
155 | break; | ||
156 | case TRL_NOMINAL_RATE_1: | ||
157 | /* 6 MHz: 64/7 * 6/8 / 20.48 * 2^16 = 0x55b6.db6 */ | ||
158 | /* 7 MHz: 64/7 * 7/8 / 20.48 * 2^16 = 0x6400 */ | ||
159 | /* 8 MHz: 64/7 * 8/8 / 20.48 * 2^16 = 0x7249.249 */ | ||
160 | buf[1] = 0x72; | ||
161 | buf[2] = 0x49; | ||
162 | mt352_write(fe, buf, 3); | ||
163 | break; | ||
164 | case INPUT_FREQ_0: | ||
165 | /* Set our custom IF in the case below */ | ||
166 | break; | ||
167 | case INPUT_FREQ_1: | ||
168 | /* 4.56 MHz IF: (20.48 - 4.56)/20.48 * 2^14 = 0x31c0 */ | ||
169 | buf[1] = 0x31; | ||
170 | buf[2] = 0xc0; | ||
171 | mt352_write(fe, buf, 3); | ||
172 | break; | ||
173 | default: | ||
174 | /* Pass through the register-value pair from the fw */ | ||
175 | buf[1] = fw->data[i+1]; | ||
176 | mt352_write(fe, buf, 2); | ||
177 | break; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | buf[0] = (u8) TUNER_GO; | ||
182 | buf[1] = 0x01; /* Go */ | ||
183 | mt352_write(fe, buf, 2); | ||
184 | release_firmware(fw); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static struct mt352_config yuan_mpc718_mt352_demod = { | ||
189 | .demod_address = 0x1e >> 1, | ||
190 | .adc_clock = 20480, /* 20.480 MHz */ | ||
191 | .if2 = 4560, /* 4.560 MHz */ | ||
192 | .no_tuner = 1, /* XC3028 is not behind the gate */ | ||
193 | .demod_init = yuan_mpc718_mt352_init, | ||
194 | }; | ||
195 | |||
196 | static struct zl10353_config yuan_mpc718_zl10353_demod = { | ||
197 | .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ | ||
198 | .if2 = 45600, /* 4.560 MHz IF from the XC3028 */ | ||
199 | .parallel_ts = 1, /* Not a serial TS */ | ||
200 | .no_tuner = 1, /* XC3028 is not behind the gate */ | ||
201 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ | ||
202 | }; | ||
203 | |||
77 | static int dvb_register(struct cx18_stream *stream); | 204 | static int dvb_register(struct cx18_stream *stream); |
78 | 205 | ||
79 | /* Kernel DVB framework calls this when the feed needs to start. | 206 | /* Kernel DVB framework calls this when the feed needs to start. |
@@ -113,6 +240,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) | |||
113 | break; | 240 | break; |
114 | 241 | ||
115 | case CX18_CARD_LEADTEK_DVR3100H: | 242 | case CX18_CARD_LEADTEK_DVR3100H: |
243 | case CX18_CARD_YUAN_MPC718: | ||
116 | default: | 244 | default: |
117 | /* Assumption - Parallel transport - Signalling | 245 | /* Assumption - Parallel transport - Signalling |
118 | * undefined or default. | 246 | * undefined or default. |
@@ -326,6 +454,38 @@ static int dvb_register(struct cx18_stream *stream) | |||
326 | fe->ops.tuner_ops.set_config(fe, &ctrl); | 454 | fe->ops.tuner_ops.set_config(fe, &ctrl); |
327 | } | 455 | } |
328 | break; | 456 | break; |
457 | case CX18_CARD_YUAN_MPC718: | ||
458 | /* | ||
459 | * TODO | ||
460 | * Apparently, these cards also could instead have a | ||
461 | * DiBcom demod supported by one of the db7000 drivers | ||
462 | */ | ||
463 | dvb->fe = dvb_attach(mt352_attach, | ||
464 | &yuan_mpc718_mt352_demod, | ||
465 | &cx->i2c_adap[1]); | ||
466 | if (dvb->fe == NULL) | ||
467 | dvb->fe = dvb_attach(zl10353_attach, | ||
468 | &yuan_mpc718_zl10353_demod, | ||
469 | &cx->i2c_adap[1]); | ||
470 | if (dvb->fe != NULL) { | ||
471 | struct dvb_frontend *fe; | ||
472 | struct xc2028_config cfg = { | ||
473 | .i2c_adap = &cx->i2c_adap[1], | ||
474 | .i2c_addr = 0xc2 >> 1, | ||
475 | .ctrl = NULL, | ||
476 | }; | ||
477 | static struct xc2028_ctrl ctrl = { | ||
478 | .fname = XC2028_DEFAULT_FIRMWARE, | ||
479 | .max_len = 64, | ||
480 | .demod = XC3028_FE_ZARLINK456, | ||
481 | .type = XC2028_AUTO, | ||
482 | }; | ||
483 | |||
484 | fe = dvb_attach(xc2028_attach, dvb->fe, &cfg); | ||
485 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | ||
486 | fe->ops.tuner_ops.set_config(fe, &ctrl); | ||
487 | } | ||
488 | break; | ||
329 | default: | 489 | default: |
330 | /* No Digital Tv Support */ | 490 | /* No Digital Tv Support */ |
331 | break; | 491 | break; |
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 48a975134ac5..86ac529e62be 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
@@ -463,6 +463,30 @@ static struct xc5000_config mygica_x8506_xc5000_config = { | |||
463 | .if_khz = 5380, | 463 | .if_khz = 5380, |
464 | }; | 464 | }; |
465 | 465 | ||
466 | static int cx23885_dvb_set_frontend(struct dvb_frontend *fe, | ||
467 | struct dvb_frontend_parameters *param) | ||
468 | { | ||
469 | struct cx23885_tsport *port = fe->dvb->priv; | ||
470 | struct cx23885_dev *dev = port->dev; | ||
471 | |||
472 | switch (dev->board) { | ||
473 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
474 | switch (param->u.vsb.modulation) { | ||
475 | case VSB_8: | ||
476 | cx23885_gpio_clear(dev, GPIO_5); | ||
477 | break; | ||
478 | case QAM_64: | ||
479 | case QAM_256: | ||
480 | default: | ||
481 | cx23885_gpio_set(dev, GPIO_5); | ||
482 | break; | ||
483 | } | ||
484 | break; | ||
485 | } | ||
486 | return (port->set_frontend_save) ? | ||
487 | port->set_frontend_save(fe, param) : -ENODEV; | ||
488 | } | ||
489 | |||
466 | static int dvb_register(struct cx23885_tsport *port) | 490 | static int dvb_register(struct cx23885_tsport *port) |
467 | { | 491 | { |
468 | struct cx23885_dev *dev = port->dev; | 492 | struct cx23885_dev *dev = port->dev; |
@@ -502,6 +526,12 @@ static int dvb_register(struct cx23885_tsport *port) | |||
502 | 0x60, &dev->i2c_bus[1].i2c_adap, | 526 | 0x60, &dev->i2c_bus[1].i2c_adap, |
503 | &hauppauge_hvr127x_config); | 527 | &hauppauge_hvr127x_config); |
504 | } | 528 | } |
529 | |||
530 | /* FIXME: temporary hack */ | ||
531 | /* define bridge override to set_frontend */ | ||
532 | port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend; | ||
533 | fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend; | ||
534 | |||
505 | break; | 535 | break; |
506 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | 536 | case CX23885_BOARD_HAUPPAUGE_HVR1255: |
507 | i2c_bus = &dev->i2c_bus[0]; | 537 | i2c_bus = &dev->i2c_bus[0]; |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 1a2ac518a3f1..214a55e943b7 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -288,6 +288,10 @@ struct cx23885_tsport { | |||
288 | /* Allow a single tsport to have multiple frontends */ | 288 | /* Allow a single tsport to have multiple frontends */ |
289 | u32 num_frontends; | 289 | u32 num_frontends; |
290 | void *port_priv; | 290 | void *port_priv; |
291 | |||
292 | /* FIXME: temporary hack */ | ||
293 | int (*set_frontend_save) (struct dvb_frontend *, | ||
294 | struct dvb_frontend_parameters *); | ||
291 | }; | 295 | }; |
292 | 296 | ||
293 | struct cx23885_dev { | 297 | struct cx23885_dev { |
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index 16a5af30e9d1..6524b493e033 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig | |||
@@ -8,6 +8,8 @@ config VIDEO_EM28XX | |||
8 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO | 8 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO |
9 | select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO | 9 | select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO |
10 | select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO | 10 | select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO |
11 | select VIDEO_MT9V011 if VIDEO_HELPER_CHIPS_AUTO | ||
12 | |||
11 | ---help--- | 13 | ---help--- |
12 | This is a video4linux driver for Empia 28xx based TV cards. | 14 | This is a video4linux driver for Empia 28xx based TV cards. |
13 | 15 | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index c43fdb9bc888..ebd24a25fb85 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -58,6 +58,8 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | |||
58 | module_param_array(card, int, NULL, 0444); | 58 | module_param_array(card, int, NULL, 0444); |
59 | MODULE_PARM_DESC(card, "card type"); | 59 | MODULE_PARM_DESC(card, "card type"); |
60 | 60 | ||
61 | #define MT9V011_VERSION 0x8243 | ||
62 | |||
61 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | 63 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ |
62 | static unsigned long em28xx_devused; | 64 | static unsigned long em28xx_devused; |
63 | 65 | ||
@@ -191,6 +193,13 @@ static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { | |||
191 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | 193 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, |
192 | { -1, -1, -1, -1}, | 194 | { -1, -1, -1, -1}, |
193 | }; | 195 | }; |
196 | |||
197 | static struct em28xx_reg_seq silvercrest_reg_seq[] = { | ||
198 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
199 | {EM28XX_R08_GPIO, 0x01, 0xf7, 10}, | ||
200 | { -1, -1, -1, -1}, | ||
201 | }; | ||
202 | |||
194 | /* | 203 | /* |
195 | * Board definitions | 204 | * Board definitions |
196 | */ | 205 | */ |
@@ -438,6 +447,18 @@ struct em28xx_board em28xx_boards[] = { | |||
438 | .amux = EM28XX_AMUX_VIDEO, | 447 | .amux = EM28XX_AMUX_VIDEO, |
439 | } }, | 448 | } }, |
440 | }, | 449 | }, |
450 | [EM2820_BOARD_SILVERCREST_WEBCAM] = { | ||
451 | .name = "Silvercrest Webcam 1.3mpix", | ||
452 | .tuner_type = TUNER_ABSENT, | ||
453 | .is_27xx = 1, | ||
454 | .decoder = EM28XX_MT9V011, | ||
455 | .input = { { | ||
456 | .type = EM28XX_VMUX_COMPOSITE1, | ||
457 | .vmux = 0, | ||
458 | .amux = EM28XX_AMUX_VIDEO, | ||
459 | .gpio = silvercrest_reg_seq, | ||
460 | } }, | ||
461 | }, | ||
441 | [EM2821_BOARD_SUPERCOMP_USB_2] = { | 462 | [EM2821_BOARD_SUPERCOMP_USB_2] = { |
442 | .name = "Supercomp USB 2.0 TV", | 463 | .name = "Supercomp USB 2.0 TV", |
443 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 464 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
@@ -826,7 +847,7 @@ struct em28xx_board em28xx_boards[] = { | |||
826 | .tuner_gpio = default_tuner_gpio, | 847 | .tuner_gpio = default_tuner_gpio, |
827 | .decoder = EM28XX_TVP5150, | 848 | .decoder = EM28XX_TVP5150, |
828 | .has_dvb = 1, | 849 | .has_dvb = 1, |
829 | .dvb_gpio = default_analog, | 850 | .dvb_gpio = default_digital, |
830 | .input = { { | 851 | .input = { { |
831 | .type = EM28XX_VMUX_TELEVISION, | 852 | .type = EM28XX_VMUX_TELEVISION, |
832 | .vmux = TVP5150_COMPOSITE0, | 853 | .vmux = TVP5150_COMPOSITE0, |
@@ -1639,6 +1660,11 @@ static unsigned short tvp5150_addrs[] = { | |||
1639 | I2C_CLIENT_END | 1660 | I2C_CLIENT_END |
1640 | }; | 1661 | }; |
1641 | 1662 | ||
1663 | static unsigned short mt9v011_addrs[] = { | ||
1664 | 0xba >> 1, | ||
1665 | I2C_CLIENT_END | ||
1666 | }; | ||
1667 | |||
1642 | static unsigned short msp3400_addrs[] = { | 1668 | static unsigned short msp3400_addrs[] = { |
1643 | 0x80 >> 1, | 1669 | 0x80 >> 1, |
1644 | 0x88 >> 1, | 1670 | 0x88 >> 1, |
@@ -1678,6 +1704,46 @@ static inline void em28xx_set_model(struct em28xx *dev) | |||
1678 | EM28XX_I2C_FREQ_100_KHZ; | 1704 | EM28XX_I2C_FREQ_100_KHZ; |
1679 | } | 1705 | } |
1680 | 1706 | ||
1707 | /* HINT method: webcam I2C chips | ||
1708 | * | ||
1709 | * This method work for webcams with Micron sensors | ||
1710 | */ | ||
1711 | static int em28xx_hint_sensor(struct em28xx *dev) | ||
1712 | { | ||
1713 | int rc; | ||
1714 | char *sensor_name; | ||
1715 | unsigned char cmd; | ||
1716 | __be16 version_be; | ||
1717 | u16 version; | ||
1718 | |||
1719 | if (dev->model != EM2820_BOARD_UNKNOWN) | ||
1720 | return 0; | ||
1721 | |||
1722 | dev->i2c_client.addr = 0xba >> 1; | ||
1723 | cmd = 0; | ||
1724 | i2c_master_send(&dev->i2c_client, &cmd, 1); | ||
1725 | rc = i2c_master_recv(&dev->i2c_client, (char *)&version_be, 2); | ||
1726 | if (rc != 2) | ||
1727 | return -EINVAL; | ||
1728 | |||
1729 | version = be16_to_cpu(version_be); | ||
1730 | |||
1731 | switch (version) { | ||
1732 | case MT9V011_VERSION: | ||
1733 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | ||
1734 | sensor_name = "mt9v011"; | ||
1735 | break; | ||
1736 | default: | ||
1737 | printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version)); | ||
1738 | return -EINVAL; | ||
1739 | } | ||
1740 | |||
1741 | em28xx_errdev("Sensor is %s, assuming that webcam is %s\n", | ||
1742 | sensor_name, em28xx_boards[dev->model].name); | ||
1743 | |||
1744 | return 0; | ||
1745 | } | ||
1746 | |||
1681 | /* Since em28xx_pre_card_setup() requires a proper dev->model, | 1747 | /* Since em28xx_pre_card_setup() requires a proper dev->model, |
1682 | * this won't work for boards with generic PCI IDs | 1748 | * this won't work for boards with generic PCI IDs |
1683 | */ | 1749 | */ |
@@ -1706,7 +1772,10 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
1706 | em28xx_info("chip ID is em2750\n"); | 1772 | em28xx_info("chip ID is em2750\n"); |
1707 | break; | 1773 | break; |
1708 | case CHIP_ID_EM2820: | 1774 | case CHIP_ID_EM2820: |
1709 | em28xx_info("chip ID is em2820\n"); | 1775 | if (dev->board.is_27xx) |
1776 | em28xx_info("chip is em2710\n"); | ||
1777 | else | ||
1778 | em28xx_info("chip ID is em2820\n"); | ||
1710 | break; | 1779 | break; |
1711 | case CHIP_ID_EM2840: | 1780 | case CHIP_ID_EM2840: |
1712 | em28xx_info("chip ID is em2840\n"); | 1781 | em28xx_info("chip ID is em2840\n"); |
@@ -2158,6 +2227,10 @@ void em28xx_card_setup(struct em28xx *dev) | |||
2158 | before probing the i2c bus. */ | 2227 | before probing the i2c bus. */ |
2159 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 2228 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
2160 | break; | 2229 | break; |
2230 | case EM2820_BOARD_SILVERCREST_WEBCAM: | ||
2231 | /* FIXME: need to document the registers bellow */ | ||
2232 | em28xx_write_reg(dev, 0x0d, 0x42); | ||
2233 | em28xx_write_reg(dev, 0x13, 0x08); | ||
2161 | } | 2234 | } |
2162 | 2235 | ||
2163 | if (dev->board.has_snapshot_button) | 2236 | if (dev->board.has_snapshot_button) |
@@ -2189,6 +2262,10 @@ void em28xx_card_setup(struct em28xx *dev) | |||
2189 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2262 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2190 | "tvp5150", "tvp5150", tvp5150_addrs); | 2263 | "tvp5150", "tvp5150", tvp5150_addrs); |
2191 | 2264 | ||
2265 | if (dev->board.decoder == EM28XX_MT9V011) | ||
2266 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2267 | "mt9v011", "mt9v011", mt9v011_addrs); | ||
2268 | |||
2192 | if (dev->board.adecoder == EM28XX_TVAUDIO) | 2269 | if (dev->board.adecoder == EM28XX_TVAUDIO) |
2193 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2270 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2194 | "tvaudio", "tvaudio", dev->board.tvaudio_addr); | 2271 | "tvaudio", "tvaudio", dev->board.tvaudio_addr); |
@@ -2333,6 +2410,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2333 | return errCode; | 2410 | return errCode; |
2334 | } | 2411 | } |
2335 | 2412 | ||
2413 | em28xx_hint_sensor(dev); | ||
2414 | |||
2336 | /* Do board specific init and eeprom reading */ | 2415 | /* Do board specific init and eeprom reading */ |
2337 | em28xx_card_setup(dev); | 2416 | em28xx_card_setup(dev); |
2338 | 2417 | ||
@@ -2573,6 +2652,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2573 | retval = em28xx_init_dev(&dev, udev, interface, nr); | 2652 | retval = em28xx_init_dev(&dev, udev, interface, nr); |
2574 | if (retval) { | 2653 | if (retval) { |
2575 | em28xx_devused &= ~(1<<dev->devno); | 2654 | em28xx_devused &= ~(1<<dev->devno); |
2655 | mutex_unlock(&dev->lock); | ||
2576 | kfree(dev); | 2656 | kfree(dev); |
2577 | goto err; | 2657 | goto err; |
2578 | } | 2658 | } |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index c8d7ce8fbd36..079ab4d563a6 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -648,17 +648,28 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
648 | int em28xx_set_outfmt(struct em28xx *dev) | 648 | int em28xx_set_outfmt(struct em28xx *dev) |
649 | { | 649 | { |
650 | int ret; | 650 | int ret; |
651 | int vinmode, vinctl, outfmt; | ||
652 | |||
653 | outfmt = dev->format->reg; | ||
654 | |||
655 | if (dev->board.is_27xx) { | ||
656 | vinmode = 0x0d; | ||
657 | vinctl = 0x00; | ||
658 | } else { | ||
659 | vinmode = 0x10; | ||
660 | vinctl = 0x11; | ||
661 | } | ||
651 | 662 | ||
652 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, | 663 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, |
653 | dev->format->reg | 0x20, 0x3f); | 664 | outfmt | 0x20, 0xff); |
654 | if (ret < 0) | 665 | if (ret < 0) |
655 | return ret; | 666 | return ret; |
656 | 667 | ||
657 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10); | 668 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, vinmode); |
658 | if (ret < 0) | 669 | if (ret < 0) |
659 | return ret; | 670 | return ret; |
660 | 671 | ||
661 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11); | 672 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctl); |
662 | } | 673 | } |
663 | 674 | ||
664 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, | 675 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, |
@@ -695,13 +706,19 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
695 | { | 706 | { |
696 | u8 mode; | 707 | u8 mode; |
697 | /* the em2800 scaler only supports scaling down to 50% */ | 708 | /* the em2800 scaler only supports scaling down to 50% */ |
698 | if (dev->board.is_em2800) | 709 | |
710 | if (dev->board.is_27xx) { | ||
711 | /* FIXME: Don't use the scaler yet */ | ||
712 | mode = 0; | ||
713 | } else if (dev->board.is_em2800) { | ||
699 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | 714 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); |
700 | else { | 715 | } else { |
701 | u8 buf[2]; | 716 | u8 buf[2]; |
717 | |||
702 | buf[0] = h; | 718 | buf[0] = h; |
703 | buf[1] = h >> 8; | 719 | buf[1] = h >> 8; |
704 | em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2); | 720 | em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2); |
721 | |||
705 | buf[0] = v; | 722 | buf[0] = v; |
706 | buf[1] = v >> 8; | 723 | buf[1] = v >> 8; |
707 | em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); | 724 | em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); |
@@ -720,8 +737,11 @@ int em28xx_resolution_set(struct em28xx *dev) | |||
720 | height = norm_maxh(dev) >> 1; | 737 | height = norm_maxh(dev) >> 1; |
721 | 738 | ||
722 | em28xx_set_outfmt(dev); | 739 | em28xx_set_outfmt(dev); |
740 | |||
741 | |||
723 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); | 742 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); |
724 | em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); | 743 | em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); |
744 | |||
725 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); | 745 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); |
726 | } | 746 | } |
727 | 747 | ||
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index e7b47c8da8f3..3da97c32b8fa 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -243,6 +243,14 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { | |||
243 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 243 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK |
244 | }; | 244 | }; |
245 | 245 | ||
246 | static struct zl10353_config em28xx_terratec_xs_zl10353_xc3028 = { | ||
247 | .demod_address = (0x1e >> 1), | ||
248 | .no_tuner = 1, | ||
249 | .disable_i2c_gate_ctrl = 1, | ||
250 | .parallel_ts = 1, | ||
251 | .if2 = 45600, | ||
252 | }; | ||
253 | |||
246 | #ifdef EM28XX_DRX397XD_SUPPORT | 254 | #ifdef EM28XX_DRX397XD_SUPPORT |
247 | /* [TODO] djh - not sure yet what the device config needs to contain */ | 255 | /* [TODO] djh - not sure yet what the device config needs to contain */ |
248 | static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { | 256 | static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { |
@@ -433,7 +441,6 @@ static int dvb_init(struct em28xx *dev) | |||
433 | } | 441 | } |
434 | break; | 442 | break; |
435 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 443 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
436 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
437 | case EM2880_BOARD_KWORLD_DVB_310U: | 444 | case EM2880_BOARD_KWORLD_DVB_310U: |
438 | case EM2880_BOARD_EMPIRE_DUAL_TV: | 445 | case EM2880_BOARD_EMPIRE_DUAL_TV: |
439 | dvb->frontend = dvb_attach(zl10353_attach, | 446 | dvb->frontend = dvb_attach(zl10353_attach, |
@@ -444,6 +451,25 @@ static int dvb_init(struct em28xx *dev) | |||
444 | goto out_free; | 451 | goto out_free; |
445 | } | 452 | } |
446 | break; | 453 | break; |
454 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
455 | dvb->frontend = dvb_attach(zl10353_attach, | ||
456 | &em28xx_terratec_xs_zl10353_xc3028, | ||
457 | &dev->i2c_adap); | ||
458 | if (dvb->frontend == NULL) { | ||
459 | /* This board could have either a zl10353 or a mt352. | ||
460 | If the chip id isn't for zl10353, try mt352 */ | ||
461 | |||
462 | /* FIXME: make support for mt352 work */ | ||
463 | printk(KERN_ERR "version of this board with mt352 not " | ||
464 | "currently supported\n"); | ||
465 | result = -EINVAL; | ||
466 | goto out_free; | ||
467 | } | ||
468 | if (attach_xc3028(0x61, dev) < 0) { | ||
469 | result = -EINVAL; | ||
470 | goto out_free; | ||
471 | } | ||
472 | break; | ||
447 | case EM2883_BOARD_KWORLD_HYBRID_330U: | 473 | case EM2883_BOARD_KWORLD_HYBRID_330U: |
448 | case EM2882_BOARD_EVGA_INDTUBE: | 474 | case EM2882_BOARD_EVGA_INDTUBE: |
449 | dvb->frontend = dvb_attach(s5h1409_attach, | 475 | dvb->frontend = dvb_attach(s5h1409_attach, |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 2c86fcf089f5..27e33a287dfc 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -483,7 +483,7 @@ static char *i2c_devs[128] = { | |||
483 | [0xa0 >> 1] = "eeprom", | 483 | [0xa0 >> 1] = "eeprom", |
484 | [0xb0 >> 1] = "tda9874", | 484 | [0xb0 >> 1] = "tda9874", |
485 | [0xb8 >> 1] = "tvp5150a", | 485 | [0xb8 >> 1] = "tvp5150a", |
486 | [0xba >> 1] = "tvp5150a", | 486 | [0xba >> 1] = "webcam sensor or tvp5150a", |
487 | [0xc0 >> 1] = "tuner (analog)", | 487 | [0xc0 >> 1] = "tuner (analog)", |
488 | [0xc2 >> 1] = "tuner (analog)", | 488 | [0xc2 >> 1] = "tuner (analog)", |
489 | [0xc4 >> 1] = "tuner (analog)", | 489 | [0xc4 >> 1] = "tuner (analog)", |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 8fe1beecfffa..14316c912179 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -90,10 +90,35 @@ MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); | |||
90 | /* supported video standards */ | 90 | /* supported video standards */ |
91 | static struct em28xx_fmt format[] = { | 91 | static struct em28xx_fmt format[] = { |
92 | { | 92 | { |
93 | .name = "16bpp YUY2, 4:2:2, packed", | 93 | .name = "16 bpp YUY2, 4:2:2, packed", |
94 | .fourcc = V4L2_PIX_FMT_YUYV, | 94 | .fourcc = V4L2_PIX_FMT_YUYV, |
95 | .depth = 16, | 95 | .depth = 16, |
96 | .reg = EM28XX_OUTFMT_YUV422_Y0UY1V, | 96 | .reg = EM28XX_OUTFMT_YUV422_Y0UY1V, |
97 | }, { | ||
98 | .name = "16 bpp RGB 565, LE", | ||
99 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
100 | .depth = 16, | ||
101 | .reg = EM28XX_OUTFMT_RGB_16_656, | ||
102 | }, { | ||
103 | .name = "8 bpp Bayer BGBG..GRGR", | ||
104 | .fourcc = V4L2_PIX_FMT_SBGGR8, | ||
105 | .depth = 8, | ||
106 | .reg = EM28XX_OUTFMT_RGB_8_BGBG, | ||
107 | }, { | ||
108 | .name = "8 bpp Bayer GRGR..BGBG", | ||
109 | .fourcc = V4L2_PIX_FMT_SGRBG8, | ||
110 | .depth = 8, | ||
111 | .reg = EM28XX_OUTFMT_RGB_8_GRGR, | ||
112 | }, { | ||
113 | .name = "8 bpp Bayer GBGB..RGRG", | ||
114 | .fourcc = V4L2_PIX_FMT_SGBRG8, | ||
115 | .depth = 8, | ||
116 | .reg = EM28XX_OUTFMT_RGB_8_GBGB, | ||
117 | }, { | ||
118 | .name = "12 bpp YUV411", | ||
119 | .fourcc = V4L2_PIX_FMT_YUV411P, | ||
120 | .depth = 12, | ||
121 | .reg = EM28XX_OUTFMT_YUV411, | ||
97 | }, | 122 | }, |
98 | }; | 123 | }; |
99 | 124 | ||
@@ -701,7 +726,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
701 | return -EINVAL; | 726 | return -EINVAL; |
702 | } | 727 | } |
703 | 728 | ||
704 | if (dev->board.is_em2800) { | 729 | if (dev->board.is_27xx) { |
730 | /* FIXME: This is the only supported fmt */ | ||
731 | width = 640; | ||
732 | height = 480; | ||
733 | } else if (dev->board.is_em2800) { | ||
705 | /* the em2800 can only scale down to 50% */ | 734 | /* the em2800 can only scale down to 50% */ |
706 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; | 735 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; |
707 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; | 736 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; |
@@ -733,13 +762,40 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
733 | return 0; | 762 | return 0; |
734 | } | 763 | } |
735 | 764 | ||
765 | static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, | ||
766 | unsigned width, unsigned height) | ||
767 | { | ||
768 | struct em28xx_fmt *fmt; | ||
769 | |||
770 | /* FIXME: This is the only supported fmt */ | ||
771 | if (dev->board.is_27xx) { | ||
772 | width = 640; | ||
773 | height = 480; | ||
774 | } | ||
775 | |||
776 | fmt = format_by_fourcc(fourcc); | ||
777 | if (!fmt) | ||
778 | return -EINVAL; | ||
779 | |||
780 | dev->format = fmt; | ||
781 | dev->width = width; | ||
782 | dev->height = height; | ||
783 | |||
784 | /* set new image size */ | ||
785 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | ||
786 | |||
787 | em28xx_set_alternate(dev); | ||
788 | em28xx_resolution_set(dev); | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
736 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | 793 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, |
737 | struct v4l2_format *f) | 794 | struct v4l2_format *f) |
738 | { | 795 | { |
739 | struct em28xx_fh *fh = priv; | 796 | struct em28xx_fh *fh = priv; |
740 | struct em28xx *dev = fh->dev; | 797 | struct em28xx *dev = fh->dev; |
741 | int rc; | 798 | int rc; |
742 | struct em28xx_fmt *fmt; | ||
743 | 799 | ||
744 | rc = check_dev(dev); | 800 | rc = check_dev(dev); |
745 | if (rc < 0) | 801 | if (rc < 0) |
@@ -749,12 +805,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
749 | 805 | ||
750 | vidioc_try_fmt_vid_cap(file, priv, f); | 806 | vidioc_try_fmt_vid_cap(file, priv, f); |
751 | 807 | ||
752 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | ||
753 | if (!fmt) { | ||
754 | rc = -EINVAL; | ||
755 | goto out; | ||
756 | } | ||
757 | |||
758 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | 808 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { |
759 | em28xx_errdev("%s queue busy\n", __func__); | 809 | em28xx_errdev("%s queue busy\n", __func__); |
760 | rc = -EBUSY; | 810 | rc = -EBUSY; |
@@ -767,16 +817,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
767 | goto out; | 817 | goto out; |
768 | } | 818 | } |
769 | 819 | ||
770 | /* set new image size */ | 820 | rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat, |
771 | dev->width = f->fmt.pix.width; | 821 | f->fmt.pix.width, f->fmt.pix.height); |
772 | dev->height = f->fmt.pix.height; | ||
773 | dev->format = fmt; | ||
774 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | ||
775 | |||
776 | em28xx_set_alternate(dev); | ||
777 | em28xx_resolution_set(dev); | ||
778 | |||
779 | rc = 0; | ||
780 | 822 | ||
781 | out: | 823 | out: |
782 | mutex_unlock(&dev->lock); | 824 | mutex_unlock(&dev->lock); |
@@ -1616,11 +1658,6 @@ static int em28xx_v4l2_open(struct file *filp) | |||
1616 | filp->private_data = fh; | 1658 | filp->private_data = fh; |
1617 | 1659 | ||
1618 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | 1660 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { |
1619 | dev->width = norm_maxw(dev); | ||
1620 | dev->height = norm_maxh(dev); | ||
1621 | dev->hscale = 0; | ||
1622 | dev->vscale = 0; | ||
1623 | |||
1624 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 1661 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
1625 | em28xx_set_alternate(dev); | 1662 | em28xx_set_alternate(dev); |
1626 | em28xx_resolution_set(dev); | 1663 | em28xx_resolution_set(dev); |
@@ -1962,15 +1999,14 @@ int em28xx_register_analog_devices(struct em28xx *dev) | |||
1962 | 1999 | ||
1963 | /* set default norm */ | 2000 | /* set default norm */ |
1964 | dev->norm = em28xx_video_template.current_norm; | 2001 | dev->norm = em28xx_video_template.current_norm; |
1965 | dev->width = norm_maxw(dev); | ||
1966 | dev->height = norm_maxh(dev); | ||
1967 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | 2002 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; |
1968 | dev->hscale = 0; | ||
1969 | dev->vscale = 0; | ||
1970 | dev->ctl_input = 0; | 2003 | dev->ctl_input = 0; |
1971 | 2004 | ||
1972 | /* Analog specific initialization */ | 2005 | /* Analog specific initialization */ |
1973 | dev->format = &format[0]; | 2006 | dev->format = &format[0]; |
2007 | em28xx_set_video_format(dev, format[0].fourcc, | ||
2008 | norm_maxw(dev), norm_maxh(dev)); | ||
2009 | |||
1974 | video_mux(dev, dev->ctl_input); | 2010 | video_mux(dev, dev->ctl_input); |
1975 | 2011 | ||
1976 | /* Audio defaults */ | 2012 | /* Audio defaults */ |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 813ce45c2f99..d90fef463764 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -107,6 +107,7 @@ | |||
107 | #define EM2860_BOARD_TERRATEC_AV350 68 | 107 | #define EM2860_BOARD_TERRATEC_AV350 68 |
108 | #define EM2882_BOARD_KWORLD_ATSC_315U 69 | 108 | #define EM2882_BOARD_KWORLD_ATSC_315U 69 |
109 | #define EM2882_BOARD_EVGA_INDTUBE 70 | 109 | #define EM2882_BOARD_EVGA_INDTUBE 70 |
110 | #define EM2820_BOARD_SILVERCREST_WEBCAM 71 | ||
110 | 111 | ||
111 | /* Limits minimum and default number of buffers */ | 112 | /* Limits minimum and default number of buffers */ |
112 | #define EM28XX_MIN_BUF 4 | 113 | #define EM28XX_MIN_BUF 4 |
@@ -360,6 +361,7 @@ enum em28xx_decoder { | |||
360 | EM28XX_NODECODER, | 361 | EM28XX_NODECODER, |
361 | EM28XX_TVP5150, | 362 | EM28XX_TVP5150, |
362 | EM28XX_SAA711X, | 363 | EM28XX_SAA711X, |
364 | EM28XX_MT9V011, | ||
363 | }; | 365 | }; |
364 | 366 | ||
365 | enum em28xx_adecoder { | 367 | enum em28xx_adecoder { |
@@ -388,6 +390,7 @@ struct em28xx_board { | |||
388 | unsigned int max_range_640_480:1; | 390 | unsigned int max_range_640_480:1; |
389 | unsigned int has_dvb:1; | 391 | unsigned int has_dvb:1; |
390 | unsigned int has_snapshot_button:1; | 392 | unsigned int has_snapshot_button:1; |
393 | unsigned int is_27xx:1; | ||
391 | unsigned int valid:1; | 394 | unsigned int valid:1; |
392 | 395 | ||
393 | unsigned char xclk, i2c_speed; | 396 | unsigned char xclk, i2c_speed; |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h index 9df7137fe67e..992ce530f138 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx.h | |||
@@ -36,10 +36,6 @@ | |||
36 | 36 | ||
37 | #define STV_ISOC_ENDPOINT_ADDR 0x81 | 37 | #define STV_ISOC_ENDPOINT_ADDR 0x81 |
38 | 38 | ||
39 | #ifndef V4L2_PIX_FMT_SGRBG8 | ||
40 | #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') | ||
41 | #endif | ||
42 | |||
43 | #define STV_REG23 0x0423 | 39 | #define STV_REG23 0x0423 |
44 | 40 | ||
45 | /* Control registers of the STV0600 ASIC */ | 41 | /* Control registers of the STV0600 ASIC */ |
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c new file mode 100644 index 000000000000..1fe8fc9183a7 --- /dev/null +++ b/drivers/media/video/mt9v011.c | |||
@@ -0,0 +1,431 @@ | |||
1 | /* | ||
2 | * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor | ||
3 | * | ||
4 | * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) | ||
5 | * This code is placed under the terms of the GNU General Public License v2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/i2c.h> | ||
9 | #include <linux/videodev2.h> | ||
10 | #include <linux/delay.h> | ||
11 | #include <media/v4l2-device.h> | ||
12 | #include "mt9v011.h" | ||
13 | #include <media/v4l2-i2c-drv.h> | ||
14 | #include <media/v4l2-chip-ident.h> | ||
15 | |||
16 | MODULE_DESCRIPTION("Micron mt9v011 sensor driver"); | ||
17 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | ||
18 | MODULE_LICENSE("GPL"); | ||
19 | |||
20 | |||
21 | static int debug; | ||
22 | module_param(debug, int, 0); | ||
23 | MODULE_PARM_DESC(debug, "Debug level (0-2)"); | ||
24 | |||
25 | /* supported controls */ | ||
26 | static struct v4l2_queryctrl mt9v011_qctrl[] = { | ||
27 | { | ||
28 | .id = V4L2_CID_GAIN, | ||
29 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
30 | .name = "Gain", | ||
31 | .minimum = 0, | ||
32 | .maximum = (1 << 10) - 1, | ||
33 | .step = 1, | ||
34 | .default_value = 0x0020, | ||
35 | .flags = 0, | ||
36 | }, { | ||
37 | .id = V4L2_CID_RED_BALANCE, | ||
38 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
39 | .name = "Red Balance", | ||
40 | .minimum = -1 << 9, | ||
41 | .maximum = (1 << 9) - 1, | ||
42 | .step = 1, | ||
43 | .default_value = 0, | ||
44 | .flags = 0, | ||
45 | }, { | ||
46 | .id = V4L2_CID_BLUE_BALANCE, | ||
47 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
48 | .name = "Blue Balance", | ||
49 | .minimum = -1 << 9, | ||
50 | .maximum = (1 << 9) - 1, | ||
51 | .step = 1, | ||
52 | .default_value = 0, | ||
53 | .flags = 0, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | struct mt9v011 { | ||
58 | struct v4l2_subdev sd; | ||
59 | unsigned width, height; | ||
60 | |||
61 | u16 global_gain, red_bal, blue_bal; | ||
62 | }; | ||
63 | |||
64 | static inline struct mt9v011 *to_mt9v011(struct v4l2_subdev *sd) | ||
65 | { | ||
66 | return container_of(sd, struct mt9v011, sd); | ||
67 | } | ||
68 | |||
69 | static int mt9v011_read(struct v4l2_subdev *sd, unsigned char addr) | ||
70 | { | ||
71 | struct i2c_client *c = v4l2_get_subdevdata(sd); | ||
72 | __be16 buffer; | ||
73 | int rc, val; | ||
74 | |||
75 | rc = i2c_master_send(c, &addr, 1); | ||
76 | if (rc != 1) | ||
77 | v4l2_dbg(0, debug, sd, | ||
78 | "i2c i/o error: rc == %d (should be 1)\n", rc); | ||
79 | |||
80 | msleep(10); | ||
81 | |||
82 | rc = i2c_master_recv(c, (char *)&buffer, 2); | ||
83 | if (rc != 2) | ||
84 | v4l2_dbg(0, debug, sd, | ||
85 | "i2c i/o error: rc == %d (should be 2)\n", rc); | ||
86 | |||
87 | val = be16_to_cpu(buffer); | ||
88 | |||
89 | v4l2_dbg(2, debug, sd, "mt9v011: read 0x%02x = 0x%04x\n", addr, val); | ||
90 | |||
91 | return val; | ||
92 | } | ||
93 | |||
94 | static void mt9v011_write(struct v4l2_subdev *sd, unsigned char addr, | ||
95 | u16 value) | ||
96 | { | ||
97 | struct i2c_client *c = v4l2_get_subdevdata(sd); | ||
98 | unsigned char buffer[3]; | ||
99 | int rc; | ||
100 | |||
101 | buffer[0] = addr; | ||
102 | buffer[1] = value >> 8; | ||
103 | buffer[2] = value & 0xff; | ||
104 | |||
105 | v4l2_dbg(2, debug, sd, | ||
106 | "mt9v011: writing 0x%02x 0x%04x\n", buffer[0], value); | ||
107 | rc = i2c_master_send(c, buffer, 3); | ||
108 | if (rc != 3) | ||
109 | v4l2_dbg(0, debug, sd, | ||
110 | "i2c i/o error: rc == %d (should be 3)\n", rc); | ||
111 | } | ||
112 | |||
113 | |||
114 | struct i2c_reg_value { | ||
115 | unsigned char reg; | ||
116 | u16 value; | ||
117 | }; | ||
118 | |||
119 | /* | ||
120 | * Values used at the original driver | ||
121 | * Some values are marked as Reserved at the datasheet | ||
122 | */ | ||
123 | static const struct i2c_reg_value mt9v011_init_default[] = { | ||
124 | { R0D_MT9V011_RESET, 0x0001 }, | ||
125 | { R0D_MT9V011_RESET, 0x0000 }, | ||
126 | |||
127 | { R0C_MT9V011_SHUTTER_DELAY, 0x0000 }, | ||
128 | { R09_MT9V011_SHUTTER_WIDTH, 0x1fc }, | ||
129 | |||
130 | { R0A_MT9V011_CLK_SPEED, 0x0000 }, | ||
131 | { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, | ||
132 | { R20_MT9V011_READ_MODE, 0x1000 }, | ||
133 | |||
134 | { R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */ | ||
135 | }; | ||
136 | |||
137 | static void set_balance(struct v4l2_subdev *sd) | ||
138 | { | ||
139 | struct mt9v011 *core = to_mt9v011(sd); | ||
140 | u16 green1_gain, green2_gain, blue_gain, red_gain; | ||
141 | |||
142 | green1_gain = core->global_gain; | ||
143 | green2_gain = core->global_gain; | ||
144 | |||
145 | blue_gain = core->global_gain + | ||
146 | core->global_gain * core->blue_bal / (1 << 9); | ||
147 | |||
148 | red_gain = core->global_gain + | ||
149 | core->global_gain * core->blue_bal / (1 << 9); | ||
150 | |||
151 | mt9v011_write(sd, R2B_MT9V011_GREEN_1_GAIN, green1_gain); | ||
152 | mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green1_gain); | ||
153 | mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain); | ||
154 | mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); | ||
155 | } | ||
156 | |||
157 | static void set_res(struct v4l2_subdev *sd) | ||
158 | { | ||
159 | struct mt9v011 *core = to_mt9v011(sd); | ||
160 | unsigned vstart, hstart; | ||
161 | |||
162 | /* | ||
163 | * The mt9v011 doesn't have scaling. So, in order to select the desired | ||
164 | * resolution, we're cropping at the middle of the sensor. | ||
165 | * hblank and vblank should be adjusted, in order to warrant that | ||
166 | * we'll preserve the line timings for 30 fps, no matter what resolution | ||
167 | * is selected. | ||
168 | * NOTE: datasheet says that width (and height) should be filled with | ||
169 | * width-1. However, this doesn't work, since one pixel per line will | ||
170 | * be missing. | ||
171 | */ | ||
172 | |||
173 | hstart = 14 + (640 - core->width) / 2; | ||
174 | mt9v011_write(sd, R02_MT9V011_COLSTART, hstart); | ||
175 | mt9v011_write(sd, R04_MT9V011_WIDTH, core->width); | ||
176 | mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width); | ||
177 | |||
178 | vstart = 8 + (640 - core->height) / 2; | ||
179 | mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); | ||
180 | mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); | ||
181 | mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); | ||
182 | }; | ||
183 | |||
184 | static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) | ||
185 | { | ||
186 | int i; | ||
187 | |||
188 | for (i = 0; i < ARRAY_SIZE(mt9v011_init_default); i++) | ||
189 | mt9v011_write(sd, mt9v011_init_default[i].reg, | ||
190 | mt9v011_init_default[i].value); | ||
191 | |||
192 | set_balance(sd); | ||
193 | set_res(sd); | ||
194 | |||
195 | return 0; | ||
196 | }; | ||
197 | |||
198 | static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
199 | { | ||
200 | struct mt9v011 *core = to_mt9v011(sd); | ||
201 | |||
202 | v4l2_dbg(1, debug, sd, "g_ctrl called\n"); | ||
203 | |||
204 | switch (ctrl->id) { | ||
205 | case V4L2_CID_GAIN: | ||
206 | ctrl->value = core->global_gain; | ||
207 | return 0; | ||
208 | case V4L2_CID_RED_BALANCE: | ||
209 | ctrl->value = core->red_bal; | ||
210 | return 0; | ||
211 | case V4L2_CID_BLUE_BALANCE: | ||
212 | ctrl->value = core->blue_bal; | ||
213 | return 0; | ||
214 | } | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
219 | { | ||
220 | struct mt9v011 *core = to_mt9v011(sd); | ||
221 | u8 i, n; | ||
222 | n = ARRAY_SIZE(mt9v011_qctrl); | ||
223 | |||
224 | for (i = 0; i < n; i++) { | ||
225 | if (ctrl->id != mt9v011_qctrl[i].id) | ||
226 | continue; | ||
227 | if (ctrl->value < mt9v011_qctrl[i].minimum || | ||
228 | ctrl->value > mt9v011_qctrl[i].maximum) | ||
229 | return -ERANGE; | ||
230 | v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n", | ||
231 | ctrl->id, ctrl->value); | ||
232 | break; | ||
233 | } | ||
234 | |||
235 | switch (ctrl->id) { | ||
236 | case V4L2_CID_GAIN: | ||
237 | core->global_gain = ctrl->value; | ||
238 | break; | ||
239 | case V4L2_CID_RED_BALANCE: | ||
240 | core->red_bal = ctrl->value; | ||
241 | break; | ||
242 | case V4L2_CID_BLUE_BALANCE: | ||
243 | core->blue_bal = ctrl->value; | ||
244 | break; | ||
245 | default: | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | set_balance(sd); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int mt9v011_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) | ||
255 | { | ||
256 | if (fmt->index > 0) | ||
257 | return -EINVAL; | ||
258 | |||
259 | fmt->flags = 0; | ||
260 | strcpy(fmt->description, "8 bpp Bayer GRGR..BGBG"); | ||
261 | fmt->pixelformat = V4L2_PIX_FMT_SGRBG8; | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | ||
267 | { | ||
268 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
269 | |||
270 | if (pix->pixelformat != V4L2_PIX_FMT_SGRBG8) | ||
271 | return -EINVAL; | ||
272 | |||
273 | v4l_bound_align_image(&pix->width, 48, 639, 1, | ||
274 | &pix->height, 32, 480, 1, 0); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | ||
280 | { | ||
281 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
282 | struct mt9v011 *core = to_mt9v011(sd); | ||
283 | int rc; | ||
284 | |||
285 | rc = mt9v011_try_fmt(sd, fmt); | ||
286 | if (rc < 0) | ||
287 | return -EINVAL; | ||
288 | |||
289 | core->width = pix->width; | ||
290 | core->height = pix->height; | ||
291 | |||
292 | set_res(sd); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | |||
298 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
299 | static int mt9v011_g_register(struct v4l2_subdev *sd, | ||
300 | struct v4l2_dbg_register *reg) | ||
301 | { | ||
302 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
303 | |||
304 | if (!v4l2_chip_match_i2c_client(client, ®->match)) | ||
305 | return -EINVAL; | ||
306 | if (!capable(CAP_SYS_ADMIN)) | ||
307 | return -EPERM; | ||
308 | |||
309 | reg->val = mt9v011_read(sd, reg->reg & 0xff); | ||
310 | reg->size = 2; | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int mt9v011_s_register(struct v4l2_subdev *sd, | ||
316 | struct v4l2_dbg_register *reg) | ||
317 | { | ||
318 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
319 | |||
320 | if (!v4l2_chip_match_i2c_client(client, ®->match)) | ||
321 | return -EINVAL; | ||
322 | if (!capable(CAP_SYS_ADMIN)) | ||
323 | return -EPERM; | ||
324 | |||
325 | mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | #endif | ||
330 | |||
331 | static int mt9v011_g_chip_ident(struct v4l2_subdev *sd, | ||
332 | struct v4l2_dbg_chip_ident *chip) | ||
333 | { | ||
334 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
335 | |||
336 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011, | ||
337 | MT9V011_VERSION); | ||
338 | } | ||
339 | |||
340 | static const struct v4l2_subdev_core_ops mt9v011_core_ops = { | ||
341 | .g_ctrl = mt9v011_g_ctrl, | ||
342 | .s_ctrl = mt9v011_s_ctrl, | ||
343 | .reset = mt9v011_reset, | ||
344 | .g_chip_ident = mt9v011_g_chip_ident, | ||
345 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
346 | .g_register = mt9v011_g_register, | ||
347 | .s_register = mt9v011_s_register, | ||
348 | #endif | ||
349 | }; | ||
350 | |||
351 | static const struct v4l2_subdev_video_ops mt9v011_video_ops = { | ||
352 | .enum_fmt = mt9v011_enum_fmt, | ||
353 | .try_fmt = mt9v011_try_fmt, | ||
354 | .s_fmt = mt9v011_s_fmt, | ||
355 | }; | ||
356 | |||
357 | static const struct v4l2_subdev_ops mt9v011_ops = { | ||
358 | .core = &mt9v011_core_ops, | ||
359 | .video = &mt9v011_video_ops, | ||
360 | }; | ||
361 | |||
362 | |||
363 | /**************************************************************************** | ||
364 | I2C Client & Driver | ||
365 | ****************************************************************************/ | ||
366 | |||
367 | static int mt9v011_probe(struct i2c_client *c, | ||
368 | const struct i2c_device_id *id) | ||
369 | { | ||
370 | u16 version; | ||
371 | struct mt9v011 *core; | ||
372 | struct v4l2_subdev *sd; | ||
373 | |||
374 | /* Check if the adapter supports the needed features */ | ||
375 | if (!i2c_check_functionality(c->adapter, | ||
376 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
377 | return -EIO; | ||
378 | |||
379 | core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL); | ||
380 | if (!core) | ||
381 | return -ENOMEM; | ||
382 | |||
383 | sd = &core->sd; | ||
384 | v4l2_i2c_subdev_init(sd, c, &mt9v011_ops); | ||
385 | |||
386 | /* Check if the sensor is really a MT9V011 */ | ||
387 | version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION); | ||
388 | if (version != MT9V011_VERSION) { | ||
389 | v4l2_info(sd, "*** unknown micron chip detected (0x%04x.\n", | ||
390 | version); | ||
391 | kfree(core); | ||
392 | return -EINVAL; | ||
393 | } | ||
394 | |||
395 | core->global_gain = 0x0024; | ||
396 | core->width = 640; | ||
397 | core->height = 480; | ||
398 | |||
399 | v4l_info(c, "chip found @ 0x%02x (%s)\n", | ||
400 | c->addr << 1, c->adapter->name); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int mt9v011_remove(struct i2c_client *c) | ||
406 | { | ||
407 | struct v4l2_subdev *sd = i2c_get_clientdata(c); | ||
408 | |||
409 | v4l2_dbg(1, debug, sd, | ||
410 | "mt9v011.c: removing mt9v011 adapter on address 0x%x\n", | ||
411 | c->addr << 1); | ||
412 | |||
413 | v4l2_device_unregister_subdev(sd); | ||
414 | kfree(to_mt9v011(sd)); | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | /* ----------------------------------------------------------------------- */ | ||
419 | |||
420 | static const struct i2c_device_id mt9v011_id[] = { | ||
421 | { "mt9v011", 0 }, | ||
422 | { } | ||
423 | }; | ||
424 | MODULE_DEVICE_TABLE(i2c, mt9v011_id); | ||
425 | |||
426 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | ||
427 | .name = "mt9v011", | ||
428 | .probe = mt9v011_probe, | ||
429 | .remove = mt9v011_remove, | ||
430 | .id_table = mt9v011_id, | ||
431 | }; | ||
diff --git a/drivers/media/video/mt9v011.h b/drivers/media/video/mt9v011.h new file mode 100644 index 000000000000..9e443ee30558 --- /dev/null +++ b/drivers/media/video/mt9v011.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor | ||
3 | * | ||
4 | * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) | ||
5 | * This code is placed under the terms of the GNU General Public License v2 | ||
6 | */ | ||
7 | |||
8 | #ifndef MT9V011_H_ | ||
9 | #define MT9V011_H_ | ||
10 | |||
11 | #define R00_MT9V011_CHIP_VERSION 0x00 | ||
12 | #define R01_MT9V011_ROWSTART 0x01 | ||
13 | #define R02_MT9V011_COLSTART 0x02 | ||
14 | #define R03_MT9V011_HEIGHT 0x03 | ||
15 | #define R04_MT9V011_WIDTH 0x04 | ||
16 | #define R05_MT9V011_HBLANK 0x05 | ||
17 | #define R06_MT9V011_VBLANK 0x06 | ||
18 | #define R07_MT9V011_OUT_CTRL 0x07 | ||
19 | #define R09_MT9V011_SHUTTER_WIDTH 0x09 | ||
20 | #define R0A_MT9V011_CLK_SPEED 0x0a | ||
21 | #define R0B_MT9V011_RESTART 0x0b | ||
22 | #define R0C_MT9V011_SHUTTER_DELAY 0x0c | ||
23 | #define R0D_MT9V011_RESET 0x0d | ||
24 | #define R1E_MT9V011_DIGITAL_ZOOM 0x1e | ||
25 | #define R20_MT9V011_READ_MODE 0x20 | ||
26 | #define R2B_MT9V011_GREEN_1_GAIN 0x2b | ||
27 | #define R2C_MT9V011_BLUE_GAIN 0x2c | ||
28 | #define R2D_MT9V011_RED_GAIN 0x2d | ||
29 | #define R2E_MT9V011_GREEN_2_GAIN 0x2e | ||
30 | #define R35_MT9V011_GLOBAL_GAIN 0x35 | ||
31 | #define RF1_MT9V011_CHIP_ENABLE 0xf1 | ||
32 | |||
33 | #define MT9V011_VERSION 0x8243 | ||
34 | |||
35 | #endif | ||
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 16f595d4337a..9f5ae8167855 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -237,11 +237,11 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) | |||
237 | return -ENOMEM; | 237 | return -ENOMEM; |
238 | 238 | ||
239 | icd->num_user_formats = fmts; | 239 | icd->num_user_formats = fmts; |
240 | fmts = 0; | ||
241 | 240 | ||
242 | dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts); | 241 | dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts); |
243 | 242 | ||
244 | /* Second pass - actually fill data formats */ | 243 | /* Second pass - actually fill data formats */ |
244 | fmts = 0; | ||
245 | for (i = 0; i < icd->num_formats; i++) | 245 | for (i = 0; i < icd->num_formats; i++) |
246 | if (!ici->ops->get_formats) { | 246 | if (!ici->ops->get_formats) { |
247 | icd->user_formats[i].host_fmt = icd->formats + i; | 247 | icd->user_formats[i].host_fmt = icd->formats + i; |
@@ -877,8 +877,11 @@ static int soc_camera_probe(struct device *dev) | |||
877 | (unsigned short)~0; | 877 | (unsigned short)~0; |
878 | 878 | ||
879 | ret = soc_camera_init_user_formats(icd); | 879 | ret = soc_camera_init_user_formats(icd); |
880 | if (ret < 0) | 880 | if (ret < 0) { |
881 | if (icd->ops->remove) | ||
882 | icd->ops->remove(icd); | ||
881 | goto eiufmt; | 883 | goto eiufmt; |
884 | } | ||
882 | 885 | ||
883 | icd->height = DEFAULT_HEIGHT; | 886 | icd->height = DEFAULT_HEIGHT; |
884 | icd->width = DEFAULT_WIDTH; | 887 | icd->width = DEFAULT_WIDTH; |
@@ -902,8 +905,10 @@ static int soc_camera_remove(struct device *dev) | |||
902 | { | 905 | { |
903 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | 906 | struct soc_camera_device *icd = to_soc_camera_dev(dev); |
904 | 907 | ||
908 | mutex_lock(&icd->video_lock); | ||
905 | if (icd->ops->remove) | 909 | if (icd->ops->remove) |
906 | icd->ops->remove(icd); | 910 | icd->ops->remove(icd); |
911 | mutex_unlock(&icd->video_lock); | ||
907 | 912 | ||
908 | soc_camera_free_user_formats(icd); | 913 | soc_camera_free_user_formats(icd); |
909 | 914 | ||
@@ -1145,6 +1150,7 @@ evidallocd: | |||
1145 | } | 1150 | } |
1146 | EXPORT_SYMBOL(soc_camera_video_start); | 1151 | EXPORT_SYMBOL(soc_camera_video_start); |
1147 | 1152 | ||
1153 | /* Called from client .remove() methods with .video_lock held */ | ||
1148 | void soc_camera_video_stop(struct soc_camera_device *icd) | 1154 | void soc_camera_video_stop(struct soc_camera_device *icd) |
1149 | { | 1155 | { |
1150 | struct video_device *vdev = icd->vdev; | 1156 | struct video_device *vdev = icd->vdev; |
@@ -1154,10 +1160,8 @@ void soc_camera_video_stop(struct soc_camera_device *icd) | |||
1154 | if (!icd->dev.parent || !vdev) | 1160 | if (!icd->dev.parent || !vdev) |
1155 | return; | 1161 | return; |
1156 | 1162 | ||
1157 | mutex_lock(&icd->video_lock); | ||
1158 | video_unregister_device(vdev); | 1163 | video_unregister_device(vdev); |
1159 | icd->vdev = NULL; | 1164 | icd->vdev = NULL; |
1160 | mutex_unlock(&icd->video_lock); | ||
1161 | } | 1165 | } |
1162 | EXPORT_SYMBOL(soc_camera_video_stop); | 1166 | EXPORT_SYMBOL(soc_camera_video_stop); |
1163 | 1167 | ||
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index cd7266858462..7705fc6baf00 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -343,6 +343,53 @@ static struct bar_std bars[] = { | |||
343 | #define TO_U(r, g, b) \ | 343 | #define TO_U(r, g, b) \ |
344 | (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) | 344 | (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) |
345 | 345 | ||
346 | /* precalculate color bar values to speed up rendering */ | ||
347 | static void precalculate_bars(struct vivi_fh *fh) | ||
348 | { | ||
349 | struct vivi_dev *dev = fh->dev; | ||
350 | unsigned char r, g, b; | ||
351 | int k, is_yuv; | ||
352 | |||
353 | fh->input = dev->input; | ||
354 | |||
355 | for (k = 0; k < 8; k++) { | ||
356 | r = bars[fh->input].bar[k][0]; | ||
357 | g = bars[fh->input].bar[k][1]; | ||
358 | b = bars[fh->input].bar[k][2]; | ||
359 | is_yuv = 0; | ||
360 | |||
361 | switch (fh->fmt->fourcc) { | ||
362 | case V4L2_PIX_FMT_YUYV: | ||
363 | case V4L2_PIX_FMT_UYVY: | ||
364 | is_yuv = 1; | ||
365 | break; | ||
366 | case V4L2_PIX_FMT_RGB565: | ||
367 | case V4L2_PIX_FMT_RGB565X: | ||
368 | r >>= 3; | ||
369 | g >>= 2; | ||
370 | b >>= 3; | ||
371 | break; | ||
372 | case V4L2_PIX_FMT_RGB555: | ||
373 | case V4L2_PIX_FMT_RGB555X: | ||
374 | r >>= 3; | ||
375 | g >>= 3; | ||
376 | b >>= 3; | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | if (is_yuv) { | ||
381 | fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ | ||
382 | fh->bars[k][1] = TO_U(r, g, b); /* Cb */ | ||
383 | fh->bars[k][2] = TO_V(r, g, b); /* Cr */ | ||
384 | } else { | ||
385 | fh->bars[k][0] = r; | ||
386 | fh->bars[k][1] = g; | ||
387 | fh->bars[k][2] = b; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | } | ||
392 | |||
346 | #define TSTAMP_MIN_Y 24 | 393 | #define TSTAMP_MIN_Y 24 |
347 | #define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15) | 394 | #define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15) |
348 | #define TSTAMP_INPUT_X 10 | 395 | #define TSTAMP_INPUT_X 10 |
@@ -755,6 +802,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
755 | buf->vb.height = fh->height; | 802 | buf->vb.height = fh->height; |
756 | buf->vb.field = field; | 803 | buf->vb.field = field; |
757 | 804 | ||
805 | precalculate_bars(fh); | ||
806 | |||
758 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 807 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
759 | rc = videobuf_iolock(vq, &buf->vb, NULL); | 808 | rc = videobuf_iolock(vq, &buf->vb, NULL); |
760 | if (rc < 0) | 809 | if (rc < 0) |
@@ -893,53 +942,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
893 | return 0; | 942 | return 0; |
894 | } | 943 | } |
895 | 944 | ||
896 | /* precalculate color bar values to speed up rendering */ | ||
897 | static void precalculate_bars(struct vivi_fh *fh) | ||
898 | { | ||
899 | struct vivi_dev *dev = fh->dev; | ||
900 | unsigned char r, g, b; | ||
901 | int k, is_yuv; | ||
902 | |||
903 | fh->input = dev->input; | ||
904 | |||
905 | for (k = 0; k < 8; k++) { | ||
906 | r = bars[fh->input].bar[k][0]; | ||
907 | g = bars[fh->input].bar[k][1]; | ||
908 | b = bars[fh->input].bar[k][2]; | ||
909 | is_yuv = 0; | ||
910 | |||
911 | switch (fh->fmt->fourcc) { | ||
912 | case V4L2_PIX_FMT_YUYV: | ||
913 | case V4L2_PIX_FMT_UYVY: | ||
914 | is_yuv = 1; | ||
915 | break; | ||
916 | case V4L2_PIX_FMT_RGB565: | ||
917 | case V4L2_PIX_FMT_RGB565X: | ||
918 | r >>= 3; | ||
919 | g >>= 2; | ||
920 | b >>= 3; | ||
921 | break; | ||
922 | case V4L2_PIX_FMT_RGB555: | ||
923 | case V4L2_PIX_FMT_RGB555X: | ||
924 | r >>= 3; | ||
925 | g >>= 3; | ||
926 | b >>= 3; | ||
927 | break; | ||
928 | } | ||
929 | |||
930 | if (is_yuv) { | ||
931 | fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ | ||
932 | fh->bars[k][1] = TO_U(r, g, b); /* Cb */ | ||
933 | fh->bars[k][2] = TO_V(r, g, b); /* Cr */ | ||
934 | } else { | ||
935 | fh->bars[k][0] = r; | ||
936 | fh->bars[k][1] = g; | ||
937 | fh->bars[k][2] = b; | ||
938 | } | ||
939 | } | ||
940 | |||
941 | } | ||
942 | |||
943 | /*FIXME: This seems to be generic enough to be at videodev2 */ | 945 | /*FIXME: This seems to be generic enough to be at videodev2 */ |
944 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | 946 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, |
945 | struct v4l2_format *f) | 947 | struct v4l2_format *f) |
@@ -965,8 +967,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
965 | fh->vb_vidq.field = f->fmt.pix.field; | 967 | fh->vb_vidq.field = f->fmt.pix.field; |
966 | fh->type = f->type; | 968 | fh->type = f->type; |
967 | 969 | ||
968 | precalculate_bars(fh); | ||
969 | |||
970 | ret = 0; | 970 | ret = 0; |
971 | out: | 971 | out: |
972 | mutex_unlock(&q->vb_lock); | 972 | mutex_unlock(&q->vb_lock); |
@@ -1357,6 +1357,7 @@ static int __init vivi_create_instance(int inst) | |||
1357 | goto unreg_dev; | 1357 | goto unreg_dev; |
1358 | 1358 | ||
1359 | *vfd = vivi_template; | 1359 | *vfd = vivi_template; |
1360 | vfd->debug = debug; | ||
1360 | 1361 | ||
1361 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); | 1362 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); |
1362 | if (ret < 0) | 1363 | if (ret < 0) |
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c index 7ac12cb0be4a..5b6e58a3ba46 100644 --- a/drivers/mfd/dm355evm_msp.c +++ b/drivers/mfd/dm355evm_msp.c | |||
@@ -32,8 +32,7 @@ | |||
32 | * This driver was tested with firmware revision A4. | 32 | * This driver was tested with firmware revision A4. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #if defined(CONFIG_KEYBOARD_DM355EVM) \ | 35 | #if defined(CONFIG_INPUT_DM355EVM) || defined(CONFIG_INPUT_DM355EVM_MODULE) |
36 | || defined(CONFIG_KEYBOARD_DM355EVM_MODULE) | ||
37 | #define msp_has_keyboard() true | 36 | #define msp_has_keyboard() true |
38 | #else | 37 | #else |
39 | #define msp_has_keyboard() false | 38 | #define msp_has_keyboard() false |
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index 671a7efe86a8..c1de4afa89a6 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c | |||
@@ -238,8 +238,10 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap) | |||
238 | mutex_lock(&pcap->adc_mutex); | 238 | mutex_lock(&pcap->adc_mutex); |
239 | req = pcap->adc_queue[pcap->adc_head]; | 239 | req = pcap->adc_queue[pcap->adc_head]; |
240 | 240 | ||
241 | if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) | 241 | if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) { |
242 | mutex_unlock(&pcap->adc_mutex); | ||
242 | return IRQ_HANDLED; | 243 | return IRQ_HANDLED; |
244 | } | ||
243 | 245 | ||
244 | /* read requested channels results */ | 246 | /* read requested channels results */ |
245 | ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); | 247 | ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 4c7b7962f6b8..0cc5eeff5ee8 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -367,7 +367,8 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to) | |||
367 | break; | 367 | break; |
368 | 368 | ||
369 | default: | 369 | default: |
370 | return -1; | 370 | gate = -1; |
371 | goto already; | ||
371 | } | 372 | } |
372 | 373 | ||
373 | writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); | 374 | writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 68ab39d7cb35..df1f86b5c83e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -233,6 +233,19 @@ config ISL29003 | |||
233 | This driver can also be built as a module. If so, the module | 233 | This driver can also be built as a module. If so, the module |
234 | will be called isl29003. | 234 | will be called isl29003. |
235 | 235 | ||
236 | config EP93XX_PWM | ||
237 | tristate "EP93xx PWM support" | ||
238 | depends on ARCH_EP93XX | ||
239 | help | ||
240 | This option enables device driver support for the PWM channels | ||
241 | on the Cirrus EP93xx processors. The EP9307 chip only has one | ||
242 | PWM channel all the others have two, the second channel is an | ||
243 | alternate function of the EGPIO14 pin. A sysfs interface is | ||
244 | provided to control the PWM channels. | ||
245 | |||
246 | To compile this driver as a module, choose M here: the module will | ||
247 | be called ep93xx_pwm. | ||
248 | |||
236 | source "drivers/misc/c2port/Kconfig" | 249 | source "drivers/misc/c2port/Kconfig" |
237 | source "drivers/misc/eeprom/Kconfig" | 250 | source "drivers/misc/eeprom/Kconfig" |
238 | source "drivers/misc/cb710/Kconfig" | 251 | source "drivers/misc/cb710/Kconfig" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 36f733cd60e6..f982d2ecfde7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_SGI_XP) += sgi-xp/ | |||
19 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ | 19 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ |
20 | obj-$(CONFIG_HP_ILO) += hpilo.o | 20 | obj-$(CONFIG_HP_ILO) += hpilo.o |
21 | obj-$(CONFIG_ISL29003) += isl29003.o | 21 | obj-$(CONFIG_ISL29003) += isl29003.o |
22 | obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o | ||
22 | obj-$(CONFIG_C2PORT) += c2port/ | 23 | obj-$(CONFIG_C2PORT) += c2port/ |
23 | obj-y += eeprom/ | 24 | obj-y += eeprom/ |
24 | obj-y += cb710/ | 25 | obj-y += cb710/ |
diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c new file mode 100644 index 000000000000..ba4694169d79 --- /dev/null +++ b/drivers/misc/ep93xx_pwm.c | |||
@@ -0,0 +1,384 @@ | |||
1 | /* | ||
2 | * Simple PWM driver for EP93XX | ||
3 | * | ||
4 | * (c) Copyright 2009 Matthieu Crapet <mcrapet@gmail.com> | ||
5 | * (c) Copyright 2009 H Hartley Sweeten <hsweeten@visionengravers.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * EP9307 has only one channel: | ||
13 | * - PWMOUT | ||
14 | * | ||
15 | * EP9301/02/12/15 have two channels: | ||
16 | * - PWMOUT | ||
17 | * - PWMOUT1 (alternate function for EGPIO14) | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #include <mach/platform.h> | ||
27 | |||
28 | #define EP93XX_PWMx_TERM_COUNT 0x00 | ||
29 | #define EP93XX_PWMx_DUTY_CYCLE 0x04 | ||
30 | #define EP93XX_PWMx_ENABLE 0x08 | ||
31 | #define EP93XX_PWMx_INVERT 0x0C | ||
32 | |||
33 | #define EP93XX_PWM_MAX_COUNT 0xFFFF | ||
34 | |||
35 | struct ep93xx_pwm { | ||
36 | void __iomem *mmio_base; | ||
37 | struct clk *clk; | ||
38 | u32 duty_percent; | ||
39 | }; | ||
40 | |||
41 | static inline void ep93xx_pwm_writel(struct ep93xx_pwm *pwm, | ||
42 | unsigned int val, unsigned int off) | ||
43 | { | ||
44 | __raw_writel(val, pwm->mmio_base + off); | ||
45 | } | ||
46 | |||
47 | static inline unsigned int ep93xx_pwm_readl(struct ep93xx_pwm *pwm, | ||
48 | unsigned int off) | ||
49 | { | ||
50 | return __raw_readl(pwm->mmio_base + off); | ||
51 | } | ||
52 | |||
53 | static inline void ep93xx_pwm_write_tc(struct ep93xx_pwm *pwm, u16 value) | ||
54 | { | ||
55 | ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_TERM_COUNT); | ||
56 | } | ||
57 | |||
58 | static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm) | ||
59 | { | ||
60 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT); | ||
61 | } | ||
62 | |||
63 | static inline void ep93xx_pwm_write_dc(struct ep93xx_pwm *pwm, u16 value) | ||
64 | { | ||
65 | ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_DUTY_CYCLE); | ||
66 | } | ||
67 | |||
68 | static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm) | ||
69 | { | ||
70 | ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE); | ||
71 | } | ||
72 | |||
73 | static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm) | ||
74 | { | ||
75 | ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE); | ||
76 | } | ||
77 | |||
78 | static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm) | ||
79 | { | ||
80 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1; | ||
81 | } | ||
82 | |||
83 | static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm) | ||
84 | { | ||
85 | ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT); | ||
86 | } | ||
87 | |||
88 | static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm) | ||
89 | { | ||
90 | ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT); | ||
91 | } | ||
92 | |||
93 | static inline int ep93xx_pwm_is_inverted(struct ep93xx_pwm *pwm) | ||
94 | { | ||
95 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_INVERT) & 0x1; | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * /sys/devices/platform/ep93xx-pwm.N | ||
100 | * /min_freq read-only minimum pwm output frequency | ||
101 | * /max_req read-only maximum pwm output frequency | ||
102 | * /freq read-write pwm output frequency (0 = disable output) | ||
103 | * /duty_percent read-write pwm duty cycle percent (1..99) | ||
104 | * /invert read-write invert pwm output | ||
105 | */ | ||
106 | |||
107 | static ssize_t ep93xx_pwm_get_min_freq(struct device *dev, | ||
108 | struct device_attribute *attr, char *buf) | ||
109 | { | ||
110 | struct platform_device *pdev = to_platform_device(dev); | ||
111 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
112 | unsigned long rate = clk_get_rate(pwm->clk); | ||
113 | |||
114 | return sprintf(buf, "%ld\n", rate / (EP93XX_PWM_MAX_COUNT + 1)); | ||
115 | } | ||
116 | |||
117 | static ssize_t ep93xx_pwm_get_max_freq(struct device *dev, | ||
118 | struct device_attribute *attr, char *buf) | ||
119 | { | ||
120 | struct platform_device *pdev = to_platform_device(dev); | ||
121 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
122 | unsigned long rate = clk_get_rate(pwm->clk); | ||
123 | |||
124 | return sprintf(buf, "%ld\n", rate / 2); | ||
125 | } | ||
126 | |||
127 | static ssize_t ep93xx_pwm_get_freq(struct device *dev, | ||
128 | struct device_attribute *attr, char *buf) | ||
129 | { | ||
130 | struct platform_device *pdev = to_platform_device(dev); | ||
131 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
132 | |||
133 | if (ep93xx_pwm_is_enabled(pwm)) { | ||
134 | unsigned long rate = clk_get_rate(pwm->clk); | ||
135 | u16 term = ep93xx_pwm_read_tc(pwm); | ||
136 | |||
137 | return sprintf(buf, "%ld\n", rate / (term + 1)); | ||
138 | } else { | ||
139 | return sprintf(buf, "disabled\n"); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static ssize_t ep93xx_pwm_set_freq(struct device *dev, | ||
144 | struct device_attribute *attr, const char *buf, size_t count) | ||
145 | { | ||
146 | struct platform_device *pdev = to_platform_device(dev); | ||
147 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
148 | long val; | ||
149 | int err; | ||
150 | |||
151 | err = strict_strtol(buf, 10, &val); | ||
152 | if (err) | ||
153 | return -EINVAL; | ||
154 | |||
155 | if (val == 0) { | ||
156 | ep93xx_pwm_disable(pwm); | ||
157 | } else if (val <= (clk_get_rate(pwm->clk) / 2)) { | ||
158 | u32 term, duty; | ||
159 | |||
160 | val = (clk_get_rate(pwm->clk) / val) - 1; | ||
161 | if (val > EP93XX_PWM_MAX_COUNT) | ||
162 | val = EP93XX_PWM_MAX_COUNT; | ||
163 | if (val < 1) | ||
164 | val = 1; | ||
165 | |||
166 | term = ep93xx_pwm_read_tc(pwm); | ||
167 | duty = ((val + 1) * pwm->duty_percent / 100) - 1; | ||
168 | |||
169 | /* If pwm is running, order is important */ | ||
170 | if (val > term) { | ||
171 | ep93xx_pwm_write_tc(pwm, val); | ||
172 | ep93xx_pwm_write_dc(pwm, duty); | ||
173 | } else { | ||
174 | ep93xx_pwm_write_dc(pwm, duty); | ||
175 | ep93xx_pwm_write_tc(pwm, val); | ||
176 | } | ||
177 | |||
178 | if (!ep93xx_pwm_is_enabled(pwm)) | ||
179 | ep93xx_pwm_enable(pwm); | ||
180 | } else { | ||
181 | return -EINVAL; | ||
182 | } | ||
183 | |||
184 | return count; | ||
185 | } | ||
186 | |||
187 | static ssize_t ep93xx_pwm_get_duty_percent(struct device *dev, | ||
188 | struct device_attribute *attr, char *buf) | ||
189 | { | ||
190 | struct platform_device *pdev = to_platform_device(dev); | ||
191 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
192 | |||
193 | return sprintf(buf, "%d\n", pwm->duty_percent); | ||
194 | } | ||
195 | |||
196 | static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev, | ||
197 | struct device_attribute *attr, const char *buf, size_t count) | ||
198 | { | ||
199 | struct platform_device *pdev = to_platform_device(dev); | ||
200 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
201 | long val; | ||
202 | int err; | ||
203 | |||
204 | err = strict_strtol(buf, 10, &val); | ||
205 | if (err) | ||
206 | return -EINVAL; | ||
207 | |||
208 | if (val > 0 && val < 100) { | ||
209 | u32 term = ep93xx_pwm_read_tc(pwm); | ||
210 | ep93xx_pwm_write_dc(pwm, ((term + 1) * val / 100) - 1); | ||
211 | pwm->duty_percent = val; | ||
212 | return count; | ||
213 | } | ||
214 | |||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | static ssize_t ep93xx_pwm_get_invert(struct device *dev, | ||
219 | struct device_attribute *attr, char *buf) | ||
220 | { | ||
221 | struct platform_device *pdev = to_platform_device(dev); | ||
222 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
223 | |||
224 | return sprintf(buf, "%d\n", ep93xx_pwm_is_inverted(pwm)); | ||
225 | } | ||
226 | |||
227 | static ssize_t ep93xx_pwm_set_invert(struct device *dev, | ||
228 | struct device_attribute *attr, const char *buf, size_t count) | ||
229 | { | ||
230 | struct platform_device *pdev = to_platform_device(dev); | ||
231 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
232 | long val; | ||
233 | int err; | ||
234 | |||
235 | err = strict_strtol(buf, 10, &val); | ||
236 | if (err) | ||
237 | return -EINVAL; | ||
238 | |||
239 | if (val == 0) | ||
240 | ep93xx_pwm_normal(pwm); | ||
241 | else if (val == 1) | ||
242 | ep93xx_pwm_invert(pwm); | ||
243 | else | ||
244 | return -EINVAL; | ||
245 | |||
246 | return count; | ||
247 | } | ||
248 | |||
249 | static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL); | ||
250 | static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL); | ||
251 | static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO, | ||
252 | ep93xx_pwm_get_freq, ep93xx_pwm_set_freq); | ||
253 | static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO, | ||
254 | ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent); | ||
255 | static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO, | ||
256 | ep93xx_pwm_get_invert, ep93xx_pwm_set_invert); | ||
257 | |||
258 | static struct attribute *ep93xx_pwm_attrs[] = { | ||
259 | &dev_attr_min_freq.attr, | ||
260 | &dev_attr_max_freq.attr, | ||
261 | &dev_attr_freq.attr, | ||
262 | &dev_attr_duty_percent.attr, | ||
263 | &dev_attr_invert.attr, | ||
264 | NULL | ||
265 | }; | ||
266 | |||
267 | static const struct attribute_group ep93xx_pwm_sysfs_files = { | ||
268 | .attrs = ep93xx_pwm_attrs, | ||
269 | }; | ||
270 | |||
271 | static int __init ep93xx_pwm_probe(struct platform_device *pdev) | ||
272 | { | ||
273 | struct ep93xx_pwm *pwm; | ||
274 | struct resource *res; | ||
275 | int err; | ||
276 | |||
277 | err = ep93xx_pwm_acquire_gpio(pdev); | ||
278 | if (err) | ||
279 | return err; | ||
280 | |||
281 | pwm = kzalloc(sizeof(struct ep93xx_pwm), GFP_KERNEL); | ||
282 | if (!pwm) { | ||
283 | err = -ENOMEM; | ||
284 | goto fail_no_mem; | ||
285 | } | ||
286 | |||
287 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
288 | if (res == NULL) { | ||
289 | err = -ENXIO; | ||
290 | goto fail_no_mem_resource; | ||
291 | } | ||
292 | |||
293 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
294 | if (res == NULL) { | ||
295 | err = -EBUSY; | ||
296 | goto fail_no_mem_resource; | ||
297 | } | ||
298 | |||
299 | pwm->mmio_base = ioremap(res->start, resource_size(res)); | ||
300 | if (pwm->mmio_base == NULL) { | ||
301 | err = -ENXIO; | ||
302 | goto fail_no_ioremap; | ||
303 | } | ||
304 | |||
305 | err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
306 | if (err) | ||
307 | goto fail_no_sysfs; | ||
308 | |||
309 | pwm->clk = clk_get(&pdev->dev, "pwm_clk"); | ||
310 | if (IS_ERR(pwm->clk)) { | ||
311 | err = PTR_ERR(pwm->clk); | ||
312 | goto fail_no_clk; | ||
313 | } | ||
314 | |||
315 | pwm->duty_percent = 50; | ||
316 | |||
317 | platform_set_drvdata(pdev, pwm); | ||
318 | |||
319 | /* disable pwm at startup. Avoids zero value. */ | ||
320 | ep93xx_pwm_disable(pwm); | ||
321 | ep93xx_pwm_write_tc(pwm, EP93XX_PWM_MAX_COUNT); | ||
322 | ep93xx_pwm_write_dc(pwm, EP93XX_PWM_MAX_COUNT / 2); | ||
323 | |||
324 | clk_enable(pwm->clk); | ||
325 | |||
326 | return 0; | ||
327 | |||
328 | fail_no_clk: | ||
329 | sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
330 | fail_no_sysfs: | ||
331 | iounmap(pwm->mmio_base); | ||
332 | fail_no_ioremap: | ||
333 | release_mem_region(res->start, resource_size(res)); | ||
334 | fail_no_mem_resource: | ||
335 | kfree(pwm); | ||
336 | fail_no_mem: | ||
337 | ep93xx_pwm_release_gpio(pdev); | ||
338 | return err; | ||
339 | } | ||
340 | |||
341 | static int __exit ep93xx_pwm_remove(struct platform_device *pdev) | ||
342 | { | ||
343 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
344 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
345 | |||
346 | ep93xx_pwm_disable(pwm); | ||
347 | clk_disable(pwm->clk); | ||
348 | clk_put(pwm->clk); | ||
349 | platform_set_drvdata(pdev, NULL); | ||
350 | sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
351 | iounmap(pwm->mmio_base); | ||
352 | release_mem_region(res->start, resource_size(res)); | ||
353 | kfree(pwm); | ||
354 | ep93xx_pwm_release_gpio(pdev); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static struct platform_driver ep93xx_pwm_driver = { | ||
360 | .driver = { | ||
361 | .name = "ep93xx-pwm", | ||
362 | .owner = THIS_MODULE, | ||
363 | }, | ||
364 | .remove = __exit_p(ep93xx_pwm_remove), | ||
365 | }; | ||
366 | |||
367 | static int __init ep93xx_pwm_init(void) | ||
368 | { | ||
369 | return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe); | ||
370 | } | ||
371 | |||
372 | static void __exit ep93xx_pwm_exit(void) | ||
373 | { | ||
374 | platform_driver_unregister(&ep93xx_pwm_driver); | ||
375 | } | ||
376 | |||
377 | module_init(ep93xx_pwm_init); | ||
378 | module_exit(ep93xx_pwm_exit); | ||
379 | |||
380 | MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, " | ||
381 | "H Hartley Sweeten <hsweeten@visionengravers.com>"); | ||
382 | MODULE_DESCRIPTION("EP93xx PWM driver"); | ||
383 | MODULE_LICENSE("GPL"); | ||
384 | MODULE_ALIAS("platform:ep93xx-pwm"); | ||
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 8d1c60a3f0df..5d778ec8cdb2 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c | |||
@@ -235,7 +235,7 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg) | |||
235 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 235 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
236 | 236 | ||
237 | dev_dbg(xpnet, "passing skb to network layer\n" | 237 | dev_dbg(xpnet, "passing skb to network layer\n" |
238 | KERN_DEBUG "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p " | 238 | "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p " |
239 | "skb->end=0x%p skb->len=%d\n", | 239 | "skb->end=0x%p skb->len=%d\n", |
240 | (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), | 240 | (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), |
241 | skb_end_pointer(skb), skb->len); | 241 | skb_end_pointer(skb), skb->len); |
@@ -399,7 +399,7 @@ xpnet_send(struct sk_buff *skb, struct xpnet_pending_msg *queued_msg, | |||
399 | msg->buf_pa = xp_pa((void *)start_addr); | 399 | msg->buf_pa = xp_pa((void *)start_addr); |
400 | 400 | ||
401 | dev_dbg(xpnet, "sending XPC message to %d:%d\n" | 401 | dev_dbg(xpnet, "sending XPC message to %d:%d\n" |
402 | KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, " | 402 | "msg->buf_pa=0x%lx, msg->size=%u, " |
403 | "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n", | 403 | "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n", |
404 | dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size, | 404 | dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size, |
405 | msg->leadin_ignore, msg->tailout_ignore); | 405 | msg->leadin_ignore, msg->tailout_ignore); |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 240608cc7ae9..a461017ce5ce 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -1313,6 +1313,12 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
1313 | struct mmc_spi_host *host; | 1313 | struct mmc_spi_host *host; |
1314 | int status; | 1314 | int status; |
1315 | 1315 | ||
1316 | /* We rely on full duplex transfers, mostly to reduce | ||
1317 | * per-transfer overheads (by making fewer transfers). | ||
1318 | */ | ||
1319 | if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) | ||
1320 | return -EINVAL; | ||
1321 | |||
1316 | /* MMC and SD specs only seem to care that sampling is on the | 1322 | /* MMC and SD specs only seem to care that sampling is on the |
1317 | * rising edge ... meaning SPI modes 0 or 3. So either SPI mode | 1323 | * rising edge ... meaning SPI modes 0 or 3. So either SPI mode |
1318 | * should be legit. We'll use mode 0 since the steady state is 0, | 1324 | * should be legit. We'll use mode 0 since the steady state is 0, |
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 5011fa73f918..1479da6d3aa6 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
@@ -194,7 +194,7 @@ static struct mtd_partition * newpart(char *s, | |||
194 | parts[this_part].name = extra_mem; | 194 | parts[this_part].name = extra_mem; |
195 | extra_mem += name_len + 1; | 195 | extra_mem += name_len + 1; |
196 | 196 | ||
197 | dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n", | 197 | dbg(("partition %d: name <%s>, offset %llx, size %llx, mask flags %x\n", |
198 | this_part, | 198 | this_part, |
199 | parts[this_part].name, | 199 | parts[this_part].name, |
200 | parts[this_part].offset, | 200 | parts[this_part].offset, |
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 59c46126a5ce..ae5fe91867e1 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #define SR_SRWD 0x80 /* SR write protect */ | 54 | #define SR_SRWD 0x80 /* SR write protect */ |
55 | 55 | ||
56 | /* Define max times to check status register before we give up. */ | 56 | /* Define max times to check status register before we give up. */ |
57 | #define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */ | 57 | #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ |
58 | #define CMD_SIZE 4 | 58 | #define CMD_SIZE 4 |
59 | 59 | ||
60 | #ifdef CONFIG_M25PXX_USE_FAST_READ | 60 | #ifdef CONFIG_M25PXX_USE_FAST_READ |
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index 73f05227dc8c..d8cf29c01cc4 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c | |||
@@ -226,7 +226,7 @@ static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate) | |||
226 | if (!desperate && inftl->numfreeEUNs < 2) { | 226 | if (!desperate && inftl->numfreeEUNs < 2) { |
227 | DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free " | 227 | DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free " |
228 | "EUNs (%d)\n", inftl->numfreeEUNs); | 228 | "EUNs (%d)\n", inftl->numfreeEUNs); |
229 | return 0xffff; | 229 | return BLOCK_NIL; |
230 | } | 230 | } |
231 | 231 | ||
232 | /* Scan for a free block */ | 232 | /* Scan for a free block */ |
@@ -281,7 +281,8 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned | |||
281 | silly = MAX_LOOPS; | 281 | silly = MAX_LOOPS; |
282 | while (thisEUN < inftl->nb_blocks) { | 282 | while (thisEUN < inftl->nb_blocks) { |
283 | for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) { | 283 | for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) { |
284 | if ((BlockMap[block] != 0xffff) || BlockDeleted[block]) | 284 | if ((BlockMap[block] != BLOCK_NIL) || |
285 | BlockDeleted[block]) | ||
285 | continue; | 286 | continue; |
286 | 287 | ||
287 | if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) | 288 | if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) |
@@ -525,7 +526,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) | |||
525 | if (!silly--) { | 526 | if (!silly--) { |
526 | printk(KERN_WARNING "INFTL: infinite loop in " | 527 | printk(KERN_WARNING "INFTL: infinite loop in " |
527 | "Virtual Unit Chain 0x%x\n", thisVUC); | 528 | "Virtual Unit Chain 0x%x\n", thisVUC); |
528 | return 0xffff; | 529 | return BLOCK_NIL; |
529 | } | 530 | } |
530 | 531 | ||
531 | /* Skip to next block in chain */ | 532 | /* Skip to next block in chain */ |
@@ -549,7 +550,7 @@ hitused: | |||
549 | * waiting to be picked up. We're going to have to fold | 550 | * waiting to be picked up. We're going to have to fold |
550 | * a chain to make room. | 551 | * a chain to make room. |
551 | */ | 552 | */ |
552 | thisEUN = INFTL_makefreeblock(inftl, 0xffff); | 553 | thisEUN = INFTL_makefreeblock(inftl, BLOCK_NIL); |
553 | 554 | ||
554 | /* | 555 | /* |
555 | * Hopefully we free something, lets try again. | 556 | * Hopefully we free something, lets try again. |
@@ -631,7 +632,7 @@ hitused: | |||
631 | 632 | ||
632 | printk(KERN_WARNING "INFTL: error folding to make room for Virtual " | 633 | printk(KERN_WARNING "INFTL: error folding to make room for Virtual " |
633 | "Unit Chain 0x%x\n", thisVUC); | 634 | "Unit Chain 0x%x\n", thisVUC); |
634 | return 0xffff; | 635 | return BLOCK_NIL; |
635 | } | 636 | } |
636 | 637 | ||
637 | /* | 638 | /* |
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c index b08a798ee254..2aac41bde8b3 100644 --- a/drivers/mtd/maps/integrator-flash.c +++ b/drivers/mtd/maps/integrator-flash.c | |||
@@ -42,10 +42,8 @@ | |||
42 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
43 | #include <asm/system.h> | 43 | #include <asm/system.h> |
44 | 44 | ||
45 | #define SUBDEV_NAME_SIZE (BUS_ID_SIZE + 2) | ||
46 | |||
47 | struct armflash_subdev_info { | 45 | struct armflash_subdev_info { |
48 | char name[SUBDEV_NAME_SIZE]; | 46 | char *name; |
49 | struct mtd_info *mtd; | 47 | struct mtd_info *mtd; |
50 | struct map_info map; | 48 | struct map_info map; |
51 | struct flash_platform_data *plat; | 49 | struct flash_platform_data *plat; |
@@ -134,6 +132,8 @@ static void armflash_subdev_remove(struct armflash_subdev_info *subdev) | |||
134 | map_destroy(subdev->mtd); | 132 | map_destroy(subdev->mtd); |
135 | if (subdev->map.virt) | 133 | if (subdev->map.virt) |
136 | iounmap(subdev->map.virt); | 134 | iounmap(subdev->map.virt); |
135 | kfree(subdev->name); | ||
136 | subdev->name = NULL; | ||
137 | release_mem_region(subdev->map.phys, subdev->map.size); | 137 | release_mem_region(subdev->map.phys, subdev->map.size); |
138 | } | 138 | } |
139 | 139 | ||
@@ -177,16 +177,22 @@ static int armflash_probe(struct platform_device *dev) | |||
177 | 177 | ||
178 | if (nr == 1) | 178 | if (nr == 1) |
179 | /* No MTD concatenation, just use the default name */ | 179 | /* No MTD concatenation, just use the default name */ |
180 | snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s", | 180 | subdev->name = kstrdup(dev_name(&dev->dev), GFP_KERNEL); |
181 | dev_name(&dev->dev)); | ||
182 | else | 181 | else |
183 | snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s-%d", | 182 | subdev->name = kasprintf(GFP_KERNEL, "%s-%d", |
184 | dev_name(&dev->dev), i); | 183 | dev_name(&dev->dev), i); |
184 | if (!subdev->name) { | ||
185 | err = -ENOMEM; | ||
186 | break; | ||
187 | } | ||
185 | subdev->plat = plat; | 188 | subdev->plat = plat; |
186 | 189 | ||
187 | err = armflash_subdev_probe(subdev, res); | 190 | err = armflash_subdev_probe(subdev, res); |
188 | if (err) | 191 | if (err) { |
192 | kfree(subdev->name); | ||
193 | subdev->name = NULL; | ||
189 | break; | 194 | break; |
195 | } | ||
190 | } | 196 | } |
191 | info->nr_subdev = i; | 197 | info->nr_subdev = i; |
192 | 198 | ||
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 2802992b39da..20c828ba9405 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -534,7 +534,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
534 | &num_partitions); | 534 | &num_partitions); |
535 | 535 | ||
536 | if ((!partitions) || (num_partitions == 0)) { | 536 | if ((!partitions) || (num_partitions == 0)) { |
537 | printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); | 537 | printk(KERN_ERR "atmel_nand: No partitions defined, or unsupported device.\n"); |
538 | res = ENXIO; | 538 | res = ENXIO; |
539 | goto err_no_partitions; | 539 | goto err_no_partitions; |
540 | } | 540 | } |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 0cd76f89f4b0..ebd07e95b814 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/jiffies.h> | ||
15 | #include <linux/sched.h> | ||
14 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
15 | #include <linux/mtd/nand.h> | 17 | #include <linux/mtd/nand.h> |
16 | #include <linux/mtd/partitions.h> | 18 | #include <linux/mtd/partitions.h> |
@@ -541,7 +543,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
541 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 543 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, |
542 | mtd); | 544 | mtd); |
543 | unsigned long timeo = jiffies; | 545 | unsigned long timeo = jiffies; |
544 | int status, state = this->state; | 546 | int status = NAND_STATUS_FAIL, state = this->state; |
545 | 547 | ||
546 | if (state == FL_ERASING) | 548 | if (state == FL_ERASING) |
547 | timeo += (HZ * 400) / 1000; | 549 | timeo += (HZ * 400) / 1000; |
@@ -556,8 +558,9 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
556 | 558 | ||
557 | while (time_before(jiffies, timeo)) { | 559 | while (time_before(jiffies, timeo)) { |
558 | status = __raw_readb(this->IO_ADDR_R); | 560 | status = __raw_readb(this->IO_ADDR_R); |
559 | if (!(status & 0x40)) | 561 | if (status & NAND_STATUS_READY) |
560 | break; | 562 | break; |
563 | cond_resched(); | ||
561 | } | 564 | } |
562 | return status; | 565 | return status; |
563 | } | 566 | } |
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c index 2c410a011317..0f5562aeedc1 100644 --- a/drivers/mtd/nand/ts7250.c +++ b/drivers/mtd/nand/ts7250.c | |||
@@ -24,8 +24,11 @@ | |||
24 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
25 | #include <linux/mtd/nand.h> | 25 | #include <linux/mtd/nand.h> |
26 | #include <linux/mtd/partitions.h> | 26 | #include <linux/mtd/partitions.h> |
27 | #include <asm/io.h> | 27 | #include <linux/io.h> |
28 | |||
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include <mach/ts72xx.h> | ||
31 | |||
29 | #include <asm/sizes.h> | 32 | #include <asm/sizes.h> |
30 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
31 | 34 | ||
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c index e3f8495a94c2..fb86cacd5bdb 100644 --- a/drivers/mtd/nftlcore.c +++ b/drivers/mtd/nftlcore.c | |||
@@ -208,7 +208,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate ) | |||
208 | /* Normally, we force a fold to happen before we run out of free blocks completely */ | 208 | /* Normally, we force a fold to happen before we run out of free blocks completely */ |
209 | if (!desperate && nftl->numfreeEUNs < 2) { | 209 | if (!desperate && nftl->numfreeEUNs < 2) { |
210 | DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n"); | 210 | DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n"); |
211 | return 0xffff; | 211 | return BLOCK_NIL; |
212 | } | 212 | } |
213 | 213 | ||
214 | /* Scan for a free block */ | 214 | /* Scan for a free block */ |
@@ -230,11 +230,11 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate ) | |||
230 | printk("Argh! No free blocks found! LastFreeEUN = %d, " | 230 | printk("Argh! No free blocks found! LastFreeEUN = %d, " |
231 | "FirstEUN = %d\n", nftl->LastFreeEUN, | 231 | "FirstEUN = %d\n", nftl->LastFreeEUN, |
232 | le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); | 232 | le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); |
233 | return 0xffff; | 233 | return BLOCK_NIL; |
234 | } | 234 | } |
235 | } while (pot != nftl->LastFreeEUN); | 235 | } while (pot != nftl->LastFreeEUN); |
236 | 236 | ||
237 | return 0xffff; | 237 | return BLOCK_NIL; |
238 | } | 238 | } |
239 | 239 | ||
240 | static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock ) | 240 | static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock ) |
@@ -431,7 +431,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p | |||
431 | 431 | ||
432 | /* add the header so that it is now a valid chain */ | 432 | /* add the header so that it is now a valid chain */ |
433 | oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC); | 433 | oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC); |
434 | oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; | 434 | oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = BLOCK_NIL; |
435 | 435 | ||
436 | nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 8, | 436 | nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 8, |
437 | 8, &retlen, (char *)&oob.u); | 437 | 8, &retlen, (char *)&oob.u); |
@@ -515,7 +515,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock) | |||
515 | if (ChainLength < 2) { | 515 | if (ChainLength < 2) { |
516 | printk(KERN_WARNING "No Virtual Unit Chains available for folding. " | 516 | printk(KERN_WARNING "No Virtual Unit Chains available for folding. " |
517 | "Failing request\n"); | 517 | "Failing request\n"); |
518 | return 0xffff; | 518 | return BLOCK_NIL; |
519 | } | 519 | } |
520 | 520 | ||
521 | return NFTL_foldchain (nftl, LongestChain, pendingblock); | 521 | return NFTL_foldchain (nftl, LongestChain, pendingblock); |
@@ -578,7 +578,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) | |||
578 | printk(KERN_WARNING | 578 | printk(KERN_WARNING |
579 | "Infinite loop in Virtual Unit Chain 0x%x\n", | 579 | "Infinite loop in Virtual Unit Chain 0x%x\n", |
580 | thisVUC); | 580 | thisVUC); |
581 | return 0xffff; | 581 | return BLOCK_NIL; |
582 | } | 582 | } |
583 | 583 | ||
584 | /* Skip to next block in chain */ | 584 | /* Skip to next block in chain */ |
@@ -601,7 +601,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) | |||
601 | //u16 startEUN = nftl->EUNtable[thisVUC]; | 601 | //u16 startEUN = nftl->EUNtable[thisVUC]; |
602 | 602 | ||
603 | //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); | 603 | //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); |
604 | writeEUN = NFTL_makefreeblock(nftl, 0xffff); | 604 | writeEUN = NFTL_makefreeblock(nftl, BLOCK_NIL); |
605 | 605 | ||
606 | if (writeEUN == BLOCK_NIL) { | 606 | if (writeEUN == BLOCK_NIL) { |
607 | /* OK, we accept that the above comment is | 607 | /* OK, we accept that the above comment is |
@@ -673,7 +673,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) | |||
673 | 673 | ||
674 | printk(KERN_WARNING "Error folding to make room for Virtual Unit Chain 0x%x\n", | 674 | printk(KERN_WARNING "Error folding to make room for Virtual Unit Chain 0x%x\n", |
675 | thisVUC); | 675 | thisVUC); |
676 | return 0xffff; | 676 | return BLOCK_NIL; |
677 | } | 677 | } |
678 | 678 | ||
679 | static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, | 679 | static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 286ed594e5a0..e1f7d0a78b9d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -657,6 +657,11 @@ static int io_init(struct ubi_device *ubi) | |||
657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) | 657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) |
658 | ubi->bad_allowed = 1; | 658 | ubi->bad_allowed = 1; |
659 | 659 | ||
660 | if (ubi->mtd->type == MTD_NORFLASH) { | ||
661 | ubi_assert(ubi->mtd->writesize == 1); | ||
662 | ubi->nor_flash = 1; | ||
663 | } | ||
664 | |||
660 | ubi->min_io_size = ubi->mtd->writesize; | 665 | ubi->min_io_size = ubi->mtd->writesize; |
661 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; | 666 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; |
662 | 667 | ||
@@ -996,6 +1001,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
996 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", | 1001 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", |
997 | ubi->beb_rsvd_pebs); | 1002 | ubi->beb_rsvd_pebs); |
998 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); | 1003 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); |
1004 | ubi_msg("image sequence number: %d", ubi->image_seq); | ||
999 | 1005 | ||
1000 | /* | 1006 | /* |
1001 | * The below lock makes sure we do not race with 'ubi_thread()' which | 1007 | * The below lock makes sure we do not race with 'ubi_thread()' which |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index c0ed60e8ade9..54b0186915fb 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
@@ -44,6 +44,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) | |||
44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); | 44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); |
45 | printk(KERN_DEBUG "\tdata_offset %d\n", | 45 | printk(KERN_DEBUG "\tdata_offset %d\n", |
46 | be32_to_cpu(ec_hdr->data_offset)); | 46 | be32_to_cpu(ec_hdr->data_offset)); |
47 | printk(KERN_DEBUG "\timage_seq %d\n", | ||
48 | be32_to_cpu(ec_hdr->image_seq)); | ||
47 | printk(KERN_DEBUG "\thdr_crc %#08x\n", | 49 | printk(KERN_DEBUG "\thdr_crc %#08x\n", |
48 | be32_to_cpu(ec_hdr->hdr_crc)); | 50 | be32_to_cpu(ec_hdr->hdr_crc)); |
49 | printk(KERN_DEBUG "erase counter header hexdump:\n"); | 51 | printk(KERN_DEBUG "erase counter header hexdump:\n"); |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 13777e5beac9..a4da7a09b949 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
@@ -93,6 +93,12 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); | |||
93 | #define UBI_IO_DEBUG 0 | 93 | #define UBI_IO_DEBUG 0 |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
97 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); | ||
98 | #else | ||
99 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
100 | #endif | ||
101 | |||
96 | #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT | 102 | #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT |
97 | #define DBG_DISABLE_BGT 1 | 103 | #define DBG_DISABLE_BGT 1 |
98 | #else | 104 | #else |
@@ -167,6 +173,7 @@ static inline int ubi_dbg_is_erase_failure(void) | |||
167 | #define ubi_dbg_is_bitflip() 0 | 173 | #define ubi_dbg_is_bitflip() 0 |
168 | #define ubi_dbg_is_write_failure() 0 | 174 | #define ubi_dbg_is_write_failure() 0 |
169 | #define ubi_dbg_is_erase_failure() 0 | 175 | #define ubi_dbg_is_erase_failure() 0 |
176 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
170 | 177 | ||
171 | #endif /* !CONFIG_MTD_UBI_DEBUG */ | 178 | #endif /* !CONFIG_MTD_UBI_DEBUG */ |
172 | #endif /* !__UBI_DEBUG_H__ */ | 179 | #endif /* !__UBI_DEBUG_H__ */ |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index effaff28bab1..4cb69925d8d9 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -98,17 +98,12 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); | 98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); |
99 | static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | 99 | static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, |
100 | const struct ubi_vid_hdr *vid_hdr); | 100 | const struct ubi_vid_hdr *vid_hdr); |
101 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | ||
102 | int len); | ||
103 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum); | ||
104 | #else | 101 | #else |
105 | #define paranoid_check_not_bad(ubi, pnum) 0 | 102 | #define paranoid_check_not_bad(ubi, pnum) 0 |
106 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 | 103 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 |
107 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 | 104 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 |
108 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 | 105 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 |
109 | #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 | 106 | #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 |
110 | #define paranoid_check_all_ff(ubi, pnum, offset, len) 0 | ||
111 | #define paranoid_check_empty(ubi, pnum) 0 | ||
112 | #endif | 107 | #endif |
113 | 108 | ||
114 | /** | 109 | /** |
@@ -244,7 +239,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
244 | return err > 0 ? -EINVAL : err; | 239 | return err > 0 ? -EINVAL : err; |
245 | 240 | ||
246 | /* The area we are writing to has to contain all 0xFF bytes */ | 241 | /* The area we are writing to has to contain all 0xFF bytes */ |
247 | err = paranoid_check_all_ff(ubi, pnum, offset, len); | 242 | err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); |
248 | if (err) | 243 | if (err) |
249 | return err > 0 ? -EINVAL : err; | 244 | return err > 0 ? -EINVAL : err; |
250 | 245 | ||
@@ -271,8 +266,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
271 | addr = (loff_t)pnum * ubi->peb_size + offset; | 266 | addr = (loff_t)pnum * ubi->peb_size + offset; |
272 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); | 267 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); |
273 | if (err) { | 268 | if (err) { |
274 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written" | 269 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written " |
275 | " %zd bytes", err, len, pnum, offset, written); | 270 | "%zd bytes", err, len, pnum, offset, written); |
276 | ubi_dbg_dump_stack(); | 271 | ubi_dbg_dump_stack(); |
277 | } else | 272 | } else |
278 | ubi_assert(written == len); | 273 | ubi_assert(written == len); |
@@ -350,7 +345,7 @@ retry: | |||
350 | return -EIO; | 345 | return -EIO; |
351 | } | 346 | } |
352 | 347 | ||
353 | err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size); | 348 | err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); |
354 | if (err) | 349 | if (err) |
355 | return err > 0 ? -EINVAL : err; | 350 | return err > 0 ? -EINVAL : err; |
356 | 351 | ||
@@ -459,6 +454,54 @@ out: | |||
459 | } | 454 | } |
460 | 455 | ||
461 | /** | 456 | /** |
457 | * nor_erase_prepare - prepare a NOR flash PEB for erasure. | ||
458 | * @ubi: UBI device description object | ||
459 | * @pnum: physical eraseblock number to prepare | ||
460 | * | ||
461 | * NOR flash, or at least some of them, have peculiar embedded PEB erasure | ||
462 | * algorithm: the PEB is first filled with zeroes, then it is erased. And | ||
463 | * filling with zeroes starts from the end of the PEB. This was observed with | ||
464 | * Spansion S29GL512N NOR flash. | ||
465 | * | ||
466 | * This means that in case of a power cut we may end up with intact data at the | ||
467 | * beginning of the PEB, and all zeroes at the end of PEB. In other words, the | ||
468 | * EC and VID headers are OK, but a large chunk of data at the end of PEB is | ||
469 | * zeroed. This makes UBI mistakenly treat this PEB as used and associate it | ||
470 | * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). | ||
471 | * | ||
472 | * This function is called before erasing NOR PEBs and it zeroes out EC and VID | ||
473 | * magic numbers in order to invalidate them and prevent the failures. Returns | ||
474 | * zero in case of success and a negative error code in case of failure. | ||
475 | */ | ||
476 | static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | ||
477 | { | ||
478 | int err; | ||
479 | size_t written; | ||
480 | loff_t addr; | ||
481 | uint32_t data = 0; | ||
482 | |||
483 | addr = (loff_t)pnum * ubi->peb_size; | ||
484 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
485 | if (err) { | ||
486 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
487 | "%zd bytes", err, pnum, 0, written); | ||
488 | ubi_dbg_dump_stack(); | ||
489 | return err; | ||
490 | } | ||
491 | |||
492 | addr += ubi->vid_hdr_aloffset; | ||
493 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
494 | if (err) { | ||
495 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
496 | "%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written); | ||
497 | ubi_dbg_dump_stack(); | ||
498 | return err; | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | /** | ||
462 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. | 505 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. |
463 | * @ubi: UBI device description object | 506 | * @ubi: UBI device description object |
464 | * @pnum: physical eraseblock number to erase | 507 | * @pnum: physical eraseblock number to erase |
@@ -489,6 +532,12 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) | |||
489 | return -EROFS; | 532 | return -EROFS; |
490 | } | 533 | } |
491 | 534 | ||
535 | if (ubi->nor_flash) { | ||
536 | err = nor_erase_prepare(ubi, pnum); | ||
537 | if (err) | ||
538 | return err; | ||
539 | } | ||
540 | |||
492 | if (torture) { | 541 | if (torture) { |
493 | ret = torture_peb(ubi, pnum); | 542 | ret = torture_peb(ubi, pnum); |
494 | if (ret < 0) | 543 | if (ret < 0) |
@@ -672,11 +721,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
672 | if (read_err != -EBADMSG && | 721 | if (read_err != -EBADMSG && |
673 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { | 722 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { |
674 | /* The physical eraseblock is supposedly empty */ | 723 | /* The physical eraseblock is supposedly empty */ |
675 | err = paranoid_check_all_ff(ubi, pnum, 0, | ||
676 | ubi->peb_size); | ||
677 | if (err) | ||
678 | return err > 0 ? UBI_IO_BAD_EC_HDR : err; | ||
679 | |||
680 | if (verbose) | 724 | if (verbose) |
681 | ubi_warn("no EC header found at PEB %d, " | 725 | ubi_warn("no EC header found at PEB %d, " |
682 | "only 0xFF bytes", pnum); | 726 | "only 0xFF bytes", pnum); |
@@ -752,6 +796,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, | |||
752 | ec_hdr->version = UBI_VERSION; | 796 | ec_hdr->version = UBI_VERSION; |
753 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); | 797 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); |
754 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); | 798 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); |
799 | ec_hdr->image_seq = cpu_to_be32(ubi->image_seq); | ||
755 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); | 800 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); |
756 | ec_hdr->hdr_crc = cpu_to_be32(crc); | 801 | ec_hdr->hdr_crc = cpu_to_be32(crc); |
757 | 802 | ||
@@ -947,15 +992,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
947 | if (read_err != -EBADMSG && | 992 | if (read_err != -EBADMSG && |
948 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { | 993 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { |
949 | /* The physical eraseblock is supposedly free */ | 994 | /* The physical eraseblock is supposedly free */ |
950 | |||
951 | /* | ||
952 | * The below is just a paranoid check, it has to be | ||
953 | * compiled out if paranoid checks are disabled. | ||
954 | */ | ||
955 | err = paranoid_check_empty(ubi, pnum); | ||
956 | if (err) | ||
957 | return err > 0 ? UBI_IO_BAD_VID_HDR : err; | ||
958 | |||
959 | if (verbose) | 995 | if (verbose) |
960 | ubi_warn("no VID header found at PEB %d, " | 996 | ubi_warn("no VID header found at PEB %d, " |
961 | "only 0xFF bytes", pnum); | 997 | "only 0xFF bytes", pnum); |
@@ -1229,7 +1265,7 @@ exit: | |||
1229 | } | 1265 | } |
1230 | 1266 | ||
1231 | /** | 1267 | /** |
1232 | * paranoid_check_all_ff - check that a region of flash is empty. | 1268 | * ubi_dbg_check_all_ff - check that a region of flash is empty. |
1233 | * @ubi: UBI device description object | 1269 | * @ubi: UBI device description object |
1234 | * @pnum: the physical eraseblock number to check | 1270 | * @pnum: the physical eraseblock number to check |
1235 | * @offset: the starting offset within the physical eraseblock to check | 1271 | * @offset: the starting offset within the physical eraseblock to check |
@@ -1239,8 +1275,7 @@ exit: | |||
1239 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error | 1275 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error |
1240 | * code if an error occurred. | 1276 | * code if an error occurred. |
1241 | */ | 1277 | */ |
1242 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | 1278 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) |
1243 | int len) | ||
1244 | { | 1279 | { |
1245 | size_t read; | 1280 | size_t read; |
1246 | int err; | 1281 | int err; |
@@ -1276,74 +1311,4 @@ error: | |||
1276 | return err; | 1311 | return err; |
1277 | } | 1312 | } |
1278 | 1313 | ||
1279 | /** | ||
1280 | * paranoid_check_empty - whether a PEB is empty. | ||
1281 | * @ubi: UBI device description object | ||
1282 | * @pnum: the physical eraseblock number to check | ||
1283 | * | ||
1284 | * This function makes sure PEB @pnum is empty, which means it contains only | ||
1285 | * %0xFF data bytes. Returns zero if the PEB is empty, %1 if not, and a | ||
1286 | * negative error code in case of failure. | ||
1287 | * | ||
1288 | * Empty PEBs have the EC header, and do not have the VID header. The caller of | ||
1289 | * this function should have already made sure the PEB does not have the VID | ||
1290 | * header. However, this function re-checks that, because it is possible that | ||
1291 | * the header and data has already been written to the PEB. | ||
1292 | * | ||
1293 | * Let's consider a possible scenario. Suppose there are 2 tasks - A and B. | ||
1294 | * Task A is in 'wear_leveling_worker()'. It is reading VID header of PEB X to | ||
1295 | * find which LEB it corresponds to. PEB X is currently unmapped, and has no | ||
1296 | * VID header. Task B is trying to write to PEB X. | ||
1297 | * | ||
1298 | * Task A: in 'ubi_io_read_vid_hdr()': reads the VID header from PEB X. The | ||
1299 | * read data contain all 0xFF bytes; | ||
1300 | * Task B: writes VID header and some data to PEB X; | ||
1301 | * Task A: assumes PEB X is empty, calls 'paranoid_check_empty()'. And if we | ||
1302 | * do not re-read the VID header, and do not cancel the checking if it | ||
1303 | * is there, we fail. | ||
1304 | */ | ||
1305 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum) | ||
1306 | { | ||
1307 | int err, offs = ubi->vid_hdr_aloffset, len = ubi->vid_hdr_alsize; | ||
1308 | size_t read; | ||
1309 | uint32_t magic; | ||
1310 | const struct ubi_vid_hdr *vid_hdr; | ||
1311 | |||
1312 | mutex_lock(&ubi->dbg_buf_mutex); | ||
1313 | err = ubi->mtd->read(ubi->mtd, offs, len, &read, ubi->dbg_peb_buf); | ||
1314 | if (err && err != -EUCLEAN) { | ||
1315 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " | ||
1316 | "read %zd bytes", err, len, pnum, offs, read); | ||
1317 | goto error; | ||
1318 | } | ||
1319 | |||
1320 | vid_hdr = ubi->dbg_peb_buf; | ||
1321 | magic = be32_to_cpu(vid_hdr->magic); | ||
1322 | if (magic == UBI_VID_HDR_MAGIC) | ||
1323 | /* The PEB contains VID header, so it is not empty */ | ||
1324 | goto out; | ||
1325 | |||
1326 | err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); | ||
1327 | if (err == 0) { | ||
1328 | ubi_err("flash region at PEB %d:%d, length %d does not " | ||
1329 | "contain all 0xFF bytes", pnum, offs, len); | ||
1330 | goto fail; | ||
1331 | } | ||
1332 | |||
1333 | out: | ||
1334 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1335 | return 0; | ||
1336 | |||
1337 | fail: | ||
1338 | ubi_err("paranoid check failed for PEB %d", pnum); | ||
1339 | ubi_msg("hex dump of the %d-%d region", offs, offs + len); | ||
1340 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | ||
1341 | ubi->dbg_peb_buf, len, 1); | ||
1342 | err = 1; | ||
1343 | error: | ||
1344 | ubi_dbg_dump_stack(); | ||
1345 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1346 | return err; | ||
1347 | } | ||
1348 | |||
1349 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1314 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index c3d653ba5ca0..f60895ee0aeb 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -757,6 +757,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
757 | si->is_empty = 0; | 757 | si->is_empty = 0; |
758 | 758 | ||
759 | if (!ec_corr) { | 759 | if (!ec_corr) { |
760 | int image_seq; | ||
761 | |||
760 | /* Make sure UBI version is OK */ | 762 | /* Make sure UBI version is OK */ |
761 | if (ech->version != UBI_VERSION) { | 763 | if (ech->version != UBI_VERSION) { |
762 | ubi_err("this UBI version is %d, image version is %d", | 764 | ubi_err("this UBI version is %d, image version is %d", |
@@ -778,6 +780,18 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
778 | ubi_dbg_dump_ec_hdr(ech); | 780 | ubi_dbg_dump_ec_hdr(ech); |
779 | return -EINVAL; | 781 | return -EINVAL; |
780 | } | 782 | } |
783 | |||
784 | image_seq = be32_to_cpu(ech->ec); | ||
785 | if (!si->image_seq_set) { | ||
786 | ubi->image_seq = image_seq; | ||
787 | si->image_seq_set = 1; | ||
788 | } else if (ubi->image_seq != image_seq) { | ||
789 | ubi_err("bad image sequence number %d in PEB %d, " | ||
790 | "expected %d", image_seq, pnum, ubi->image_seq); | ||
791 | ubi_dbg_dump_ec_hdr(ech); | ||
792 | return -EINVAL; | ||
793 | } | ||
794 | |||
781 | } | 795 | } |
782 | 796 | ||
783 | /* OK, we've done with the EC header, let's look at the VID header */ | 797 | /* OK, we've done with the EC header, let's look at the VID header */ |
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 61df208e2f20..1017cf12def5 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h | |||
@@ -102,6 +102,7 @@ struct ubi_scan_volume { | |||
102 | * @mean_ec: mean erase counter value | 102 | * @mean_ec: mean erase counter value |
103 | * @ec_sum: a temporary variable used when calculating @mean_ec | 103 | * @ec_sum: a temporary variable used when calculating @mean_ec |
104 | * @ec_count: a temporary variable used when calculating @mean_ec | 104 | * @ec_count: a temporary variable used when calculating @mean_ec |
105 | * @image_seq_set: indicates @ubi->image_seq is known | ||
105 | * | 106 | * |
106 | * This data structure contains the result of scanning and may be used by other | 107 | * This data structure contains the result of scanning and may be used by other |
107 | * UBI sub-systems to build final UBI data structures, further error-recovery | 108 | * UBI sub-systems to build final UBI data structures, further error-recovery |
@@ -124,6 +125,7 @@ struct ubi_scan_info { | |||
124 | int mean_ec; | 125 | int mean_ec; |
125 | uint64_t ec_sum; | 126 | uint64_t ec_sum; |
126 | int ec_count; | 127 | int ec_count; |
128 | int image_seq_set; | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | struct ubi_device; | 131 | struct ubi_device; |
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 8419fdccc79c..503ea9b27309 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h | |||
@@ -129,6 +129,7 @@ enum { | |||
129 | * @ec: the erase counter | 129 | * @ec: the erase counter |
130 | * @vid_hdr_offset: where the VID header starts | 130 | * @vid_hdr_offset: where the VID header starts |
131 | * @data_offset: where the user data start | 131 | * @data_offset: where the user data start |
132 | * @image_seq: image sequence number | ||
132 | * @padding2: reserved for future, zeroes | 133 | * @padding2: reserved for future, zeroes |
133 | * @hdr_crc: erase counter header CRC checksum | 134 | * @hdr_crc: erase counter header CRC checksum |
134 | * | 135 | * |
@@ -144,6 +145,14 @@ enum { | |||
144 | * volume identifier header and user data, relative to the beginning of the | 145 | * volume identifier header and user data, relative to the beginning of the |
145 | * physical eraseblock. These values have to be the same for all physical | 146 | * physical eraseblock. These values have to be the same for all physical |
146 | * eraseblocks. | 147 | * eraseblocks. |
148 | * | ||
149 | * The @image_seq field is used to validate a UBI image that has been prepared | ||
150 | * for a UBI device. The @image_seq value can be any value, but it must be the | ||
151 | * same on all eraseblocks. UBI will ensure that all new erase counter headers | ||
152 | * also contain this value, and will check the value when scanning at start-up. | ||
153 | * One way to make use of @image_seq is to increase its value by one every time | ||
154 | * an image is flashed over an existing image, then, if the flashing does not | ||
155 | * complete, UBI will detect the error when scanning. | ||
147 | */ | 156 | */ |
148 | struct ubi_ec_hdr { | 157 | struct ubi_ec_hdr { |
149 | __be32 magic; | 158 | __be32 magic; |
@@ -152,7 +161,8 @@ struct ubi_ec_hdr { | |||
152 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ | 161 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ |
153 | __be32 vid_hdr_offset; | 162 | __be32 vid_hdr_offset; |
154 | __be32 data_offset; | 163 | __be32 data_offset; |
155 | __u8 padding2[36]; | 164 | __be32 image_seq; |
165 | __u8 padding2[32]; | ||
156 | __be32 hdr_crc; | 166 | __be32 hdr_crc; |
157 | } __attribute__ ((packed)); | 167 | } __attribute__ ((packed)); |
158 | 168 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 28acd133c997..6a5fe9633783 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -301,6 +301,7 @@ struct ubi_wl_entry; | |||
301 | * @vol->readers, @vol->writers, @vol->exclusive, | 301 | * @vol->readers, @vol->writers, @vol->exclusive, |
302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. | 302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. |
303 | * @ref_count: count of references on the UBI device | 303 | * @ref_count: count of references on the UBI device |
304 | * @image_seq: image sequence number recorded on EC headers | ||
304 | * | 305 | * |
305 | * @rsvd_pebs: count of reserved physical eraseblocks | 306 | * @rsvd_pebs: count of reserved physical eraseblocks |
306 | * @avail_pebs: count of available physical eraseblocks | 307 | * @avail_pebs: count of available physical eraseblocks |
@@ -372,6 +373,7 @@ struct ubi_wl_entry; | |||
372 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset | 373 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset |
373 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or | 374 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or |
374 | * not | 375 | * not |
376 | * @nor_flash: non-zero if working on top of NOR flash | ||
375 | * @mtd: MTD device descriptor | 377 | * @mtd: MTD device descriptor |
376 | * | 378 | * |
377 | * @peb_buf1: a buffer of PEB size used for different purposes | 379 | * @peb_buf1: a buffer of PEB size used for different purposes |
@@ -390,6 +392,7 @@ struct ubi_device { | |||
390 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; | 392 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; |
391 | spinlock_t volumes_lock; | 393 | spinlock_t volumes_lock; |
392 | int ref_count; | 394 | int ref_count; |
395 | int image_seq; | ||
393 | 396 | ||
394 | int rsvd_pebs; | 397 | int rsvd_pebs; |
395 | int avail_pebs; | 398 | int avail_pebs; |
@@ -452,7 +455,8 @@ struct ubi_device { | |||
452 | int vid_hdr_offset; | 455 | int vid_hdr_offset; |
453 | int vid_hdr_aloffset; | 456 | int vid_hdr_aloffset; |
454 | int vid_hdr_shift; | 457 | int vid_hdr_shift; |
455 | int bad_allowed; | 458 | unsigned int bad_allowed:1; |
459 | unsigned int nor_flash:1; | ||
456 | struct mtd_info *mtd; | 460 | struct mtd_info *mtd; |
457 | 461 | ||
458 | void *peb_buf1; | 462 | void *peb_buf1; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 2b2472300610..600c7229d5cf 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -459,6 +459,14 @@ retry: | |||
459 | dbg_wl("PEB %d EC %d", e->pnum, e->ec); | 459 | dbg_wl("PEB %d EC %d", e->pnum, e->ec); |
460 | prot_queue_add(ubi, e); | 460 | prot_queue_add(ubi, e); |
461 | spin_unlock(&ubi->wl_lock); | 461 | spin_unlock(&ubi->wl_lock); |
462 | |||
463 | err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, | ||
464 | ubi->peb_size - ubi->vid_hdr_aloffset); | ||
465 | if (err) { | ||
466 | ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); | ||
467 | return err > 0 ? -EINVAL : err; | ||
468 | } | ||
469 | |||
462 | return e->pnum; | 470 | return e->pnum; |
463 | } | 471 | } |
464 | 472 | ||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c155bd3ec9f1..f053ba5c37ba 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -209,7 +209,7 @@ config MII | |||
209 | 209 | ||
210 | config MACB | 210 | config MACB |
211 | tristate "Atmel MACB support" | 211 | tristate "Atmel MACB support" |
212 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 | 212 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 |
213 | select PHYLIB | 213 | select PHYLIB |
214 | help | 214 | help |
215 | The Atmel MACB ethernet interface is found on many AT32 and AT91 | 215 | The Atmel MACB ethernet interface is found on many AT32 and AT91 |
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 85a18175730b..08787f5a22a3 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c | |||
@@ -569,16 +569,8 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
569 | 569 | ||
570 | #ifdef DEBUG_DRIVER | 570 | #ifdef DEBUG_DRIVER |
571 | /* dump the packet */ | 571 | /* dump the packet */ |
572 | { | 572 | print_hex_dump(KERN_DEBUG, "skb->data: ", DUMP_PREFIX_NONE, |
573 | int i; | 573 | 16, 1, skb->data, 64, true); |
574 | |||
575 | for (i = 0; i < 64; i++) { | ||
576 | if ((i % 16) == 0) | ||
577 | printk("\n" KERN_DEBUG); | ||
578 | printk ("%2.2x ", skb->data [i]); | ||
579 | } | ||
580 | printk("\n"); | ||
581 | } | ||
582 | #endif | 574 | #endif |
583 | entry = lp->tx_new & lp->tx_ring_mod_mask; | 575 | entry = lp->tx_new & lp->tx_ring_mod_mask; |
584 | ib->btx_ring [entry].length = (-skblen) | 0xf000; | 576 | ib->btx_ring [entry].length = (-skblen) | 0xf000; |
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index d6d4ab3b430c..7d227cdab9f8 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c | |||
@@ -158,15 +158,12 @@ module_exit(arcnet_exit); | |||
158 | void arcnet_dump_skb(struct net_device *dev, | 158 | void arcnet_dump_skb(struct net_device *dev, |
159 | struct sk_buff *skb, char *desc) | 159 | struct sk_buff *skb, char *desc) |
160 | { | 160 | { |
161 | int i; | 161 | char hdr[32]; |
162 | 162 | ||
163 | printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc); | 163 | /* dump the packet */ |
164 | for (i = 0; i < skb->len; i++) { | 164 | snprintf(hdr, sizeof(hdr), "%6s:%s skb->data:", dev->name, desc); |
165 | if (i % 16 == 0) | 165 | print_hex_dump(KERN_DEBUG, hdr, DUMP_PREFIX_OFFSET, |
166 | printk("\n" KERN_DEBUG "[%04X] ", i); | 166 | 16, 1, skb->data, skb->len, true); |
167 | printk("%02X ", ((u_char *) skb->data)[i]); | ||
168 | } | ||
169 | printk("\n"); | ||
170 | } | 167 | } |
171 | 168 | ||
172 | EXPORT_SYMBOL(arcnet_dump_skb); | 169 | EXPORT_SYMBOL(arcnet_dump_skb); |
@@ -184,6 +181,7 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum, | |||
184 | int i, length; | 181 | int i, length; |
185 | unsigned long flags = 0; | 182 | unsigned long flags = 0; |
186 | static uint8_t buf[512]; | 183 | static uint8_t buf[512]; |
184 | char hdr[32]; | ||
187 | 185 | ||
188 | /* hw.copy_from_card expects IRQ context so take the IRQ lock | 186 | /* hw.copy_from_card expects IRQ context so take the IRQ lock |
189 | to keep it single threaded */ | 187 | to keep it single threaded */ |
@@ -197,14 +195,10 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum, | |||
197 | /* if the offset[0] byte is nonzero, this is a 256-byte packet */ | 195 | /* if the offset[0] byte is nonzero, this is a 256-byte packet */ |
198 | length = (buf[2] ? 256 : 512); | 196 | length = (buf[2] ? 256 : 512); |
199 | 197 | ||
200 | printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc); | 198 | /* dump the packet */ |
201 | for (i = 0; i < length; i++) { | 199 | snprintf(hdr, sizeof(hdr), "%6s:%s packet dump:", dev->name, desc); |
202 | if (i % 16 == 0) | 200 | print_hex_dump(KERN_DEBUG, hdr, DUMP_PREFIX_OFFSET, |
203 | printk("\n" KERN_DEBUG "[%04X] ", i); | 201 | 16, 1, buf, length, true); |
204 | printk("%02X ", buf[i]); | ||
205 | } | ||
206 | printk("\n"); | ||
207 | |||
208 | } | 202 | } |
209 | 203 | ||
210 | #else | 204 | #else |
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c index e4afbd628c23..607007d75b6f 100644 --- a/drivers/net/atl1c/atl1c_ethtool.c +++ b/drivers/net/atl1c/atl1c_ethtool.c | |||
@@ -281,6 +281,8 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
281 | if (wol->wolopts & WAKE_PHY) | 281 | if (wol->wolopts & WAKE_PHY) |
282 | adapter->wol |= AT_WUFC_LNKC; | 282 | adapter->wol |= AT_WUFC_LNKC; |
283 | 283 | ||
284 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
285 | |||
284 | return 0; | 286 | return 0; |
285 | } | 287 | } |
286 | 288 | ||
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c index 619c6583e1aa..4003955d7a96 100644 --- a/drivers/net/atl1e/atl1e_ethtool.c +++ b/drivers/net/atl1e/atl1e_ethtool.c | |||
@@ -365,6 +365,8 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
365 | if (wol->wolopts & WAKE_PHY) | 365 | if (wol->wolopts & WAKE_PHY) |
366 | adapter->wol |= AT_WUFC_LNKC; | 366 | adapter->wol |= AT_WUFC_LNKC; |
367 | 367 | ||
368 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
369 | |||
368 | return 0; | 370 | return 0; |
369 | } | 371 | } |
370 | 372 | ||
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index f703758f0a6e..5b4bf3d2cdc2 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -73,7 +73,7 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
73 | #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) | 73 | #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) |
74 | 74 | ||
75 | #define BE_MAX_LRO_DESCRIPTORS 16 | 75 | #define BE_MAX_LRO_DESCRIPTORS 16 |
76 | #define BE_MAX_FRAGS_PER_FRAME 16 | 76 | #define BE_MAX_FRAGS_PER_FRAME (min((u32) 16, (u32) MAX_SKB_FRAGS)) |
77 | 77 | ||
78 | struct be_dma_mem { | 78 | struct be_dma_mem { |
79 | void *va; | 79 | void *va; |
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 9592f22e4c8c..cccc5419ad72 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -162,8 +162,8 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) | |||
162 | return -EINVAL; | 162 | return -EINVAL; |
163 | 163 | ||
164 | adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; | 164 | adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; |
165 | if (adapter->max_rx_coal > MAX_SKB_FRAGS) | 165 | if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME) |
166 | adapter->max_rx_coal = MAX_SKB_FRAGS - 1; | 166 | adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME; |
167 | 167 | ||
168 | /* if AIC is being turned on now, start with an EQD of 0 */ | 168 | /* if AIC is being turned on now, start with an EQD of 0 */ |
169 | if (rx_eq->enable_aic == 0 && | 169 | if (rx_eq->enable_aic == 0 && |
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index b02e805c1db3..29c33c709c6d 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -55,6 +55,10 @@ | |||
55 | #define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK 0x7 /* bits 26 - 28 */ | 55 | #define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK 0x7 /* bits 26 - 28 */ |
56 | #define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT 26 | 56 | #define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT 26 |
57 | 57 | ||
58 | /********* ISR0 Register offset **********/ | ||
59 | #define CEV_ISR0_OFFSET 0xC18 | ||
60 | #define CEV_ISR_SIZE 4 | ||
61 | |||
58 | /********* Event Q door bell *************/ | 62 | /********* Event Q door bell *************/ |
59 | #define DB_EQ_OFFSET DB_CQ_OFFSET | 63 | #define DB_EQ_OFFSET DB_CQ_OFFSET |
60 | #define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ | 64 | #define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 66c10c87f517..c43f6a119295 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -666,7 +666,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
666 | { | 666 | { |
667 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 667 | struct be_queue_info *rxq = &adapter->rx_obj.q; |
668 | struct be_rx_page_info *page_info; | 668 | struct be_rx_page_info *page_info; |
669 | u16 rxq_idx, i, num_rcvd; | 669 | u16 rxq_idx, i, num_rcvd, j; |
670 | u32 pktsize, hdr_len, curr_frag_len; | 670 | u32 pktsize, hdr_len, curr_frag_len; |
671 | u8 *start; | 671 | u8 *start; |
672 | 672 | ||
@@ -709,22 +709,33 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
709 | 709 | ||
710 | /* More frags present for this completion */ | 710 | /* More frags present for this completion */ |
711 | pktsize -= curr_frag_len; /* account for above copied frag */ | 711 | pktsize -= curr_frag_len; /* account for above copied frag */ |
712 | for (i = 1; i < num_rcvd; i++) { | 712 | for (i = 1, j = 0; i < num_rcvd; i++) { |
713 | index_inc(&rxq_idx, rxq->len); | 713 | index_inc(&rxq_idx, rxq->len); |
714 | page_info = get_rx_page_info(adapter, rxq_idx); | 714 | page_info = get_rx_page_info(adapter, rxq_idx); |
715 | 715 | ||
716 | curr_frag_len = min(pktsize, rx_frag_size); | 716 | curr_frag_len = min(pktsize, rx_frag_size); |
717 | 717 | ||
718 | skb_shinfo(skb)->frags[i].page = page_info->page; | 718 | /* Coalesce all frags from the same physical page in one slot */ |
719 | skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset; | 719 | if (page_info->page_offset == 0) { |
720 | skb_shinfo(skb)->frags[i].size = curr_frag_len; | 720 | /* Fresh page */ |
721 | j++; | ||
722 | skb_shinfo(skb)->frags[j].page = page_info->page; | ||
723 | skb_shinfo(skb)->frags[j].page_offset = | ||
724 | page_info->page_offset; | ||
725 | skb_shinfo(skb)->frags[j].size = 0; | ||
726 | skb_shinfo(skb)->nr_frags++; | ||
727 | } else { | ||
728 | put_page(page_info->page); | ||
729 | } | ||
730 | |||
731 | skb_shinfo(skb)->frags[j].size += curr_frag_len; | ||
721 | skb->len += curr_frag_len; | 732 | skb->len += curr_frag_len; |
722 | skb->data_len += curr_frag_len; | 733 | skb->data_len += curr_frag_len; |
723 | skb_shinfo(skb)->nr_frags++; | ||
724 | pktsize -= curr_frag_len; | 734 | pktsize -= curr_frag_len; |
725 | 735 | ||
726 | memset(page_info, 0, sizeof(*page_info)); | 736 | memset(page_info, 0, sizeof(*page_info)); |
727 | } | 737 | } |
738 | BUG_ON(j > MAX_SKB_FRAGS); | ||
728 | 739 | ||
729 | done: | 740 | done: |
730 | be_rx_stats_update(adapter, pktsize, num_rcvd); | 741 | be_rx_stats_update(adapter, pktsize, num_rcvd); |
@@ -786,7 +797,7 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, | |||
786 | struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; | 797 | struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; |
787 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 798 | struct be_queue_info *rxq = &adapter->rx_obj.q; |
788 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; | 799 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; |
789 | u16 i, rxq_idx = 0, vid; | 800 | u16 i, rxq_idx = 0, vid, j; |
790 | 801 | ||
791 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | 802 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); |
792 | pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | 803 | pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); |
@@ -794,20 +805,28 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, | |||
794 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 805 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
795 | 806 | ||
796 | remaining = pkt_size; | 807 | remaining = pkt_size; |
797 | for (i = 0; i < num_rcvd; i++) { | 808 | for (i = 0, j = -1; i < num_rcvd; i++) { |
798 | page_info = get_rx_page_info(adapter, rxq_idx); | 809 | page_info = get_rx_page_info(adapter, rxq_idx); |
799 | 810 | ||
800 | curr_frag_len = min(remaining, rx_frag_size); | 811 | curr_frag_len = min(remaining, rx_frag_size); |
801 | 812 | ||
802 | rx_frags[i].page = page_info->page; | 813 | /* Coalesce all frags from the same physical page in one slot */ |
803 | rx_frags[i].page_offset = page_info->page_offset; | 814 | if (i == 0 || page_info->page_offset == 0) { |
804 | rx_frags[i].size = curr_frag_len; | 815 | /* First frag or Fresh page */ |
805 | remaining -= curr_frag_len; | 816 | j++; |
817 | rx_frags[j].page = page_info->page; | ||
818 | rx_frags[j].page_offset = page_info->page_offset; | ||
819 | rx_frags[j].size = 0; | ||
820 | } else { | ||
821 | put_page(page_info->page); | ||
822 | } | ||
823 | rx_frags[j].size += curr_frag_len; | ||
806 | 824 | ||
825 | remaining -= curr_frag_len; | ||
807 | index_inc(&rxq_idx, rxq->len); | 826 | index_inc(&rxq_idx, rxq->len); |
808 | |||
809 | memset(page_info, 0, sizeof(*page_info)); | 827 | memset(page_info, 0, sizeof(*page_info)); |
810 | } | 828 | } |
829 | BUG_ON(j > MAX_SKB_FRAGS); | ||
811 | 830 | ||
812 | if (likely(!vlanf)) { | 831 | if (likely(!vlanf)) { |
813 | lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, | 832 | lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, |
@@ -1255,15 +1274,17 @@ static irqreturn_t be_intx(int irq, void *dev) | |||
1255 | { | 1274 | { |
1256 | struct be_adapter *adapter = dev; | 1275 | struct be_adapter *adapter = dev; |
1257 | struct be_ctrl_info *ctrl = &adapter->ctrl; | 1276 | struct be_ctrl_info *ctrl = &adapter->ctrl; |
1258 | int rx, tx; | 1277 | int isr; |
1259 | 1278 | ||
1260 | tx = event_handle(ctrl, &adapter->tx_eq); | 1279 | isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET + |
1261 | rx = event_handle(ctrl, &adapter->rx_eq); | 1280 | ctrl->pci_func * CEV_ISR_SIZE); |
1281 | if (!isr) | ||
1282 | return IRQ_NONE; | ||
1262 | 1283 | ||
1263 | if (rx || tx) | 1284 | event_handle(ctrl, &adapter->tx_eq); |
1264 | return IRQ_HANDLED; | 1285 | event_handle(ctrl, &adapter->rx_eq); |
1265 | else | 1286 | |
1266 | return IRQ_NONE; | 1287 | return IRQ_HANDLED; |
1267 | } | 1288 | } |
1268 | 1289 | ||
1269 | static irqreturn_t be_msix_rx(int irq, void *dev) | 1290 | static irqreturn_t be_msix_rx(int irq, void *dev) |
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 9578a3dfac01..206144f2470f 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c | |||
@@ -428,10 +428,11 @@ bmac_init_phy(struct net_device *dev) | |||
428 | printk(KERN_DEBUG "phy registers:"); | 428 | printk(KERN_DEBUG "phy registers:"); |
429 | for (addr = 0; addr < 32; ++addr) { | 429 | for (addr = 0; addr < 32; ++addr) { |
430 | if ((addr & 7) == 0) | 430 | if ((addr & 7) == 0) |
431 | printk("\n" KERN_DEBUG); | 431 | printk(KERN_DEBUG); |
432 | printk(" %.4x", bmac_mif_read(dev, addr)); | 432 | printk(KERN_CONT " %.4x", bmac_mif_read(dev, addr)); |
433 | } | 433 | } |
434 | printk("\n"); | 434 | printk(KERN_CONT "\n"); |
435 | |||
435 | if (bp->is_bmac_plus) { | 436 | if (bp->is_bmac_plus) { |
436 | unsigned int capable, ctrl; | 437 | unsigned int capable, ctrl; |
437 | 438 | ||
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 8678457849f9..85a737c5c23f 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h | |||
@@ -902,6 +902,8 @@ struct bnx2x { | |||
902 | u16 rx_quick_cons_trip; | 902 | u16 rx_quick_cons_trip; |
903 | u16 rx_ticks_int; | 903 | u16 rx_ticks_int; |
904 | u16 rx_ticks; | 904 | u16 rx_ticks; |
905 | /* Maximal coalescing timeout in us */ | ||
906 | #define BNX2X_MAX_COALESCE_TOUT (0xf0*12) | ||
905 | 907 | ||
906 | u32 lin_cnt; | 908 | u32 lin_cnt; |
907 | 909 | ||
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index fbf1352e9c1c..c36a5f33739f 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -484,8 +484,9 @@ static void bnx2x_fw_dump(struct bnx2x *bp) | |||
484 | 484 | ||
485 | mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104); | 485 | mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104); |
486 | mark = ((mark + 0x3) & ~0x3); | 486 | mark = ((mark + 0x3) & ~0x3); |
487 | printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark); | 487 | printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark); |
488 | 488 | ||
489 | printk(KERN_ERR PFX); | ||
489 | for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) { | 490 | for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) { |
490 | for (word = 0; word < 8; word++) | 491 | for (word = 0; word < 8; word++) |
491 | data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + | 492 | data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + |
@@ -500,7 +501,7 @@ static void bnx2x_fw_dump(struct bnx2x *bp) | |||
500 | data[8] = 0x0; | 501 | data[8] = 0x0; |
501 | printk(KERN_CONT "%s", (char *)data); | 502 | printk(KERN_CONT "%s", (char *)data); |
502 | } | 503 | } |
503 | printk("\n" KERN_ERR PFX "end of fw dump\n"); | 504 | printk(KERN_ERR PFX "end of fw dump\n"); |
504 | } | 505 | } |
505 | 506 | ||
506 | static void bnx2x_panic_dump(struct bnx2x *bp) | 507 | static void bnx2x_panic_dump(struct bnx2x *bp) |
@@ -4434,7 +4435,7 @@ static void bnx2x_update_coalesce(struct bnx2x *bp) | |||
4434 | REG_WR16(bp, BAR_USTRORM_INTMEM + | 4435 | REG_WR16(bp, BAR_USTRORM_INTMEM + |
4435 | USTORM_SB_HC_DISABLE_OFFSET(port, sb_id, | 4436 | USTORM_SB_HC_DISABLE_OFFSET(port, sb_id, |
4436 | U_SB_ETH_RX_CQ_INDEX), | 4437 | U_SB_ETH_RX_CQ_INDEX), |
4437 | bp->rx_ticks ? 0 : 1); | 4438 | (bp->rx_ticks/12) ? 0 : 1); |
4438 | 4439 | ||
4439 | /* HC_INDEX_C_ETH_TX_CQ_CONS */ | 4440 | /* HC_INDEX_C_ETH_TX_CQ_CONS */ |
4440 | REG_WR8(bp, BAR_CSTRORM_INTMEM + | 4441 | REG_WR8(bp, BAR_CSTRORM_INTMEM + |
@@ -4444,7 +4445,7 @@ static void bnx2x_update_coalesce(struct bnx2x *bp) | |||
4444 | REG_WR16(bp, BAR_CSTRORM_INTMEM + | 4445 | REG_WR16(bp, BAR_CSTRORM_INTMEM + |
4445 | CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id, | 4446 | CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id, |
4446 | C_SB_ETH_TX_CQ_INDEX), | 4447 | C_SB_ETH_TX_CQ_INDEX), |
4447 | bp->tx_ticks ? 0 : 1); | 4448 | (bp->tx_ticks/12) ? 0 : 1); |
4448 | } | 4449 | } |
4449 | } | 4450 | } |
4450 | 4451 | ||
@@ -7354,7 +7355,7 @@ static void bnx2x_reset_task(struct work_struct *work) | |||
7354 | #ifdef BNX2X_STOP_ON_ERROR | 7355 | #ifdef BNX2X_STOP_ON_ERROR |
7355 | BNX2X_ERR("reset task called but STOP_ON_ERROR defined" | 7356 | BNX2X_ERR("reset task called but STOP_ON_ERROR defined" |
7356 | " so reset not done to allow debug dump,\n" | 7357 | " so reset not done to allow debug dump,\n" |
7357 | KERN_ERR " you will need to reboot when done\n"); | 7358 | " you will need to reboot when done\n"); |
7358 | return; | 7359 | return; |
7359 | #endif | 7360 | #endif |
7360 | 7361 | ||
@@ -8637,6 +8638,14 @@ static int bnx2x_nway_reset(struct net_device *dev) | |||
8637 | return 0; | 8638 | return 0; |
8638 | } | 8639 | } |
8639 | 8640 | ||
8641 | static u32 | ||
8642 | bnx2x_get_link(struct net_device *dev) | ||
8643 | { | ||
8644 | struct bnx2x *bp = netdev_priv(dev); | ||
8645 | |||
8646 | return bp->link_vars.link_up; | ||
8647 | } | ||
8648 | |||
8640 | static int bnx2x_get_eeprom_len(struct net_device *dev) | 8649 | static int bnx2x_get_eeprom_len(struct net_device *dev) |
8641 | { | 8650 | { |
8642 | struct bnx2x *bp = netdev_priv(dev); | 8651 | struct bnx2x *bp = netdev_priv(dev); |
@@ -9061,12 +9070,12 @@ static int bnx2x_set_coalesce(struct net_device *dev, | |||
9061 | struct bnx2x *bp = netdev_priv(dev); | 9070 | struct bnx2x *bp = netdev_priv(dev); |
9062 | 9071 | ||
9063 | bp->rx_ticks = (u16) coal->rx_coalesce_usecs; | 9072 | bp->rx_ticks = (u16) coal->rx_coalesce_usecs; |
9064 | if (bp->rx_ticks > 3000) | 9073 | if (bp->rx_ticks > BNX2X_MAX_COALESCE_TOUT) |
9065 | bp->rx_ticks = 3000; | 9074 | bp->rx_ticks = BNX2X_MAX_COALESCE_TOUT; |
9066 | 9075 | ||
9067 | bp->tx_ticks = (u16) coal->tx_coalesce_usecs; | 9076 | bp->tx_ticks = (u16) coal->tx_coalesce_usecs; |
9068 | if (bp->tx_ticks > 0x3000) | 9077 | if (bp->tx_ticks > BNX2X_MAX_COALESCE_TOUT) |
9069 | bp->tx_ticks = 0x3000; | 9078 | bp->tx_ticks = BNX2X_MAX_COALESCE_TOUT; |
9070 | 9079 | ||
9071 | if (netif_running(dev)) | 9080 | if (netif_running(dev)) |
9072 | bnx2x_update_coalesce(bp); | 9081 | bnx2x_update_coalesce(bp); |
@@ -10034,7 +10043,7 @@ static struct ethtool_ops bnx2x_ethtool_ops = { | |||
10034 | .get_msglevel = bnx2x_get_msglevel, | 10043 | .get_msglevel = bnx2x_get_msglevel, |
10035 | .set_msglevel = bnx2x_set_msglevel, | 10044 | .set_msglevel = bnx2x_set_msglevel, |
10036 | .nway_reset = bnx2x_nway_reset, | 10045 | .nway_reset = bnx2x_nway_reset, |
10037 | .get_link = ethtool_op_get_link, | 10046 | .get_link = bnx2x_get_link, |
10038 | .get_eeprom_len = bnx2x_get_eeprom_len, | 10047 | .get_eeprom_len = bnx2x_get_eeprom_len, |
10039 | .get_eeprom = bnx2x_get_eeprom, | 10048 | .get_eeprom = bnx2x_get_eeprom, |
10040 | .set_eeprom = bnx2x_set_eeprom, | 10049 | .set_eeprom = bnx2x_set_eeprom, |
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 58afafbd3b9c..fd5e32cbcb87 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c | |||
@@ -1097,7 +1097,7 @@ static const struct net_device_ops cpmac_netdev_ops = { | |||
1097 | .ndo_start_xmit = cpmac_start_xmit, | 1097 | .ndo_start_xmit = cpmac_start_xmit, |
1098 | .ndo_tx_timeout = cpmac_tx_timeout, | 1098 | .ndo_tx_timeout = cpmac_tx_timeout, |
1099 | .ndo_set_multicast_list = cpmac_set_multicast_list, | 1099 | .ndo_set_multicast_list = cpmac_set_multicast_list, |
1100 | .ndo_so_ioctl = cpmac_ioctl, | 1100 | .ndo_do_ioctl = cpmac_ioctl, |
1101 | .ndo_set_config = cpmac_config, | 1101 | .ndo_set_config = cpmac_config, |
1102 | .ndo_change_mtu = eth_change_mtu, | 1102 | .ndo_change_mtu = eth_change_mtu, |
1103 | .ndo_validate_addr = eth_validate_addr, | 1103 | .ndo_validate_addr = eth_validate_addr, |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 538dda4422dc..fb5df5c6203e 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -642,8 +642,7 @@ static int setup_sge_qsets(struct adapter *adap) | |||
642 | struct port_info *pi = netdev_priv(dev); | 642 | struct port_info *pi = netdev_priv(dev); |
643 | 643 | ||
644 | pi->qs = &adap->sge.qs[pi->first_qset]; | 644 | pi->qs = &adap->sge.qs[pi->first_qset]; |
645 | for (j = pi->first_qset; j < pi->first_qset + pi->nqsets; | 645 | for (j = 0; j < pi->nqsets; ++j, ++qset_idx) { |
646 | ++j, ++qset_idx) { | ||
647 | set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO); | 646 | set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO); |
648 | err = t3_sge_alloc_qset(adap, qset_idx, 1, | 647 | err = t3_sge_alloc_qset(adap, qset_idx, 1, |
649 | (adap->flags & USING_MSIX) ? qset_idx + 1 : | 648 | (adap->flags & USING_MSIX) ? qset_idx + 1 : |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 2df8fb0af701..12fd446f9895 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -1820,11 +1820,19 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr) | |||
1820 | struct device *emac_dev = &priv->ndev->dev; | 1820 | struct device *emac_dev = &priv->ndev->dev; |
1821 | struct sockaddr *sa = addr; | 1821 | struct sockaddr *sa = addr; |
1822 | 1822 | ||
1823 | if (!is_valid_ether_addr(sa->sa_data)) | ||
1824 | return -EINVAL; | ||
1825 | |||
1823 | /* Store mac addr in priv and rx channel and set it in EMAC hw */ | 1826 | /* Store mac addr in priv and rx channel and set it in EMAC hw */ |
1824 | memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len); | 1827 | memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len); |
1825 | memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len); | ||
1826 | memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len); | 1828 | memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len); |
1827 | emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr); | 1829 | |
1830 | /* If the interface is down - rxch is NULL. */ | ||
1831 | /* MAC address is configured only after the interface is enabled. */ | ||
1832 | if (netif_running(ndev)) { | ||
1833 | memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len); | ||
1834 | emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr); | ||
1835 | } | ||
1828 | 1836 | ||
1829 | if (netif_msg_drv(priv)) | 1837 | if (netif_msg_drv(priv)) |
1830 | dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n", | 1838 | dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n", |
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 895d72143ee0..4b6a219fecea 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c | |||
@@ -268,8 +268,9 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
268 | printk(KERN_INFO "tx_coalesce:\t%d packets\n", | 268 | printk(KERN_INFO "tx_coalesce:\t%d packets\n", |
269 | tx_coalesce); | 269 | tx_coalesce); |
270 | if (np->coalesce) | 270 | if (np->coalesce) |
271 | printk(KERN_INFO "rx_coalesce:\t%d packets\n" | 271 | printk(KERN_INFO |
272 | KERN_INFO "rx_timeout: \t%d ns\n", | 272 | "rx_coalesce:\t%d packets\n" |
273 | "rx_timeout: \t%d ns\n", | ||
273 | np->rx_coalesce, np->rx_timeout*640); | 274 | np->rx_coalesce, np->rx_timeout*640); |
274 | if (np->vlan) | 275 | if (np->vlan) |
275 | printk(KERN_INFO "vlan(id):\t%d\n", np->vlan); | 276 | printk(KERN_INFO "vlan(id):\t%d\n", np->vlan); |
@@ -1522,9 +1523,9 @@ mii_get_media (struct net_device *dev) | |||
1522 | printk (KERN_INFO "Operating at 10 Mbps, "); | 1523 | printk (KERN_INFO "Operating at 10 Mbps, "); |
1523 | } | 1524 | } |
1524 | if (bmcr & MII_BMCR_DUPLEX_MODE) { | 1525 | if (bmcr & MII_BMCR_DUPLEX_MODE) { |
1525 | printk ("Full duplex\n"); | 1526 | printk (KERN_CONT "Full duplex\n"); |
1526 | } else { | 1527 | } else { |
1527 | printk ("Half duplex\n"); | 1528 | printk (KERN_CONT "Half duplex\n"); |
1528 | } | 1529 | } |
1529 | } | 1530 | } |
1530 | if (np->tx_flow) | 1531 | if (np->tx_flow) |
@@ -1614,9 +1615,9 @@ mii_set_media (struct net_device *dev) | |||
1614 | } | 1615 | } |
1615 | if (np->full_duplex) { | 1616 | if (np->full_duplex) { |
1616 | bmcr |= MII_BMCR_DUPLEX_MODE; | 1617 | bmcr |= MII_BMCR_DUPLEX_MODE; |
1617 | printk ("Full duplex\n"); | 1618 | printk (KERN_CONT "Full duplex\n"); |
1618 | } else { | 1619 | } else { |
1619 | printk ("Half duplex\n"); | 1620 | printk (KERN_CONT "Half duplex\n"); |
1620 | } | 1621 | } |
1621 | #if 0 | 1622 | #if 0 |
1622 | /* Set 1000BaseT Master/Slave setting */ | 1623 | /* Set 1000BaseT Master/Slave setting */ |
@@ -1669,9 +1670,9 @@ mii_get_media_pcs (struct net_device *dev) | |||
1669 | __u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR); | 1670 | __u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR); |
1670 | printk (KERN_INFO "Operating at 1000 Mbps, "); | 1671 | printk (KERN_INFO "Operating at 1000 Mbps, "); |
1671 | if (bmcr & MII_BMCR_DUPLEX_MODE) { | 1672 | if (bmcr & MII_BMCR_DUPLEX_MODE) { |
1672 | printk ("Full duplex\n"); | 1673 | printk (KERN_CONT "Full duplex\n"); |
1673 | } else { | 1674 | } else { |
1674 | printk ("Half duplex\n"); | 1675 | printk (KERN_CONT "Half duplex\n"); |
1675 | } | 1676 | } |
1676 | } | 1677 | } |
1677 | if (np->tx_flow) | 1678 | if (np->tx_flow) |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5e3356f8eb5a..5b8cbdb4b520 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2185,12 +2185,16 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, | |||
2185 | /* Free all the Rx ring sk_buffs */ | 2185 | /* Free all the Rx ring sk_buffs */ |
2186 | for (i = 0; i < rx_ring->count; i++) { | 2186 | for (i = 0; i < rx_ring->count; i++) { |
2187 | buffer_info = &rx_ring->buffer_info[i]; | 2187 | buffer_info = &rx_ring->buffer_info[i]; |
2188 | if (buffer_info->skb) { | 2188 | if (buffer_info->dma) { |
2189 | pci_unmap_single(pdev, | 2189 | pci_unmap_single(pdev, |
2190 | buffer_info->dma, | 2190 | buffer_info->dma, |
2191 | buffer_info->length, | 2191 | buffer_info->length, |
2192 | PCI_DMA_FROMDEVICE); | 2192 | PCI_DMA_FROMDEVICE); |
2193 | } | ||
2194 | |||
2195 | buffer_info->dma = 0; | ||
2193 | 2196 | ||
2197 | if (buffer_info->skb) { | ||
2194 | dev_kfree_skb(buffer_info->skb); | 2198 | dev_kfree_skb(buffer_info->skb); |
2195 | buffer_info->skb = NULL; | 2199 | buffer_info->skb = NULL; |
2196 | } | 2200 | } |
@@ -4033,6 +4037,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
4033 | buffer_info->dma, | 4037 | buffer_info->dma, |
4034 | buffer_info->length, | 4038 | buffer_info->length, |
4035 | PCI_DMA_FROMDEVICE); | 4039 | PCI_DMA_FROMDEVICE); |
4040 | buffer_info->dma = 0; | ||
4036 | 4041 | ||
4037 | length = le16_to_cpu(rx_desc->length); | 4042 | length = le16_to_cpu(rx_desc->length); |
4038 | /* !EOP means multiple descriptors were used to store a single | 4043 | /* !EOP means multiple descriptors were used to store a single |
@@ -4222,6 +4227,7 @@ map_skb: | |||
4222 | pci_unmap_single(pdev, buffer_info->dma, | 4227 | pci_unmap_single(pdev, buffer_info->dma, |
4223 | adapter->rx_buffer_len, | 4228 | adapter->rx_buffer_len, |
4224 | PCI_DMA_FROMDEVICE); | 4229 | PCI_DMA_FROMDEVICE); |
4230 | buffer_info->dma = 0; | ||
4225 | 4231 | ||
4226 | break; /* while !buffer_info->skb */ | 4232 | break; /* while !buffer_info->skb */ |
4227 | } | 4233 | } |
@@ -4817,6 +4823,9 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, | |||
4817 | 4823 | ||
4818 | netif_device_detach(netdev); | 4824 | netif_device_detach(netdev); |
4819 | 4825 | ||
4826 | if (state == pci_channel_io_perm_failure) | ||
4827 | return PCI_ERS_RESULT_DISCONNECT; | ||
4828 | |||
4820 | if (netif_running(netdev)) | 4829 | if (netif_running(netdev)) |
4821 | e1000_down(adapter); | 4830 | e1000_down(adapter); |
4822 | pci_disable_device(pdev); | 4831 | pci_disable_device(pdev); |
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 8890c97e1120..c0f185beb8bc 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -238,6 +238,7 @@ | |||
238 | #define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ | 238 | #define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ |
239 | #define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ | 239 | #define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ |
240 | #define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */ | 240 | #define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */ |
241 | #define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ | ||
241 | #define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ | 242 | #define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ |
242 | 243 | ||
243 | /* Constants used to interpret the masked PCI-X bus speed. */ | 244 | /* Constants used to interpret the masked PCI-X bus speed. */ |
@@ -575,6 +576,8 @@ | |||
575 | #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ | 576 | #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ |
576 | #define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ | 577 | #define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ |
577 | 578 | ||
579 | #define PHY_CONTROL_LB 0x4000 /* PHY Loopback bit */ | ||
580 | |||
578 | /* NVM Control */ | 581 | /* NVM Control */ |
579 | #define E1000_EECD_SK 0x00000001 /* NVM Clock */ | 582 | #define E1000_EECD_SK 0x00000001 /* NVM Clock */ |
580 | #define E1000_EECD_CS 0x00000002 /* NVM Chip Select */ | 583 | #define E1000_EECD_CS 0x00000002 /* NVM Chip Select */ |
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 163c1c0cfee7..fd44d9f90769 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -215,6 +215,7 @@ enum e1e_registers { | |||
215 | E1000_SWSM = 0x05B50, /* SW Semaphore */ | 215 | E1000_SWSM = 0x05B50, /* SW Semaphore */ |
216 | E1000_FWSM = 0x05B54, /* FW Semaphore */ | 216 | E1000_FWSM = 0x05B54, /* FW Semaphore */ |
217 | E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */ | 217 | E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */ |
218 | E1000_CRC_OFFSET = 0x05F50, /* CRC Offset register */ | ||
218 | E1000_HICR = 0x08F00, /* Host Interface Control */ | 219 | E1000_HICR = 0x08F00, /* Host Interface Control */ |
219 | }; | 220 | }; |
220 | 221 | ||
@@ -302,6 +303,9 @@ enum e1e_registers { | |||
302 | #define E1000_KMRNCTRLSTA_REN 0x00200000 | 303 | #define E1000_KMRNCTRLSTA_REN 0x00200000 |
303 | #define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ | 304 | #define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ |
304 | #define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ | 305 | #define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ |
306 | #define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 | ||
307 | #define E1000_KMRNCTRLSTA_K1_ENABLE 0x140E | ||
308 | #define E1000_KMRNCTRLSTA_K1_DISABLE 0x1400 | ||
305 | 309 | ||
306 | #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 | 310 | #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 |
307 | #define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ | 311 | #define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 9e23f50fb9cd..d56c7473144a 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -338,6 +338,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) | |||
338 | { | 338 | { |
339 | struct e1000_nvm_info *nvm = &hw->nvm; | 339 | struct e1000_nvm_info *nvm = &hw->nvm; |
340 | struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; | 340 | struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; |
341 | union ich8_hws_flash_status hsfsts; | ||
341 | u32 gfpreg; | 342 | u32 gfpreg; |
342 | u32 sector_base_addr; | 343 | u32 sector_base_addr; |
343 | u32 sector_end_addr; | 344 | u32 sector_end_addr; |
@@ -374,6 +375,20 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) | |||
374 | /* Adjust to word count */ | 375 | /* Adjust to word count */ |
375 | nvm->flash_bank_size /= sizeof(u16); | 376 | nvm->flash_bank_size /= sizeof(u16); |
376 | 377 | ||
378 | /* | ||
379 | * Make sure the flash bank size does not overwrite the 4k | ||
380 | * sector ranges. We may have 64k allotted to us but we only care | ||
381 | * about the first 2 4k sectors. Therefore, if we have anything less | ||
382 | * than 64k set in the HSFSTS register, we will reduce the bank size | ||
383 | * down to 4k and let the rest remain unused. If berasesz == 3, then | ||
384 | * we are working in 64k mode. Otherwise we are not. | ||
385 | */ | ||
386 | if (nvm->flash_bank_size > E1000_ICH8_SHADOW_RAM_WORDS) { | ||
387 | hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); | ||
388 | if (hsfsts.hsf_status.berasesz != 3) | ||
389 | nvm->flash_bank_size = E1000_ICH8_SHADOW_RAM_WORDS; | ||
390 | } | ||
391 | |||
377 | nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS; | 392 | nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS; |
378 | 393 | ||
379 | /* Clear shadow ram */ | 394 | /* Clear shadow ram */ |
@@ -446,6 +461,95 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) | |||
446 | return 0; | 461 | return 0; |
447 | } | 462 | } |
448 | 463 | ||
464 | /** | ||
465 | * e1000_check_for_copper_link_ich8lan - Check for link (Copper) | ||
466 | * @hw: pointer to the HW structure | ||
467 | * | ||
468 | * Checks to see of the link status of the hardware has changed. If a | ||
469 | * change in link status has been detected, then we read the PHY registers | ||
470 | * to get the current speed/duplex if link exists. | ||
471 | **/ | ||
472 | static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | ||
473 | { | ||
474 | struct e1000_mac_info *mac = &hw->mac; | ||
475 | s32 ret_val; | ||
476 | bool link; | ||
477 | |||
478 | /* | ||
479 | * We only want to go out to the PHY registers to see if Auto-Neg | ||
480 | * has completed and/or if our link status has changed. The | ||
481 | * get_link_status flag is set upon receiving a Link Status | ||
482 | * Change or Rx Sequence Error interrupt. | ||
483 | */ | ||
484 | if (!mac->get_link_status) { | ||
485 | ret_val = 0; | ||
486 | goto out; | ||
487 | } | ||
488 | |||
489 | if (hw->mac.type == e1000_pchlan) { | ||
490 | ret_val = e1000e_write_kmrn_reg(hw, | ||
491 | E1000_KMRNCTRLSTA_K1_CONFIG, | ||
492 | E1000_KMRNCTRLSTA_K1_ENABLE); | ||
493 | if (ret_val) | ||
494 | goto out; | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * First we want to see if the MII Status Register reports | ||
499 | * link. If so, then we want to get the current speed/duplex | ||
500 | * of the PHY. | ||
501 | */ | ||
502 | ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); | ||
503 | if (ret_val) | ||
504 | goto out; | ||
505 | |||
506 | if (!link) | ||
507 | goto out; /* No link detected */ | ||
508 | |||
509 | mac->get_link_status = false; | ||
510 | |||
511 | if (hw->phy.type == e1000_phy_82578) { | ||
512 | ret_val = e1000_link_stall_workaround_hv(hw); | ||
513 | if (ret_val) | ||
514 | goto out; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * Check if there was DownShift, must be checked | ||
519 | * immediately after link-up | ||
520 | */ | ||
521 | e1000e_check_downshift(hw); | ||
522 | |||
523 | /* | ||
524 | * If we are forcing speed/duplex, then we simply return since | ||
525 | * we have already determined whether we have link or not. | ||
526 | */ | ||
527 | if (!mac->autoneg) { | ||
528 | ret_val = -E1000_ERR_CONFIG; | ||
529 | goto out; | ||
530 | } | ||
531 | |||
532 | /* | ||
533 | * Auto-Neg is enabled. Auto Speed Detection takes care | ||
534 | * of MAC speed/duplex configuration. So we only need to | ||
535 | * configure Collision Distance in the MAC. | ||
536 | */ | ||
537 | e1000e_config_collision_dist(hw); | ||
538 | |||
539 | /* | ||
540 | * Configure Flow Control now that Auto-Neg has completed. | ||
541 | * First, we need to restore the desired flow control | ||
542 | * settings because we may have had to re-autoneg with a | ||
543 | * different link partner. | ||
544 | */ | ||
545 | ret_val = e1000e_config_fc_after_link_up(hw); | ||
546 | if (ret_val) | ||
547 | hw_dbg(hw, "Error configuring flow control\n"); | ||
548 | |||
549 | out: | ||
550 | return ret_val; | ||
551 | } | ||
552 | |||
449 | static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) | 553 | static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) |
450 | { | 554 | { |
451 | struct e1000_hw *hw = &adapter->hw; | 555 | struct e1000_hw *hw = &adapter->hw; |
@@ -694,6 +798,38 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) | |||
694 | } | 798 | } |
695 | 799 | ||
696 | /** | 800 | /** |
801 | * e1000_lan_init_done_ich8lan - Check for PHY config completion | ||
802 | * @hw: pointer to the HW structure | ||
803 | * | ||
804 | * Check the appropriate indication the MAC has finished configuring the | ||
805 | * PHY after a software reset. | ||
806 | **/ | ||
807 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) | ||
808 | { | ||
809 | u32 data, loop = E1000_ICH8_LAN_INIT_TIMEOUT; | ||
810 | |||
811 | /* Wait for basic configuration completes before proceeding */ | ||
812 | do { | ||
813 | data = er32(STATUS); | ||
814 | data &= E1000_STATUS_LAN_INIT_DONE; | ||
815 | udelay(100); | ||
816 | } while ((!data) && --loop); | ||
817 | |||
818 | /* | ||
819 | * If basic configuration is incomplete before the above loop | ||
820 | * count reaches 0, loading the configuration from NVM will | ||
821 | * leave the PHY in a bad state possibly resulting in no link. | ||
822 | */ | ||
823 | if (loop == 0) | ||
824 | hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n"); | ||
825 | |||
826 | /* Clear the Init Done bit for the next init event */ | ||
827 | data = er32(STATUS); | ||
828 | data &= ~E1000_STATUS_LAN_INIT_DONE; | ||
829 | ew32(STATUS, data); | ||
830 | } | ||
831 | |||
832 | /** | ||
697 | * e1000_phy_hw_reset_ich8lan - Performs a PHY reset | 833 | * e1000_phy_hw_reset_ich8lan - Performs a PHY reset |
698 | * @hw: pointer to the HW structure | 834 | * @hw: pointer to the HW structure |
699 | * | 835 | * |
@@ -707,13 +843,15 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
707 | u32 i; | 843 | u32 i; |
708 | u32 data, cnf_size, cnf_base_addr, sw_cfg_mask; | 844 | u32 data, cnf_size, cnf_base_addr, sw_cfg_mask; |
709 | s32 ret_val; | 845 | s32 ret_val; |
710 | u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT; | ||
711 | u16 word_addr, reg_data, reg_addr, phy_page = 0; | 846 | u16 word_addr, reg_data, reg_addr, phy_page = 0; |
712 | 847 | ||
713 | ret_val = e1000e_phy_hw_reset_generic(hw); | 848 | ret_val = e1000e_phy_hw_reset_generic(hw); |
714 | if (ret_val) | 849 | if (ret_val) |
715 | return ret_val; | 850 | return ret_val; |
716 | 851 | ||
852 | /* Allow time for h/w to get to a quiescent state after reset */ | ||
853 | mdelay(10); | ||
854 | |||
717 | if (hw->mac.type == e1000_pchlan) { | 855 | if (hw->mac.type == e1000_pchlan) { |
718 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); | 856 | ret_val = e1000_hv_phy_workarounds_ich8lan(hw); |
719 | if (ret_val) | 857 | if (ret_val) |
@@ -741,26 +879,8 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
741 | if (!(data & sw_cfg_mask)) | 879 | if (!(data & sw_cfg_mask)) |
742 | return 0; | 880 | return 0; |
743 | 881 | ||
744 | /* Wait for basic configuration completes before proceeding*/ | 882 | /* Wait for basic configuration completes before proceeding */ |
745 | do { | 883 | e1000_lan_init_done_ich8lan(hw); |
746 | data = er32(STATUS); | ||
747 | data &= E1000_STATUS_LAN_INIT_DONE; | ||
748 | udelay(100); | ||
749 | } while ((!data) && --loop); | ||
750 | |||
751 | /* | ||
752 | * If basic configuration is incomplete before the above loop | ||
753 | * count reaches 0, loading the configuration from NVM will | ||
754 | * leave the PHY in a bad state possibly resulting in no link. | ||
755 | */ | ||
756 | if (loop == 0) { | ||
757 | hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n"); | ||
758 | } | ||
759 | |||
760 | /* Clear the Init Done bit for the next init event */ | ||
761 | data = er32(STATUS); | ||
762 | data &= ~E1000_STATUS_LAN_INIT_DONE; | ||
763 | ew32(STATUS, data); | ||
764 | 884 | ||
765 | /* | 885 | /* |
766 | * Make sure HW does not configure LCD from PHY | 886 | * Make sure HW does not configure LCD from PHY |
@@ -961,12 +1081,14 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) | |||
961 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; | 1081 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; |
962 | ew32(PHY_CTRL, phy_ctrl); | 1082 | ew32(PHY_CTRL, phy_ctrl); |
963 | 1083 | ||
1084 | if (phy->type != e1000_phy_igp_3) | ||
1085 | return 0; | ||
1086 | |||
964 | /* | 1087 | /* |
965 | * Call gig speed drop workaround on LPLU before accessing | 1088 | * Call gig speed drop workaround on LPLU before accessing |
966 | * any PHY registers | 1089 | * any PHY registers |
967 | */ | 1090 | */ |
968 | if ((hw->mac.type == e1000_ich8lan) && | 1091 | if (hw->mac.type == e1000_ich8lan) |
969 | (hw->phy.type == e1000_phy_igp_3)) | ||
970 | e1000e_gig_downshift_workaround_ich8lan(hw); | 1092 | e1000e_gig_downshift_workaround_ich8lan(hw); |
971 | 1093 | ||
972 | /* When LPLU is enabled, we should disable SmartSpeed */ | 1094 | /* When LPLU is enabled, we should disable SmartSpeed */ |
@@ -979,6 +1101,9 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) | |||
979 | phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; | 1101 | phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; |
980 | ew32(PHY_CTRL, phy_ctrl); | 1102 | ew32(PHY_CTRL, phy_ctrl); |
981 | 1103 | ||
1104 | if (phy->type != e1000_phy_igp_3) | ||
1105 | return 0; | ||
1106 | |||
982 | /* | 1107 | /* |
983 | * LPLU and SmartSpeed are mutually exclusive. LPLU is used | 1108 | * LPLU and SmartSpeed are mutually exclusive. LPLU is used |
984 | * during Dx states where the power conservation is most | 1109 | * during Dx states where the power conservation is most |
@@ -1038,6 +1163,10 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) | |||
1038 | if (!active) { | 1163 | if (!active) { |
1039 | phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; | 1164 | phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; |
1040 | ew32(PHY_CTRL, phy_ctrl); | 1165 | ew32(PHY_CTRL, phy_ctrl); |
1166 | |||
1167 | if (phy->type != e1000_phy_igp_3) | ||
1168 | return 0; | ||
1169 | |||
1041 | /* | 1170 | /* |
1042 | * LPLU and SmartSpeed are mutually exclusive. LPLU is used | 1171 | * LPLU and SmartSpeed are mutually exclusive. LPLU is used |
1043 | * during Dx states where the power conservation is most | 1172 | * during Dx states where the power conservation is most |
@@ -1073,12 +1202,14 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) | |||
1073 | phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; | 1202 | phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; |
1074 | ew32(PHY_CTRL, phy_ctrl); | 1203 | ew32(PHY_CTRL, phy_ctrl); |
1075 | 1204 | ||
1205 | if (phy->type != e1000_phy_igp_3) | ||
1206 | return 0; | ||
1207 | |||
1076 | /* | 1208 | /* |
1077 | * Call gig speed drop workaround on LPLU before accessing | 1209 | * Call gig speed drop workaround on LPLU before accessing |
1078 | * any PHY registers | 1210 | * any PHY registers |
1079 | */ | 1211 | */ |
1080 | if ((hw->mac.type == e1000_ich8lan) && | 1212 | if (hw->mac.type == e1000_ich8lan) |
1081 | (hw->phy.type == e1000_phy_igp_3)) | ||
1082 | e1000e_gig_downshift_workaround_ich8lan(hw); | 1213 | e1000e_gig_downshift_workaround_ich8lan(hw); |
1083 | 1214 | ||
1084 | /* When LPLU is enabled, we should disable SmartSpeed */ | 1215 | /* When LPLU is enabled, we should disable SmartSpeed */ |
@@ -1905,7 +2036,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) | |||
1905 | break; | 2036 | break; |
1906 | case 1: | 2037 | case 1: |
1907 | sector_size = ICH_FLASH_SEG_SIZE_4K; | 2038 | sector_size = ICH_FLASH_SEG_SIZE_4K; |
1908 | iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K; | 2039 | iteration = 1; |
1909 | break; | 2040 | break; |
1910 | case 2: | 2041 | case 2: |
1911 | if (hw->mac.type == e1000_ich9lan) { | 2042 | if (hw->mac.type == e1000_ich9lan) { |
@@ -1917,7 +2048,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) | |||
1917 | break; | 2048 | break; |
1918 | case 3: | 2049 | case 3: |
1919 | sector_size = ICH_FLASH_SEG_SIZE_64K; | 2050 | sector_size = ICH_FLASH_SEG_SIZE_64K; |
1920 | iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K; | 2051 | iteration = 1; |
1921 | break; | 2052 | break; |
1922 | default: | 2053 | default: |
1923 | return -E1000_ERR_NVM; | 2054 | return -E1000_ERR_NVM; |
@@ -2143,6 +2274,12 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2143 | ctrl = er32(CTRL); | 2274 | ctrl = er32(CTRL); |
2144 | 2275 | ||
2145 | if (!e1000_check_reset_block(hw)) { | 2276 | if (!e1000_check_reset_block(hw)) { |
2277 | /* Clear PHY Reset Asserted bit */ | ||
2278 | if (hw->mac.type >= e1000_pchlan) { | ||
2279 | u32 status = er32(STATUS); | ||
2280 | ew32(STATUS, status & ~E1000_STATUS_PHYRA); | ||
2281 | } | ||
2282 | |||
2146 | /* | 2283 | /* |
2147 | * PHY HW reset requires MAC CORE reset at the same | 2284 | * PHY HW reset requires MAC CORE reset at the same |
2148 | * time to make sure the interface between MAC and the | 2285 | * time to make sure the interface between MAC and the |
@@ -2156,23 +2293,34 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2156 | ew32(CTRL, (ctrl | E1000_CTRL_RST)); | 2293 | ew32(CTRL, (ctrl | E1000_CTRL_RST)); |
2157 | msleep(20); | 2294 | msleep(20); |
2158 | 2295 | ||
2159 | if (!ret_val) { | 2296 | if (!ret_val) |
2160 | /* release the swflag because it is not reset by | ||
2161 | * hardware reset | ||
2162 | */ | ||
2163 | e1000_release_swflag_ich8lan(hw); | 2297 | e1000_release_swflag_ich8lan(hw); |
2164 | } | ||
2165 | 2298 | ||
2166 | ret_val = e1000e_get_auto_rd_done(hw); | 2299 | if (ctrl & E1000_CTRL_PHY_RST) |
2167 | if (ret_val) { | 2300 | ret_val = hw->phy.ops.get_cfg_done(hw); |
2168 | /* | 2301 | |
2169 | * When auto config read does not complete, do not | 2302 | if (hw->mac.type >= e1000_ich10lan) { |
2170 | * return with an error. This can happen in situations | 2303 | e1000_lan_init_done_ich8lan(hw); |
2171 | * where there is no eeprom and prevents getting link. | 2304 | } else { |
2172 | */ | 2305 | ret_val = e1000e_get_auto_rd_done(hw); |
2173 | hw_dbg(hw, "Auto Read Done did not complete\n"); | 2306 | if (ret_val) { |
2307 | /* | ||
2308 | * When auto config read does not complete, do not | ||
2309 | * return with an error. This can happen in situations | ||
2310 | * where there is no eeprom and prevents getting link. | ||
2311 | */ | ||
2312 | hw_dbg(hw, "Auto Read Done did not complete\n"); | ||
2313 | } | ||
2174 | } | 2314 | } |
2175 | 2315 | ||
2316 | /* | ||
2317 | * For PCH, this write will make sure that any noise | ||
2318 | * will be detected as a CRC error and be dropped rather than show up | ||
2319 | * as a bad packet to the DMA engine. | ||
2320 | */ | ||
2321 | if (hw->mac.type == e1000_pchlan) | ||
2322 | ew32(CRC_OFFSET, 0x65656565); | ||
2323 | |||
2176 | ew32(IMC, 0xffffffff); | 2324 | ew32(IMC, 0xffffffff); |
2177 | icr = er32(ICR); | 2325 | icr = er32(ICR); |
2178 | 2326 | ||
@@ -2222,6 +2370,18 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) | |||
2222 | for (i = 0; i < mac->mta_reg_count; i++) | 2370 | for (i = 0; i < mac->mta_reg_count; i++) |
2223 | E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); | 2371 | E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); |
2224 | 2372 | ||
2373 | /* | ||
2374 | * The 82578 Rx buffer will stall if wakeup is enabled in host and | ||
2375 | * the ME. Reading the BM_WUC register will clear the host wakeup bit. | ||
2376 | * Reset the phy after disabling host wakeup to reset the Rx buffer. | ||
2377 | */ | ||
2378 | if (hw->phy.type == e1000_phy_82578) { | ||
2379 | hw->phy.ops.read_phy_reg(hw, BM_WUC, &i); | ||
2380 | ret_val = e1000_phy_hw_reset_ich8lan(hw); | ||
2381 | if (ret_val) | ||
2382 | return ret_val; | ||
2383 | } | ||
2384 | |||
2225 | /* Setup link and flow control */ | 2385 | /* Setup link and flow control */ |
2226 | ret_val = e1000_setup_link_ich8lan(hw); | 2386 | ret_val = e1000_setup_link_ich8lan(hw); |
2227 | 2387 | ||
@@ -2254,16 +2414,6 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) | |||
2254 | ew32(CTRL_EXT, ctrl_ext); | 2414 | ew32(CTRL_EXT, ctrl_ext); |
2255 | 2415 | ||
2256 | /* | 2416 | /* |
2257 | * The 82578 Rx buffer will stall if wakeup is enabled in host and | ||
2258 | * the ME. Reading the BM_WUC register will clear the host wakeup bit. | ||
2259 | * Reset the phy after disabling host wakeup to reset the Rx buffer. | ||
2260 | */ | ||
2261 | if (hw->phy.type == e1000_phy_82578) { | ||
2262 | e1e_rphy(hw, BM_WUC, &i); | ||
2263 | e1000e_phy_hw_reset_generic(hw); | ||
2264 | } | ||
2265 | |||
2266 | /* | ||
2267 | * Clear all of the statistics registers (clear on read). It is | 2417 | * Clear all of the statistics registers (clear on read). It is |
2268 | * important that we do this after we have tried to establish link | 2418 | * important that we do this after we have tried to establish link |
2269 | * because the symbol error count will increment wildly if there | 2419 | * because the symbol error count will increment wildly if there |
@@ -2485,6 +2635,14 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, | |||
2485 | if (ret_val) | 2635 | if (ret_val) |
2486 | return ret_val; | 2636 | return ret_val; |
2487 | 2637 | ||
2638 | if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) { | ||
2639 | ret_val = e1000e_write_kmrn_reg(hw, | ||
2640 | E1000_KMRNCTRLSTA_K1_CONFIG, | ||
2641 | E1000_KMRNCTRLSTA_K1_DISABLE); | ||
2642 | if (ret_val) | ||
2643 | return ret_val; | ||
2644 | } | ||
2645 | |||
2488 | if ((hw->mac.type == e1000_ich8lan) && | 2646 | if ((hw->mac.type == e1000_ich8lan) && |
2489 | (hw->phy.type == e1000_phy_igp_3) && | 2647 | (hw->phy.type == e1000_phy_igp_3) && |
2490 | (*speed == SPEED_1000)) { | 2648 | (*speed == SPEED_1000)) { |
@@ -2850,6 +3008,16 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) | |||
2850 | { | 3008 | { |
2851 | u32 bank = 0; | 3009 | u32 bank = 0; |
2852 | 3010 | ||
3011 | if (hw->mac.type >= e1000_pchlan) { | ||
3012 | u32 status = er32(STATUS); | ||
3013 | |||
3014 | if (status & E1000_STATUS_PHYRA) | ||
3015 | ew32(STATUS, status & ~E1000_STATUS_PHYRA); | ||
3016 | else | ||
3017 | hw_dbg(hw, | ||
3018 | "PHY Reset Asserted not set - needs delay\n"); | ||
3019 | } | ||
3020 | |||
2853 | e1000e_get_cfg_done(hw); | 3021 | e1000e_get_cfg_done(hw); |
2854 | 3022 | ||
2855 | /* If EEPROM is not marked present, init the IGP 3 PHY manually */ | 3023 | /* If EEPROM is not marked present, init the IGP 3 PHY manually */ |
@@ -2921,7 +3089,7 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) | |||
2921 | static struct e1000_mac_operations ich8_mac_ops = { | 3089 | static struct e1000_mac_operations ich8_mac_ops = { |
2922 | .id_led_init = e1000e_id_led_init, | 3090 | .id_led_init = e1000e_id_led_init, |
2923 | .check_mng_mode = e1000_check_mng_mode_ich8lan, | 3091 | .check_mng_mode = e1000_check_mng_mode_ich8lan, |
2924 | .check_for_link = e1000e_check_for_copper_link, | 3092 | .check_for_link = e1000_check_for_copper_link_ich8lan, |
2925 | /* cleanup_led dependent on mac type */ | 3093 | /* cleanup_led dependent on mac type */ |
2926 | .clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan, | 3094 | .clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan, |
2927 | .get_bus_info = e1000_get_bus_info_ich8lan, | 3095 | .get_bus_info = e1000_get_bus_info_ich8lan, |
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index be6d9e990374..99ba2b8a2a05 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -378,12 +378,6 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw) | |||
378 | 378 | ||
379 | mac->get_link_status = 0; | 379 | mac->get_link_status = 0; |
380 | 380 | ||
381 | if (hw->phy.type == e1000_phy_82578) { | ||
382 | ret_val = e1000_link_stall_workaround_hv(hw); | ||
383 | if (ret_val) | ||
384 | return ret_val; | ||
385 | } | ||
386 | |||
387 | /* | 381 | /* |
388 | * Check if there was DownShift, must be checked | 382 | * Check if there was DownShift, must be checked |
389 | * immediately after link-up | 383 | * immediately after link-up |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 679885a122b4..63415bb6f48f 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -4785,6 +4785,9 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, | |||
4785 | 4785 | ||
4786 | netif_device_detach(netdev); | 4786 | netif_device_detach(netdev); |
4787 | 4787 | ||
4788 | if (state == pci_channel_io_perm_failure) | ||
4789 | return PCI_ERS_RESULT_DISCONNECT; | ||
4790 | |||
4788 | if (netif_running(netdev)) | 4791 | if (netif_running(netdev)) |
4789 | e1000e_down(adapter); | 4792 | e1000e_down(adapter); |
4790 | pci_disable_device(pdev); | 4793 | pci_disable_device(pdev); |
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index e23459cf3d0e..994401fd0664 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -1531,7 +1531,12 @@ s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, | |||
1531 | */ | 1531 | */ |
1532 | ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); | 1532 | ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); |
1533 | if (ret_val) | 1533 | if (ret_val) |
1534 | break; | 1534 | /* |
1535 | * If the first read fails, another entity may have | ||
1536 | * ownership of the resources, wait and try again to | ||
1537 | * see if they have relinquished the resources yet. | ||
1538 | */ | ||
1539 | udelay(usec_interval); | ||
1535 | ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); | 1540 | ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); |
1536 | if (ret_val) | 1541 | if (ret_val) |
1537 | break; | 1542 | break; |
@@ -2737,6 +2742,11 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) | |||
2737 | if (hw->phy.type != e1000_phy_82578) | 2742 | if (hw->phy.type != e1000_phy_82578) |
2738 | goto out; | 2743 | goto out; |
2739 | 2744 | ||
2745 | /* Do not apply workaround if in PHY loopback bit 14 set */ | ||
2746 | hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &data); | ||
2747 | if (data & PHY_CONTROL_LB) | ||
2748 | goto out; | ||
2749 | |||
2740 | /* check if link is up and at 1Gbps */ | 2750 | /* check if link is up and at 1Gbps */ |
2741 | ret_val = hw->phy.ops.read_phy_reg(hw, BM_CS_STATUS, &data); | 2751 | ret_val = hw->phy.ops.read_phy_reg(hw, BM_CS_STATUS, &data); |
2742 | if (ret_val) | 2752 | if (ret_val) |
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index b60e27dfcfa7..88d7ebf31220 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c | |||
@@ -338,8 +338,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, | |||
338 | #ifndef MODULE | 338 | #ifndef MODULE |
339 | static int printed_version; | 339 | static int printed_version; |
340 | if (!printed_version++) | 340 | if (!printed_version++) |
341 | printk (KERN_INFO "%s" KERN_INFO "%s", | 341 | printk(KERN_INFO "%s%s", version, version2); |
342 | version, version2); | ||
343 | #endif | 342 | #endif |
344 | 343 | ||
345 | card_idx++; | 344 | card_idx++; |
@@ -1600,7 +1599,7 @@ static int __init epic_init (void) | |||
1600 | { | 1599 | { |
1601 | /* when a module, this is printed whether or not devices are found in probe */ | 1600 | /* when a module, this is printed whether or not devices are found in probe */ |
1602 | #ifdef MODULE | 1601 | #ifdef MODULE |
1603 | printk (KERN_INFO "%s" KERN_INFO "%s", | 1602 | printk (KERN_INFO "%s%s", |
1604 | version, version2); | 1603 | version, version2); |
1605 | #endif | 1604 | #endif |
1606 | 1605 | ||
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 891be28a7d4f..48385c42ab57 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c | |||
@@ -1209,17 +1209,20 @@ static void fealnx_tx_timeout(struct net_device *dev) | |||
1209 | unsigned long flags; | 1209 | unsigned long flags; |
1210 | int i; | 1210 | int i; |
1211 | 1211 | ||
1212 | printk(KERN_WARNING "%s: Transmit timed out, status %8.8x," | 1212 | printk(KERN_WARNING |
1213 | " resetting...\n", dev->name, ioread32(ioaddr + ISR)); | 1213 | "%s: Transmit timed out, status %8.8x, resetting...\n", |
1214 | dev->name, ioread32(ioaddr + ISR)); | ||
1214 | 1215 | ||
1215 | { | 1216 | { |
1216 | printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); | 1217 | printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); |
1217 | for (i = 0; i < RX_RING_SIZE; i++) | 1218 | for (i = 0; i < RX_RING_SIZE; i++) |
1218 | printk(" %8.8x", (unsigned int) np->rx_ring[i].status); | 1219 | printk(KERN_CONT " %8.8x", |
1219 | printk("\n" KERN_DEBUG " Tx ring %p: ", np->tx_ring); | 1220 | (unsigned int) np->rx_ring[i].status); |
1221 | printk(KERN_CONT "\n"); | ||
1222 | printk(KERN_DEBUG " Tx ring %p: ", np->tx_ring); | ||
1220 | for (i = 0; i < TX_RING_SIZE; i++) | 1223 | for (i = 0; i < TX_RING_SIZE; i++) |
1221 | printk(" %4.4x", np->tx_ring[i].status); | 1224 | printk(KERN_CONT " %4.4x", np->tx_ring[i].status); |
1222 | printk("\n"); | 1225 | printk(KERN_CONT "\n"); |
1223 | } | 1226 | } |
1224 | 1227 | ||
1225 | spin_lock_irqsave(&np->lock, flags); | 1228 | spin_lock_irqsave(&np->lock, flags); |
diff --git a/drivers/net/fec.h b/drivers/net/fec.h index 30b7dd671336..cc47f3f057c7 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h | |||
@@ -46,12 +46,12 @@ | |||
46 | 46 | ||
47 | #else | 47 | #else |
48 | 48 | ||
49 | #define FEC_ECNTRL; 0x000 /* Ethernet control reg */ | 49 | #define FEC_ECNTRL 0x000 /* Ethernet control reg */ |
50 | #define FEC_IEVENT; 0x004 /* Interrupt even reg */ | 50 | #define FEC_IEVENT 0x004 /* Interrupt even reg */ |
51 | #define FEC_IMASK; 0x008 /* Interrupt mask reg */ | 51 | #define FEC_IMASK 0x008 /* Interrupt mask reg */ |
52 | #define FEC_IVEC; 0x00c /* Interrupt vec status reg */ | 52 | #define FEC_IVEC 0x00c /* Interrupt vec status reg */ |
53 | #define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */ | 53 | #define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */ |
54 | #define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */ | 54 | #define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */ |
55 | #define FEC_MII_DATA 0x040 /* MII manage frame reg */ | 55 | #define FEC_MII_DATA 0x040 /* MII manage frame reg */ |
56 | #define FEC_MII_SPEED 0x044 /* MII speed control reg */ | 56 | #define FEC_MII_SPEED 0x044 /* MII speed control reg */ |
57 | #define FEC_R_BOUND 0x08c /* FIFO receive bound reg */ | 57 | #define FEC_R_BOUND 0x08c /* FIFO receive bound reg */ |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 1094d292630f..3b4e0766c7b2 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -3514,11 +3514,13 @@ static irqreturn_t nv_nic_irq(int foo, void *data) | |||
3514 | nv_msi_workaround(np); | 3514 | nv_msi_workaround(np); |
3515 | 3515 | ||
3516 | #ifdef CONFIG_FORCEDETH_NAPI | 3516 | #ifdef CONFIG_FORCEDETH_NAPI |
3517 | napi_schedule(&np->napi); | 3517 | if (napi_schedule_prep(&np->napi)) { |
3518 | 3518 | /* | |
3519 | /* Disable furthur irq's | 3519 | * Disable further irq's (msix not enabled with napi) |
3520 | (msix not enabled with napi) */ | 3520 | */ |
3521 | writel(0, base + NvRegIrqMask); | 3521 | writel(0, base + NvRegIrqMask); |
3522 | __napi_schedule(&np->napi); | ||
3523 | } | ||
3522 | 3524 | ||
3523 | #else | 3525 | #else |
3524 | do | 3526 | do |
@@ -3615,12 +3617,13 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) | |||
3615 | nv_msi_workaround(np); | 3617 | nv_msi_workaround(np); |
3616 | 3618 | ||
3617 | #ifdef CONFIG_FORCEDETH_NAPI | 3619 | #ifdef CONFIG_FORCEDETH_NAPI |
3618 | napi_schedule(&np->napi); | 3620 | if (napi_schedule_prep(&np->napi)) { |
3619 | 3621 | /* | |
3620 | /* Disable furthur irq's | 3622 | * Disable further irq's (msix not enabled with napi) |
3621 | (msix not enabled with napi) */ | 3623 | */ |
3622 | writel(0, base + NvRegIrqMask); | 3624 | writel(0, base + NvRegIrqMask); |
3623 | 3625 | __napi_schedule(&np->napi); | |
3626 | } | ||
3624 | #else | 3627 | #else |
3625 | do | 3628 | do |
3626 | { | 3629 | { |
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 3af581303ca2..d167090248e2 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c | |||
@@ -188,7 +188,7 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) | |||
188 | } | 188 | } |
189 | 189 | ||
190 | 190 | ||
191 | #ifdef CONFIG_GIANFAR | 191 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) |
192 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) | 192 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) |
193 | { | 193 | { |
194 | struct gfar __iomem *enet_regs; | 194 | struct gfar __iomem *enet_regs; |
@@ -206,7 +206,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) | |||
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | 208 | ||
209 | #ifdef CONFIG_UCC_GETH | 209 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) |
210 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) | 210 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) |
211 | { | 211 | { |
212 | struct device_node *np = NULL; | 212 | struct device_node *np = NULL; |
@@ -291,7 +291,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
291 | if (of_device_is_compatible(np, "fsl,gianfar-mdio") || | 291 | if (of_device_is_compatible(np, "fsl,gianfar-mdio") || |
292 | of_device_is_compatible(np, "fsl,gianfar-tbi") || | 292 | of_device_is_compatible(np, "fsl,gianfar-tbi") || |
293 | of_device_is_compatible(np, "gianfar")) { | 293 | of_device_is_compatible(np, "gianfar")) { |
294 | #ifdef CONFIG_GIANFAR | 294 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) |
295 | tbipa = get_gfar_tbipa(regs); | 295 | tbipa = get_gfar_tbipa(regs); |
296 | #else | 296 | #else |
297 | err = -ENODEV; | 297 | err = -ENODEV; |
@@ -299,7 +299,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
299 | #endif | 299 | #endif |
300 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || | 300 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || |
301 | of_device_is_compatible(np, "ucc_geth_phy")) { | 301 | of_device_is_compatible(np, "ucc_geth_phy")) { |
302 | #ifdef CONFIG_UCC_GETH | 302 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) |
303 | u32 id; | 303 | u32 id; |
304 | static u32 mii_mng_master; | 304 | static u32 mii_mng_master; |
305 | 305 | ||
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 9d5b62cb30f7..d62378cbc149 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c | |||
@@ -173,8 +173,8 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; | |||
173 | 173 | ||
174 | static const char version[] __devinitconst = | 174 | static const char version[] __devinitconst = |
175 | KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n" | 175 | KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n" |
176 | KERN_INFO " Some modifications by Eric kasten <kasten@nscl.msu.edu>\n" | 176 | " Some modifications by Eric kasten <kasten@nscl.msu.edu>\n" |
177 | KERN_INFO " Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n"; | 177 | " Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n"; |
178 | 178 | ||
179 | 179 | ||
180 | /* IP_MF appears to be only defined in <netinet/ip.h>, however, | 180 | /* IP_MF appears to be only defined in <netinet/ip.h>, however, |
@@ -1080,11 +1080,14 @@ static void hamachi_tx_timeout(struct net_device *dev) | |||
1080 | { | 1080 | { |
1081 | printk(KERN_DEBUG " Rx ring %p: ", hmp->rx_ring); | 1081 | printk(KERN_DEBUG " Rx ring %p: ", hmp->rx_ring); |
1082 | for (i = 0; i < RX_RING_SIZE; i++) | 1082 | for (i = 0; i < RX_RING_SIZE; i++) |
1083 | printk(" %8.8x", le32_to_cpu(hmp->rx_ring[i].status_n_length)); | 1083 | printk(KERN_CONT " %8.8x", |
1084 | printk("\n"KERN_DEBUG" Tx ring %p: ", hmp->tx_ring); | 1084 | le32_to_cpu(hmp->rx_ring[i].status_n_length)); |
1085 | printk(KERN_CONT "\n"); | ||
1086 | printk(KERN_DEBUG" Tx ring %p: ", hmp->tx_ring); | ||
1085 | for (i = 0; i < TX_RING_SIZE; i++) | 1087 | for (i = 0; i < TX_RING_SIZE; i++) |
1086 | printk(" %4.4x", le32_to_cpu(hmp->tx_ring[i].status_n_length)); | 1088 | printk(KERN_CONT " %4.4x", |
1087 | printk("\n"); | 1089 | le32_to_cpu(hmp->tx_ring[i].status_n_length)); |
1090 | printk(KERN_CONT "\n"); | ||
1088 | } | 1091 | } |
1089 | 1092 | ||
1090 | /* Reinit the hardware and make sure the Rx and Tx processes | 1093 | /* Reinit the hardware and make sure the Rx and Tx processes |
@@ -1753,13 +1756,13 @@ static int hamachi_close(struct net_device *dev) | |||
1753 | 1756 | ||
1754 | #ifdef __i386__ | 1757 | #ifdef __i386__ |
1755 | if (hamachi_debug > 2) { | 1758 | if (hamachi_debug > 2) { |
1756 | printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", | 1759 | printk(KERN_DEBUG " Tx ring at %8.8x:\n", |
1757 | (int)hmp->tx_ring_dma); | 1760 | (int)hmp->tx_ring_dma); |
1758 | for (i = 0; i < TX_RING_SIZE; i++) | 1761 | for (i = 0; i < TX_RING_SIZE; i++) |
1759 | printk(" %c #%d desc. %8.8x %8.8x.\n", | 1762 | printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x.\n", |
1760 | readl(ioaddr + TxCurPtr) == (long)&hmp->tx_ring[i] ? '>' : ' ', | 1763 | readl(ioaddr + TxCurPtr) == (long)&hmp->tx_ring[i] ? '>' : ' ', |
1761 | i, hmp->tx_ring[i].status_n_length, hmp->tx_ring[i].addr); | 1764 | i, hmp->tx_ring[i].status_n_length, hmp->tx_ring[i].addr); |
1762 | printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", | 1765 | printk(KERN_DEBUG " Rx ring %8.8x:\n", |
1763 | (int)hmp->rx_ring_dma); | 1766 | (int)hmp->rx_ring_dma); |
1764 | for (i = 0; i < RX_RING_SIZE; i++) { | 1767 | for (i = 0; i < RX_RING_SIZE; i++) { |
1765 | printk(KERN_DEBUG " %c #%d desc. %4.4x %8.8x\n", | 1768 | printk(KERN_DEBUG " %c #%d desc. %4.4x %8.8x\n", |
@@ -1770,7 +1773,7 @@ static int hamachi_close(struct net_device *dev) | |||
1770 | u16 *addr = (u16 *) | 1773 | u16 *addr = (u16 *) |
1771 | hmp->rx_skbuff[i]->data; | 1774 | hmp->rx_skbuff[i]->data; |
1772 | int j; | 1775 | int j; |
1773 | 1776 | printk(KERN_DEBUG "Addr: "); | |
1774 | for (j = 0; j < 0x50; j++) | 1777 | for (j = 0; j < 0x50; j++) |
1775 | printk(" %4.4x", addr[j]); | 1778 | printk(" %4.4x", addr[j]); |
1776 | printk("\n"); | 1779 | printk("\n"); |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 5e4b7afd0683..352703255bba 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -68,7 +68,7 @@ static const char paranoia_str[] = KERN_ERR | |||
68 | 68 | ||
69 | static const char bc_drvname[] = "baycom_epp"; | 69 | static const char bc_drvname[] = "baycom_epp"; |
70 | static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n" | 70 | static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n" |
71 | KERN_INFO "baycom_epp: version 0.7 compiled " __TIME__ " " __DATE__ "\n"; | 71 | "baycom_epp: version 0.7 compiled " __TIME__ " " __DATE__ "\n"; |
72 | 72 | ||
73 | /* --------------------------------------------------------------------- */ | 73 | /* --------------------------------------------------------------------- */ |
74 | 74 | ||
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 2e6fc4dc74b1..5f5af9a606f8 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c | |||
@@ -102,7 +102,7 @@ | |||
102 | 102 | ||
103 | static const char bc_drvname[] = "baycom_par"; | 103 | static const char bc_drvname[] = "baycom_par"; |
104 | static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" | 104 | static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" |
105 | KERN_INFO "baycom_par: version 0.9 compiled " __TIME__ " " __DATE__ "\n"; | 105 | "baycom_par: version 0.9 compiled " __TIME__ " " __DATE__ "\n"; |
106 | 106 | ||
107 | /* --------------------------------------------------------------------- */ | 107 | /* --------------------------------------------------------------------- */ |
108 | 108 | ||
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index b6a816e60c0f..aa4488e871b2 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c | |||
@@ -91,7 +91,7 @@ | |||
91 | 91 | ||
92 | static const char bc_drvname[] = "baycom_ser_fdx"; | 92 | static const char bc_drvname[] = "baycom_ser_fdx"; |
93 | static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" | 93 | static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" |
94 | KERN_INFO "baycom_ser_fdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n"; | 94 | "baycom_ser_fdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n"; |
95 | 95 | ||
96 | /* --------------------------------------------------------------------- */ | 96 | /* --------------------------------------------------------------------- */ |
97 | 97 | ||
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index 3bcc57acbe6d..88c593596020 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c | |||
@@ -79,7 +79,7 @@ | |||
79 | 79 | ||
80 | static const char bc_drvname[] = "baycom_ser_hdx"; | 80 | static const char bc_drvname[] = "baycom_ser_hdx"; |
81 | static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" | 81 | static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" |
82 | KERN_INFO "baycom_ser_hdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n"; | 82 | "baycom_ser_hdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n"; |
83 | 83 | ||
84 | /* --------------------------------------------------------------------- */ | 84 | /* --------------------------------------------------------------------- */ |
85 | 85 | ||
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index efd9be214885..ac28dd5a4fd1 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -190,6 +190,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
190 | phy->ops.write_reg = igb_write_phy_reg_igp; | 190 | phy->ops.write_reg = igb_write_phy_reg_igp; |
191 | } | 191 | } |
192 | 192 | ||
193 | /* set lan id */ | ||
194 | hw->bus.func = (rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) >> | ||
195 | E1000_STATUS_FUNC_SHIFT; | ||
196 | |||
193 | /* Set phy->phy_addr and phy->id. */ | 197 | /* Set phy->phy_addr and phy->id. */ |
194 | ret_val = igb_get_phy_id_82575(hw); | 198 | ret_val = igb_get_phy_id_82575(hw); |
195 | if (ret_val) | 199 | if (ret_val) |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ea17319624aa..be480292aba1 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -4549,11 +4549,12 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, | |||
4549 | cleaned = true; | 4549 | cleaned = true; |
4550 | cleaned_count++; | 4550 | cleaned_count++; |
4551 | 4551 | ||
4552 | /* this is the fast path for the non-packet split case */ | ||
4552 | if (!adapter->rx_ps_hdr_size) { | 4553 | if (!adapter->rx_ps_hdr_size) { |
4553 | pci_unmap_single(pdev, buffer_info->dma, | 4554 | pci_unmap_single(pdev, buffer_info->dma, |
4554 | adapter->rx_buffer_len + | 4555 | adapter->rx_buffer_len, |
4555 | NET_IP_ALIGN, | ||
4556 | PCI_DMA_FROMDEVICE); | 4556 | PCI_DMA_FROMDEVICE); |
4557 | buffer_info->dma = 0; | ||
4557 | skb_put(skb, length); | 4558 | skb_put(skb, length); |
4558 | goto send_up; | 4559 | goto send_up; |
4559 | } | 4560 | } |
@@ -4570,8 +4571,9 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, | |||
4570 | 4571 | ||
4571 | if (!skb_shinfo(skb)->nr_frags) { | 4572 | if (!skb_shinfo(skb)->nr_frags) { |
4572 | pci_unmap_single(pdev, buffer_info->dma, | 4573 | pci_unmap_single(pdev, buffer_info->dma, |
4573 | adapter->rx_ps_hdr_size + NET_IP_ALIGN, | 4574 | adapter->rx_ps_hdr_size, |
4574 | PCI_DMA_FROMDEVICE); | 4575 | PCI_DMA_FROMDEVICE); |
4576 | buffer_info->dma = 0; | ||
4575 | skb_put(skb, hlen); | 4577 | skb_put(skb, hlen); |
4576 | } | 4578 | } |
4577 | 4579 | ||
@@ -4713,7 +4715,6 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, | |||
4713 | bufsz = adapter->rx_ps_hdr_size; | 4715 | bufsz = adapter->rx_ps_hdr_size; |
4714 | else | 4716 | else |
4715 | bufsz = adapter->rx_buffer_len; | 4717 | bufsz = adapter->rx_buffer_len; |
4716 | bufsz += NET_IP_ALIGN; | ||
4717 | 4718 | ||
4718 | while (cleaned_count--) { | 4719 | while (cleaned_count--) { |
4719 | rx_desc = E1000_RX_DESC_ADV(*rx_ring, i); | 4720 | rx_desc = E1000_RX_DESC_ADV(*rx_ring, i); |
@@ -4737,7 +4738,7 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, | |||
4737 | } | 4738 | } |
4738 | 4739 | ||
4739 | if (!buffer_info->skb) { | 4740 | if (!buffer_info->skb) { |
4740 | skb = netdev_alloc_skb(netdev, bufsz); | 4741 | skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN); |
4741 | if (!skb) { | 4742 | if (!skb) { |
4742 | adapter->alloc_rx_buff_failed++; | 4743 | adapter->alloc_rx_buff_failed++; |
4743 | goto no_buffers; | 4744 | goto no_buffers; |
@@ -5338,6 +5339,9 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev, | |||
5338 | 5339 | ||
5339 | netif_device_detach(netdev); | 5340 | netif_device_detach(netdev); |
5340 | 5341 | ||
5342 | if (state == pci_channel_io_perm_failure) | ||
5343 | return PCI_ERS_RESULT_DISCONNECT; | ||
5344 | |||
5341 | if (netif_running(netdev)) | 5345 | if (netif_running(netdev)) |
5342 | igb_down(adapter); | 5346 | igb_down(adapter); |
5343 | pci_disable_device(pdev); | 5347 | pci_disable_device(pdev); |
diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c index f3eed6a8fba5..911c082cee5a 100644 --- a/drivers/net/irda/bfin_sir.c +++ b/drivers/net/irda/bfin_sir.c | |||
@@ -677,6 +677,14 @@ static int bfin_sir_init_iobuf(iobuff_t *io, int size) | |||
677 | return 0; | 677 | return 0; |
678 | } | 678 | } |
679 | 679 | ||
680 | static const struct net_device_ops bfin_sir_ndo = { | ||
681 | .ndo_open = bfin_sir_open, | ||
682 | .ndo_stop = bfin_sir_stop, | ||
683 | .ndo_start_xmit = bfin_sir_hard_xmit, | ||
684 | .ndo_do_ioctl = bfin_sir_ioctl, | ||
685 | .ndo_get_stats = bfin_sir_stats, | ||
686 | }; | ||
687 | |||
680 | static int __devinit bfin_sir_probe(struct platform_device *pdev) | 688 | static int __devinit bfin_sir_probe(struct platform_device *pdev) |
681 | { | 689 | { |
682 | struct net_device *dev; | 690 | struct net_device *dev; |
@@ -718,12 +726,8 @@ static int __devinit bfin_sir_probe(struct platform_device *pdev) | |||
718 | if (err) | 726 | if (err) |
719 | goto err_mem_3; | 727 | goto err_mem_3; |
720 | 728 | ||
721 | dev->hard_start_xmit = bfin_sir_hard_xmit; | 729 | dev->netdev_ops = &bfin_sir_ndo; |
722 | dev->open = bfin_sir_open; | 730 | dev->irq = sir_port->irq; |
723 | dev->stop = bfin_sir_stop; | ||
724 | dev->do_ioctl = bfin_sir_ioctl; | ||
725 | dev->get_stats = bfin_sir_stats; | ||
726 | dev->irq = sir_port->irq; | ||
727 | 731 | ||
728 | irda_init_max_qos_capabilies(&self->qos); | 732 | irda_init_max_qos_capabilies(&self->qos); |
729 | 733 | ||
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index d56890f5c9d5..7c5978ad929a 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -138,6 +138,10 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
138 | adapter->hw.fc.requested_mode = ixgbe_fc_none; | 138 | adapter->hw.fc.requested_mode = ixgbe_fc_none; |
139 | } | 139 | } |
140 | adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; | 140 | adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; |
141 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
142 | adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
143 | adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | ||
144 | } | ||
141 | adapter->flags |= IXGBE_FLAG_DCB_ENABLED; | 145 | adapter->flags |= IXGBE_FLAG_DCB_ENABLED; |
142 | ixgbe_init_interrupt_scheme(adapter); | 146 | ixgbe_init_interrupt_scheme(adapter); |
143 | if (netif_running(netdev)) | 147 | if (netif_running(netdev)) |
@@ -154,6 +158,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
154 | adapter->dcb_cfg.pfc_mode_enable = false; | 158 | adapter->dcb_cfg.pfc_mode_enable = false; |
155 | adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; | 159 | adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; |
156 | adapter->flags |= IXGBE_FLAG_RSS_ENABLED; | 160 | adapter->flags |= IXGBE_FLAG_RSS_ENABLED; |
161 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) | ||
162 | adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
157 | ixgbe_init_interrupt_scheme(adapter); | 163 | ixgbe_init_interrupt_scheme(adapter); |
158 | if (netif_running(netdev)) | 164 | if (netif_running(netdev)) |
159 | netdev->netdev_ops->ndo_open(netdev); | 165 | netdev->netdev_ops->ndo_open(netdev); |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 86f4f3e36f27..2a978008fd6e 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -139,7 +139,7 @@ static int ixgbe_get_settings(struct net_device *netdev, | |||
139 | ecmd->autoneg = AUTONEG_ENABLE; | 139 | ecmd->autoneg = AUTONEG_ENABLE; |
140 | ecmd->transceiver = XCVR_EXTERNAL; | 140 | ecmd->transceiver = XCVR_EXTERNAL; |
141 | if ((hw->phy.media_type == ixgbe_media_type_copper) || | 141 | if ((hw->phy.media_type == ixgbe_media_type_copper) || |
142 | (hw->mac.type == ixgbe_mac_82599EB)) { | 142 | (hw->phy.multispeed_fiber)) { |
143 | ecmd->supported |= (SUPPORTED_1000baseT_Full | | 143 | ecmd->supported |= (SUPPORTED_1000baseT_Full | |
144 | SUPPORTED_Autoneg); | 144 | SUPPORTED_Autoneg); |
145 | 145 | ||
@@ -217,7 +217,7 @@ static int ixgbe_set_settings(struct net_device *netdev, | |||
217 | s32 err = 0; | 217 | s32 err = 0; |
218 | 218 | ||
219 | if ((hw->phy.media_type == ixgbe_media_type_copper) || | 219 | if ((hw->phy.media_type == ixgbe_media_type_copper) || |
220 | (hw->mac.type == ixgbe_mac_82599EB)) { | 220 | (hw->phy.multispeed_fiber)) { |
221 | /* 10000/copper and 1000/copper must autoneg | 221 | /* 10000/copper and 1000/copper must autoneg |
222 | * this function does not support any duplex forcing, but can | 222 | * this function does not support any duplex forcing, but can |
223 | * limit the advertising of the adapter to only 10000 or 1000 */ | 223 | * limit the advertising of the adapter to only 10000 or 1000 */ |
@@ -245,6 +245,7 @@ static int ixgbe_set_settings(struct net_device *netdev, | |||
245 | } else { | 245 | } else { |
246 | /* in this case we currently only support 10Gb/FULL */ | 246 | /* in this case we currently only support 10Gb/FULL */ |
247 | if ((ecmd->autoneg == AUTONEG_ENABLE) || | 247 | if ((ecmd->autoneg == AUTONEG_ENABLE) || |
248 | (ecmd->advertising != ADVERTISED_10000baseT_Full) || | ||
248 | (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) | 249 | (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) |
249 | return -EINVAL; | 250 | return -EINVAL; |
250 | } | 251 | } |
@@ -1829,7 +1830,6 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, | |||
1829 | break; | 1830 | break; |
1830 | default: | 1831 | default: |
1831 | wol->supported = 0; | 1832 | wol->supported = 0; |
1832 | retval = 0; | ||
1833 | } | 1833 | } |
1834 | 1834 | ||
1835 | return retval; | 1835 | return retval; |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e756e220db32..e3442f47f932 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -563,7 +563,6 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, | |||
563 | union ixgbe_adv_rx_desc *rx_desc; | 563 | union ixgbe_adv_rx_desc *rx_desc; |
564 | struct ixgbe_rx_buffer *bi; | 564 | struct ixgbe_rx_buffer *bi; |
565 | unsigned int i; | 565 | unsigned int i; |
566 | unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN; | ||
567 | 566 | ||
568 | i = rx_ring->next_to_use; | 567 | i = rx_ring->next_to_use; |
569 | bi = &rx_ring->rx_buffer_info[i]; | 568 | bi = &rx_ring->rx_buffer_info[i]; |
@@ -593,7 +592,9 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, | |||
593 | 592 | ||
594 | if (!bi->skb) { | 593 | if (!bi->skb) { |
595 | struct sk_buff *skb; | 594 | struct sk_buff *skb; |
596 | skb = netdev_alloc_skb(adapter->netdev, bufsz); | 595 | skb = netdev_alloc_skb(adapter->netdev, |
596 | (rx_ring->rx_buf_len + | ||
597 | NET_IP_ALIGN)); | ||
597 | 598 | ||
598 | if (!skb) { | 599 | if (!skb) { |
599 | adapter->alloc_rx_buff_failed++; | 600 | adapter->alloc_rx_buff_failed++; |
@@ -608,7 +609,8 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, | |||
608 | skb_reserve(skb, NET_IP_ALIGN); | 609 | skb_reserve(skb, NET_IP_ALIGN); |
609 | 610 | ||
610 | bi->skb = skb; | 611 | bi->skb = skb; |
611 | bi->dma = pci_map_single(pdev, skb->data, bufsz, | 612 | bi->dma = pci_map_single(pdev, skb->data, |
613 | rx_ring->rx_buf_len, | ||
612 | PCI_DMA_FROMDEVICE); | 614 | PCI_DMA_FROMDEVICE); |
613 | } | 615 | } |
614 | /* Refresh the desc even if buffer_addrs didn't change because | 616 | /* Refresh the desc even if buffer_addrs didn't change because |
@@ -732,6 +734,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
732 | pci_unmap_single(pdev, rx_buffer_info->dma, | 734 | pci_unmap_single(pdev, rx_buffer_info->dma, |
733 | rx_ring->rx_buf_len, | 735 | rx_ring->rx_buf_len, |
734 | PCI_DMA_FROMDEVICE); | 736 | PCI_DMA_FROMDEVICE); |
737 | rx_buffer_info->dma = 0; | ||
735 | skb_put(skb, len); | 738 | skb_put(skb, len); |
736 | } | 739 | } |
737 | 740 | ||
@@ -2694,16 +2697,23 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) | |||
2694 | 2697 | ||
2695 | /* | 2698 | /* |
2696 | * For hot-pluggable SFP+ devices, a new SFP+ module may have | 2699 | * For hot-pluggable SFP+ devices, a new SFP+ module may have |
2697 | * arrived before interrupts were enabled. We need to kick off | 2700 | * arrived before interrupts were enabled but after probe. Such |
2698 | * the SFP+ module setup first, then try to bring up link. | 2701 | * devices wouldn't have their type identified yet. We need to |
2702 | * kick off the SFP+ module setup first, then try to bring up link. | ||
2699 | * If we're not hot-pluggable SFP+, we just need to configure link | 2703 | * If we're not hot-pluggable SFP+, we just need to configure link |
2700 | * and bring it up. | 2704 | * and bring it up. |
2701 | */ | 2705 | */ |
2702 | err = hw->phy.ops.identify(hw); | 2706 | if (hw->phy.type == ixgbe_phy_unknown) { |
2703 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | 2707 | err = hw->phy.ops.identify(hw); |
2704 | DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); | 2708 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { |
2705 | ixgbe_down(adapter); | 2709 | /* |
2706 | return err; | 2710 | * Take the device down and schedule the sfp tasklet |
2711 | * which will unregister_netdev and log it. | ||
2712 | */ | ||
2713 | ixgbe_down(adapter); | ||
2714 | schedule_work(&adapter->sfp_config_module_task); | ||
2715 | return err; | ||
2716 | } | ||
2707 | } | 2717 | } |
2708 | 2718 | ||
2709 | if (ixgbe_is_sfp(hw)) { | 2719 | if (ixgbe_is_sfp(hw)) { |
@@ -2812,9 +2822,11 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, | |||
2812 | } | 2822 | } |
2813 | if (!rx_buffer_info->page) | 2823 | if (!rx_buffer_info->page) |
2814 | continue; | 2824 | continue; |
2815 | pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2, | 2825 | if (rx_buffer_info->page_dma) { |
2816 | PCI_DMA_FROMDEVICE); | 2826 | pci_unmap_page(pdev, rx_buffer_info->page_dma, |
2817 | rx_buffer_info->page_dma = 0; | 2827 | PAGE_SIZE / 2, PCI_DMA_FROMDEVICE); |
2828 | rx_buffer_info->page_dma = 0; | ||
2829 | } | ||
2818 | put_page(rx_buffer_info->page); | 2830 | put_page(rx_buffer_info->page); |
2819 | rx_buffer_info->page = NULL; | 2831 | rx_buffer_info->page = NULL; |
2820 | rx_buffer_info->page_offset = 0; | 2832 | rx_buffer_info->page_offset = 0; |
@@ -3118,7 +3130,11 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) | |||
3118 | #endif | 3130 | #endif |
3119 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | 3131 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { |
3120 | DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n"); | 3132 | DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n"); |
3121 | ixgbe_set_rss_queues(adapter); | 3133 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || |
3134 | (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) | ||
3135 | ixgbe_set_fdir_queues(adapter); | ||
3136 | else | ||
3137 | ixgbe_set_rss_queues(adapter); | ||
3122 | } | 3138 | } |
3123 | /* adding FCoE rx rings to the end */ | 3139 | /* adding FCoE rx rings to the end */ |
3124 | f->mask = adapter->num_rx_queues; | 3140 | f->mask = adapter->num_rx_queues; |
@@ -3376,7 +3392,12 @@ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) | |||
3376 | } | 3392 | } |
3377 | #endif /* CONFIG_IXGBE_DCB */ | 3393 | #endif /* CONFIG_IXGBE_DCB */ |
3378 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | 3394 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { |
3379 | ixgbe_cache_ring_rss(adapter); | 3395 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || |
3396 | (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) | ||
3397 | ixgbe_cache_ring_fdir(adapter); | ||
3398 | else | ||
3399 | ixgbe_cache_ring_rss(adapter); | ||
3400 | |||
3380 | fcoe_i = f->mask; | 3401 | fcoe_i = f->mask; |
3381 | } | 3402 | } |
3382 | for (i = 0; i < f->indices; i++, fcoe_i++) | 3403 | for (i = 0; i < f->indices; i++, fcoe_i++) |
@@ -3716,14 +3737,15 @@ static void ixgbe_sfp_task(struct work_struct *work) | |||
3716 | if ((hw->phy.type == ixgbe_phy_nl) && | 3737 | if ((hw->phy.type == ixgbe_phy_nl) && |
3717 | (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) { | 3738 | (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) { |
3718 | s32 ret = hw->phy.ops.identify_sfp(hw); | 3739 | s32 ret = hw->phy.ops.identify_sfp(hw); |
3719 | if (ret) | 3740 | if (ret == IXGBE_ERR_SFP_NOT_PRESENT) |
3720 | goto reschedule; | 3741 | goto reschedule; |
3721 | ret = hw->phy.ops.reset(hw); | 3742 | ret = hw->phy.ops.reset(hw); |
3722 | if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { | 3743 | if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { |
3723 | DPRINTK(PROBE, ERR, "failed to initialize because an " | 3744 | dev_err(&adapter->pdev->dev, "failed to initialize " |
3724 | "unsupported SFP+ module type was detected.\n" | 3745 | "because an unsupported SFP+ module type " |
3725 | "Reload the driver after installing a " | 3746 | "was detected.\n" |
3726 | "supported module.\n"); | 3747 | "Reload the driver after installing a " |
3748 | "supported module.\n"); | ||
3727 | unregister_netdev(adapter->netdev); | 3749 | unregister_netdev(adapter->netdev); |
3728 | } else { | 3750 | } else { |
3729 | DPRINTK(PROBE, INFO, "detected SFP+: %d\n", | 3751 | DPRINTK(PROBE, INFO, "detected SFP+: %d\n", |
@@ -4502,7 +4524,8 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) | |||
4502 | u32 autoneg; | 4524 | u32 autoneg; |
4503 | 4525 | ||
4504 | adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK; | 4526 | adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK; |
4505 | if (hw->mac.ops.get_link_capabilities) | 4527 | autoneg = hw->phy.autoneg_advertised; |
4528 | if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | ||
4506 | hw->mac.ops.get_link_capabilities(hw, &autoneg, | 4529 | hw->mac.ops.get_link_capabilities(hw, &autoneg, |
4507 | &hw->mac.autoneg); | 4530 | &hw->mac.autoneg); |
4508 | if (hw->mac.ops.setup_link_speed) | 4531 | if (hw->mac.ops.setup_link_speed) |
@@ -4524,10 +4547,17 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) | |||
4524 | u32 err; | 4547 | u32 err; |
4525 | 4548 | ||
4526 | adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; | 4549 | adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; |
4550 | |||
4551 | /* Time for electrical oscillations to settle down */ | ||
4552 | msleep(100); | ||
4527 | err = hw->phy.ops.identify_sfp(hw); | 4553 | err = hw->phy.ops.identify_sfp(hw); |
4554 | |||
4528 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | 4555 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { |
4529 | DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); | 4556 | dev_err(&adapter->pdev->dev, "failed to initialize because " |
4530 | ixgbe_down(adapter); | 4557 | "an unsupported SFP+ module type was detected.\n" |
4558 | "Reload the driver after installing a supported " | ||
4559 | "module.\n"); | ||
4560 | unregister_netdev(adapter->netdev); | ||
4531 | return; | 4561 | return; |
4532 | } | 4562 | } |
4533 | hw->mac.ops.setup_sfp(hw); | 4563 | hw->mac.ops.setup_sfp(hw); |
@@ -5513,8 +5543,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5513 | round_jiffies(jiffies + (2 * HZ))); | 5543 | round_jiffies(jiffies + (2 * HZ))); |
5514 | err = 0; | 5544 | err = 0; |
5515 | } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | 5545 | } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { |
5516 | dev_err(&adapter->pdev->dev, "failed to load because an " | 5546 | dev_err(&adapter->pdev->dev, "failed to initialize because " |
5517 | "unsupported SFP+ module type was detected.\n"); | 5547 | "an unsupported SFP+ module type was detected.\n" |
5548 | "Reload the driver after installing a supported " | ||
5549 | "module.\n"); | ||
5518 | goto err_sw_init; | 5550 | goto err_sw_init; |
5519 | } else if (err) { | 5551 | } else if (err) { |
5520 | dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err); | 5552 | dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err); |
@@ -5555,12 +5587,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5555 | netdev->features |= NETIF_F_FCOE_CRC; | 5587 | netdev->features |= NETIF_F_FCOE_CRC; |
5556 | netdev->features |= NETIF_F_FSO; | 5588 | netdev->features |= NETIF_F_FSO; |
5557 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; | 5589 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; |
5558 | DPRINTK(DRV, INFO, "FCoE enabled, " | ||
5559 | "disabling Flow Director\n"); | ||
5560 | adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; | ||
5561 | adapter->flags &= | ||
5562 | ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | ||
5563 | adapter->atr_sample_rate = 0; | ||
5564 | } else { | 5590 | } else { |
5565 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; | 5591 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; |
5566 | } | 5592 | } |
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 453e966762f0..9ecad17522c3 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c | |||
@@ -60,6 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) | |||
60 | 60 | ||
61 | if (hw->phy.type == ixgbe_phy_unknown) { | 61 | if (hw->phy.type == ixgbe_phy_unknown) { |
62 | for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { | 62 | for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { |
63 | hw->phy.mdio.prtad = phy_addr; | ||
63 | if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) { | 64 | if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) { |
64 | ixgbe_get_phy_id(hw); | 65 | ixgbe_get_phy_id(hw); |
65 | hw->phy.type = | 66 | hw->phy.type = |
@@ -68,6 +69,8 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) | |||
68 | break; | 69 | break; |
69 | } | 70 | } |
70 | } | 71 | } |
72 | /* clear value if nothing found */ | ||
73 | hw->phy.mdio.prtad = 0; | ||
71 | } else { | 74 | } else { |
72 | status = 0; | 75 | status = 0; |
73 | } | 76 | } |
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index dc45e9856c35..6851bdb2ce29 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c | |||
@@ -14,6 +14,10 @@ | |||
14 | #include <linux/mdio.h> | 14 | #include <linux/mdio.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | 16 | ||
17 | MODULE_DESCRIPTION("Generic support for MDIO-compatible transceivers"); | ||
18 | MODULE_AUTHOR("Copyright 2006-2009 Solarflare Communications Inc."); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
17 | /** | 21 | /** |
18 | * mdio45_probe - probe for an MDIO (clause 45) device | 22 | * mdio45_probe - probe for an MDIO (clause 45) device |
19 | * @mdio: MDIO interface | 23 | * @mdio: MDIO interface |
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index c9bfe4eea189..78c088331f57 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c | |||
@@ -130,8 +130,8 @@ static int full_duplex[MAX_UNITS]; | |||
130 | static const char version[] __devinitconst = | 130 | static const char version[] __devinitconst = |
131 | KERN_INFO DRV_NAME " dp8381x driver, version " | 131 | KERN_INFO DRV_NAME " dp8381x driver, version " |
132 | DRV_VERSION ", " DRV_RELDATE "\n" | 132 | DRV_VERSION ", " DRV_RELDATE "\n" |
133 | KERN_INFO " originally by Donald Becker <becker@scyld.com>\n" | 133 | " originally by Donald Becker <becker@scyld.com>\n" |
134 | KERN_INFO " 2.4.x kernel port by Jeff Garzik, Tjeerd Mulder\n"; | 134 | " 2.4.x kernel port by Jeff Garzik, Tjeerd Mulder\n"; |
135 | 135 | ||
136 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); | 136 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); |
137 | MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver"); | 137 | MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver"); |
diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 5c3e242428f1..992dbfffdb05 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c | |||
@@ -321,7 +321,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | if (ei_debug && version_printed++ == 0) | 323 | if (ei_debug && version_printed++ == 0) |
324 | printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); | 324 | printk(KERN_INFO "%s%s", version1, version2); |
325 | 325 | ||
326 | printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr); | 326 | printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr); |
327 | 327 | ||
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 970cedeb5f37..e1cdba752e09 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -60,7 +60,18 @@ | |||
60 | #define _NETXEN_NIC_LINUX_SUBVERSION 30 | 60 | #define _NETXEN_NIC_LINUX_SUBVERSION 30 |
61 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.30" | 61 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.30" |
62 | 62 | ||
63 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c)) | 63 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
64 | #define _major(v) (((v) >> 24) & 0xff) | ||
65 | #define _minor(v) (((v) >> 16) & 0xff) | ||
66 | #define _build(v) ((v) & 0xffff) | ||
67 | |||
68 | /* version in image has weird encoding: | ||
69 | * 7:0 - major | ||
70 | * 15:8 - minor | ||
71 | * 31:16 - build (little endian) | ||
72 | */ | ||
73 | #define NETXEN_DECODE_VERSION(v) \ | ||
74 | NETXEN_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16)) | ||
64 | 75 | ||
65 | #define NETXEN_NUM_FLASH_SECTORS (64) | 76 | #define NETXEN_NUM_FLASH_SECTORS (64) |
66 | #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) | 77 | #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) |
@@ -614,6 +625,7 @@ struct netxen_new_user_info { | |||
614 | #define NX_P2_MN_ROMIMAGE 0 | 625 | #define NX_P2_MN_ROMIMAGE 0 |
615 | #define NX_P3_CT_ROMIMAGE 1 | 626 | #define NX_P3_CT_ROMIMAGE 1 |
616 | #define NX_P3_MN_ROMIMAGE 2 | 627 | #define NX_P3_MN_ROMIMAGE 2 |
628 | #define NX_FLASH_ROMIMAGE 3 | ||
617 | 629 | ||
618 | #define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */ | 630 | #define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */ |
619 | 631 | ||
@@ -1243,7 +1255,7 @@ struct netxen_adapter { | |||
1243 | u32 resv3; | 1255 | u32 resv3; |
1244 | 1256 | ||
1245 | u8 has_link_events; | 1257 | u8 has_link_events; |
1246 | u8 resv1; | 1258 | u8 fw_type; |
1247 | u16 tx_context_id; | 1259 | u16 tx_context_id; |
1248 | u16 mtu; | 1260 | u16 mtu; |
1249 | u16 is_up; | 1261 | u16 is_up; |
@@ -1387,6 +1399,7 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter); | |||
1387 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); | 1399 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); |
1388 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); | 1400 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); |
1389 | int netxen_load_firmware(struct netxen_adapter *adapter); | 1401 | int netxen_load_firmware(struct netxen_adapter *adapter); |
1402 | int netxen_need_fw_reset(struct netxen_adapter *adapter); | ||
1390 | void netxen_request_firmware(struct netxen_adapter *adapter); | 1403 | void netxen_request_firmware(struct netxen_adapter *adapter); |
1391 | void netxen_release_firmware(struct netxen_adapter *adapter); | 1404 | void netxen_release_firmware(struct netxen_adapter *adapter); |
1392 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1405 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 3cc047844af3..824103675648 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -853,6 +853,7 @@ enum { | |||
853 | #define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c)) | 853 | #define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c)) |
854 | 854 | ||
855 | #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) | 855 | #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) |
856 | #define NETXEN_PEG_ALIVE_COUNTER (NETXEN_CAM_RAM(0xb0)) | ||
856 | 857 | ||
857 | #define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) | 858 | #define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) |
858 | #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) | 859 | #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 055bb61d6e77..b899bd51fcd8 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -684,11 +684,84 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
684 | } | 684 | } |
685 | 685 | ||
686 | int | 686 | int |
687 | netxen_need_fw_reset(struct netxen_adapter *adapter) | ||
688 | { | ||
689 | u32 count, old_count; | ||
690 | u32 val, version, major, minor, build; | ||
691 | int i, timeout; | ||
692 | u8 fw_type; | ||
693 | |||
694 | /* NX2031 firmware doesn't support heartbit */ | ||
695 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
696 | return 1; | ||
697 | |||
698 | /* last attempt had failed */ | ||
699 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) | ||
700 | return 1; | ||
701 | |||
702 | old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | ||
703 | |||
704 | for (i = 0; i < 10; i++) { | ||
705 | |||
706 | timeout = msleep_interruptible(200); | ||
707 | if (timeout) { | ||
708 | NXWR32(adapter, CRB_CMDPEG_STATE, | ||
709 | PHAN_INITIALIZE_FAILED); | ||
710 | return -EINTR; | ||
711 | } | ||
712 | |||
713 | count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | ||
714 | if (count != old_count) | ||
715 | break; | ||
716 | } | ||
717 | |||
718 | /* firmware is dead */ | ||
719 | if (count == old_count) | ||
720 | return 1; | ||
721 | |||
722 | /* check if we have got newer or different file firmware */ | ||
723 | if (adapter->fw) { | ||
724 | |||
725 | const struct firmware *fw = adapter->fw; | ||
726 | |||
727 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
728 | version = NETXEN_DECODE_VERSION(val); | ||
729 | |||
730 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); | ||
731 | minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); | ||
732 | build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); | ||
733 | |||
734 | if (version > NETXEN_VERSION_CODE(major, minor, build)) | ||
735 | return 1; | ||
736 | |||
737 | if (version == NETXEN_VERSION_CODE(major, minor, build)) { | ||
738 | |||
739 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); | ||
740 | fw_type = (val & 0x4) ? | ||
741 | NX_P3_CT_ROMIMAGE : NX_P3_MN_ROMIMAGE; | ||
742 | |||
743 | if (adapter->fw_type != fw_type) | ||
744 | return 1; | ||
745 | } | ||
746 | } | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static char *fw_name[] = { | ||
752 | "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash", | ||
753 | }; | ||
754 | |||
755 | int | ||
687 | netxen_load_firmware(struct netxen_adapter *adapter) | 756 | netxen_load_firmware(struct netxen_adapter *adapter) |
688 | { | 757 | { |
689 | u64 *ptr64; | 758 | u64 *ptr64; |
690 | u32 i, flashaddr, size; | 759 | u32 i, flashaddr, size; |
691 | const struct firmware *fw = adapter->fw; | 760 | const struct firmware *fw = adapter->fw; |
761 | struct pci_dev *pdev = adapter->pdev; | ||
762 | |||
763 | dev_info(&pdev->dev, "loading firmware from %s\n", | ||
764 | fw_name[adapter->fw_type]); | ||
692 | 765 | ||
693 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 766 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
694 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); | 767 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); |
@@ -756,7 +829,7 @@ static int | |||
756 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | 829 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) |
757 | { | 830 | { |
758 | __le32 val; | 831 | __le32 val; |
759 | u32 major, minor, build, ver, min_ver, bios; | 832 | u32 ver, min_ver, bios; |
760 | struct pci_dev *pdev = adapter->pdev; | 833 | struct pci_dev *pdev = adapter->pdev; |
761 | const struct firmware *fw = adapter->fw; | 834 | const struct firmware *fw = adapter->fw; |
762 | 835 | ||
@@ -768,21 +841,18 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
768 | return -EINVAL; | 841 | return -EINVAL; |
769 | 842 | ||
770 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | 843 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); |
771 | major = (__force u32)val & 0xff; | ||
772 | minor = ((__force u32)val >> 8) & 0xff; | ||
773 | build = (__force u32)val >> 16; | ||
774 | 844 | ||
775 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 845 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
776 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); | 846 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); |
777 | else | 847 | else |
778 | min_ver = NETXEN_VERSION_CODE(3, 4, 216); | 848 | min_ver = NETXEN_VERSION_CODE(3, 4, 216); |
779 | 849 | ||
780 | ver = NETXEN_VERSION_CODE(major, minor, build); | 850 | ver = NETXEN_DECODE_VERSION(val); |
781 | 851 | ||
782 | if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { | 852 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { |
783 | dev_err(&pdev->dev, | 853 | dev_err(&pdev->dev, |
784 | "%s: firmware version %d.%d.%d unsupported\n", | 854 | "%s: firmware version %d.%d.%d unsupported\n", |
785 | fwname, major, minor, build); | 855 | fwname, _major(ver), _minor(ver), _build(ver)); |
786 | return -EINVAL; | 856 | return -EINVAL; |
787 | } | 857 | } |
788 | 858 | ||
@@ -798,22 +868,21 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
798 | if (netxen_rom_fast_read(adapter, | 868 | if (netxen_rom_fast_read(adapter, |
799 | NX_FW_VERSION_OFFSET, (int *)&val)) | 869 | NX_FW_VERSION_OFFSET, (int *)&val)) |
800 | return -EIO; | 870 | return -EIO; |
801 | major = (__force u32)val & 0xff; | 871 | val = NETXEN_DECODE_VERSION(val); |
802 | minor = ((__force u32)val >> 8) & 0xff; | 872 | if (val > ver) { |
803 | build = (__force u32)val >> 16; | 873 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", |
804 | if (NETXEN_VERSION_CODE(major, minor, build) > ver) | 874 | fwname); |
805 | return -EINVAL; | 875 | return -EINVAL; |
876 | } | ||
806 | 877 | ||
807 | NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | 878 | NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); |
808 | return 0; | 879 | return 0; |
809 | } | 880 | } |
810 | 881 | ||
811 | static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" }; | ||
812 | |||
813 | void netxen_request_firmware(struct netxen_adapter *adapter) | 882 | void netxen_request_firmware(struct netxen_adapter *adapter) |
814 | { | 883 | { |
815 | u32 capability, flashed_ver; | 884 | u32 capability, flashed_ver; |
816 | int fw_type; | 885 | u8 fw_type; |
817 | struct pci_dev *pdev = adapter->pdev; | 886 | struct pci_dev *pdev = adapter->pdev; |
818 | int rc = 0; | 887 | int rc = 0; |
819 | 888 | ||
@@ -830,6 +899,8 @@ request_mn: | |||
830 | 899 | ||
831 | netxen_rom_fast_read(adapter, | 900 | netxen_rom_fast_read(adapter, |
832 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); | 901 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); |
902 | flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); | ||
903 | |||
833 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { | 904 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { |
834 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); | 905 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); |
835 | if (capability & NX_PEG_TUNE_MN_PRESENT) { | 906 | if (capability & NX_PEG_TUNE_MN_PRESENT) { |
@@ -838,6 +909,10 @@ request_mn: | |||
838 | } | 909 | } |
839 | } | 910 | } |
840 | 911 | ||
912 | fw_type = NX_FLASH_ROMIMAGE; | ||
913 | adapter->fw = NULL; | ||
914 | goto done; | ||
915 | |||
841 | request_fw: | 916 | request_fw: |
842 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); | 917 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); |
843 | if (rc != 0) { | 918 | if (rc != 0) { |
@@ -846,6 +921,7 @@ request_fw: | |||
846 | goto request_mn; | 921 | goto request_mn; |
847 | } | 922 | } |
848 | 923 | ||
924 | fw_type = NX_FLASH_ROMIMAGE; | ||
849 | adapter->fw = NULL; | 925 | adapter->fw = NULL; |
850 | goto done; | 926 | goto done; |
851 | } | 927 | } |
@@ -859,16 +935,13 @@ request_fw: | |||
859 | goto request_mn; | 935 | goto request_mn; |
860 | } | 936 | } |
861 | 937 | ||
938 | fw_type = NX_FLASH_ROMIMAGE; | ||
862 | adapter->fw = NULL; | 939 | adapter->fw = NULL; |
863 | goto done; | 940 | goto done; |
864 | } | 941 | } |
865 | 942 | ||
866 | done: | 943 | done: |
867 | if (adapter->fw) | 944 | adapter->fw_type = fw_type; |
868 | dev_info(&pdev->dev, "loading firmware from file %s\n", | ||
869 | fw_name[fw_type]); | ||
870 | else | ||
871 | dev_info(&pdev->dev, "loading firmware from flash\n"); | ||
872 | } | 945 | } |
873 | 946 | ||
874 | 947 | ||
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2919a2d12bf4..27539ddf94c4 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -718,6 +718,10 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw) | |||
718 | if (request_fw) | 718 | if (request_fw) |
719 | netxen_request_firmware(adapter); | 719 | netxen_request_firmware(adapter); |
720 | 720 | ||
721 | err = netxen_need_fw_reset(adapter); | ||
722 | if (err <= 0) | ||
723 | return err; | ||
724 | |||
721 | if (first_boot != 0x55555555) { | 725 | if (first_boot != 0x55555555) { |
722 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); | 726 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); |
723 | netxen_pinit_from_rom(adapter, 0); | 727 | netxen_pinit_from_rom(adapter, 0); |
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 8c1f6988f398..89f7b2ad5231 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c | |||
@@ -105,7 +105,7 @@ IVc. Errata | |||
105 | 105 | ||
106 | static char version[] __devinitdata = | 106 | static char version[] __devinitdata = |
107 | KERN_INFO NETDRV_DRIVER_LOAD_MSG "\n" | 107 | KERN_INFO NETDRV_DRIVER_LOAD_MSG "\n" |
108 | KERN_INFO " Support available from http://foo.com/bar/baz.html\n"; | 108 | " Support available from http://foo.com/bar/baz.html\n"; |
109 | 109 | ||
110 | /* define to 1 to enable PIO instead of MMIO */ | 110 | /* define to 1 to enable PIO instead of MMIO */ |
111 | #undef USE_IO_OPS | 111 | #undef USE_IO_OPS |
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index f51944b28cfa..06618af1a468 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c | |||
@@ -298,14 +298,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) | |||
298 | 298 | ||
299 | strcpy(info->node.dev_name, dev->name); | 299 | strcpy(info->node.dev_name, dev->name); |
300 | 300 | ||
301 | printk(KERN_INFO "%s: port %#3lx, irq %d,", | 301 | printk(KERN_INFO |
302 | dev->name, dev->base_addr, dev->irq); | 302 | "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", |
303 | printk (" mmio %#5lx,", (u_long)ti->mmio); | 303 | dev->name, dev->base_addr, dev->irq, |
304 | printk (" sram %#5lx,", (u_long)ti->sram_base << 12); | 304 | (u_long)ti->mmio, (u_long)(ti->sram_base << 12), |
305 | printk ("\n" KERN_INFO " hwaddr="); | 305 | dev->dev_addr); |
306 | for (i = 0; i < TR_ALEN; i++) | ||
307 | printk("%02X", dev->dev_addr[i]); | ||
308 | printk("\n"); | ||
309 | return 0; | 306 | return 0; |
310 | 307 | ||
311 | cs_failed: | 308 | cs_failed: |
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 02ef63ed1f99..36de91baf238 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c | |||
@@ -1425,15 +1425,12 @@ static void BuildLAF(int *ladrf, int *adr) | |||
1425 | ladrf[byte] |= (1 << (hashcode & 7)); | 1425 | ladrf[byte] |= (1 << (hashcode & 7)); |
1426 | 1426 | ||
1427 | #ifdef PCMCIA_DEBUG | 1427 | #ifdef PCMCIA_DEBUG |
1428 | if (pc_debug > 2) { | 1428 | if (pc_debug > 2) |
1429 | printk(KERN_DEBUG " adr ="); | 1429 | printk(KERN_DEBUG " adr =%pM\n", adr); |
1430 | for (i = 0; i < 6; i++) | 1430 | printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode); |
1431 | printk(" %02X", adr[i]); | 1431 | for (i = 0; i < 8; i++) |
1432 | printk("\n" KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63]" | 1432 | printk(KERN_CONT " %02X", ladrf[i]); |
1433 | " =", hashcode); | 1433 | printk(KERN_CONT "\n"); |
1434 | for (i = 0; i < 8; i++) | ||
1435 | printk(" %02X", ladrf[i]); | ||
1436 | printk("\n"); | ||
1437 | } | 1434 | } |
1438 | #endif | 1435 | #endif |
1439 | } /* BuildLAF */ | 1436 | } /* BuildLAF */ |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 652a36888361..9ef1c1bfa83d 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1727,6 +1727,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1727 | PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50), | 1727 | PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50), |
1728 | PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110), | 1728 | PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110), |
1729 | PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941), | 1729 | PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941), |
1730 | PCMCIA_DEVICE_PROD_ID12("RIOS Systems Co.", "PC CARD3 ETHERNET", 0x7dd33481, 0x10b41826), | ||
1730 | PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df), | 1731 | PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df), |
1731 | PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0), | 1732 | PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0), |
1732 | PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd), | 1733 | PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd), |
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 1c35e1d637a0..28368157dac4 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -485,7 +485,7 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev, | |||
485 | &new_ring_dma_addr); | 485 | &new_ring_dma_addr); |
486 | if (new_tx_ring == NULL) { | 486 | if (new_tx_ring == NULL) { |
487 | if (netif_msg_drv(lp)) | 487 | if (netif_msg_drv(lp)) |
488 | printk("\n" KERN_ERR | 488 | printk(KERN_ERR |
489 | "%s: Consistent memory allocation failed.\n", | 489 | "%s: Consistent memory allocation failed.\n", |
490 | dev->name); | 490 | dev->name); |
491 | return; | 491 | return; |
@@ -496,7 +496,7 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev, | |||
496 | GFP_ATOMIC); | 496 | GFP_ATOMIC); |
497 | if (!new_dma_addr_list) { | 497 | if (!new_dma_addr_list) { |
498 | if (netif_msg_drv(lp)) | 498 | if (netif_msg_drv(lp)) |
499 | printk("\n" KERN_ERR | 499 | printk(KERN_ERR |
500 | "%s: Memory allocation failed.\n", dev->name); | 500 | "%s: Memory allocation failed.\n", dev->name); |
501 | goto free_new_tx_ring; | 501 | goto free_new_tx_ring; |
502 | } | 502 | } |
@@ -505,7 +505,7 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev, | |||
505 | GFP_ATOMIC); | 505 | GFP_ATOMIC); |
506 | if (!new_skb_list) { | 506 | if (!new_skb_list) { |
507 | if (netif_msg_drv(lp)) | 507 | if (netif_msg_drv(lp)) |
508 | printk("\n" KERN_ERR | 508 | printk(KERN_ERR |
509 | "%s: Memory allocation failed.\n", dev->name); | 509 | "%s: Memory allocation failed.\n", dev->name); |
510 | goto free_new_lists; | 510 | goto free_new_lists; |
511 | } | 511 | } |
@@ -563,7 +563,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, | |||
563 | &new_ring_dma_addr); | 563 | &new_ring_dma_addr); |
564 | if (new_rx_ring == NULL) { | 564 | if (new_rx_ring == NULL) { |
565 | if (netif_msg_drv(lp)) | 565 | if (netif_msg_drv(lp)) |
566 | printk("\n" KERN_ERR | 566 | printk(KERN_ERR |
567 | "%s: Consistent memory allocation failed.\n", | 567 | "%s: Consistent memory allocation failed.\n", |
568 | dev->name); | 568 | dev->name); |
569 | return; | 569 | return; |
@@ -574,7 +574,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, | |||
574 | GFP_ATOMIC); | 574 | GFP_ATOMIC); |
575 | if (!new_dma_addr_list) { | 575 | if (!new_dma_addr_list) { |
576 | if (netif_msg_drv(lp)) | 576 | if (netif_msg_drv(lp)) |
577 | printk("\n" KERN_ERR | 577 | printk(KERN_ERR |
578 | "%s: Memory allocation failed.\n", dev->name); | 578 | "%s: Memory allocation failed.\n", dev->name); |
579 | goto free_new_rx_ring; | 579 | goto free_new_rx_ring; |
580 | } | 580 | } |
@@ -583,7 +583,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, | |||
583 | GFP_ATOMIC); | 583 | GFP_ATOMIC); |
584 | if (!new_skb_list) { | 584 | if (!new_skb_list) { |
585 | if (netif_msg_drv(lp)) | 585 | if (netif_msg_drv(lp)) |
586 | printk("\n" KERN_ERR | 586 | printk(KERN_ERR |
587 | "%s: Memory allocation failed.\n", dev->name); | 587 | "%s: Memory allocation failed.\n", dev->name); |
588 | goto free_new_lists; | 588 | goto free_new_lists; |
589 | } | 589 | } |
@@ -1766,38 +1766,38 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1766 | /* Version 0x2623 and 0x2624 */ | 1766 | /* Version 0x2623 and 0x2624 */ |
1767 | if (((chip_version + 1) & 0xfffe) == 0x2624) { | 1767 | if (((chip_version + 1) & 0xfffe) == 0x2624) { |
1768 | i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ | 1768 | i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ |
1769 | printk("\n" KERN_INFO " tx_start_pt(0x%04x):", i); | 1769 | printk(KERN_INFO " tx_start_pt(0x%04x):", i); |
1770 | switch (i >> 10) { | 1770 | switch (i >> 10) { |
1771 | case 0: | 1771 | case 0: |
1772 | printk(" 20 bytes,"); | 1772 | printk(KERN_CONT " 20 bytes,"); |
1773 | break; | 1773 | break; |
1774 | case 1: | 1774 | case 1: |
1775 | printk(" 64 bytes,"); | 1775 | printk(KERN_CONT " 64 bytes,"); |
1776 | break; | 1776 | break; |
1777 | case 2: | 1777 | case 2: |
1778 | printk(" 128 bytes,"); | 1778 | printk(KERN_CONT " 128 bytes,"); |
1779 | break; | 1779 | break; |
1780 | case 3: | 1780 | case 3: |
1781 | printk("~220 bytes,"); | 1781 | printk(KERN_CONT "~220 bytes,"); |
1782 | break; | 1782 | break; |
1783 | } | 1783 | } |
1784 | i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ | 1784 | i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ |
1785 | printk(" BCR18(%x):", i & 0xffff); | 1785 | printk(KERN_CONT " BCR18(%x):", i & 0xffff); |
1786 | if (i & (1 << 5)) | 1786 | if (i & (1 << 5)) |
1787 | printk("BurstWrEn "); | 1787 | printk(KERN_CONT "BurstWrEn "); |
1788 | if (i & (1 << 6)) | 1788 | if (i & (1 << 6)) |
1789 | printk("BurstRdEn "); | 1789 | printk(KERN_CONT "BurstRdEn "); |
1790 | if (i & (1 << 7)) | 1790 | if (i & (1 << 7)) |
1791 | printk("DWordIO "); | 1791 | printk(KERN_CONT "DWordIO "); |
1792 | if (i & (1 << 11)) | 1792 | if (i & (1 << 11)) |
1793 | printk("NoUFlow "); | 1793 | printk(KERN_CONT "NoUFlow "); |
1794 | i = a->read_bcr(ioaddr, 25); | 1794 | i = a->read_bcr(ioaddr, 25); |
1795 | printk("\n" KERN_INFO " SRAMSIZE=0x%04x,", i << 8); | 1795 | printk(KERN_INFO " SRAMSIZE=0x%04x,", i << 8); |
1796 | i = a->read_bcr(ioaddr, 26); | 1796 | i = a->read_bcr(ioaddr, 26); |
1797 | printk(" SRAM_BND=0x%04x,", i << 8); | 1797 | printk(KERN_CONT " SRAM_BND=0x%04x,", i << 8); |
1798 | i = a->read_bcr(ioaddr, 27); | 1798 | i = a->read_bcr(ioaddr, 27); |
1799 | if (i & (1 << 14)) | 1799 | if (i & (1 << 14)) |
1800 | printk("LowLatRx"); | 1800 | printk(KERN_CONT "LowLatRx"); |
1801 | } | 1801 | } |
1802 | } | 1802 | } |
1803 | 1803 | ||
@@ -1996,7 +1996,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name) | |||
1996 | &lp->tx_ring_dma_addr); | 1996 | &lp->tx_ring_dma_addr); |
1997 | if (lp->tx_ring == NULL) { | 1997 | if (lp->tx_ring == NULL) { |
1998 | if (netif_msg_drv(lp)) | 1998 | if (netif_msg_drv(lp)) |
1999 | printk("\n" KERN_ERR PFX | 1999 | printk(KERN_ERR PFX |
2000 | "%s: Consistent memory allocation failed.\n", | 2000 | "%s: Consistent memory allocation failed.\n", |
2001 | name); | 2001 | name); |
2002 | return -ENOMEM; | 2002 | return -ENOMEM; |
@@ -2008,7 +2008,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name) | |||
2008 | &lp->rx_ring_dma_addr); | 2008 | &lp->rx_ring_dma_addr); |
2009 | if (lp->rx_ring == NULL) { | 2009 | if (lp->rx_ring == NULL) { |
2010 | if (netif_msg_drv(lp)) | 2010 | if (netif_msg_drv(lp)) |
2011 | printk("\n" KERN_ERR PFX | 2011 | printk(KERN_ERR PFX |
2012 | "%s: Consistent memory allocation failed.\n", | 2012 | "%s: Consistent memory allocation failed.\n", |
2013 | name); | 2013 | name); |
2014 | return -ENOMEM; | 2014 | return -ENOMEM; |
@@ -2018,7 +2018,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name) | |||
2018 | GFP_ATOMIC); | 2018 | GFP_ATOMIC); |
2019 | if (!lp->tx_dma_addr) { | 2019 | if (!lp->tx_dma_addr) { |
2020 | if (netif_msg_drv(lp)) | 2020 | if (netif_msg_drv(lp)) |
2021 | printk("\n" KERN_ERR PFX | 2021 | printk(KERN_ERR PFX |
2022 | "%s: Memory allocation failed.\n", name); | 2022 | "%s: Memory allocation failed.\n", name); |
2023 | return -ENOMEM; | 2023 | return -ENOMEM; |
2024 | } | 2024 | } |
@@ -2027,7 +2027,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name) | |||
2027 | GFP_ATOMIC); | 2027 | GFP_ATOMIC); |
2028 | if (!lp->rx_dma_addr) { | 2028 | if (!lp->rx_dma_addr) { |
2029 | if (netif_msg_drv(lp)) | 2029 | if (netif_msg_drv(lp)) |
2030 | printk("\n" KERN_ERR PFX | 2030 | printk(KERN_ERR PFX |
2031 | "%s: Memory allocation failed.\n", name); | 2031 | "%s: Memory allocation failed.\n", name); |
2032 | return -ENOMEM; | 2032 | return -ENOMEM; |
2033 | } | 2033 | } |
@@ -2036,7 +2036,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name) | |||
2036 | GFP_ATOMIC); | 2036 | GFP_ATOMIC); |
2037 | if (!lp->tx_skbuff) { | 2037 | if (!lp->tx_skbuff) { |
2038 | if (netif_msg_drv(lp)) | 2038 | if (netif_msg_drv(lp)) |
2039 | printk("\n" KERN_ERR PFX | 2039 | printk(KERN_ERR PFX |
2040 | "%s: Memory allocation failed.\n", name); | 2040 | "%s: Memory allocation failed.\n", name); |
2041 | return -ENOMEM; | 2041 | return -ENOMEM; |
2042 | } | 2042 | } |
@@ -2045,7 +2045,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name) | |||
2045 | GFP_ATOMIC); | 2045 | GFP_ATOMIC); |
2046 | if (!lp->rx_skbuff) { | 2046 | if (!lp->rx_skbuff) { |
2047 | if (netif_msg_drv(lp)) | 2047 | if (netif_msg_drv(lp)) |
2048 | printk("\n" KERN_ERR PFX | 2048 | printk(KERN_ERR PFX |
2049 | "%s: Memory allocation failed.\n", name); | 2049 | "%s: Memory allocation failed.\n", name); |
2050 | return -ENOMEM; | 2050 | return -ENOMEM; |
2051 | } | 2051 | } |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 61755cbd978e..eda94fcd4065 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -928,13 +928,32 @@ static void phy_state_machine(struct work_struct *work) | |||
928 | * Otherwise, it's 0, and we're | 928 | * Otherwise, it's 0, and we're |
929 | * still waiting for AN */ | 929 | * still waiting for AN */ |
930 | if (err > 0) { | 930 | if (err > 0) { |
931 | phydev->state = PHY_RUNNING; | 931 | err = phy_read_status(phydev); |
932 | if (err) | ||
933 | break; | ||
934 | |||
935 | if (phydev->link) { | ||
936 | phydev->state = PHY_RUNNING; | ||
937 | netif_carrier_on(phydev->attached_dev); | ||
938 | } else | ||
939 | phydev->state = PHY_NOLINK; | ||
940 | phydev->adjust_link(phydev->attached_dev); | ||
932 | } else { | 941 | } else { |
933 | phydev->state = PHY_AN; | 942 | phydev->state = PHY_AN; |
934 | phydev->link_timeout = PHY_AN_TIMEOUT; | 943 | phydev->link_timeout = PHY_AN_TIMEOUT; |
935 | } | 944 | } |
936 | } else | 945 | } else { |
937 | phydev->state = PHY_RUNNING; | 946 | err = phy_read_status(phydev); |
947 | if (err) | ||
948 | break; | ||
949 | |||
950 | if (phydev->link) { | ||
951 | phydev->state = PHY_RUNNING; | ||
952 | netif_carrier_on(phydev->attached_dev); | ||
953 | } else | ||
954 | phydev->state = PHY_NOLINK; | ||
955 | phydev->adjust_link(phydev->attached_dev); | ||
956 | } | ||
938 | break; | 957 | break; |
939 | } | 958 | } |
940 | 959 | ||
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 156e02e8905d..6ed5317ab1c0 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -1607,6 +1607,8 @@ int ql_mb_get_fw_state(struct ql_adapter *qdev); | |||
1607 | int ql_cam_route_initialize(struct ql_adapter *qdev); | 1607 | int ql_cam_route_initialize(struct ql_adapter *qdev); |
1608 | int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); | 1608 | int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); |
1609 | int ql_mb_about_fw(struct ql_adapter *qdev); | 1609 | int ql_mb_about_fw(struct ql_adapter *qdev); |
1610 | void ql_link_on(struct ql_adapter *qdev); | ||
1611 | void ql_link_off(struct ql_adapter *qdev); | ||
1610 | 1612 | ||
1611 | #if 1 | 1613 | #if 1 |
1612 | #define QL_ALL_DUMP | 1614 | #define QL_ALL_DUMP |
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 37c99fe79770..eb6a9ee640ed 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c | |||
@@ -59,7 +59,7 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev) | |||
59 | cqicb->pkt_delay = | 59 | cqicb->pkt_delay = |
60 | cpu_to_le16(qdev->tx_max_coalesced_frames); | 60 | cpu_to_le16(qdev->tx_max_coalesced_frames); |
61 | cqicb->flags = FLAGS_LI; | 61 | cqicb->flags = FLAGS_LI; |
62 | status = ql_write_cfg(qdev, cqicb, sizeof(cqicb), | 62 | status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb), |
63 | CFG_LCQ, rx_ring->cq_id); | 63 | CFG_LCQ, rx_ring->cq_id); |
64 | if (status) { | 64 | if (status) { |
65 | QPRINTK(qdev, IFUP, ERR, | 65 | QPRINTK(qdev, IFUP, ERR, |
@@ -82,7 +82,7 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev) | |||
82 | cqicb->pkt_delay = | 82 | cqicb->pkt_delay = |
83 | cpu_to_le16(qdev->rx_max_coalesced_frames); | 83 | cpu_to_le16(qdev->rx_max_coalesced_frames); |
84 | cqicb->flags = FLAGS_LI; | 84 | cqicb->flags = FLAGS_LI; |
85 | status = ql_write_cfg(qdev, cqicb, sizeof(cqicb), | 85 | status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb), |
86 | CFG_LCQ, rx_ring->cq_id); | 86 | CFG_LCQ, rx_ring->cq_id); |
87 | if (status) { | 87 | if (status) { |
88 | QPRINTK(qdev, IFUP, ERR, | 88 | QPRINTK(qdev, IFUP, ERR, |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 90d1f76c0e8b..5768af17f168 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -214,6 +214,10 @@ int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit, | |||
214 | return -ENOMEM; | 214 | return -ENOMEM; |
215 | } | 215 | } |
216 | 216 | ||
217 | status = ql_sem_spinlock(qdev, SEM_ICB_MASK); | ||
218 | if (status) | ||
219 | return status; | ||
220 | |||
217 | status = ql_wait_cfg(qdev, bit); | 221 | status = ql_wait_cfg(qdev, bit); |
218 | if (status) { | 222 | if (status) { |
219 | QPRINTK(qdev, IFUP, ERR, | 223 | QPRINTK(qdev, IFUP, ERR, |
@@ -221,12 +225,8 @@ int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit, | |||
221 | goto exit; | 225 | goto exit; |
222 | } | 226 | } |
223 | 227 | ||
224 | status = ql_sem_spinlock(qdev, SEM_ICB_MASK); | ||
225 | if (status) | ||
226 | goto exit; | ||
227 | ql_write32(qdev, ICB_L, (u32) map); | 228 | ql_write32(qdev, ICB_L, (u32) map); |
228 | ql_write32(qdev, ICB_H, (u32) (map >> 32)); | 229 | ql_write32(qdev, ICB_H, (u32) (map >> 32)); |
229 | ql_sem_unlock(qdev, SEM_ICB_MASK); /* does flush too */ | ||
230 | 230 | ||
231 | mask = CFG_Q_MASK | (bit << 16); | 231 | mask = CFG_Q_MASK | (bit << 16); |
232 | value = bit | (q_id << CFG_Q_SHIFT); | 232 | value = bit | (q_id << CFG_Q_SHIFT); |
@@ -237,6 +237,7 @@ int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit, | |||
237 | */ | 237 | */ |
238 | status = ql_wait_cfg(qdev, bit); | 238 | status = ql_wait_cfg(qdev, bit); |
239 | exit: | 239 | exit: |
240 | ql_sem_unlock(qdev, SEM_ICB_MASK); /* does flush too */ | ||
240 | pci_unmap_single(qdev->pdev, map, size, direction); | 241 | pci_unmap_single(qdev->pdev, map, size, direction); |
241 | return status; | 242 | return status; |
242 | } | 243 | } |
@@ -412,6 +413,57 @@ exit: | |||
412 | return status; | 413 | return status; |
413 | } | 414 | } |
414 | 415 | ||
416 | /* Set or clear MAC address in hardware. We sometimes | ||
417 | * have to clear it to prevent wrong frame routing | ||
418 | * especially in a bonding environment. | ||
419 | */ | ||
420 | static int ql_set_mac_addr(struct ql_adapter *qdev, int set) | ||
421 | { | ||
422 | int status; | ||
423 | char zero_mac_addr[ETH_ALEN]; | ||
424 | char *addr; | ||
425 | |||
426 | if (set) { | ||
427 | addr = &qdev->ndev->dev_addr[0]; | ||
428 | QPRINTK(qdev, IFUP, DEBUG, | ||
429 | "Set Mac addr %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
430 | addr[0], addr[1], addr[2], addr[3], | ||
431 | addr[4], addr[5]); | ||
432 | } else { | ||
433 | memset(zero_mac_addr, 0, ETH_ALEN); | ||
434 | addr = &zero_mac_addr[0]; | ||
435 | QPRINTK(qdev, IFUP, DEBUG, | ||
436 | "Clearing MAC address on %s\n", | ||
437 | qdev->ndev->name); | ||
438 | } | ||
439 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | ||
440 | if (status) | ||
441 | return status; | ||
442 | status = ql_set_mac_addr_reg(qdev, (u8 *) addr, | ||
443 | MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); | ||
444 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | ||
445 | if (status) | ||
446 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac " | ||
447 | "address.\n"); | ||
448 | return status; | ||
449 | } | ||
450 | |||
451 | void ql_link_on(struct ql_adapter *qdev) | ||
452 | { | ||
453 | QPRINTK(qdev, LINK, ERR, "%s: Link is up.\n", | ||
454 | qdev->ndev->name); | ||
455 | netif_carrier_on(qdev->ndev); | ||
456 | ql_set_mac_addr(qdev, 1); | ||
457 | } | ||
458 | |||
459 | void ql_link_off(struct ql_adapter *qdev) | ||
460 | { | ||
461 | QPRINTK(qdev, LINK, ERR, "%s: Link is down.\n", | ||
462 | qdev->ndev->name); | ||
463 | netif_carrier_off(qdev->ndev); | ||
464 | ql_set_mac_addr(qdev, 0); | ||
465 | } | ||
466 | |||
415 | /* Get a specific frame routing value from the CAM. | 467 | /* Get a specific frame routing value from the CAM. |
416 | * Used for debug and reg dump. | 468 | * Used for debug and reg dump. |
417 | */ | 469 | */ |
@@ -1628,7 +1680,7 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev, | |||
1628 | tx_ring = &qdev->tx_ring[mac_rsp->txq_idx]; | 1680 | tx_ring = &qdev->tx_ring[mac_rsp->txq_idx]; |
1629 | tx_ring_desc = &tx_ring->q[mac_rsp->tid]; | 1681 | tx_ring_desc = &tx_ring->q[mac_rsp->tid]; |
1630 | ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt); | 1682 | ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt); |
1631 | qdev->stats.tx_bytes += tx_ring_desc->map_cnt; | 1683 | qdev->stats.tx_bytes += (tx_ring_desc->skb)->len; |
1632 | qdev->stats.tx_packets++; | 1684 | qdev->stats.tx_packets++; |
1633 | dev_kfree_skb(tx_ring_desc->skb); | 1685 | dev_kfree_skb(tx_ring_desc->skb); |
1634 | tx_ring_desc->skb = NULL; | 1686 | tx_ring_desc->skb = NULL; |
@@ -1660,13 +1712,13 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev, | |||
1660 | /* Fire up a handler to reset the MPI processor. */ | 1712 | /* Fire up a handler to reset the MPI processor. */ |
1661 | void ql_queue_fw_error(struct ql_adapter *qdev) | 1713 | void ql_queue_fw_error(struct ql_adapter *qdev) |
1662 | { | 1714 | { |
1663 | netif_carrier_off(qdev->ndev); | 1715 | ql_link_off(qdev); |
1664 | queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0); | 1716 | queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0); |
1665 | } | 1717 | } |
1666 | 1718 | ||
1667 | void ql_queue_asic_error(struct ql_adapter *qdev) | 1719 | void ql_queue_asic_error(struct ql_adapter *qdev) |
1668 | { | 1720 | { |
1669 | netif_carrier_off(qdev->ndev); | 1721 | ql_link_off(qdev); |
1670 | ql_disable_interrupts(qdev); | 1722 | ql_disable_interrupts(qdev); |
1671 | /* Clear adapter up bit to signal the recovery | 1723 | /* Clear adapter up bit to signal the recovery |
1672 | * process that it shouldn't kill the reset worker | 1724 | * process that it shouldn't kill the reset worker |
@@ -2104,7 +2156,7 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev) | |||
2104 | } | 2156 | } |
2105 | tx_ring_desc = &tx_ring->q[tx_ring->prod_idx]; | 2157 | tx_ring_desc = &tx_ring->q[tx_ring->prod_idx]; |
2106 | mac_iocb_ptr = tx_ring_desc->queue_entry; | 2158 | mac_iocb_ptr = tx_ring_desc->queue_entry; |
2107 | memset((void *)mac_iocb_ptr, 0, sizeof(mac_iocb_ptr)); | 2159 | memset((void *)mac_iocb_ptr, 0, sizeof(*mac_iocb_ptr)); |
2108 | 2160 | ||
2109 | mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB; | 2161 | mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB; |
2110 | mac_iocb_ptr->tid = tx_ring_desc->index; | 2162 | mac_iocb_ptr->tid = tx_ring_desc->index; |
@@ -2743,7 +2795,7 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring) | |||
2743 | 2795 | ||
2744 | ql_init_tx_ring(qdev, tx_ring); | 2796 | ql_init_tx_ring(qdev, tx_ring); |
2745 | 2797 | ||
2746 | err = ql_write_cfg(qdev, wqicb, sizeof(wqicb), CFG_LRQ, | 2798 | err = ql_write_cfg(qdev, wqicb, sizeof(*wqicb), CFG_LRQ, |
2747 | (u16) tx_ring->wq_id); | 2799 | (u16) tx_ring->wq_id); |
2748 | if (err) { | 2800 | if (err) { |
2749 | QPRINTK(qdev, IFUP, ERR, "Failed to load tx_ring.\n"); | 2801 | QPRINTK(qdev, IFUP, ERR, "Failed to load tx_ring.\n"); |
@@ -3008,7 +3060,7 @@ static int ql_start_rss(struct ql_adapter *qdev) | |||
3008 | int i; | 3060 | int i; |
3009 | u8 *hash_id = (u8 *) ricb->hash_cq_id; | 3061 | u8 *hash_id = (u8 *) ricb->hash_cq_id; |
3010 | 3062 | ||
3011 | memset((void *)ricb, 0, sizeof(ricb)); | 3063 | memset((void *)ricb, 0, sizeof(*ricb)); |
3012 | 3064 | ||
3013 | ricb->base_cq = qdev->rss_ring_first_cq_id | RSS_L4K; | 3065 | ricb->base_cq = qdev->rss_ring_first_cq_id | RSS_L4K; |
3014 | ricb->flags = | 3066 | ricb->flags = |
@@ -3030,7 +3082,7 @@ static int ql_start_rss(struct ql_adapter *qdev) | |||
3030 | 3082 | ||
3031 | QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); | 3083 | QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); |
3032 | 3084 | ||
3033 | status = ql_write_cfg(qdev, ricb, sizeof(ricb), CFG_LR, 0); | 3085 | status = ql_write_cfg(qdev, ricb, sizeof(*ricb), CFG_LR, 0); |
3034 | if (status) { | 3086 | if (status) { |
3035 | QPRINTK(qdev, IFUP, ERR, "Failed to load RICB.\n"); | 3087 | QPRINTK(qdev, IFUP, ERR, "Failed to load RICB.\n"); |
3036 | return status; | 3088 | return status; |
@@ -3039,25 +3091,40 @@ static int ql_start_rss(struct ql_adapter *qdev) | |||
3039 | return status; | 3091 | return status; |
3040 | } | 3092 | } |
3041 | 3093 | ||
3042 | /* Initialize the frame-to-queue routing. */ | 3094 | static int ql_clear_routing_entries(struct ql_adapter *qdev) |
3043 | static int ql_route_initialize(struct ql_adapter *qdev) | ||
3044 | { | 3095 | { |
3045 | int status = 0; | 3096 | int i, status = 0; |
3046 | int i; | ||
3047 | 3097 | ||
3048 | status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); | 3098 | status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); |
3049 | if (status) | 3099 | if (status) |
3050 | return status; | 3100 | return status; |
3051 | |||
3052 | /* Clear all the entries in the routing table. */ | 3101 | /* Clear all the entries in the routing table. */ |
3053 | for (i = 0; i < 16; i++) { | 3102 | for (i = 0; i < 16; i++) { |
3054 | status = ql_set_routing_reg(qdev, i, 0, 0); | 3103 | status = ql_set_routing_reg(qdev, i, 0, 0); |
3055 | if (status) { | 3104 | if (status) { |
3056 | QPRINTK(qdev, IFUP, ERR, | 3105 | QPRINTK(qdev, IFUP, ERR, |
3057 | "Failed to init routing register for CAM packets.\n"); | 3106 | "Failed to init routing register for CAM " |
3058 | goto exit; | 3107 | "packets.\n"); |
3108 | break; | ||
3059 | } | 3109 | } |
3060 | } | 3110 | } |
3111 | ql_sem_unlock(qdev, SEM_RT_IDX_MASK); | ||
3112 | return status; | ||
3113 | } | ||
3114 | |||
3115 | /* Initialize the frame-to-queue routing. */ | ||
3116 | static int ql_route_initialize(struct ql_adapter *qdev) | ||
3117 | { | ||
3118 | int status = 0; | ||
3119 | |||
3120 | status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); | ||
3121 | if (status) | ||
3122 | return status; | ||
3123 | |||
3124 | /* Clear all the entries in the routing table. */ | ||
3125 | status = ql_clear_routing_entries(qdev); | ||
3126 | if (status) | ||
3127 | goto exit; | ||
3061 | 3128 | ||
3062 | status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1); | 3129 | status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1); |
3063 | if (status) { | 3130 | if (status) { |
@@ -3096,14 +3163,15 @@ exit: | |||
3096 | 3163 | ||
3097 | int ql_cam_route_initialize(struct ql_adapter *qdev) | 3164 | int ql_cam_route_initialize(struct ql_adapter *qdev) |
3098 | { | 3165 | { |
3099 | int status; | 3166 | int status, set; |
3100 | 3167 | ||
3101 | status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); | 3168 | /* If check if the link is up and use to |
3102 | if (status) | 3169 | * determine if we are setting or clearing |
3103 | return status; | 3170 | * the MAC address in the CAM. |
3104 | status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr, | 3171 | */ |
3105 | MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); | 3172 | set = ql_read32(qdev, STS); |
3106 | ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); | 3173 | set &= qdev->port_link_up; |
3174 | status = ql_set_mac_addr(qdev, set); | ||
3107 | if (status) { | 3175 | if (status) { |
3108 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n"); | 3176 | QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n"); |
3109 | return status; | 3177 | return status; |
@@ -3210,9 +3278,17 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
3210 | { | 3278 | { |
3211 | u32 value; | 3279 | u32 value; |
3212 | int status = 0; | 3280 | int status = 0; |
3213 | unsigned long end_jiffies = jiffies + | 3281 | unsigned long end_jiffies; |
3214 | max((unsigned long)1, usecs_to_jiffies(30)); | ||
3215 | 3282 | ||
3283 | /* Clear all the entries in the routing table. */ | ||
3284 | status = ql_clear_routing_entries(qdev); | ||
3285 | if (status) { | ||
3286 | QPRINTK(qdev, IFUP, ERR, "Failed to clear routing bits.\n"); | ||
3287 | return status; | ||
3288 | } | ||
3289 | |||
3290 | end_jiffies = jiffies + | ||
3291 | max((unsigned long)1, usecs_to_jiffies(30)); | ||
3216 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); | 3292 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); |
3217 | 3293 | ||
3218 | do { | 3294 | do { |
@@ -3252,7 +3328,7 @@ static int ql_adapter_down(struct ql_adapter *qdev) | |||
3252 | int i, status = 0; | 3328 | int i, status = 0; |
3253 | struct rx_ring *rx_ring; | 3329 | struct rx_ring *rx_ring; |
3254 | 3330 | ||
3255 | netif_carrier_off(qdev->ndev); | 3331 | ql_link_off(qdev); |
3256 | 3332 | ||
3257 | /* Don't kill the reset worker thread if we | 3333 | /* Don't kill the reset worker thread if we |
3258 | * are in the process of recovery. | 3334 | * are in the process of recovery. |
@@ -3319,8 +3395,12 @@ static int ql_adapter_up(struct ql_adapter *qdev) | |||
3319 | } | 3395 | } |
3320 | set_bit(QL_ADAPTER_UP, &qdev->flags); | 3396 | set_bit(QL_ADAPTER_UP, &qdev->flags); |
3321 | ql_alloc_rx_buffers(qdev); | 3397 | ql_alloc_rx_buffers(qdev); |
3322 | if ((ql_read32(qdev, STS) & qdev->port_init)) | 3398 | /* If the port is initialized and the |
3323 | netif_carrier_on(qdev->ndev); | 3399 | * link is up the turn on the carrier. |
3400 | */ | ||
3401 | if ((ql_read32(qdev, STS) & qdev->port_init) && | ||
3402 | (ql_read32(qdev, STS) & qdev->port_link_up)) | ||
3403 | ql_link_on(qdev); | ||
3324 | ql_enable_interrupts(qdev); | 3404 | ql_enable_interrupts(qdev); |
3325 | ql_enable_all_completion_interrupts(qdev); | 3405 | ql_enable_all_completion_interrupts(qdev); |
3326 | netif_tx_start_all_queues(qdev->ndev); | 3406 | netif_tx_start_all_queues(qdev->ndev); |
@@ -3346,11 +3426,6 @@ static int ql_get_adapter_resources(struct ql_adapter *qdev) | |||
3346 | return -ENOMEM; | 3426 | return -ENOMEM; |
3347 | } | 3427 | } |
3348 | status = ql_request_irq(qdev); | 3428 | status = ql_request_irq(qdev); |
3349 | if (status) | ||
3350 | goto err_irq; | ||
3351 | return status; | ||
3352 | err_irq: | ||
3353 | ql_free_mem_resources(qdev); | ||
3354 | return status; | 3429 | return status; |
3355 | } | 3430 | } |
3356 | 3431 | ||
@@ -3414,7 +3489,7 @@ static int ql_configure_rings(struct ql_adapter *qdev) | |||
3414 | 3489 | ||
3415 | for (i = 0; i < qdev->tx_ring_count; i++) { | 3490 | for (i = 0; i < qdev->tx_ring_count; i++) { |
3416 | tx_ring = &qdev->tx_ring[i]; | 3491 | tx_ring = &qdev->tx_ring[i]; |
3417 | memset((void *)tx_ring, 0, sizeof(tx_ring)); | 3492 | memset((void *)tx_ring, 0, sizeof(*tx_ring)); |
3418 | tx_ring->qdev = qdev; | 3493 | tx_ring->qdev = qdev; |
3419 | tx_ring->wq_id = i; | 3494 | tx_ring->wq_id = i; |
3420 | tx_ring->wq_len = qdev->tx_ring_size; | 3495 | tx_ring->wq_len = qdev->tx_ring_size; |
@@ -3430,7 +3505,7 @@ static int ql_configure_rings(struct ql_adapter *qdev) | |||
3430 | 3505 | ||
3431 | for (i = 0; i < qdev->rx_ring_count; i++) { | 3506 | for (i = 0; i < qdev->rx_ring_count; i++) { |
3432 | rx_ring = &qdev->rx_ring[i]; | 3507 | rx_ring = &qdev->rx_ring[i]; |
3433 | memset((void *)rx_ring, 0, sizeof(rx_ring)); | 3508 | memset((void *)rx_ring, 0, sizeof(*rx_ring)); |
3434 | rx_ring->qdev = qdev; | 3509 | rx_ring->qdev = qdev; |
3435 | rx_ring->cq_id = i; | 3510 | rx_ring->cq_id = i; |
3436 | rx_ring->cpu = i % cpu_cnt; /* CPU to run handler on. */ | 3511 | rx_ring->cpu = i % cpu_cnt; /* CPU to run handler on. */ |
@@ -3789,7 +3864,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, | |||
3789 | int pos, err = 0; | 3864 | int pos, err = 0; |
3790 | u16 val16; | 3865 | u16 val16; |
3791 | 3866 | ||
3792 | memset((void *)qdev, 0, sizeof(qdev)); | 3867 | memset((void *)qdev, 0, sizeof(*qdev)); |
3793 | err = pci_enable_device(pdev); | 3868 | err = pci_enable_device(pdev); |
3794 | if (err) { | 3869 | if (err) { |
3795 | dev_err(&pdev->dev, "PCI device enable failed.\n"); | 3870 | dev_err(&pdev->dev, "PCI device enable failed.\n"); |
@@ -3976,7 +4051,7 @@ static int __devinit qlge_probe(struct pci_dev *pdev, | |||
3976 | pci_disable_device(pdev); | 4051 | pci_disable_device(pdev); |
3977 | return err; | 4052 | return err; |
3978 | } | 4053 | } |
3979 | netif_carrier_off(ndev); | 4054 | ql_link_off(qdev); |
3980 | ql_display_dev_info(ndev); | 4055 | ql_display_dev_info(ndev); |
3981 | cards_found++; | 4056 | cards_found++; |
3982 | return 0; | 4057 | return 0; |
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 71afbf8b9c50..6685bd97da91 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c | |||
@@ -238,7 +238,7 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp) | |||
238 | &qdev->mpi_port_cfg_work, 0); | 238 | &qdev->mpi_port_cfg_work, 0); |
239 | } | 239 | } |
240 | 240 | ||
241 | netif_carrier_on(qdev->ndev); | 241 | ql_link_on(qdev); |
242 | } | 242 | } |
243 | 243 | ||
244 | static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp) | 244 | static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp) |
@@ -251,7 +251,7 @@ static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp) | |||
251 | if (status) | 251 | if (status) |
252 | QPRINTK(qdev, DRV, ERR, "Link down AEN broken!\n"); | 252 | QPRINTK(qdev, DRV, ERR, "Link down AEN broken!\n"); |
253 | 253 | ||
254 | netif_carrier_off(qdev->ndev); | 254 | ql_link_off(qdev); |
255 | } | 255 | } |
256 | 256 | ||
257 | static int ql_sfp_in(struct ql_adapter *qdev, struct mbox_params *mbcp) | 257 | static int ql_sfp_in(struct ql_adapter *qdev, struct mbox_params *mbcp) |
@@ -849,7 +849,7 @@ void ql_mpi_idc_work(struct work_struct *work) | |||
849 | case MB_CMD_PORT_RESET: | 849 | case MB_CMD_PORT_RESET: |
850 | case MB_CMD_SET_PORT_CFG: | 850 | case MB_CMD_SET_PORT_CFG: |
851 | case MB_CMD_STOP_FW: | 851 | case MB_CMD_STOP_FW: |
852 | netif_carrier_off(qdev->ndev); | 852 | ql_link_off(qdev); |
853 | /* Signal the resulting link up AEN | 853 | /* Signal the resulting link up AEN |
854 | * that the frame routing and mac addr | 854 | * that the frame routing and mac addr |
855 | * needs to be set. | 855 | * needs to be set. |
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index ed63d23a6452..961b5397a531 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -49,8 +49,8 @@ | |||
49 | #include <asm/processor.h> | 49 | #include <asm/processor.h> |
50 | 50 | ||
51 | #define DRV_NAME "r6040" | 51 | #define DRV_NAME "r6040" |
52 | #define DRV_VERSION "0.23" | 52 | #define DRV_VERSION "0.24" |
53 | #define DRV_RELDATE "05May2009" | 53 | #define DRV_RELDATE "08Jul2009" |
54 | 54 | ||
55 | /* PHY CHIP Address */ | 55 | /* PHY CHIP Address */ |
56 | #define PHY1_ADDR 1 /* For MAC1 */ | 56 | #define PHY1_ADDR 1 /* For MAC1 */ |
@@ -704,8 +704,11 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id) | |||
704 | /* Read MISR status and clear */ | 704 | /* Read MISR status and clear */ |
705 | status = ioread16(ioaddr + MISR); | 705 | status = ioread16(ioaddr + MISR); |
706 | 706 | ||
707 | if (status == 0x0000 || status == 0xffff) | 707 | if (status == 0x0000 || status == 0xffff) { |
708 | /* Restore RDC MAC interrupt */ | ||
709 | iowrite16(misr, ioaddr + MIER); | ||
708 | return IRQ_NONE; | 710 | return IRQ_NONE; |
711 | } | ||
709 | 712 | ||
710 | /* RX interrupt request */ | 713 | /* RX interrupt request */ |
711 | if (status & RX_INTS) { | 714 | if (status & RX_INTS) { |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 341882f959f3..a2d82ddb3b4d 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -865,8 +865,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
865 | struct sh_eth_private *mdp = netdev_priv(ndev); | 865 | struct sh_eth_private *mdp = netdev_priv(ndev); |
866 | struct sh_eth_cpu_data *cd = mdp->cd; | 866 | struct sh_eth_cpu_data *cd = mdp->cd; |
867 | irqreturn_t ret = IRQ_NONE; | 867 | irqreturn_t ret = IRQ_NONE; |
868 | u32 ioaddr, boguscnt = RX_RING_SIZE; | 868 | u32 ioaddr, intr_status = 0; |
869 | u32 intr_status = 0; | ||
870 | 869 | ||
871 | ioaddr = ndev->base_addr; | 870 | ioaddr = ndev->base_addr; |
872 | spin_lock(&mdp->lock); | 871 | spin_lock(&mdp->lock); |
@@ -901,12 +900,6 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
901 | if (intr_status & cd->eesr_err_check) | 900 | if (intr_status & cd->eesr_err_check) |
902 | sh_eth_error(ndev, intr_status); | 901 | sh_eth_error(ndev, intr_status); |
903 | 902 | ||
904 | if (--boguscnt < 0) { | ||
905 | printk(KERN_WARNING | ||
906 | "%s: Too much work at interrupt, status=0x%4.4x.\n", | ||
907 | ndev->name, intr_status); | ||
908 | } | ||
909 | |||
910 | other_irq: | 903 | other_irq: |
911 | spin_unlock(&mdp->lock); | 904 | spin_unlock(&mdp->lock); |
912 | 905 | ||
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7681d28c53d7..daf961ab68bc 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -2495,7 +2495,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2495 | if (likely(status >> 16 == (status & 0xffff))) { | 2495 | if (likely(status >> 16 == (status & 0xffff))) { |
2496 | skb = sky2->rx_ring[sky2->rx_next].skb; | 2496 | skb = sky2->rx_ring[sky2->rx_next].skb; |
2497 | skb->ip_summed = CHECKSUM_COMPLETE; | 2497 | skb->ip_summed = CHECKSUM_COMPLETE; |
2498 | skb->csum = status & 0xffff; | 2498 | skb->csum = le16_to_cpu(status); |
2499 | } else { | 2499 | } else { |
2500 | printk(KERN_NOTICE PFX "%s: hardware receive " | 2500 | printk(KERN_NOTICE PFX "%s: hardware receive " |
2501 | "checksum problem (status = %#x)\n", | 2501 | "checksum problem (status = %#x)\n", |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index b60639bd181b..66067f9d91c0 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -1938,7 +1938,7 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev) | |||
1938 | if (!res) | 1938 | if (!res) |
1939 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1939 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1940 | 1940 | ||
1941 | release_mem_region(res->start, res->end - res->start); | 1941 | release_mem_region(res->start, resource_size(res)); |
1942 | 1942 | ||
1943 | iounmap(pdata->ioaddr); | 1943 | iounmap(pdata->ioaddr); |
1944 | 1944 | ||
@@ -1976,7 +1976,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) | |||
1976 | retval = -ENODEV; | 1976 | retval = -ENODEV; |
1977 | goto out_0; | 1977 | goto out_0; |
1978 | } | 1978 | } |
1979 | res_size = res->end - res->start + 1; | 1979 | res_size = resource_size(res); |
1980 | 1980 | ||
1981 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1981 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1982 | if (!irq_res) { | 1982 | if (!irq_res) { |
@@ -2104,7 +2104,7 @@ out_unmap_io_3: | |||
2104 | out_free_netdev_2: | 2104 | out_free_netdev_2: |
2105 | free_netdev(dev); | 2105 | free_netdev(dev); |
2106 | out_release_io_1: | 2106 | out_release_io_1: |
2107 | release_mem_region(res->start, res->end - res->start); | 2107 | release_mem_region(res->start, resource_size(res)); |
2108 | out_0: | 2108 | out_0: |
2109 | return retval; | 2109 | return retval; |
2110 | } | 2110 | } |
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 838cce8b8fff..669253c7bd41 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c | |||
@@ -180,7 +180,7 @@ static int full_duplex[MAX_UNITS] = {0, }; | |||
180 | /* These identify the driver base version and may not be removed. */ | 180 | /* These identify the driver base version and may not be removed. */ |
181 | static const char version[] __devinitconst = | 181 | static const char version[] __devinitconst = |
182 | KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n" | 182 | KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n" |
183 | KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n"; | 183 | " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n"; |
184 | 184 | ||
185 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); | 185 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); |
186 | MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); | 186 | MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); |
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 545f81b34ad7..d1521c3875b2 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c | |||
@@ -1698,13 +1698,13 @@ static int netdev_close(struct net_device *dev) | |||
1698 | 1698 | ||
1699 | #ifdef __i386__ | 1699 | #ifdef __i386__ |
1700 | if (netif_msg_hw(np)) { | 1700 | if (netif_msg_hw(np)) { |
1701 | printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", | 1701 | printk(KERN_DEBUG " Tx ring at %8.8x:\n", |
1702 | (int)(np->tx_ring_dma)); | 1702 | (int)(np->tx_ring_dma)); |
1703 | for (i = 0; i < TX_RING_SIZE; i++) | 1703 | for (i = 0; i < TX_RING_SIZE; i++) |
1704 | printk(" #%d desc. %4.4x %8.8x %8.8x.\n", | 1704 | printk(KERN_DEBUG " #%d desc. %4.4x %8.8x %8.8x.\n", |
1705 | i, np->tx_ring[i].status, np->tx_ring[i].frag[0].addr, | 1705 | i, np->tx_ring[i].status, np->tx_ring[i].frag[0].addr, |
1706 | np->tx_ring[i].frag[0].length); | 1706 | np->tx_ring[i].frag[0].length); |
1707 | printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", | 1707 | printk(KERN_DEBUG " Rx ring %8.8x:\n", |
1708 | (int)(np->rx_ring_dma)); | 1708 | (int)(np->rx_ring_dma)); |
1709 | for (i = 0; i < /*RX_RING_SIZE*/4 ; i++) { | 1709 | for (i = 0; i < /*RX_RING_SIZE*/4 ; i++) { |
1710 | printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n", | 1710 | printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n", |
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 0f78f99f9b20..7030bd5e9848 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c | |||
@@ -1132,7 +1132,9 @@ static int tsi108_get_mac(struct net_device *dev) | |||
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | if (!is_valid_ether_addr(dev->dev_addr)) { | 1134 | if (!is_valid_ether_addr(dev->dev_addr)) { |
1135 | printk("KERN_ERR: word1: %08x, word2: %08x\n", word1, word2); | 1135 | printk(KERN_ERR |
1136 | "%s: Invalid MAC address. word1: %08x, word2: %08x\n", | ||
1137 | dev->name, word1, word2); | ||
1136 | return -EINVAL; | 1138 | return -EINVAL; |
1137 | } | 1139 | } |
1138 | 1140 | ||
@@ -1201,8 +1203,8 @@ static void tsi108_set_rx_mode(struct net_device *dev) | |||
1201 | __set_bit(hash, &data->mc_hash[0]); | 1203 | __set_bit(hash, &data->mc_hash[0]); |
1202 | } else { | 1204 | } else { |
1203 | printk(KERN_ERR | 1205 | printk(KERN_ERR |
1204 | "%s: got multicast address of length %d " | 1206 | "%s: got multicast address of length %d instead of 6.\n", |
1205 | "instead of 6.\n", dev->name, | 1207 | dev->name, |
1206 | mc->dmi_addrlen); | 1208 | mc->dmi_addrlen); |
1207 | } | 1209 | } |
1208 | 1210 | ||
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 81f054dbb88d..ef49744a5085 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -944,9 +944,10 @@ static void de_set_media (struct de_private *de) | |||
944 | macmode &= ~FullDuplex; | 944 | macmode &= ~FullDuplex; |
945 | 945 | ||
946 | if (netif_msg_link(de)) { | 946 | if (netif_msg_link(de)) { |
947 | printk(KERN_INFO "%s: set link %s\n" | 947 | printk(KERN_INFO |
948 | KERN_INFO "%s: mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n" | 948 | "%s: set link %s\n" |
949 | KERN_INFO "%s: set mode 0x%x, set sia 0x%x,0x%x,0x%x\n", | 949 | "%s: mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n" |
950 | "%s: set mode 0x%x, set sia 0x%x,0x%x,0x%x\n", | ||
950 | de->dev->name, media_name[media], | 951 | de->dev->name, media_name[media], |
951 | de->dev->name, dr32(MacMode), dr32(SIAStatus), | 952 | de->dev->name, dr32(MacMode), dr32(SIAStatus), |
952 | dr32(CSR13), dr32(CSR14), dr32(CSR15), | 953 | dr32(CSR13), dr32(CSR14), dr32(CSR15), |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 2abb5d3becc6..99a63649f4fc 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -570,16 +570,18 @@ static void tulip_tx_timeout(struct net_device *dev) | |||
570 | (unsigned int)tp->rx_ring[i].buffer2, | 570 | (unsigned int)tp->rx_ring[i].buffer2, |
571 | buf[0], buf[1], buf[2]); | 571 | buf[0], buf[1], buf[2]); |
572 | for (j = 0; buf[j] != 0xee && j < 1600; j++) | 572 | for (j = 0; buf[j] != 0xee && j < 1600; j++) |
573 | if (j < 100) printk(" %2.2x", buf[j]); | 573 | if (j < 100) |
574 | printk(" j=%d.\n", j); | 574 | printk(KERN_CONT " %2.2x", buf[j]); |
575 | printk(KERN_CONT " j=%d.\n", j); | ||
575 | } | 576 | } |
576 | printk(KERN_DEBUG " Rx ring %8.8x: ", (int)tp->rx_ring); | 577 | printk(KERN_DEBUG " Rx ring %8.8x: ", (int)tp->rx_ring); |
577 | for (i = 0; i < RX_RING_SIZE; i++) | 578 | for (i = 0; i < RX_RING_SIZE; i++) |
578 | printk(" %8.8x", (unsigned int)tp->rx_ring[i].status); | 579 | printk(KERN_CONT " %8.8x", |
579 | printk("\n" KERN_DEBUG " Tx ring %8.8x: ", (int)tp->tx_ring); | 580 | (unsigned int)tp->rx_ring[i].status); |
581 | printk(KERN_DEBUG " Tx ring %8.8x: ", (int)tp->tx_ring); | ||
580 | for (i = 0; i < TX_RING_SIZE; i++) | 582 | for (i = 0; i < TX_RING_SIZE; i++) |
581 | printk(" %8.8x", (unsigned int)tp->tx_ring[i].status); | 583 | printk(KERN_CONT " %8.8x", (unsigned int)tp->tx_ring[i].status); |
582 | printk("\n"); | 584 | printk(KERN_CONT "\n"); |
583 | } | 585 | } |
584 | #endif | 586 | #endif |
585 | 587 | ||
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 842b1a2c40d4..0f15773dae52 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c | |||
@@ -142,7 +142,7 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; | |||
142 | static const char version[] __initconst = | 142 | static const char version[] __initconst = |
143 | KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " | 143 | KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " |
144 | DRV_RELDATE " Donald Becker <becker@scyld.com>\n" | 144 | DRV_RELDATE " Donald Becker <becker@scyld.com>\n" |
145 | KERN_INFO " http://www.scyld.com/network/drivers.html\n"; | 145 | " http://www.scyld.com/network/drivers.html\n"; |
146 | 146 | ||
147 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); | 147 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); |
148 | MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver"); | 148 | MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver"); |
@@ -939,7 +939,7 @@ static void tx_timeout(struct net_device *dev) | |||
939 | printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); | 939 | printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); |
940 | for (i = 0; i < RX_RING_SIZE; i++) | 940 | for (i = 0; i < RX_RING_SIZE; i++) |
941 | printk(" %8.8x", (unsigned int)np->rx_ring[i].status); | 941 | printk(" %8.8x", (unsigned int)np->rx_ring[i].status); |
942 | printk("\n"KERN_DEBUG" Tx ring %p: ", np->tx_ring); | 942 | printk(KERN_DEBUG" Tx ring %p: ", np->tx_ring); |
943 | for (i = 0; i < TX_RING_SIZE; i++) | 943 | for (i = 0; i < TX_RING_SIZE; i++) |
944 | printk(" %8.8x", np->tx_ring[i].status); | 944 | printk(" %8.8x", np->tx_ring[i].status); |
945 | printk("\n"); | 945 | printk("\n"); |
@@ -1520,7 +1520,7 @@ static int netdev_close(struct net_device *dev) | |||
1520 | printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x.\n", | 1520 | printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x.\n", |
1521 | i, np->tx_ring[i].length, | 1521 | i, np->tx_ring[i].length, |
1522 | np->tx_ring[i].status, np->tx_ring[i].buffer1); | 1522 | np->tx_ring[i].status, np->tx_ring[i].buffer1); |
1523 | printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", | 1523 | printk(KERN_DEBUG " Rx ring %8.8x:\n", |
1524 | (int)np->rx_ring); | 1524 | (int)np->rx_ring); |
1525 | for (i = 0; i < RX_RING_SIZE; i++) { | 1525 | for (i = 0; i < RX_RING_SIZE; i++) { |
1526 | printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n", | 1526 | printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n", |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 11a0ba47b677..027f7aba26af 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -486,12 +486,14 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) | |||
486 | { | 486 | { |
487 | struct tun_file *tfile = file->private_data; | 487 | struct tun_file *tfile = file->private_data; |
488 | struct tun_struct *tun = __tun_get(tfile); | 488 | struct tun_struct *tun = __tun_get(tfile); |
489 | struct sock *sk = tun->sk; | 489 | struct sock *sk; |
490 | unsigned int mask = 0; | 490 | unsigned int mask = 0; |
491 | 491 | ||
492 | if (!tun) | 492 | if (!tun) |
493 | return POLLERR; | 493 | return POLLERR; |
494 | 494 | ||
495 | sk = tun->sk; | ||
496 | |||
495 | DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); | 497 | DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); |
496 | 498 | ||
497 | poll_wait(file, &tun->socket.wait, wait); | 499 | poll_wait(file, &tun->socket.wait, wait); |
@@ -1324,20 +1326,22 @@ static int tun_chr_close(struct inode *inode, struct file *file) | |||
1324 | struct tun_file *tfile = file->private_data; | 1326 | struct tun_file *tfile = file->private_data; |
1325 | struct tun_struct *tun; | 1327 | struct tun_struct *tun; |
1326 | 1328 | ||
1327 | |||
1328 | rtnl_lock(); | ||
1329 | tun = __tun_get(tfile); | 1329 | tun = __tun_get(tfile); |
1330 | if (tun) { | 1330 | if (tun) { |
1331 | DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); | 1331 | struct net_device *dev = tun->dev; |
1332 | |||
1333 | DBG(KERN_INFO "%s: tun_chr_close\n", dev->name); | ||
1332 | 1334 | ||
1333 | __tun_detach(tun); | 1335 | __tun_detach(tun); |
1334 | 1336 | ||
1335 | /* If desireable, unregister the netdevice. */ | 1337 | /* If desireable, unregister the netdevice. */ |
1336 | if (!(tun->flags & TUN_PERSIST)) | 1338 | if (!(tun->flags & TUN_PERSIST)) { |
1337 | unregister_netdevice(tun->dev); | 1339 | rtnl_lock(); |
1338 | 1340 | if (dev->reg_state == NETREG_REGISTERED) | |
1341 | unregister_netdevice(dev); | ||
1342 | rtnl_unlock(); | ||
1343 | } | ||
1339 | } | 1344 | } |
1340 | rtnl_unlock(); | ||
1341 | 1345 | ||
1342 | tun = tfile->tun; | 1346 | tun = tfile->tun; |
1343 | if (tun) | 1347 | if (tun) |
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 80e01778dd3b..cd35d50e46d4 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c | |||
@@ -319,7 +319,7 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
319 | return crc == crc2; | 319 | return crc == crc2; |
320 | 320 | ||
321 | if (unlikely(crc != crc2)) { | 321 | if (unlikely(crc != crc2)) { |
322 | dev->stats.rx_errors++; | 322 | dev->net->stats.rx_errors++; |
323 | dev_kfree_skb_any(skb2); | 323 | dev_kfree_skb_any(skb2); |
324 | } else | 324 | } else |
325 | usbnet_skb_return(dev, skb2); | 325 | usbnet_skb_return(dev, skb2); |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 7ae82446b93a..1d3730d6690f 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
@@ -513,11 +513,11 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
513 | len = (skb->data[1] | (skb->data[2] << 8)) - 4; | 513 | len = (skb->data[1] | (skb->data[2] << 8)) - 4; |
514 | 514 | ||
515 | if (unlikely(status & 0xbf)) { | 515 | if (unlikely(status & 0xbf)) { |
516 | if (status & 0x01) dev->stats.rx_fifo_errors++; | 516 | if (status & 0x01) dev->net->stats.rx_fifo_errors++; |
517 | if (status & 0x02) dev->stats.rx_crc_errors++; | 517 | if (status & 0x02) dev->net->stats.rx_crc_errors++; |
518 | if (status & 0x04) dev->stats.rx_frame_errors++; | 518 | if (status & 0x04) dev->net->stats.rx_frame_errors++; |
519 | if (status & 0x20) dev->stats.rx_missed_errors++; | 519 | if (status & 0x20) dev->net->stats.rx_missed_errors++; |
520 | if (status & 0x90) dev->stats.rx_length_errors++; | 520 | if (status & 0x90) dev->net->stats.rx_length_errors++; |
521 | return 0; | 521 | return 0; |
522 | } | 522 | } |
523 | 523 | ||
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index 034e8a73ca6b..aeb1ab03a9ee 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c | |||
@@ -433,7 +433,7 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
433 | dbg("rx framesize %d range %d..%d mtu %d", skb->len, | 433 | dbg("rx framesize %d range %d..%d mtu %d", skb->len, |
434 | net->hard_header_len, dev->hard_mtu, net->mtu); | 434 | net->hard_header_len, dev->hard_mtu, net->mtu); |
435 | #endif | 435 | #endif |
436 | dev->stats.rx_frame_errors++; | 436 | dev->net->stats.rx_frame_errors++; |
437 | nc_ensure_sync(dev); | 437 | nc_ensure_sync(dev); |
438 | return 0; | 438 | return 0; |
439 | } | 439 | } |
@@ -442,12 +442,12 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
442 | hdr_len = le16_to_cpup(&header->hdr_len); | 442 | hdr_len = le16_to_cpup(&header->hdr_len); |
443 | packet_len = le16_to_cpup(&header->packet_len); | 443 | packet_len = le16_to_cpup(&header->packet_len); |
444 | if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) { | 444 | if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) { |
445 | dev->stats.rx_frame_errors++; | 445 | dev->net->stats.rx_frame_errors++; |
446 | dbg("packet too big, %d", packet_len); | 446 | dbg("packet too big, %d", packet_len); |
447 | nc_ensure_sync(dev); | 447 | nc_ensure_sync(dev); |
448 | return 0; | 448 | return 0; |
449 | } else if (hdr_len < MIN_HEADER) { | 449 | } else if (hdr_len < MIN_HEADER) { |
450 | dev->stats.rx_frame_errors++; | 450 | dev->net->stats.rx_frame_errors++; |
451 | dbg("header too short, %d", hdr_len); | 451 | dbg("header too short, %d", hdr_len); |
452 | nc_ensure_sync(dev); | 452 | nc_ensure_sync(dev); |
453 | return 0; | 453 | return 0; |
@@ -465,21 +465,21 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
465 | 465 | ||
466 | if ((packet_len & 0x01) == 0) { | 466 | if ((packet_len & 0x01) == 0) { |
467 | if (skb->data [packet_len] != PAD_BYTE) { | 467 | if (skb->data [packet_len] != PAD_BYTE) { |
468 | dev->stats.rx_frame_errors++; | 468 | dev->net->stats.rx_frame_errors++; |
469 | dbg("bad pad"); | 469 | dbg("bad pad"); |
470 | return 0; | 470 | return 0; |
471 | } | 471 | } |
472 | skb_trim(skb, skb->len - 1); | 472 | skb_trim(skb, skb->len - 1); |
473 | } | 473 | } |
474 | if (skb->len != packet_len) { | 474 | if (skb->len != packet_len) { |
475 | dev->stats.rx_frame_errors++; | 475 | dev->net->stats.rx_frame_errors++; |
476 | dbg("bad packet len %d (expected %d)", | 476 | dbg("bad packet len %d (expected %d)", |
477 | skb->len, packet_len); | 477 | skb->len, packet_len); |
478 | nc_ensure_sync(dev); | 478 | nc_ensure_sync(dev); |
479 | return 0; | 479 | return 0; |
480 | } | 480 | } |
481 | if (header->packet_id != get_unaligned(&trailer->packet_id)) { | 481 | if (header->packet_id != get_unaligned(&trailer->packet_id)) { |
482 | dev->stats.rx_fifo_errors++; | 482 | dev->net->stats.rx_fifo_errors++; |
483 | dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x", | 483 | dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x", |
484 | le16_to_cpu(header->packet_id), | 484 | le16_to_cpu(header->packet_id), |
485 | le16_to_cpu(trailer->packet_id)); | 485 | le16_to_cpu(trailer->packet_id)); |
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 1bf243ef950e..2232232b7989 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -487,7 +487,7 @@ int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
487 | if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET | 487 | if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET |
488 | || skb->len < msg_len | 488 | || skb->len < msg_len |
489 | || (data_offset + data_len + 8) > msg_len)) { | 489 | || (data_offset + data_len + 8) > msg_len)) { |
490 | dev->stats.rx_frame_errors++; | 490 | dev->net->stats.rx_frame_errors++; |
491 | devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d", | 491 | devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d", |
492 | le32_to_cpu(hdr->msg_type), | 492 | le32_to_cpu(hdr->msg_type), |
493 | msg_len, data_offset, data_len, skb->len); | 493 | msg_len, data_offset, data_len, skb->len); |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 89a91f8c22de..fe045896406b 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -1108,18 +1108,18 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1108 | if (unlikely(header & RX_STS_ES_)) { | 1108 | if (unlikely(header & RX_STS_ES_)) { |
1109 | if (netif_msg_rx_err(dev)) | 1109 | if (netif_msg_rx_err(dev)) |
1110 | devdbg(dev, "Error header=0x%08x", header); | 1110 | devdbg(dev, "Error header=0x%08x", header); |
1111 | dev->stats.rx_errors++; | 1111 | dev->net->stats.rx_errors++; |
1112 | dev->stats.rx_dropped++; | 1112 | dev->net->stats.rx_dropped++; |
1113 | 1113 | ||
1114 | if (header & RX_STS_CRC_) { | 1114 | if (header & RX_STS_CRC_) { |
1115 | dev->stats.rx_crc_errors++; | 1115 | dev->net->stats.rx_crc_errors++; |
1116 | } else { | 1116 | } else { |
1117 | if (header & (RX_STS_TL_ | RX_STS_RF_)) | 1117 | if (header & (RX_STS_TL_ | RX_STS_RF_)) |
1118 | dev->stats.rx_frame_errors++; | 1118 | dev->net->stats.rx_frame_errors++; |
1119 | 1119 | ||
1120 | if ((header & RX_STS_LE_) && | 1120 | if ((header & RX_STS_LE_) && |
1121 | (!(header & RX_STS_FT_))) | 1121 | (!(header & RX_STS_FT_))) |
1122 | dev->stats.rx_length_errors++; | 1122 | dev->net->stats.rx_length_errors++; |
1123 | } | 1123 | } |
1124 | } else { | 1124 | } else { |
1125 | /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ | 1125 | /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 22c0585a0319..edfd9e10ceba 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -234,8 +234,8 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) | |||
234 | int status; | 234 | int status; |
235 | 235 | ||
236 | skb->protocol = eth_type_trans (skb, dev->net); | 236 | skb->protocol = eth_type_trans (skb, dev->net); |
237 | dev->stats.rx_packets++; | 237 | dev->net->stats.rx_packets++; |
238 | dev->stats.rx_bytes += skb->len; | 238 | dev->net->stats.rx_bytes += skb->len; |
239 | 239 | ||
240 | if (netif_msg_rx_status (dev)) | 240 | if (netif_msg_rx_status (dev)) |
241 | devdbg (dev, "< rx, len %zu, type 0x%x", | 241 | devdbg (dev, "< rx, len %zu, type 0x%x", |
@@ -397,7 +397,7 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | |||
397 | if (netif_msg_rx_err (dev)) | 397 | if (netif_msg_rx_err (dev)) |
398 | devdbg (dev, "drop"); | 398 | devdbg (dev, "drop"); |
399 | error: | 399 | error: |
400 | dev->stats.rx_errors++; | 400 | dev->net->stats.rx_errors++; |
401 | skb_queue_tail (&dev->done, skb); | 401 | skb_queue_tail (&dev->done, skb); |
402 | } | 402 | } |
403 | } | 403 | } |
@@ -420,8 +420,8 @@ static void rx_complete (struct urb *urb) | |||
420 | case 0: | 420 | case 0: |
421 | if (skb->len < dev->net->hard_header_len) { | 421 | if (skb->len < dev->net->hard_header_len) { |
422 | entry->state = rx_cleanup; | 422 | entry->state = rx_cleanup; |
423 | dev->stats.rx_errors++; | 423 | dev->net->stats.rx_errors++; |
424 | dev->stats.rx_length_errors++; | 424 | dev->net->stats.rx_length_errors++; |
425 | if (netif_msg_rx_err (dev)) | 425 | if (netif_msg_rx_err (dev)) |
426 | devdbg (dev, "rx length %d", skb->len); | 426 | devdbg (dev, "rx length %d", skb->len); |
427 | } | 427 | } |
@@ -433,7 +433,7 @@ static void rx_complete (struct urb *urb) | |||
433 | * storm, recovering as needed. | 433 | * storm, recovering as needed. |
434 | */ | 434 | */ |
435 | case -EPIPE: | 435 | case -EPIPE: |
436 | dev->stats.rx_errors++; | 436 | dev->net->stats.rx_errors++; |
437 | usbnet_defer_kevent (dev, EVENT_RX_HALT); | 437 | usbnet_defer_kevent (dev, EVENT_RX_HALT); |
438 | // FALLTHROUGH | 438 | // FALLTHROUGH |
439 | 439 | ||
@@ -451,7 +451,7 @@ static void rx_complete (struct urb *urb) | |||
451 | case -EPROTO: | 451 | case -EPROTO: |
452 | case -ETIME: | 452 | case -ETIME: |
453 | case -EILSEQ: | 453 | case -EILSEQ: |
454 | dev->stats.rx_errors++; | 454 | dev->net->stats.rx_errors++; |
455 | if (!timer_pending (&dev->delay)) { | 455 | if (!timer_pending (&dev->delay)) { |
456 | mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); | 456 | mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); |
457 | if (netif_msg_link (dev)) | 457 | if (netif_msg_link (dev)) |
@@ -465,12 +465,12 @@ block: | |||
465 | 465 | ||
466 | /* data overrun ... flush fifo? */ | 466 | /* data overrun ... flush fifo? */ |
467 | case -EOVERFLOW: | 467 | case -EOVERFLOW: |
468 | dev->stats.rx_over_errors++; | 468 | dev->net->stats.rx_over_errors++; |
469 | // FALLTHROUGH | 469 | // FALLTHROUGH |
470 | 470 | ||
471 | default: | 471 | default: |
472 | entry->state = rx_cleanup; | 472 | entry->state = rx_cleanup; |
473 | dev->stats.rx_errors++; | 473 | dev->net->stats.rx_errors++; |
474 | if (netif_msg_rx_err (dev)) | 474 | if (netif_msg_rx_err (dev)) |
475 | devdbg (dev, "rx status %d", urb_status); | 475 | devdbg (dev, "rx status %d", urb_status); |
476 | break; | 476 | break; |
@@ -583,8 +583,8 @@ int usbnet_stop (struct net_device *net) | |||
583 | 583 | ||
584 | if (netif_msg_ifdown (dev)) | 584 | if (netif_msg_ifdown (dev)) |
585 | devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld", | 585 | devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld", |
586 | dev->stats.rx_packets, dev->stats.tx_packets, | 586 | net->stats.rx_packets, net->stats.tx_packets, |
587 | dev->stats.rx_errors, dev->stats.tx_errors | 587 | net->stats.rx_errors, net->stats.tx_errors |
588 | ); | 588 | ); |
589 | 589 | ||
590 | // ensure there are no more active urbs | 590 | // ensure there are no more active urbs |
@@ -891,10 +891,10 @@ static void tx_complete (struct urb *urb) | |||
891 | struct usbnet *dev = entry->dev; | 891 | struct usbnet *dev = entry->dev; |
892 | 892 | ||
893 | if (urb->status == 0) { | 893 | if (urb->status == 0) { |
894 | dev->stats.tx_packets++; | 894 | dev->net->stats.tx_packets++; |
895 | dev->stats.tx_bytes += entry->length; | 895 | dev->net->stats.tx_bytes += entry->length; |
896 | } else { | 896 | } else { |
897 | dev->stats.tx_errors++; | 897 | dev->net->stats.tx_errors++; |
898 | 898 | ||
899 | switch (urb->status) { | 899 | switch (urb->status) { |
900 | case -EPIPE: | 900 | case -EPIPE: |
@@ -1020,7 +1020,7 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) | |||
1020 | devdbg (dev, "drop, code %d", retval); | 1020 | devdbg (dev, "drop, code %d", retval); |
1021 | drop: | 1021 | drop: |
1022 | retval = NET_XMIT_SUCCESS; | 1022 | retval = NET_XMIT_SUCCESS; |
1023 | dev->stats.tx_dropped++; | 1023 | dev->net->stats.tx_dropped++; |
1024 | if (skb) | 1024 | if (skb) |
1025 | dev_kfree_skb_any (skb); | 1025 | dev_kfree_skb_any (skb); |
1026 | usb_free_urb (urb); | 1026 | usb_free_urb (urb); |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 87197dd9c788..1097c72e44d5 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -208,11 +208,14 @@ rx_drop: | |||
208 | 208 | ||
209 | static struct net_device_stats *veth_get_stats(struct net_device *dev) | 209 | static struct net_device_stats *veth_get_stats(struct net_device *dev) |
210 | { | 210 | { |
211 | struct veth_priv *priv = netdev_priv(dev); | 211 | struct veth_priv *priv; |
212 | struct net_device_stats *dev_stats = &dev->stats; | 212 | struct net_device_stats *dev_stats; |
213 | unsigned int cpu; | 213 | int cpu; |
214 | struct veth_net_stats *stats; | 214 | struct veth_net_stats *stats; |
215 | 215 | ||
216 | priv = netdev_priv(dev); | ||
217 | dev_stats = &dev->stats; | ||
218 | |||
216 | dev_stats->rx_packets = 0; | 219 | dev_stats->rx_packets = 0; |
217 | dev_stats->tx_packets = 0; | 220 | dev_stats->tx_packets = 0; |
218 | dev_stats->rx_bytes = 0; | 221 | dev_stats->rx_bytes = 0; |
@@ -220,17 +223,16 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev) | |||
220 | dev_stats->tx_dropped = 0; | 223 | dev_stats->tx_dropped = 0; |
221 | dev_stats->rx_dropped = 0; | 224 | dev_stats->rx_dropped = 0; |
222 | 225 | ||
223 | if (priv->stats) | 226 | for_each_online_cpu(cpu) { |
224 | for_each_online_cpu(cpu) { | 227 | stats = per_cpu_ptr(priv->stats, cpu); |
225 | stats = per_cpu_ptr(priv->stats, cpu); | ||
226 | 228 | ||
227 | dev_stats->rx_packets += stats->rx_packets; | 229 | dev_stats->rx_packets += stats->rx_packets; |
228 | dev_stats->tx_packets += stats->tx_packets; | 230 | dev_stats->tx_packets += stats->tx_packets; |
229 | dev_stats->rx_bytes += stats->rx_bytes; | 231 | dev_stats->rx_bytes += stats->rx_bytes; |
230 | dev_stats->tx_bytes += stats->tx_bytes; | 232 | dev_stats->tx_bytes += stats->tx_bytes; |
231 | dev_stats->tx_dropped += stats->tx_dropped; | 233 | dev_stats->tx_dropped += stats->tx_dropped; |
232 | dev_stats->rx_dropped += stats->rx_dropped; | 234 | dev_stats->rx_dropped += stats->rx_dropped; |
233 | } | 235 | } |
234 | 236 | ||
235 | return dev_stats; | 237 | return dev_stats; |
236 | } | 238 | } |
@@ -257,8 +259,6 @@ static int veth_close(struct net_device *dev) | |||
257 | netif_carrier_off(dev); | 259 | netif_carrier_off(dev); |
258 | netif_carrier_off(priv->peer); | 260 | netif_carrier_off(priv->peer); |
259 | 261 | ||
260 | free_percpu(priv->stats); | ||
261 | priv->stats = NULL; | ||
262 | return 0; | 262 | return 0; |
263 | } | 263 | } |
264 | 264 | ||
@@ -289,6 +289,15 @@ static int veth_dev_init(struct net_device *dev) | |||
289 | return 0; | 289 | return 0; |
290 | } | 290 | } |
291 | 291 | ||
292 | static void veth_dev_free(struct net_device *dev) | ||
293 | { | ||
294 | struct veth_priv *priv; | ||
295 | |||
296 | priv = netdev_priv(dev); | ||
297 | free_percpu(priv->stats); | ||
298 | free_netdev(dev); | ||
299 | } | ||
300 | |||
292 | static const struct net_device_ops veth_netdev_ops = { | 301 | static const struct net_device_ops veth_netdev_ops = { |
293 | .ndo_init = veth_dev_init, | 302 | .ndo_init = veth_dev_init, |
294 | .ndo_open = veth_open, | 303 | .ndo_open = veth_open, |
@@ -306,7 +315,7 @@ static void veth_setup(struct net_device *dev) | |||
306 | dev->netdev_ops = &veth_netdev_ops; | 315 | dev->netdev_ops = &veth_netdev_ops; |
307 | dev->ethtool_ops = &veth_ethtool_ops; | 316 | dev->ethtool_ops = &veth_ethtool_ops; |
308 | dev->features |= NETIF_F_LLTX; | 317 | dev->features |= NETIF_F_LLTX; |
309 | dev->destructor = free_netdev; | 318 | dev->destructor = veth_dev_free; |
310 | } | 319 | } |
311 | 320 | ||
312 | /* | 321 | /* |
diff --git a/drivers/net/wan/hd64570.c b/drivers/net/wan/hd64570.c index 223238de475c..1ea1ef6c3b96 100644 --- a/drivers/net/wan/hd64570.c +++ b/drivers/net/wan/hd64570.c | |||
@@ -584,8 +584,9 @@ static void sca_dump_rings(struct net_device *dev) | |||
584 | sca_in(DSR_RX(phy_node(port)), card) & DSR_DE ? "" : "in"); | 584 | sca_in(DSR_RX(phy_node(port)), card) & DSR_DE ? "" : "in"); |
585 | for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++) | 585 | for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++) |
586 | printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); | 586 | printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); |
587 | printk(KERN_CONT "\n"); | ||
587 | 588 | ||
588 | printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " | 589 | printk(KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " |
589 | "last=%u %sactive", | 590 | "last=%u %sactive", |
590 | sca_inw(get_dmac_tx(port) + CDAL, card), | 591 | sca_inw(get_dmac_tx(port) + CDAL, card), |
591 | sca_inw(get_dmac_tx(port) + EDAL, card), | 592 | sca_inw(get_dmac_tx(port) + EDAL, card), |
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index 497b003d7239..f099c34a3ae2 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c | |||
@@ -529,8 +529,9 @@ static void sca_dump_rings(struct net_device *dev) | |||
529 | sca_in(DSR_RX(port->chan), card) & DSR_DE ? "" : "in"); | 529 | sca_in(DSR_RX(port->chan), card) & DSR_DE ? "" : "in"); |
530 | for (cnt = 0; cnt < port->card->rx_ring_buffers; cnt++) | 530 | for (cnt = 0; cnt < port->card->rx_ring_buffers; cnt++) |
531 | printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); | 531 | printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); |
532 | printk(KERN_CONT "\n"); | ||
532 | 533 | ||
533 | printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " | 534 | printk(KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " |
534 | "last=%u %sactive", | 535 | "last=%u %sactive", |
535 | sca_inl(get_dmac_tx(port) + CDAL, card), | 536 | sca_inl(get_dmac_tx(port) + CDAL, card), |
536 | sca_inl(get_dmac_tx(port) + EDAL, card), | 537 | sca_inl(get_dmac_tx(port) + EDAL, card), |
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 3fb9dbc88a1a..d14e95a08d66 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c | |||
@@ -326,11 +326,9 @@ sbni_pci_probe( struct net_device *dev ) | |||
326 | } | 326 | } |
327 | 327 | ||
328 | if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs) | 328 | if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs) |
329 | printk( KERN_WARNING " WARNING: The PCI BIOS assigned " | 329 | printk( KERN_WARNING |
330 | "this PCI card to IRQ %d, which is unlikely " | 330 | " WARNING: The PCI BIOS assigned this PCI card to IRQ %d, which is unlikely to work!.\n" |
331 | "to work!.\n" | 331 | " You should use the PCI BIOS setup to assign a valid IRQ line.\n", |
332 | KERN_WARNING " You should use the PCI BIOS " | ||
333 | "setup to assign a valid IRQ line.\n", | ||
334 | pci_irq_line ); | 332 | pci_irq_line ); |
335 | 333 | ||
336 | /* avoiding re-enable dual adapters */ | 334 | /* avoiding re-enable dual adapters */ |
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index d26e7b485315..eb0337c49546 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config ATH_COMMON | 1 | config ATH_COMMON |
2 | tristate "Atheros Wireless Cards" | 2 | tristate "Atheros Wireless Cards" |
3 | depends on WLAN_80211 | ||
3 | depends on ATH5K || ATH9K || AR9170_USB | 4 | depends on ATH5K || ATH9K || AR9170_USB |
4 | 5 | ||
5 | source "drivers/net/wireless/ath/ath5k/Kconfig" | 6 | source "drivers/net/wireless/ath/ath5k/Kconfig" |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b61a071788a5..4ccf48e396df 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -355,7 +355,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
355 | } | 355 | } |
356 | 356 | ||
357 | if (bf_next == NULL) { | 357 | if (bf_next == NULL) { |
358 | INIT_LIST_HEAD(&bf_head); | 358 | /* |
359 | * Make sure the last desc is reclaimed if it | ||
360 | * not a holding desc. | ||
361 | */ | ||
362 | if (!bf_last->bf_stale) | ||
363 | list_move_tail(&bf->list, &bf_head); | ||
364 | else | ||
365 | INIT_LIST_HEAD(&bf_head); | ||
359 | } else { | 366 | } else { |
360 | ASSERT(!list_empty(bf_q)); | 367 | ASSERT(!list_empty(bf_q)); |
361 | list_move_tail(&bf->list, &bf_head); | 368 | list_move_tail(&bf->list, &bf_head); |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f580c2812d91..40448067e4cc 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -648,6 +648,7 @@ struct b43_wl { | |||
648 | u8 nr_devs; | 648 | u8 nr_devs; |
649 | 649 | ||
650 | bool radiotap_enabled; | 650 | bool radiotap_enabled; |
651 | bool radio_enabled; | ||
651 | 652 | ||
652 | /* The beacon we are currently using (AP or IBSS mode). | 653 | /* The beacon we are currently using (AP or IBSS mode). |
653 | * This beacon stuff is protected by the irq_lock. */ | 654 | * This beacon stuff is protected by the irq_lock. */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6456afebdba1..e71c8d9cd706 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3497,8 +3497,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3497 | if (phy->ops->set_rx_antenna) | 3497 | if (phy->ops->set_rx_antenna) |
3498 | phy->ops->set_rx_antenna(dev, antenna); | 3498 | phy->ops->set_rx_antenna(dev, antenna); |
3499 | 3499 | ||
3500 | if (!!conf->radio_enabled != phy->radio_on) { | 3500 | if (wl->radio_enabled != phy->radio_on) { |
3501 | if (conf->radio_enabled) { | 3501 | if (wl->radio_enabled) { |
3502 | b43_software_rfkill(dev, false); | 3502 | b43_software_rfkill(dev, false); |
3503 | b43info(dev->wl, "Radio turned on by software\n"); | 3503 | b43info(dev->wl, "Radio turned on by software\n"); |
3504 | if (!dev->radio_hw_enable) { | 3504 | if (!dev->radio_hw_enable) { |
@@ -4339,6 +4339,7 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4339 | wl->beacon0_uploaded = 0; | 4339 | wl->beacon0_uploaded = 0; |
4340 | wl->beacon1_uploaded = 0; | 4340 | wl->beacon1_uploaded = 0; |
4341 | wl->beacon_templates_virgin = 1; | 4341 | wl->beacon_templates_virgin = 1; |
4342 | wl->radio_enabled = 1; | ||
4342 | 4343 | ||
4343 | mutex_lock(&wl->mutex); | 4344 | mutex_lock(&wl->mutex); |
4344 | 4345 | ||
@@ -4378,6 +4379,7 @@ static void b43_op_stop(struct ieee80211_hw *hw) | |||
4378 | if (b43_status(dev) >= B43_STAT_STARTED) | 4379 | if (b43_status(dev) >= B43_STAT_STARTED) |
4379 | b43_wireless_core_stop(dev); | 4380 | b43_wireless_core_stop(dev); |
4380 | b43_wireless_core_exit(dev); | 4381 | b43_wireless_core_exit(dev); |
4382 | wl->radio_enabled = 0; | ||
4381 | mutex_unlock(&wl->mutex); | 4383 | mutex_unlock(&wl->mutex); |
4382 | 4384 | ||
4383 | cancel_work_sync(&(wl->txpower_adjust_work)); | 4385 | cancel_work_sync(&(wl->txpower_adjust_work)); |
@@ -4560,6 +4562,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4560 | B43_WARN_ON(1); | 4562 | B43_WARN_ON(1); |
4561 | 4563 | ||
4562 | dev->phy.gmode = have_2ghz_phy; | 4564 | dev->phy.gmode = have_2ghz_phy; |
4565 | dev->phy.radio_on = 1; | ||
4563 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; | 4566 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; |
4564 | b43_wireless_core_reset(dev, tmp); | 4567 | b43_wireless_core_reset(dev, tmp); |
4565 | 4568 | ||
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 3cfc30307a27..6c3a74964ab8 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = { | 36 | static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = { |
37 | PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), | 37 | PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), |
38 | PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476), | ||
38 | PCMCIA_DEVICE_NULL, | 39 | PCMCIA_DEVICE_NULL, |
39 | }; | 40 | }; |
40 | 41 | ||
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 77fda148ac46..038baa8869e2 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -607,6 +607,7 @@ struct b43legacy_wl { | |||
607 | u8 nr_devs; | 607 | u8 nr_devs; |
608 | 608 | ||
609 | bool radiotap_enabled; | 609 | bool radiotap_enabled; |
610 | bool radio_enabled; | ||
610 | 611 | ||
611 | /* The beacon we are currently using (AP or IBSS mode). | 612 | /* The beacon we are currently using (AP or IBSS mode). |
612 | * This beacon stuff is protected by the irq_lock. */ | 613 | * This beacon stuff is protected by the irq_lock. */ |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index e5136fb65ddd..c4973c1942bf 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -2689,8 +2689,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2689 | /* Antennas for RX and management frame TX. */ | 2689 | /* Antennas for RX and management frame TX. */ |
2690 | b43legacy_mgmtframe_txantenna(dev, antenna_tx); | 2690 | b43legacy_mgmtframe_txantenna(dev, antenna_tx); |
2691 | 2691 | ||
2692 | if (!!conf->radio_enabled != phy->radio_on) { | 2692 | if (wl->radio_enabled != phy->radio_on) { |
2693 | if (conf->radio_enabled) { | 2693 | if (wl->radio_enabled) { |
2694 | b43legacy_radio_turn_on(dev); | 2694 | b43legacy_radio_turn_on(dev); |
2695 | b43legacyinfo(dev->wl, "Radio turned on by software\n"); | 2695 | b43legacyinfo(dev->wl, "Radio turned on by software\n"); |
2696 | if (!dev->radio_hw_enable) | 2696 | if (!dev->radio_hw_enable) |
@@ -3441,6 +3441,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3441 | wl->beacon0_uploaded = 0; | 3441 | wl->beacon0_uploaded = 0; |
3442 | wl->beacon1_uploaded = 0; | 3442 | wl->beacon1_uploaded = 0; |
3443 | wl->beacon_templates_virgin = 1; | 3443 | wl->beacon_templates_virgin = 1; |
3444 | wl->radio_enabled = 1; | ||
3444 | 3445 | ||
3445 | mutex_lock(&wl->mutex); | 3446 | mutex_lock(&wl->mutex); |
3446 | 3447 | ||
@@ -3479,6 +3480,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) | |||
3479 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) | 3480 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) |
3480 | b43legacy_wireless_core_stop(dev); | 3481 | b43legacy_wireless_core_stop(dev); |
3481 | b43legacy_wireless_core_exit(dev); | 3482 | b43legacy_wireless_core_exit(dev); |
3483 | wl->radio_enabled = 0; | ||
3482 | mutex_unlock(&wl->mutex); | 3484 | mutex_unlock(&wl->mutex); |
3483 | } | 3485 | } |
3484 | 3486 | ||
@@ -3620,6 +3622,7 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) | |||
3620 | have_bphy = 1; | 3622 | have_bphy = 1; |
3621 | 3623 | ||
3622 | dev->phy.gmode = (have_gphy || have_bphy); | 3624 | dev->phy.gmode = (have_gphy || have_bphy); |
3625 | dev->phy.radio_on = 1; | ||
3623 | tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; | 3626 | tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; |
3624 | b43legacy_wireless_core_reset(dev, tmp); | 3627 | b43legacy_wireless_core_reset(dev, tmp); |
3625 | 3628 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig index 1eccb6df46dd..030401d367d3 100644 --- a/drivers/net/wireless/iwmc3200wifi/Kconfig +++ b/drivers/net/wireless/iwmc3200wifi/Kconfig | |||
@@ -4,6 +4,15 @@ config IWM | |||
4 | depends on CFG80211 | 4 | depends on CFG80211 |
5 | select WIRELESS_EXT | 5 | select WIRELESS_EXT |
6 | select FW_LOADER | 6 | select FW_LOADER |
7 | help | ||
8 | The Intel Wireless Multicomm 3200 hardware is a combo | ||
9 | card with GPS, Bluetooth, WiMax and 802.11 radios. It | ||
10 | runs over SDIO and is typically found on Moorestown | ||
11 | based platform. This driver takes care of the 802.11 | ||
12 | part, which is a fullmac one. | ||
13 | |||
14 | If you choose to build it as a module, it'll be called | ||
15 | iwmc3200wifi.ko. | ||
7 | 16 | ||
8 | config IWM_DEBUG | 17 | config IWM_DEBUG |
9 | bool "Enable full debugging output in iwmc3200wifi" | 18 | bool "Enable full debugging output in iwmc3200wifi" |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e789c6e9938c..a111bda392e2 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -418,6 +418,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
418 | continue; | 418 | continue; |
419 | 419 | ||
420 | if (!data2->started || !hwsim_ps_rx_ok(data2, skb) || | 420 | if (!data2->started || !hwsim_ps_rx_ok(data2, skb) || |
421 | !data->channel || !data2->channel || | ||
421 | data->channel->center_freq != data2->channel->center_freq || | 422 | data->channel->center_freq != data2->channel->center_freq || |
422 | !(data->group & data2->group)) | 423 | !(data->group & data2->group)) |
423 | continue; | 424 | continue; |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index b618bd14583f..22ca122bd798 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -823,30 +823,30 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
823 | struct p54_tx_info *range; | 823 | struct p54_tx_info *range; |
824 | unsigned long flags; | 824 | unsigned long flags; |
825 | 825 | ||
826 | if (unlikely(!skb || !dev || skb_queue_empty(&priv->tx_queue))) | 826 | if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue))) |
827 | return; | 827 | return; |
828 | 828 | ||
829 | /* There used to be a check here to see if the SKB was on the | 829 | /* |
830 | * TX queue or not. This can never happen because all SKBs we | 830 | * don't try to free an already unlinked skb |
831 | * see here successfully went through p54_assign_address() | ||
832 | * which means the SKB is on the ->tx_queue. | ||
833 | */ | 831 | */ |
832 | if (unlikely((!skb->next) || (!skb->prev))) | ||
833 | return; | ||
834 | 834 | ||
835 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 835 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
836 | info = IEEE80211_SKB_CB(skb); | 836 | info = IEEE80211_SKB_CB(skb); |
837 | range = (void *)info->rate_driver_data; | 837 | range = (void *)info->rate_driver_data; |
838 | if (!skb_queue_is_first(&priv->tx_queue, skb)) { | 838 | if (skb->prev != (struct sk_buff *)&priv->tx_queue) { |
839 | struct ieee80211_tx_info *ni; | 839 | struct ieee80211_tx_info *ni; |
840 | struct p54_tx_info *mr; | 840 | struct p54_tx_info *mr; |
841 | 841 | ||
842 | ni = IEEE80211_SKB_CB(skb_queue_prev(&priv->tx_queue, skb)); | 842 | ni = IEEE80211_SKB_CB(skb->prev); |
843 | mr = (struct p54_tx_info *)ni->rate_driver_data; | 843 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
844 | } | 844 | } |
845 | if (!skb_queue_is_last(&priv->tx_queue, skb)) { | 845 | if (skb->next != (struct sk_buff *)&priv->tx_queue) { |
846 | struct ieee80211_tx_info *ni; | 846 | struct ieee80211_tx_info *ni; |
847 | struct p54_tx_info *mr; | 847 | struct p54_tx_info *mr; |
848 | 848 | ||
849 | ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, skb)); | 849 | ni = IEEE80211_SKB_CB(skb->next); |
850 | mr = (struct p54_tx_info *)ni->rate_driver_data; | 850 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
851 | } | 851 | } |
852 | __skb_unlink(skb, &priv->tx_queue); | 852 | __skb_unlink(skb, &priv->tx_queue); |
@@ -864,13 +864,15 @@ static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev, | |||
864 | unsigned long flags; | 864 | unsigned long flags; |
865 | 865 | ||
866 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 866 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
867 | skb_queue_walk(&priv->tx_queue, entry) { | 867 | entry = priv->tx_queue.next; |
868 | while (entry != (struct sk_buff *)&priv->tx_queue) { | ||
868 | struct p54_hdr *hdr = (struct p54_hdr *) entry->data; | 869 | struct p54_hdr *hdr = (struct p54_hdr *) entry->data; |
869 | 870 | ||
870 | if (hdr->req_id == req_id) { | 871 | if (hdr->req_id == req_id) { |
871 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 872 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
872 | return entry; | 873 | return entry; |
873 | } | 874 | } |
875 | entry = entry->next; | ||
874 | } | 876 | } |
875 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 877 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
876 | return NULL; | 878 | return NULL; |
@@ -888,33 +890,36 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
888 | int count, idx; | 890 | int count, idx; |
889 | 891 | ||
890 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 892 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
891 | skb_queue_walk(&priv->tx_queue, entry) { | 893 | entry = (struct sk_buff *) priv->tx_queue.next; |
894 | while (entry != (struct sk_buff *)&priv->tx_queue) { | ||
892 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); | 895 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); |
893 | struct p54_hdr *entry_hdr; | 896 | struct p54_hdr *entry_hdr; |
894 | struct p54_tx_data *entry_data; | 897 | struct p54_tx_data *entry_data; |
895 | unsigned int pad = 0, frame_len; | 898 | unsigned int pad = 0, frame_len; |
896 | 899 | ||
897 | range = (void *)info->rate_driver_data; | 900 | range = (void *)info->rate_driver_data; |
898 | if (range->start_addr != addr) | 901 | if (range->start_addr != addr) { |
902 | entry = entry->next; | ||
899 | continue; | 903 | continue; |
904 | } | ||
900 | 905 | ||
901 | if (!skb_queue_is_last(&priv->tx_queue, entry)) { | 906 | if (entry->next != (struct sk_buff *)&priv->tx_queue) { |
902 | struct ieee80211_tx_info *ni; | 907 | struct ieee80211_tx_info *ni; |
903 | struct p54_tx_info *mr; | 908 | struct p54_tx_info *mr; |
904 | 909 | ||
905 | ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, | 910 | ni = IEEE80211_SKB_CB(entry->next); |
906 | entry)); | ||
907 | mr = (struct p54_tx_info *)ni->rate_driver_data; | 911 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
908 | } | 912 | } |
909 | 913 | ||
910 | __skb_unlink(entry, &priv->tx_queue); | 914 | __skb_unlink(entry, &priv->tx_queue); |
911 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | ||
912 | 915 | ||
913 | frame_len = entry->len; | 916 | frame_len = entry->len; |
914 | entry_hdr = (struct p54_hdr *) entry->data; | 917 | entry_hdr = (struct p54_hdr *) entry->data; |
915 | entry_data = (struct p54_tx_data *) entry_hdr->data; | 918 | entry_data = (struct p54_tx_data *) entry_hdr->data; |
916 | priv->tx_stats[entry_data->hw_queue].len--; | 919 | if (priv->tx_stats[entry_data->hw_queue].len) |
920 | priv->tx_stats[entry_data->hw_queue].len--; | ||
917 | priv->stats.dot11ACKFailureCount += payload->tries - 1; | 921 | priv->stats.dot11ACKFailureCount += payload->tries - 1; |
922 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | ||
918 | 923 | ||
919 | /* | 924 | /* |
920 | * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are | 925 | * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are |
@@ -1164,21 +1169,23 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1164 | } | 1169 | } |
1165 | } | 1170 | } |
1166 | 1171 | ||
1167 | skb_queue_walk(&priv->tx_queue, entry) { | 1172 | entry = priv->tx_queue.next; |
1173 | while (left--) { | ||
1168 | u32 hole_size; | 1174 | u32 hole_size; |
1169 | info = IEEE80211_SKB_CB(entry); | 1175 | info = IEEE80211_SKB_CB(entry); |
1170 | range = (void *)info->rate_driver_data; | 1176 | range = (void *)info->rate_driver_data; |
1171 | hole_size = range->start_addr - last_addr; | 1177 | hole_size = range->start_addr - last_addr; |
1172 | if (!target_skb && hole_size >= len) { | 1178 | if (!target_skb && hole_size >= len) { |
1173 | target_skb = skb_queue_prev(&priv->tx_queue, entry); | 1179 | target_skb = entry->prev; |
1174 | hole_size -= len; | 1180 | hole_size -= len; |
1175 | target_addr = last_addr; | 1181 | target_addr = last_addr; |
1176 | } | 1182 | } |
1177 | largest_hole = max(largest_hole, hole_size); | 1183 | largest_hole = max(largest_hole, hole_size); |
1178 | last_addr = range->end_addr; | 1184 | last_addr = range->end_addr; |
1185 | entry = entry->next; | ||
1179 | } | 1186 | } |
1180 | if (!target_skb && priv->rx_end - last_addr >= len) { | 1187 | if (!target_skb && priv->rx_end - last_addr >= len) { |
1181 | target_skb = skb_peek_tail(&priv->tx_queue); | 1188 | target_skb = priv->tx_queue.prev; |
1182 | largest_hole = max(largest_hole, priv->rx_end - last_addr - len); | 1189 | largest_hole = max(largest_hole, priv->rx_end - last_addr - len); |
1183 | if (!skb_queue_empty(&priv->tx_queue)) { | 1190 | if (!skb_queue_empty(&priv->tx_queue)) { |
1184 | info = IEEE80211_SKB_CB(target_skb); | 1191 | info = IEEE80211_SKB_CB(target_skb); |
@@ -2084,6 +2091,7 @@ out: | |||
2084 | static void p54_stop(struct ieee80211_hw *dev) | 2091 | static void p54_stop(struct ieee80211_hw *dev) |
2085 | { | 2092 | { |
2086 | struct p54_common *priv = dev->priv; | 2093 | struct p54_common *priv = dev->priv; |
2094 | struct sk_buff *skb; | ||
2087 | 2095 | ||
2088 | mutex_lock(&priv->conf_mutex); | 2096 | mutex_lock(&priv->conf_mutex); |
2089 | priv->mode = NL80211_IFTYPE_UNSPECIFIED; | 2097 | priv->mode = NL80211_IFTYPE_UNSPECIFIED; |
@@ -2098,7 +2106,8 @@ static void p54_stop(struct ieee80211_hw *dev) | |||
2098 | p54_tx_cancel(dev, priv->cached_beacon); | 2106 | p54_tx_cancel(dev, priv->cached_beacon); |
2099 | 2107 | ||
2100 | priv->stop(dev); | 2108 | priv->stop(dev); |
2101 | skb_queue_purge(&priv->tx_queue); | 2109 | while ((skb = skb_dequeue(&priv->tx_queue))) |
2110 | kfree_skb(skb); | ||
2102 | priv->cached_beacon = NULL; | 2111 | priv->cached_beacon = NULL; |
2103 | priv->tsf_high32 = priv->tsf_low32 = 0; | 2112 | priv->tsf_high32 = priv->tsf_low32 = 0; |
2104 | mutex_unlock(&priv->conf_mutex); | 2113 | mutex_unlock(&priv->conf_mutex); |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index b10b0383dfa5..698b11b1cadb 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -2427,11 +2427,10 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) | |||
2427 | 2427 | ||
2428 | #ifdef PCMCIA_DEBUG | 2428 | #ifdef PCMCIA_DEBUG |
2429 | if (pc_debug > 3) { | 2429 | if (pc_debug > 3) { |
2430 | int i; | 2430 | print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ", |
2431 | printk(KERN_DEBUG "skb->data before untranslate"); | 2431 | DUMP_PREFIX_NONE, 16, 1, |
2432 | for (i = 0; i < 64; i++) | 2432 | skb->data, 64, true); |
2433 | printk("%02x ", skb->data[i]); | 2433 | printk(KERN_DEBUG |
2434 | printk("\n" KERN_DEBUG | ||
2435 | "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n", | 2434 | "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n", |
2436 | ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl, | 2435 | ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl, |
2437 | psnap->org[0], psnap->org[1], psnap->org[2]); | 2436 | psnap->org[0], psnap->org[1], psnap->org[2]); |
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 6af706408ac0..c6d300666ad8 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c | |||
@@ -3556,17 +3556,8 @@ wv_82593_config(struct net_device * dev) | |||
3556 | cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */ | 3556 | cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */ |
3557 | 3557 | ||
3558 | #ifdef DEBUG_I82593_SHOW | 3558 | #ifdef DEBUG_I82593_SHOW |
3559 | { | 3559 | print_hex_dump(KERN_DEBUG, "wavelan_cs: config block: ", DUMP_PREFIX_NONE, |
3560 | u_char *c = (u_char *) &cfblk; | 3560 | 16, 1, &cfblk, sizeof(struct i82593_conf_block), false); |
3561 | int i; | ||
3562 | printk(KERN_DEBUG "wavelan_cs: config block:"); | ||
3563 | for(i = 0; i < sizeof(struct i82593_conf_block); i++,c++) | ||
3564 | { | ||
3565 | if((i % 16) == 0) printk("\n" KERN_DEBUG); | ||
3566 | printk("%02x ", *c); | ||
3567 | } | ||
3568 | printk("\n"); | ||
3569 | } | ||
3570 | #endif | 3561 | #endif |
3571 | 3562 | ||
3572 | /* Copy the config block to the i82593 */ | 3563 | /* Copy the config block to the i82593 */ |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 14a19baff214..0e6e44689cc6 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -38,7 +38,6 @@ static struct usb_device_id usb_ids[] = { | |||
38 | /* ZD1211 */ | 38 | /* ZD1211 */ |
39 | { USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 }, | 39 | { USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 }, |
40 | { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, | 40 | { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, |
41 | { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 }, | ||
42 | { USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 }, | 41 | { USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 }, |
43 | { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, | 42 | { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, |
44 | { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, | 43 | { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, |
@@ -61,6 +60,7 @@ static struct usb_device_id usb_ids[] = { | |||
61 | { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, | 60 | { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, |
62 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, | 61 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, |
63 | /* ZD1211B */ | 62 | /* ZD1211B */ |
63 | { USB_DEVICE(0x054c, 0x0257), .driver_info = DEVICE_ZD1211B }, | ||
64 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, | 64 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, |
65 | { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B }, | 65 | { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B }, |
66 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, | 66 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, |
@@ -87,6 +87,7 @@ static struct usb_device_id usb_ids[] = { | |||
87 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, | 87 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, |
88 | { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, | 88 | { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, |
89 | { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, | 89 | { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, |
90 | { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B }, | ||
90 | /* "Driverless" devices that need ejecting */ | 91 | /* "Driverless" devices that need ejecting */ |
91 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, | 92 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, |
92 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, | 93 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, |
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 3c7a5053f1da..a07580138e81 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c | |||
@@ -109,7 +109,7 @@ static int gx_fix; | |||
109 | /* These identify the driver base version and may not be removed. */ | 109 | /* These identify the driver base version and may not be removed. */ |
110 | static const char version[] __devinitconst = | 110 | static const char version[] __devinitconst = |
111 | KERN_INFO DRV_NAME ".c:v1.05 1/09/2001 Written by Donald Becker <becker@scyld.com>\n" | 111 | KERN_INFO DRV_NAME ".c:v1.05 1/09/2001 Written by Donald Becker <becker@scyld.com>\n" |
112 | KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n"; | 112 | " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n"; |
113 | 113 | ||
114 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); | 114 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); |
115 | MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver"); | 115 | MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver"); |
@@ -700,12 +700,15 @@ static void yellowfin_tx_timeout(struct net_device *dev) | |||
700 | int i; | 700 | int i; |
701 | printk(KERN_WARNING " Rx ring %p: ", yp->rx_ring); | 701 | printk(KERN_WARNING " Rx ring %p: ", yp->rx_ring); |
702 | for (i = 0; i < RX_RING_SIZE; i++) | 702 | for (i = 0; i < RX_RING_SIZE; i++) |
703 | printk(" %8.8x", yp->rx_ring[i].result_status); | 703 | printk(KERN_CONT " %8.8x", |
704 | printk("\n"KERN_WARNING" Tx ring %p: ", yp->tx_ring); | 704 | yp->rx_ring[i].result_status); |
705 | printk(KERN_CONT "\n"); | ||
706 | printk(KERN_WARNING" Tx ring %p: ", yp->tx_ring); | ||
705 | for (i = 0; i < TX_RING_SIZE; i++) | 707 | for (i = 0; i < TX_RING_SIZE; i++) |
706 | printk(" %4.4x /%8.8x", yp->tx_status[i].tx_errs, | 708 | printk(KERN_CONT " %4.4x /%8.8x", |
707 | yp->tx_ring[i].result_status); | 709 | yp->tx_status[i].tx_errs, |
708 | printk("\n"); | 710 | yp->tx_ring[i].result_status); |
711 | printk(KERN_CONT "\n"); | ||
709 | } | 712 | } |
710 | 713 | ||
711 | /* If the hardware is found to hang regularly, we will update the code | 714 | /* If the hardware is found to hang regularly, we will update the code |
@@ -1216,20 +1219,20 @@ static int yellowfin_close(struct net_device *dev) | |||
1216 | 1219 | ||
1217 | #if defined(__i386__) | 1220 | #if defined(__i386__) |
1218 | if (yellowfin_debug > 2) { | 1221 | if (yellowfin_debug > 2) { |
1219 | printk("\n"KERN_DEBUG" Tx ring at %8.8llx:\n", | 1222 | printk(KERN_DEBUG" Tx ring at %8.8llx:\n", |
1220 | (unsigned long long)yp->tx_ring_dma); | 1223 | (unsigned long long)yp->tx_ring_dma); |
1221 | for (i = 0; i < TX_RING_SIZE*2; i++) | 1224 | for (i = 0; i < TX_RING_SIZE*2; i++) |
1222 | printk(" %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n", | 1225 | printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n", |
1223 | ioread32(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ', | 1226 | ioread32(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ', |
1224 | i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr, | 1227 | i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr, |
1225 | yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status); | 1228 | yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status); |
1226 | printk(KERN_DEBUG " Tx status %p:\n", yp->tx_status); | 1229 | printk(KERN_DEBUG " Tx status %p:\n", yp->tx_status); |
1227 | for (i = 0; i < TX_RING_SIZE; i++) | 1230 | for (i = 0; i < TX_RING_SIZE; i++) |
1228 | printk(" #%d status %4.4x %4.4x %4.4x %4.4x.\n", | 1231 | printk(KERN_DEBUG " #%d status %4.4x %4.4x %4.4x %4.4x.\n", |
1229 | i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs, | 1232 | i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs, |
1230 | yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused); | 1233 | yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused); |
1231 | 1234 | ||
1232 | printk("\n"KERN_DEBUG " Rx ring %8.8llx:\n", | 1235 | printk(KERN_DEBUG " Rx ring %8.8llx:\n", |
1233 | (unsigned long long)yp->rx_ring_dma); | 1236 | (unsigned long long)yp->rx_ring_dma); |
1234 | for (i = 0; i < RX_RING_SIZE; i++) { | 1237 | for (i = 0; i < RX_RING_SIZE; i++) { |
1235 | printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n", | 1238 | printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n", |
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c index e1f6ce03705e..3c2270a8300c 100644 --- a/drivers/oprofile/oprofile_stats.c +++ b/drivers/oprofile/oprofile_stats.c | |||
@@ -33,6 +33,7 @@ void oprofile_reset_stats(void) | |||
33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); | 33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); |
34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); | 34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); |
35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); | 35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); |
36 | atomic_set(&oprofile_stats.bt_lost_no_mapping, 0); | ||
36 | } | 37 | } |
37 | 38 | ||
38 | 39 | ||
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 5d610cbcfe80..0f0e0b919ef4 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
@@ -1134,7 +1134,7 @@ static const struct file_operations ccio_proc_bitmap_fops = { | |||
1134 | .llseek = seq_lseek, | 1134 | .llseek = seq_lseek, |
1135 | .release = single_release, | 1135 | .release = single_release, |
1136 | }; | 1136 | }; |
1137 | #endif | 1137 | #endif /* CONFIG_PROC_FS */ |
1138 | 1138 | ||
1139 | /** | 1139 | /** |
1140 | * ccio_find_ioc - Find the ioc in the ioc_list | 1140 | * ccio_find_ioc - Find the ioc in the ioc_list |
@@ -1568,14 +1568,15 @@ static int __init ccio_probe(struct parisc_device *dev) | |||
1568 | /* if this fails, no I/O cards will work, so may as well bug */ | 1568 | /* if this fails, no I/O cards will work, so may as well bug */ |
1569 | BUG_ON(dev->dev.platform_data == NULL); | 1569 | BUG_ON(dev->dev.platform_data == NULL); |
1570 | HBA_DATA(dev->dev.platform_data)->iommu = ioc; | 1570 | HBA_DATA(dev->dev.platform_data)->iommu = ioc; |
1571 | 1571 | ||
1572 | #ifdef CONFIG_PROC_FS | ||
1572 | if (ioc_count == 0) { | 1573 | if (ioc_count == 0) { |
1573 | proc_create(MODULE_NAME, 0, proc_runway_root, | 1574 | proc_create(MODULE_NAME, 0, proc_runway_root, |
1574 | &ccio_proc_info_fops); | 1575 | &ccio_proc_info_fops); |
1575 | proc_create(MODULE_NAME"-bitmap", 0, proc_runway_root, | 1576 | proc_create(MODULE_NAME"-bitmap", 0, proc_runway_root, |
1576 | &ccio_proc_bitmap_fops); | 1577 | &ccio_proc_bitmap_fops); |
1577 | } | 1578 | } |
1578 | 1579 | #endif | |
1579 | ioc_count++; | 1580 | ioc_count++; |
1580 | 1581 | ||
1581 | parisc_has_iommu(); | 1582 | parisc_has_iommu(); |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 52ae0b1d470c..c590974e9815 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -353,7 +353,7 @@ static unsigned int dino_startup_irq(unsigned int irq) | |||
353 | return 0; | 353 | return 0; |
354 | } | 354 | } |
355 | 355 | ||
356 | static struct hw_interrupt_type dino_interrupt_type = { | 356 | static struct irq_chip dino_interrupt_type = { |
357 | .typename = "GSC-PCI", | 357 | .typename = "GSC-PCI", |
358 | .startup = dino_startup_irq, | 358 | .startup = dino_startup_irq, |
359 | .shutdown = dino_disable_irq, | 359 | .shutdown = dino_disable_irq, |
@@ -1019,22 +1019,22 @@ static int __init dino_probe(struct parisc_device *dev) | |||
1019 | ** It's not used to avoid chicken/egg problems | 1019 | ** It's not used to avoid chicken/egg problems |
1020 | ** with configuration accessor functions. | 1020 | ** with configuration accessor functions. |
1021 | */ | 1021 | */ |
1022 | bus = pci_scan_bus_parented(&dev->dev, dino_current_bus, | 1022 | dino_dev->hba.hba_bus = bus = pci_scan_bus_parented(&dev->dev, |
1023 | &dino_cfg_ops, NULL); | 1023 | dino_current_bus, &dino_cfg_ops, NULL); |
1024 | |||
1024 | if(bus) { | 1025 | if(bus) { |
1025 | pci_bus_add_devices(bus); | ||
1026 | /* This code *depends* on scanning being single threaded | 1026 | /* This code *depends* on scanning being single threaded |
1027 | * if it isn't, this global bus number count will fail | 1027 | * if it isn't, this global bus number count will fail |
1028 | */ | 1028 | */ |
1029 | dino_current_bus = bus->subordinate + 1; | 1029 | dino_current_bus = bus->subordinate + 1; |
1030 | pci_bus_assign_resources(bus); | 1030 | pci_bus_assign_resources(bus); |
1031 | pci_bus_add_devices(bus); | ||
1031 | } else { | 1032 | } else { |
1032 | printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", | 1033 | printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n", |
1033 | dev_name(&dev->dev), dino_current_bus); | 1034 | dev_name(&dev->dev), dino_current_bus); |
1034 | /* increment the bus number in case of duplicates */ | 1035 | /* increment the bus number in case of duplicates */ |
1035 | dino_current_bus++; | 1036 | dino_current_bus++; |
1036 | } | 1037 | } |
1037 | dino_dev->hba.hba_bus = bus; | ||
1038 | return 0; | 1038 | return 0; |
1039 | } | 1039 | } |
1040 | 1040 | ||
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 5b89f404e668..51220749cb65 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c | |||
@@ -188,7 +188,7 @@ static unsigned int eisa_startup_irq(unsigned int irq) | |||
188 | return 0; | 188 | return 0; |
189 | } | 189 | } |
190 | 190 | ||
191 | static struct hw_interrupt_type eisa_interrupt_type = { | 191 | static struct irq_chip eisa_interrupt_type = { |
192 | .typename = "EISA", | 192 | .typename = "EISA", |
193 | .startup = eisa_startup_irq, | 193 | .startup = eisa_startup_irq, |
194 | .shutdown = eisa_disable_irq, | 194 | .shutdown = eisa_disable_irq, |
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c index c709ecc2b7f7..0be1d50645ab 100644 --- a/drivers/parisc/eisa_enumerator.c +++ b/drivers/parisc/eisa_enumerator.c | |||
@@ -101,7 +101,7 @@ static int configure_memory(const unsigned char *buf, | |||
101 | printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end); | 101 | printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end); |
102 | result = request_resource(mem_parent, res); | 102 | result = request_resource(mem_parent, res); |
103 | if (result < 0) { | 103 | if (result < 0) { |
104 | printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n"); | 104 | printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n"); |
105 | return result; | 105 | return result; |
106 | } | 106 | } |
107 | } | 107 | } |
@@ -191,7 +191,7 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent, | |||
191 | printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end); | 191 | printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end); |
192 | result = request_resource(io_parent, res); | 192 | result = request_resource(io_parent, res); |
193 | if (result < 0) { | 193 | if (result < 0) { |
194 | printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n"); | 194 | printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n"); |
195 | return result; | 195 | return result; |
196 | } | 196 | } |
197 | } | 197 | } |
@@ -224,7 +224,7 @@ static int configure_port_init(const unsigned char *buf) | |||
224 | case HPEE_PORT_INIT_WIDTH_BYTE: | 224 | case HPEE_PORT_INIT_WIDTH_BYTE: |
225 | s=1; | 225 | s=1; |
226 | if (c & HPEE_PORT_INIT_MASK) { | 226 | if (c & HPEE_PORT_INIT_MASK) { |
227 | printk("\n" KERN_WARNING "port_init: unverified mask attribute\n"); | 227 | printk(KERN_WARNING "port_init: unverified mask attribute\n"); |
228 | outb((inb(get_16(buf+len+1) & | 228 | outb((inb(get_16(buf+len+1) & |
229 | get_8(buf+len+3)) | | 229 | get_8(buf+len+3)) | |
230 | get_8(buf+len+4)), get_16(buf+len+1)); | 230 | get_8(buf+len+4)), get_16(buf+len+1)); |
@@ -249,7 +249,7 @@ static int configure_port_init(const unsigned char *buf) | |||
249 | case HPEE_PORT_INIT_WIDTH_DWORD: | 249 | case HPEE_PORT_INIT_WIDTH_DWORD: |
250 | s=4; | 250 | s=4; |
251 | if (c & HPEE_PORT_INIT_MASK) { | 251 | if (c & HPEE_PORT_INIT_MASK) { |
252 | printk("\n" KERN_WARNING "port_init: unverified mask attribute\n"); | 252 | printk(KERN_WARNING "port_init: unverified mask attribute\n"); |
253 | outl((inl(get_16(buf+len+1) & | 253 | outl((inl(get_16(buf+len+1) & |
254 | get_32(buf+len+3)) | | 254 | get_32(buf+len+3)) | |
255 | get_32(buf+len+7)), get_16(buf+len+1)); | 255 | get_32(buf+len+7)), get_16(buf+len+1)); |
@@ -259,7 +259,7 @@ static int configure_port_init(const unsigned char *buf) | |||
259 | 259 | ||
260 | break; | 260 | break; |
261 | default: | 261 | default: |
262 | printk("\n" KERN_ERR "Invalid port init word %02x\n", c); | 262 | printk(KERN_ERR "Invalid port init word %02x\n", c); |
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | 265 | ||
@@ -297,7 +297,7 @@ static int configure_type_string(const unsigned char *buf) | |||
297 | /* just skip past the type field */ | 297 | /* just skip past the type field */ |
298 | len = get_8(buf); | 298 | len = get_8(buf); |
299 | if (len > 80) { | 299 | if (len > 80) { |
300 | printk("\n" KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len); | 300 | printk(KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len); |
301 | } | 301 | } |
302 | 302 | ||
303 | return 1+len; | 303 | return 1+len; |
@@ -398,7 +398,7 @@ static int parse_slot_config(int slot, | |||
398 | } | 398 | } |
399 | 399 | ||
400 | if (p0 + function_len < pos) { | 400 | if (p0 + function_len < pos) { |
401 | printk("\n" KERN_ERR "eisa_enumerator: function %d length mis-match " | 401 | printk(KERN_ERR "eisa_enumerator: function %d length mis-match " |
402 | "got %d, expected %d\n", | 402 | "got %d, expected %d\n", |
403 | num_func, pos-p0, function_len); | 403 | num_func, pos-p0, function_len); |
404 | res=-1; | 404 | res=-1; |
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index d33632917696..647adc9f85ad 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c | |||
@@ -148,7 +148,7 @@ static unsigned int gsc_asic_startup_irq(unsigned int irq) | |||
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | 150 | ||
151 | static struct hw_interrupt_type gsc_asic_interrupt_type = { | 151 | static struct irq_chip gsc_asic_interrupt_type = { |
152 | .typename = "GSC-ASIC", | 152 | .typename = "GSC-ASIC", |
153 | .startup = gsc_asic_startup_irq, | 153 | .startup = gsc_asic_startup_irq, |
154 | .shutdown = gsc_asic_disable_irq, | 154 | .shutdown = gsc_asic_disable_irq, |
@@ -158,7 +158,7 @@ static struct hw_interrupt_type gsc_asic_interrupt_type = { | |||
158 | .end = no_end_irq, | 158 | .end = no_end_irq, |
159 | }; | 159 | }; |
160 | 160 | ||
161 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data) | 161 | int gsc_assign_irq(struct irq_chip *type, void *data) |
162 | { | 162 | { |
163 | static int irq = GSC_IRQ_BASE; | 163 | static int irq = GSC_IRQ_BASE; |
164 | struct irq_desc *desc; | 164 | struct irq_desc *desc; |
diff --git a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h index 762a1babad60..b9d7bfb68e24 100644 --- a/drivers/parisc/gsc.h +++ b/drivers/parisc/gsc.h | |||
@@ -38,7 +38,7 @@ struct gsc_asic { | |||
38 | int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic); | 38 | int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic); |
39 | int gsc_alloc_irq(struct gsc_irq *dev); /* dev needs an irq */ | 39 | int gsc_alloc_irq(struct gsc_irq *dev); /* dev needs an irq */ |
40 | int gsc_claim_irq(struct gsc_irq *dev, int irq); /* dev needs this irq */ | 40 | int gsc_claim_irq(struct gsc_irq *dev, int irq); /* dev needs this irq */ |
41 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data); | 41 | int gsc_assign_irq(struct irq_chip *type, void *data); |
42 | int gsc_find_local_irq(unsigned int irq, int *global_irq, int limit); | 42 | int gsc_find_local_irq(unsigned int irq, int *global_irq, int limit); |
43 | void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, | 43 | void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, |
44 | void (*choose)(struct parisc_device *child, void *ctrl)); | 44 | void (*choose)(struct parisc_device *child, void *ctrl)); |
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 4a9cc92d4d18..88e333553212 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -729,7 +729,7 @@ static int iosapic_set_affinity_irq(unsigned int irq, | |||
729 | } | 729 | } |
730 | #endif | 730 | #endif |
731 | 731 | ||
732 | static struct hw_interrupt_type iosapic_interrupt_type = { | 732 | static struct irq_chip iosapic_interrupt_type = { |
733 | .typename = "IO-SAPIC-level", | 733 | .typename = "IO-SAPIC-level", |
734 | .startup = iosapic_startup_irq, | 734 | .startup = iosapic_startup_irq, |
735 | .shutdown = iosapic_disable_irq, | 735 | .shutdown = iosapic_disable_irq, |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 59fbbf128365..ede614616f8e 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -980,28 +980,38 @@ static void | |||
980 | lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) | 980 | lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) |
981 | { | 981 | { |
982 | unsigned long bytecnt; | 982 | unsigned long bytecnt; |
983 | pdc_pat_cell_mod_maddr_block_t pa_pdc_cell; /* PA_VIEW */ | ||
984 | pdc_pat_cell_mod_maddr_block_t io_pdc_cell; /* IO_VIEW */ | ||
985 | long io_count; | 983 | long io_count; |
986 | long status; /* PDC return status */ | 984 | long status; /* PDC return status */ |
987 | long pa_count; | 985 | long pa_count; |
986 | pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; /* PA_VIEW */ | ||
987 | pdc_pat_cell_mod_maddr_block_t *io_pdc_cell; /* IO_VIEW */ | ||
988 | int i; | 988 | int i; |
989 | 989 | ||
990 | pa_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL); | ||
991 | if (!pa_pdc_cell) | ||
992 | return; | ||
993 | |||
994 | io_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL); | ||
995 | if (!pa_pdc_cell) { | ||
996 | kfree(pa_pdc_cell); | ||
997 | return; | ||
998 | } | ||
999 | |||
990 | /* return cell module (IO view) */ | 1000 | /* return cell module (IO view) */ |
991 | status = pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index, | 1001 | status = pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index, |
992 | PA_VIEW, & pa_pdc_cell); | 1002 | PA_VIEW, pa_pdc_cell); |
993 | pa_count = pa_pdc_cell.mod[1]; | 1003 | pa_count = pa_pdc_cell->mod[1]; |
994 | 1004 | ||
995 | status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index, | 1005 | status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index, |
996 | IO_VIEW, &io_pdc_cell); | 1006 | IO_VIEW, io_pdc_cell); |
997 | io_count = io_pdc_cell.mod[1]; | 1007 | io_count = io_pdc_cell->mod[1]; |
998 | 1008 | ||
999 | /* We've already done this once for device discovery...*/ | 1009 | /* We've already done this once for device discovery...*/ |
1000 | if (status != PDC_OK) { | 1010 | if (status != PDC_OK) { |
1001 | panic("pdc_pat_cell_module() call failed for LBA!\n"); | 1011 | panic("pdc_pat_cell_module() call failed for LBA!\n"); |
1002 | } | 1012 | } |
1003 | 1013 | ||
1004 | if (PAT_GET_ENTITY(pa_pdc_cell.mod_info) != PAT_ENTITY_LBA) { | 1014 | if (PAT_GET_ENTITY(pa_pdc_cell->mod_info) != PAT_ENTITY_LBA) { |
1005 | panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n"); | 1015 | panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n"); |
1006 | } | 1016 | } |
1007 | 1017 | ||
@@ -1016,8 +1026,8 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) | |||
1016 | } *p, *io; | 1026 | } *p, *io; |
1017 | struct resource *r; | 1027 | struct resource *r; |
1018 | 1028 | ||
1019 | p = (void *) &(pa_pdc_cell.mod[2+i*3]); | 1029 | p = (void *) &(pa_pdc_cell->mod[2+i*3]); |
1020 | io = (void *) &(io_pdc_cell.mod[2+i*3]); | 1030 | io = (void *) &(io_pdc_cell->mod[2+i*3]); |
1021 | 1031 | ||
1022 | /* Convert the PAT range data to PCI "struct resource" */ | 1032 | /* Convert the PAT range data to PCI "struct resource" */ |
1023 | switch(p->type & 0xff) { | 1033 | switch(p->type & 0xff) { |
@@ -1096,6 +1106,9 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) | |||
1096 | break; | 1106 | break; |
1097 | } | 1107 | } |
1098 | } | 1108 | } |
1109 | |||
1110 | kfree(pa_pdc_cell); | ||
1111 | kfree(io_pdc_cell); | ||
1099 | } | 1112 | } |
1100 | #else | 1113 | #else |
1101 | /* keep compiler from complaining about missing declarations */ | 1114 | /* keep compiler from complaining about missing declarations */ |
@@ -1509,10 +1522,6 @@ lba_driver_probe(struct parisc_device *dev) | |||
1509 | lba_bus = lba_dev->hba.hba_bus = | 1522 | lba_bus = lba_dev->hba.hba_bus = |
1510 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, | 1523 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, |
1511 | cfg_ops, NULL); | 1524 | cfg_ops, NULL); |
1512 | if (lba_bus) { | ||
1513 | lba_next_bus = lba_bus->subordinate + 1; | ||
1514 | pci_bus_add_devices(lba_bus); | ||
1515 | } | ||
1516 | 1525 | ||
1517 | /* This is in lieu of calling pci_assign_unassigned_resources() */ | 1526 | /* This is in lieu of calling pci_assign_unassigned_resources() */ |
1518 | if (is_pdc_pat()) { | 1527 | if (is_pdc_pat()) { |
@@ -1533,7 +1542,6 @@ lba_driver_probe(struct parisc_device *dev) | |||
1533 | } | 1542 | } |
1534 | pci_enable_bridges(lba_bus); | 1543 | pci_enable_bridges(lba_bus); |
1535 | 1544 | ||
1536 | |||
1537 | /* | 1545 | /* |
1538 | ** Once PCI register ops has walked the bus, access to config | 1546 | ** Once PCI register ops has walked the bus, access to config |
1539 | ** space is restricted. Avoids master aborts on config cycles. | 1547 | ** space is restricted. Avoids master aborts on config cycles. |
@@ -1543,6 +1551,11 @@ lba_driver_probe(struct parisc_device *dev) | |||
1543 | lba_dev->flags |= LBA_FLAG_SKIP_PROBE; | 1551 | lba_dev->flags |= LBA_FLAG_SKIP_PROBE; |
1544 | } | 1552 | } |
1545 | 1553 | ||
1554 | if (lba_bus) { | ||
1555 | lba_next_bus = lba_bus->subordinate + 1; | ||
1556 | pci_bus_add_devices(lba_bus); | ||
1557 | } | ||
1558 | |||
1546 | /* Whew! Finally done! Tell services we got this one covered. */ | 1559 | /* Whew! Finally done! Tell services we got this one covered. */ |
1547 | return 0; | 1560 | return 0; |
1548 | } | 1561 | } |
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index d46dd57450ac..123d8fe3427d 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -2057,6 +2057,7 @@ void sba_directed_lmmio(struct parisc_device *pci_hba, struct resource *r) | |||
2057 | r->start = (base & ~1UL) | PCI_F_EXTEND; | 2057 | r->start = (base & ~1UL) | PCI_F_EXTEND; |
2058 | size = ~ READ_REG32(reg + LMMIO_DIRECT0_MASK); | 2058 | size = ~ READ_REG32(reg + LMMIO_DIRECT0_MASK); |
2059 | r->end = r->start + size; | 2059 | r->end = r->start + size; |
2060 | r->flags = IORESOURCE_MEM; | ||
2060 | } | 2061 | } |
2061 | } | 2062 | } |
2062 | 2063 | ||
@@ -2093,4 +2094,5 @@ void sba_distributed_lmmio(struct parisc_device *pci_hba, struct resource *r ) | |||
2093 | size = (~READ_REG32(sba->sba_hpa + LMMIO_DIST_MASK)) / ROPES_PER_IOC; | 2094 | size = (~READ_REG32(sba->sba_hpa + LMMIO_DIST_MASK)) / ROPES_PER_IOC; |
2094 | r->start += rope * (size + 1); /* adjust base for this rope */ | 2095 | r->start += rope * (size + 1); /* adjust base for this rope */ |
2095 | r->end = r->start + size; | 2096 | r->end = r->start + size; |
2097 | r->flags = IORESOURCE_MEM; | ||
2096 | } | 2098 | } |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 33e5ade774ca..675f04e6597a 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -325,7 +325,7 @@ static unsigned int superio_startup_irq(unsigned int irq) | |||
325 | return 0; | 325 | return 0; |
326 | } | 326 | } |
327 | 327 | ||
328 | static struct hw_interrupt_type superio_interrupt_type = { | 328 | static struct irq_chip superio_interrupt_type = { |
329 | .typename = SUPERIO, | 329 | .typename = SUPERIO, |
330 | .startup = superio_startup_irq, | 330 | .startup = superio_startup_irq, |
331 | .shutdown = superio_disable_irq, | 331 | .shutdown = superio_disable_irq, |
@@ -434,8 +434,8 @@ static void __init superio_parport_init(void) | |||
434 | 0 /*base_hi*/, | 434 | 0 /*base_hi*/, |
435 | PAR_IRQ, | 435 | PAR_IRQ, |
436 | PARPORT_DMA_NONE /* dma */, | 436 | PARPORT_DMA_NONE /* dma */, |
437 | NULL /*struct pci_dev* */), | 437 | NULL /*struct pci_dev* */, |
438 | 0 /* shared irq flags */ ) | 438 | 0 /* shared irq flags */)) |
439 | 439 | ||
440 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); | 440 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); |
441 | #endif /* CONFIG_PARPORT_PC */ | 441 | #endif /* CONFIG_PARPORT_PC */ |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 1032d5fdbd42..2597145a066e 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -2907,6 +2907,7 @@ enum parport_pc_pci_cards { | |||
2907 | netmos_9755, | 2907 | netmos_9755, |
2908 | netmos_9805, | 2908 | netmos_9805, |
2909 | netmos_9815, | 2909 | netmos_9815, |
2910 | netmos_9901, | ||
2910 | quatech_sppxp100, | 2911 | quatech_sppxp100, |
2911 | }; | 2912 | }; |
2912 | 2913 | ||
@@ -2987,7 +2988,7 @@ static struct parport_pc_pci { | |||
2987 | /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, | 2988 | /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, |
2988 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, | 2989 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, |
2989 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, | 2990 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, |
2990 | 2991 | /* netmos_9901 */ { 1, { { 0, -1 }, } }, | |
2991 | /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, | 2992 | /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, |
2992 | }; | 2993 | }; |
2993 | 2994 | ||
@@ -3089,6 +3090,8 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { | |||
3089 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, | 3090 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, |
3090 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, | 3091 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, |
3091 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, | 3092 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, |
3093 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, | ||
3094 | 0xA000, 0x2000, 0, 0, netmos_9901 }, | ||
3092 | /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ | 3095 | /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ |
3093 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, | 3096 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, |
3094 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, | 3097 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 844580489d4d..5c5043f239cf 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -555,6 +555,8 @@ static struct hotplug_slot *get_slot_from_name (const char *name) | |||
555 | * @slot: pointer to the &struct hotplug_slot to register | 555 | * @slot: pointer to the &struct hotplug_slot to register |
556 | * @devnr: device number | 556 | * @devnr: device number |
557 | * @name: name registered with kobject core | 557 | * @name: name registered with kobject core |
558 | * @owner: caller module owner | ||
559 | * @mod_name: caller module name | ||
558 | * | 560 | * |
559 | * Registers a hotplug slot with the pci hotplug subsystem, which will allow | 561 | * Registers a hotplug slot with the pci hotplug subsystem, which will allow |
560 | * userspace interaction to the slot. | 562 | * userspace interaction to the slot. |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index e53eacd75c8d..ebc9b8dca881 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/sysdev.h> | 39 | #include <linux/sysdev.h> |
40 | #include <asm/cacheflush.h> | 40 | #include <asm/cacheflush.h> |
41 | #include <asm/iommu.h> | 41 | #include <asm/iommu.h> |
42 | #include <asm/e820.h> | ||
43 | #include "pci.h" | 42 | #include "pci.h" |
44 | 43 | ||
45 | #define ROOT_SIZE VTD_PAGE_SIZE | 44 | #define ROOT_SIZE VTD_PAGE_SIZE |
@@ -57,14 +56,32 @@ | |||
57 | #define MAX_AGAW_WIDTH 64 | 56 | #define MAX_AGAW_WIDTH 64 |
58 | 57 | ||
59 | #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) | 58 | #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) |
59 | #define DOMAIN_MAX_PFN(gaw) ((((u64)1) << (gaw-VTD_PAGE_SHIFT)) - 1) | ||
60 | 60 | ||
61 | #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) | 61 | #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) |
62 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) | 62 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) |
63 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) | 63 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) |
64 | 64 | ||
65 | #ifndef PHYSICAL_PAGE_MASK | 65 | |
66 | #define PHYSICAL_PAGE_MASK PAGE_MASK | 66 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things |
67 | #endif | 67 | are never going to work. */ |
68 | static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn) | ||
69 | { | ||
70 | return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT); | ||
71 | } | ||
72 | |||
73 | static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn) | ||
74 | { | ||
75 | return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT); | ||
76 | } | ||
77 | static inline unsigned long page_to_dma_pfn(struct page *pg) | ||
78 | { | ||
79 | return mm_to_dma_pfn(page_to_pfn(pg)); | ||
80 | } | ||
81 | static inline unsigned long virt_to_dma_pfn(void *p) | ||
82 | { | ||
83 | return page_to_dma_pfn(virt_to_page(p)); | ||
84 | } | ||
68 | 85 | ||
69 | /* global iommu list, set NULL for ignored DMAR units */ | 86 | /* global iommu list, set NULL for ignored DMAR units */ |
70 | static struct intel_iommu **g_iommus; | 87 | static struct intel_iommu **g_iommus; |
@@ -205,12 +222,17 @@ static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) | |||
205 | 222 | ||
206 | static inline u64 dma_pte_addr(struct dma_pte *pte) | 223 | static inline u64 dma_pte_addr(struct dma_pte *pte) |
207 | { | 224 | { |
208 | return (pte->val & VTD_PAGE_MASK); | 225 | #ifdef CONFIG_64BIT |
226 | return pte->val & VTD_PAGE_MASK; | ||
227 | #else | ||
228 | /* Must have a full atomic 64-bit read */ | ||
229 | return __cmpxchg64(pte, 0ULL, 0ULL) & VTD_PAGE_MASK; | ||
230 | #endif | ||
209 | } | 231 | } |
210 | 232 | ||
211 | static inline void dma_set_pte_addr(struct dma_pte *pte, u64 addr) | 233 | static inline void dma_set_pte_pfn(struct dma_pte *pte, unsigned long pfn) |
212 | { | 234 | { |
213 | pte->val |= (addr & VTD_PAGE_MASK); | 235 | pte->val |= (uint64_t)pfn << VTD_PAGE_SHIFT; |
214 | } | 236 | } |
215 | 237 | ||
216 | static inline bool dma_pte_present(struct dma_pte *pte) | 238 | static inline bool dma_pte_present(struct dma_pte *pte) |
@@ -218,6 +240,11 @@ static inline bool dma_pte_present(struct dma_pte *pte) | |||
218 | return (pte->val & 3) != 0; | 240 | return (pte->val & 3) != 0; |
219 | } | 241 | } |
220 | 242 | ||
243 | static inline int first_pte_in_page(struct dma_pte *pte) | ||
244 | { | ||
245 | return !((unsigned long)pte & ~VTD_PAGE_MASK); | ||
246 | } | ||
247 | |||
221 | /* | 248 | /* |
222 | * This domain is a statically identity mapping domain. | 249 | * This domain is a statically identity mapping domain. |
223 | * 1. This domain creats a static 1:1 mapping to all usable memory. | 250 | * 1. This domain creats a static 1:1 mapping to all usable memory. |
@@ -245,7 +272,6 @@ struct dmar_domain { | |||
245 | struct iova_domain iovad; /* iova's that belong to this domain */ | 272 | struct iova_domain iovad; /* iova's that belong to this domain */ |
246 | 273 | ||
247 | struct dma_pte *pgd; /* virtual address */ | 274 | struct dma_pte *pgd; /* virtual address */ |
248 | spinlock_t mapping_lock; /* page table lock */ | ||
249 | int gaw; /* max guest address width */ | 275 | int gaw; /* max guest address width */ |
250 | 276 | ||
251 | /* adjusted guest address width, 0 is level 2 30-bit */ | 277 | /* adjusted guest address width, 0 is level 2 30-bit */ |
@@ -649,80 +675,78 @@ static inline int width_to_agaw(int width) | |||
649 | 675 | ||
650 | static inline unsigned int level_to_offset_bits(int level) | 676 | static inline unsigned int level_to_offset_bits(int level) |
651 | { | 677 | { |
652 | return (12 + (level - 1) * LEVEL_STRIDE); | 678 | return (level - 1) * LEVEL_STRIDE; |
653 | } | 679 | } |
654 | 680 | ||
655 | static inline int address_level_offset(u64 addr, int level) | 681 | static inline int pfn_level_offset(unsigned long pfn, int level) |
656 | { | 682 | { |
657 | return ((addr >> level_to_offset_bits(level)) & LEVEL_MASK); | 683 | return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; |
658 | } | 684 | } |
659 | 685 | ||
660 | static inline u64 level_mask(int level) | 686 | static inline unsigned long level_mask(int level) |
661 | { | 687 | { |
662 | return ((u64)-1 << level_to_offset_bits(level)); | 688 | return -1UL << level_to_offset_bits(level); |
663 | } | 689 | } |
664 | 690 | ||
665 | static inline u64 level_size(int level) | 691 | static inline unsigned long level_size(int level) |
666 | { | 692 | { |
667 | return ((u64)1 << level_to_offset_bits(level)); | 693 | return 1UL << level_to_offset_bits(level); |
668 | } | 694 | } |
669 | 695 | ||
670 | static inline u64 align_to_level(u64 addr, int level) | 696 | static inline unsigned long align_to_level(unsigned long pfn, int level) |
671 | { | 697 | { |
672 | return ((addr + level_size(level) - 1) & level_mask(level)); | 698 | return (pfn + level_size(level) - 1) & level_mask(level); |
673 | } | 699 | } |
674 | 700 | ||
675 | static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr) | 701 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, |
702 | unsigned long pfn) | ||
676 | { | 703 | { |
677 | int addr_width = agaw_to_width(domain->agaw); | 704 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
678 | struct dma_pte *parent, *pte = NULL; | 705 | struct dma_pte *parent, *pte = NULL; |
679 | int level = agaw_to_level(domain->agaw); | 706 | int level = agaw_to_level(domain->agaw); |
680 | int offset; | 707 | int offset; |
681 | unsigned long flags; | ||
682 | 708 | ||
683 | BUG_ON(!domain->pgd); | 709 | BUG_ON(!domain->pgd); |
684 | 710 | BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); | |
685 | addr &= (((u64)1) << addr_width) - 1; | ||
686 | parent = domain->pgd; | 711 | parent = domain->pgd; |
687 | 712 | ||
688 | spin_lock_irqsave(&domain->mapping_lock, flags); | ||
689 | while (level > 0) { | 713 | while (level > 0) { |
690 | void *tmp_page; | 714 | void *tmp_page; |
691 | 715 | ||
692 | offset = address_level_offset(addr, level); | 716 | offset = pfn_level_offset(pfn, level); |
693 | pte = &parent[offset]; | 717 | pte = &parent[offset]; |
694 | if (level == 1) | 718 | if (level == 1) |
695 | break; | 719 | break; |
696 | 720 | ||
697 | if (!dma_pte_present(pte)) { | 721 | if (!dma_pte_present(pte)) { |
722 | uint64_t pteval; | ||
723 | |||
698 | tmp_page = alloc_pgtable_page(); | 724 | tmp_page = alloc_pgtable_page(); |
699 | 725 | ||
700 | if (!tmp_page) { | 726 | if (!tmp_page) |
701 | spin_unlock_irqrestore(&domain->mapping_lock, | ||
702 | flags); | ||
703 | return NULL; | 727 | return NULL; |
728 | |||
729 | domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE); | ||
730 | pteval = (virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE; | ||
731 | if (cmpxchg64(&pte->val, 0ULL, pteval)) { | ||
732 | /* Someone else set it while we were thinking; use theirs. */ | ||
733 | free_pgtable_page(tmp_page); | ||
734 | } else { | ||
735 | dma_pte_addr(pte); | ||
736 | domain_flush_cache(domain, pte, sizeof(*pte)); | ||
704 | } | 737 | } |
705 | domain_flush_cache(domain, tmp_page, PAGE_SIZE); | ||
706 | dma_set_pte_addr(pte, virt_to_phys(tmp_page)); | ||
707 | /* | ||
708 | * high level table always sets r/w, last level page | ||
709 | * table control read/write | ||
710 | */ | ||
711 | dma_set_pte_readable(pte); | ||
712 | dma_set_pte_writable(pte); | ||
713 | domain_flush_cache(domain, pte, sizeof(*pte)); | ||
714 | } | 738 | } |
715 | parent = phys_to_virt(dma_pte_addr(pte)); | 739 | parent = phys_to_virt(dma_pte_addr(pte)); |
716 | level--; | 740 | level--; |
717 | } | 741 | } |
718 | 742 | ||
719 | spin_unlock_irqrestore(&domain->mapping_lock, flags); | ||
720 | return pte; | 743 | return pte; |
721 | } | 744 | } |
722 | 745 | ||
723 | /* return address's pte at specific level */ | 746 | /* return address's pte at specific level */ |
724 | static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr, | 747 | static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, |
725 | int level) | 748 | unsigned long pfn, |
749 | int level) | ||
726 | { | 750 | { |
727 | struct dma_pte *parent, *pte = NULL; | 751 | struct dma_pte *parent, *pte = NULL; |
728 | int total = agaw_to_level(domain->agaw); | 752 | int total = agaw_to_level(domain->agaw); |
@@ -730,7 +754,7 @@ static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr, | |||
730 | 754 | ||
731 | parent = domain->pgd; | 755 | parent = domain->pgd; |
732 | while (level <= total) { | 756 | while (level <= total) { |
733 | offset = address_level_offset(addr, total); | 757 | offset = pfn_level_offset(pfn, total); |
734 | pte = &parent[offset]; | 758 | pte = &parent[offset]; |
735 | if (level == total) | 759 | if (level == total) |
736 | return pte; | 760 | return pte; |
@@ -743,74 +767,82 @@ static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr, | |||
743 | return NULL; | 767 | return NULL; |
744 | } | 768 | } |
745 | 769 | ||
746 | /* clear one page's page table */ | ||
747 | static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr) | ||
748 | { | ||
749 | struct dma_pte *pte = NULL; | ||
750 | |||
751 | /* get last level pte */ | ||
752 | pte = dma_addr_level_pte(domain, addr, 1); | ||
753 | |||
754 | if (pte) { | ||
755 | dma_clear_pte(pte); | ||
756 | domain_flush_cache(domain, pte, sizeof(*pte)); | ||
757 | } | ||
758 | } | ||
759 | |||
760 | /* clear last level pte, a tlb flush should be followed */ | 770 | /* clear last level pte, a tlb flush should be followed */ |
761 | static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end) | 771 | static void dma_pte_clear_range(struct dmar_domain *domain, |
772 | unsigned long start_pfn, | ||
773 | unsigned long last_pfn) | ||
762 | { | 774 | { |
763 | int addr_width = agaw_to_width(domain->agaw); | 775 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
764 | int npages; | 776 | struct dma_pte *first_pte, *pte; |
765 | 777 | ||
766 | start &= (((u64)1) << addr_width) - 1; | 778 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); |
767 | end &= (((u64)1) << addr_width) - 1; | 779 | BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); |
768 | /* in case it's partial page */ | ||
769 | start &= PAGE_MASK; | ||
770 | end = PAGE_ALIGN(end); | ||
771 | npages = (end - start) / VTD_PAGE_SIZE; | ||
772 | 780 | ||
773 | /* we don't need lock here, nobody else touches the iova range */ | 781 | /* we don't need lock here; nobody else touches the iova range */ |
774 | while (npages--) { | 782 | while (start_pfn <= last_pfn) { |
775 | dma_pte_clear_one(domain, start); | 783 | first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1); |
776 | start += VTD_PAGE_SIZE; | 784 | if (!pte) { |
785 | start_pfn = align_to_level(start_pfn + 1, 2); | ||
786 | continue; | ||
787 | } | ||
788 | do { | ||
789 | dma_clear_pte(pte); | ||
790 | start_pfn++; | ||
791 | pte++; | ||
792 | } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); | ||
793 | |||
794 | domain_flush_cache(domain, first_pte, | ||
795 | (void *)pte - (void *)first_pte); | ||
777 | } | 796 | } |
778 | } | 797 | } |
779 | 798 | ||
780 | /* free page table pages. last level pte should already be cleared */ | 799 | /* free page table pages. last level pte should already be cleared */ |
781 | static void dma_pte_free_pagetable(struct dmar_domain *domain, | 800 | static void dma_pte_free_pagetable(struct dmar_domain *domain, |
782 | u64 start, u64 end) | 801 | unsigned long start_pfn, |
802 | unsigned long last_pfn) | ||
783 | { | 803 | { |
784 | int addr_width = agaw_to_width(domain->agaw); | 804 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
785 | struct dma_pte *pte; | 805 | struct dma_pte *first_pte, *pte; |
786 | int total = agaw_to_level(domain->agaw); | 806 | int total = agaw_to_level(domain->agaw); |
787 | int level; | 807 | int level; |
788 | u64 tmp; | 808 | unsigned long tmp; |
789 | 809 | ||
790 | start &= (((u64)1) << addr_width) - 1; | 810 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); |
791 | end &= (((u64)1) << addr_width) - 1; | 811 | BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); |
792 | 812 | ||
793 | /* we don't need lock here, nobody else touches the iova range */ | 813 | /* We don't need lock here; nobody else touches the iova range */ |
794 | level = 2; | 814 | level = 2; |
795 | while (level <= total) { | 815 | while (level <= total) { |
796 | tmp = align_to_level(start, level); | 816 | tmp = align_to_level(start_pfn, level); |
797 | if (tmp >= end || (tmp + level_size(level) > end)) | 817 | |
818 | /* If we can't even clear one PTE at this level, we're done */ | ||
819 | if (tmp + level_size(level) - 1 > last_pfn) | ||
798 | return; | 820 | return; |
799 | 821 | ||
800 | while (tmp < end) { | 822 | while (tmp + level_size(level) - 1 <= last_pfn) { |
801 | pte = dma_addr_level_pte(domain, tmp, level); | 823 | first_pte = pte = dma_pfn_level_pte(domain, tmp, level); |
802 | if (pte) { | 824 | if (!pte) { |
803 | free_pgtable_page( | 825 | tmp = align_to_level(tmp + 1, level + 1); |
804 | phys_to_virt(dma_pte_addr(pte))); | 826 | continue; |
805 | dma_clear_pte(pte); | ||
806 | domain_flush_cache(domain, pte, sizeof(*pte)); | ||
807 | } | 827 | } |
808 | tmp += level_size(level); | 828 | do { |
829 | if (dma_pte_present(pte)) { | ||
830 | free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); | ||
831 | dma_clear_pte(pte); | ||
832 | } | ||
833 | pte++; | ||
834 | tmp += level_size(level); | ||
835 | } while (!first_pte_in_page(pte) && | ||
836 | tmp + level_size(level) - 1 <= last_pfn); | ||
837 | |||
838 | domain_flush_cache(domain, first_pte, | ||
839 | (void *)pte - (void *)first_pte); | ||
840 | |||
809 | } | 841 | } |
810 | level++; | 842 | level++; |
811 | } | 843 | } |
812 | /* free pgd */ | 844 | /* free pgd */ |
813 | if (start == 0 && end >= ((((u64)1) << addr_width) - 1)) { | 845 | if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) { |
814 | free_pgtable_page(domain->pgd); | 846 | free_pgtable_page(domain->pgd); |
815 | domain->pgd = NULL; | 847 | domain->pgd = NULL; |
816 | } | 848 | } |
@@ -1036,11 +1068,11 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain, | |||
1036 | } | 1068 | } |
1037 | 1069 | ||
1038 | static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, | 1070 | static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, |
1039 | u64 addr, unsigned int pages) | 1071 | unsigned long pfn, unsigned int pages) |
1040 | { | 1072 | { |
1041 | unsigned int mask = ilog2(__roundup_pow_of_two(pages)); | 1073 | unsigned int mask = ilog2(__roundup_pow_of_two(pages)); |
1074 | uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT; | ||
1042 | 1075 | ||
1043 | BUG_ON(addr & (~VTD_PAGE_MASK)); | ||
1044 | BUG_ON(pages == 0); | 1076 | BUG_ON(pages == 0); |
1045 | 1077 | ||
1046 | /* | 1078 | /* |
@@ -1055,7 +1087,12 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, | |||
1055 | else | 1087 | else |
1056 | iommu->flush.flush_iotlb(iommu, did, addr, mask, | 1088 | iommu->flush.flush_iotlb(iommu, did, addr, mask, |
1057 | DMA_TLB_PSI_FLUSH); | 1089 | DMA_TLB_PSI_FLUSH); |
1058 | if (did) | 1090 | |
1091 | /* | ||
1092 | * In caching mode, domain ID 0 is reserved for non-present to present | ||
1093 | * mapping flush. Device IOTLB doesn't need to be flushed in this case. | ||
1094 | */ | ||
1095 | if (!cap_caching_mode(iommu->cap) || did) | ||
1059 | iommu_flush_dev_iotlb(iommu->domains[did], addr, mask); | 1096 | iommu_flush_dev_iotlb(iommu->domains[did], addr, mask); |
1060 | } | 1097 | } |
1061 | 1098 | ||
@@ -1280,7 +1317,6 @@ static void dmar_init_reserved_ranges(void) | |||
1280 | struct pci_dev *pdev = NULL; | 1317 | struct pci_dev *pdev = NULL; |
1281 | struct iova *iova; | 1318 | struct iova *iova; |
1282 | int i; | 1319 | int i; |
1283 | u64 addr, size; | ||
1284 | 1320 | ||
1285 | init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN); | 1321 | init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN); |
1286 | 1322 | ||
@@ -1303,12 +1339,9 @@ static void dmar_init_reserved_ranges(void) | |||
1303 | r = &pdev->resource[i]; | 1339 | r = &pdev->resource[i]; |
1304 | if (!r->flags || !(r->flags & IORESOURCE_MEM)) | 1340 | if (!r->flags || !(r->flags & IORESOURCE_MEM)) |
1305 | continue; | 1341 | continue; |
1306 | addr = r->start; | 1342 | iova = reserve_iova(&reserved_iova_list, |
1307 | addr &= PHYSICAL_PAGE_MASK; | 1343 | IOVA_PFN(r->start), |
1308 | size = r->end - addr; | 1344 | IOVA_PFN(r->end)); |
1309 | size = PAGE_ALIGN(size); | ||
1310 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr), | ||
1311 | IOVA_PFN(size + addr) - 1); | ||
1312 | if (!iova) | 1345 | if (!iova) |
1313 | printk(KERN_ERR "Reserve iova failed\n"); | 1346 | printk(KERN_ERR "Reserve iova failed\n"); |
1314 | } | 1347 | } |
@@ -1342,7 +1375,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
1342 | unsigned long sagaw; | 1375 | unsigned long sagaw; |
1343 | 1376 | ||
1344 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); | 1377 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); |
1345 | spin_lock_init(&domain->mapping_lock); | ||
1346 | spin_lock_init(&domain->iommu_lock); | 1378 | spin_lock_init(&domain->iommu_lock); |
1347 | 1379 | ||
1348 | domain_reserve_special_ranges(domain); | 1380 | domain_reserve_special_ranges(domain); |
@@ -1389,7 +1421,6 @@ static void domain_exit(struct dmar_domain *domain) | |||
1389 | { | 1421 | { |
1390 | struct dmar_drhd_unit *drhd; | 1422 | struct dmar_drhd_unit *drhd; |
1391 | struct intel_iommu *iommu; | 1423 | struct intel_iommu *iommu; |
1392 | u64 end; | ||
1393 | 1424 | ||
1394 | /* Domain 0 is reserved, so dont process it */ | 1425 | /* Domain 0 is reserved, so dont process it */ |
1395 | if (!domain) | 1426 | if (!domain) |
@@ -1398,14 +1429,12 @@ static void domain_exit(struct dmar_domain *domain) | |||
1398 | domain_remove_dev_info(domain); | 1429 | domain_remove_dev_info(domain); |
1399 | /* destroy iovas */ | 1430 | /* destroy iovas */ |
1400 | put_iova_domain(&domain->iovad); | 1431 | put_iova_domain(&domain->iovad); |
1401 | end = DOMAIN_MAX_ADDR(domain->gaw); | ||
1402 | end = end & (~PAGE_MASK); | ||
1403 | 1432 | ||
1404 | /* clear ptes */ | 1433 | /* clear ptes */ |
1405 | dma_pte_clear_range(domain, 0, end); | 1434 | dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); |
1406 | 1435 | ||
1407 | /* free page tables */ | 1436 | /* free page tables */ |
1408 | dma_pte_free_pagetable(domain, 0, end); | 1437 | dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); |
1409 | 1438 | ||
1410 | for_each_active_iommu(iommu, drhd) | 1439 | for_each_active_iommu(iommu, drhd) |
1411 | if (test_bit(iommu->seq_id, &domain->iommu_bmp)) | 1440 | if (test_bit(iommu->seq_id, &domain->iommu_bmp)) |
@@ -1619,42 +1648,86 @@ static int domain_context_mapped(struct pci_dev *pdev) | |||
1619 | tmp->devfn); | 1648 | tmp->devfn); |
1620 | } | 1649 | } |
1621 | 1650 | ||
1622 | static int | 1651 | static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, |
1623 | domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, | 1652 | struct scatterlist *sg, unsigned long phys_pfn, |
1624 | u64 hpa, size_t size, int prot) | 1653 | unsigned long nr_pages, int prot) |
1625 | { | 1654 | { |
1626 | u64 start_pfn, end_pfn; | 1655 | struct dma_pte *first_pte = NULL, *pte = NULL; |
1627 | struct dma_pte *pte; | 1656 | phys_addr_t uninitialized_var(pteval); |
1628 | int index; | 1657 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
1629 | int addr_width = agaw_to_width(domain->agaw); | 1658 | unsigned long sg_res; |
1630 | 1659 | ||
1631 | hpa &= (((u64)1) << addr_width) - 1; | 1660 | BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width); |
1632 | 1661 | ||
1633 | if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0) | 1662 | if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0) |
1634 | return -EINVAL; | 1663 | return -EINVAL; |
1635 | iova &= PAGE_MASK; | 1664 | |
1636 | start_pfn = ((u64)hpa) >> VTD_PAGE_SHIFT; | 1665 | prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP; |
1637 | end_pfn = (VTD_PAGE_ALIGN(((u64)hpa) + size)) >> VTD_PAGE_SHIFT; | 1666 | |
1638 | index = 0; | 1667 | if (sg) |
1639 | while (start_pfn < end_pfn) { | 1668 | sg_res = 0; |
1640 | pte = addr_to_dma_pte(domain, iova + VTD_PAGE_SIZE * index); | 1669 | else { |
1641 | if (!pte) | 1670 | sg_res = nr_pages + 1; |
1642 | return -ENOMEM; | 1671 | pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot; |
1672 | } | ||
1673 | |||
1674 | while (nr_pages--) { | ||
1675 | uint64_t tmp; | ||
1676 | |||
1677 | if (!sg_res) { | ||
1678 | sg_res = (sg->offset + sg->length + VTD_PAGE_SIZE - 1) >> VTD_PAGE_SHIFT; | ||
1679 | sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; | ||
1680 | sg->dma_length = sg->length; | ||
1681 | pteval = page_to_phys(sg_page(sg)) | prot; | ||
1682 | } | ||
1683 | if (!pte) { | ||
1684 | first_pte = pte = pfn_to_dma_pte(domain, iov_pfn); | ||
1685 | if (!pte) | ||
1686 | return -ENOMEM; | ||
1687 | } | ||
1643 | /* We don't need lock here, nobody else | 1688 | /* We don't need lock here, nobody else |
1644 | * touches the iova range | 1689 | * touches the iova range |
1645 | */ | 1690 | */ |
1646 | BUG_ON(dma_pte_addr(pte)); | 1691 | tmp = cmpxchg64_local(&pte->val, 0ULL, pteval); |
1647 | dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); | 1692 | if (tmp) { |
1648 | dma_set_pte_prot(pte, prot); | 1693 | static int dumps = 5; |
1649 | if (prot & DMA_PTE_SNP) | 1694 | printk(KERN_CRIT "ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n", |
1650 | dma_set_pte_snp(pte); | 1695 | iov_pfn, tmp, (unsigned long long)pteval); |
1651 | domain_flush_cache(domain, pte, sizeof(*pte)); | 1696 | if (dumps) { |
1652 | start_pfn++; | 1697 | dumps--; |
1653 | index++; | 1698 | debug_dma_dump_mappings(NULL); |
1699 | } | ||
1700 | WARN_ON(1); | ||
1701 | } | ||
1702 | pte++; | ||
1703 | if (!nr_pages || first_pte_in_page(pte)) { | ||
1704 | domain_flush_cache(domain, first_pte, | ||
1705 | (void *)pte - (void *)first_pte); | ||
1706 | pte = NULL; | ||
1707 | } | ||
1708 | iov_pfn++; | ||
1709 | pteval += VTD_PAGE_SIZE; | ||
1710 | sg_res--; | ||
1711 | if (!sg_res) | ||
1712 | sg = sg_next(sg); | ||
1654 | } | 1713 | } |
1655 | return 0; | 1714 | return 0; |
1656 | } | 1715 | } |
1657 | 1716 | ||
1717 | static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | ||
1718 | struct scatterlist *sg, unsigned long nr_pages, | ||
1719 | int prot) | ||
1720 | { | ||
1721 | return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot); | ||
1722 | } | ||
1723 | |||
1724 | static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | ||
1725 | unsigned long phys_pfn, unsigned long nr_pages, | ||
1726 | int prot) | ||
1727 | { | ||
1728 | return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot); | ||
1729 | } | ||
1730 | |||
1658 | static void iommu_detach_dev(struct intel_iommu *iommu, u8 bus, u8 devfn) | 1731 | static void iommu_detach_dev(struct intel_iommu *iommu, u8 bus, u8 devfn) |
1659 | { | 1732 | { |
1660 | if (!iommu) | 1733 | if (!iommu) |
@@ -1845,58 +1918,61 @@ error: | |||
1845 | 1918 | ||
1846 | static int iommu_identity_mapping; | 1919 | static int iommu_identity_mapping; |
1847 | 1920 | ||
1921 | static int iommu_domain_identity_map(struct dmar_domain *domain, | ||
1922 | unsigned long long start, | ||
1923 | unsigned long long end) | ||
1924 | { | ||
1925 | unsigned long first_vpfn = start >> VTD_PAGE_SHIFT; | ||
1926 | unsigned long last_vpfn = end >> VTD_PAGE_SHIFT; | ||
1927 | |||
1928 | if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn), | ||
1929 | dma_to_mm_pfn(last_vpfn))) { | ||
1930 | printk(KERN_ERR "IOMMU: reserve iova failed\n"); | ||
1931 | return -ENOMEM; | ||
1932 | } | ||
1933 | |||
1934 | pr_debug("Mapping reserved region %llx-%llx for domain %d\n", | ||
1935 | start, end, domain->id); | ||
1936 | /* | ||
1937 | * RMRR range might have overlap with physical memory range, | ||
1938 | * clear it first | ||
1939 | */ | ||
1940 | dma_pte_clear_range(domain, first_vpfn, last_vpfn); | ||
1941 | |||
1942 | return domain_pfn_mapping(domain, first_vpfn, first_vpfn, | ||
1943 | last_vpfn - first_vpfn + 1, | ||
1944 | DMA_PTE_READ|DMA_PTE_WRITE); | ||
1945 | } | ||
1946 | |||
1848 | static int iommu_prepare_identity_map(struct pci_dev *pdev, | 1947 | static int iommu_prepare_identity_map(struct pci_dev *pdev, |
1849 | unsigned long long start, | 1948 | unsigned long long start, |
1850 | unsigned long long end) | 1949 | unsigned long long end) |
1851 | { | 1950 | { |
1852 | struct dmar_domain *domain; | 1951 | struct dmar_domain *domain; |
1853 | unsigned long size; | ||
1854 | unsigned long long base; | ||
1855 | int ret; | 1952 | int ret; |
1856 | 1953 | ||
1857 | printk(KERN_INFO | 1954 | printk(KERN_INFO |
1858 | "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", | 1955 | "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", |
1859 | pci_name(pdev), start, end); | 1956 | pci_name(pdev), start, end); |
1860 | if (iommu_identity_mapping) | 1957 | |
1861 | domain = si_domain; | 1958 | domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); |
1862 | else | ||
1863 | /* page table init */ | ||
1864 | domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); | ||
1865 | if (!domain) | 1959 | if (!domain) |
1866 | return -ENOMEM; | 1960 | return -ENOMEM; |
1867 | 1961 | ||
1868 | /* The address might not be aligned */ | 1962 | ret = iommu_domain_identity_map(domain, start, end); |
1869 | base = start & PAGE_MASK; | ||
1870 | size = end - base; | ||
1871 | size = PAGE_ALIGN(size); | ||
1872 | if (!reserve_iova(&domain->iovad, IOVA_PFN(base), | ||
1873 | IOVA_PFN(base + size) - 1)) { | ||
1874 | printk(KERN_ERR "IOMMU: reserve iova failed\n"); | ||
1875 | ret = -ENOMEM; | ||
1876 | goto error; | ||
1877 | } | ||
1878 | |||
1879 | pr_debug("Mapping reserved region %lx@%llx for %s\n", | ||
1880 | size, base, pci_name(pdev)); | ||
1881 | /* | ||
1882 | * RMRR range might have overlap with physical memory range, | ||
1883 | * clear it first | ||
1884 | */ | ||
1885 | dma_pte_clear_range(domain, base, base + size); | ||
1886 | |||
1887 | ret = domain_page_mapping(domain, base, base, size, | ||
1888 | DMA_PTE_READ|DMA_PTE_WRITE); | ||
1889 | if (ret) | 1963 | if (ret) |
1890 | goto error; | 1964 | goto error; |
1891 | 1965 | ||
1892 | /* context entry init */ | 1966 | /* context entry init */ |
1893 | ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); | 1967 | ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); |
1894 | if (!ret) | 1968 | if (ret) |
1895 | return 0; | 1969 | goto error; |
1896 | error: | 1970 | |
1971 | return 0; | ||
1972 | |||
1973 | error: | ||
1897 | domain_exit(domain); | 1974 | domain_exit(domain); |
1898 | return ret; | 1975 | return ret; |
1899 | |||
1900 | } | 1976 | } |
1901 | 1977 | ||
1902 | static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, | 1978 | static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, |
@@ -1908,64 +1984,6 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, | |||
1908 | rmrr->end_address + 1); | 1984 | rmrr->end_address + 1); |
1909 | } | 1985 | } |
1910 | 1986 | ||
1911 | #ifdef CONFIG_DMAR_GFX_WA | ||
1912 | struct iommu_prepare_data { | ||
1913 | struct pci_dev *pdev; | ||
1914 | int ret; | ||
1915 | }; | ||
1916 | |||
1917 | static int __init iommu_prepare_work_fn(unsigned long start_pfn, | ||
1918 | unsigned long end_pfn, void *datax) | ||
1919 | { | ||
1920 | struct iommu_prepare_data *data; | ||
1921 | |||
1922 | data = (struct iommu_prepare_data *)datax; | ||
1923 | |||
1924 | data->ret = iommu_prepare_identity_map(data->pdev, | ||
1925 | start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); | ||
1926 | return data->ret; | ||
1927 | |||
1928 | } | ||
1929 | |||
1930 | static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev) | ||
1931 | { | ||
1932 | int nid; | ||
1933 | struct iommu_prepare_data data; | ||
1934 | |||
1935 | data.pdev = pdev; | ||
1936 | data.ret = 0; | ||
1937 | |||
1938 | for_each_online_node(nid) { | ||
1939 | work_with_active_regions(nid, iommu_prepare_work_fn, &data); | ||
1940 | if (data.ret) | ||
1941 | return data.ret; | ||
1942 | } | ||
1943 | return data.ret; | ||
1944 | } | ||
1945 | |||
1946 | static void __init iommu_prepare_gfx_mapping(void) | ||
1947 | { | ||
1948 | struct pci_dev *pdev = NULL; | ||
1949 | int ret; | ||
1950 | |||
1951 | for_each_pci_dev(pdev) { | ||
1952 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO || | ||
1953 | !IS_GFX_DEVICE(pdev)) | ||
1954 | continue; | ||
1955 | printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n", | ||
1956 | pci_name(pdev)); | ||
1957 | ret = iommu_prepare_with_active_regions(pdev); | ||
1958 | if (ret) | ||
1959 | printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); | ||
1960 | } | ||
1961 | } | ||
1962 | #else /* !CONFIG_DMAR_GFX_WA */ | ||
1963 | static inline void iommu_prepare_gfx_mapping(void) | ||
1964 | { | ||
1965 | return; | ||
1966 | } | ||
1967 | #endif | ||
1968 | |||
1969 | #ifdef CONFIG_DMAR_FLOPPY_WA | 1987 | #ifdef CONFIG_DMAR_FLOPPY_WA |
1970 | static inline void iommu_prepare_isa(void) | 1988 | static inline void iommu_prepare_isa(void) |
1971 | { | 1989 | { |
@@ -1976,12 +1994,12 @@ static inline void iommu_prepare_isa(void) | |||
1976 | if (!pdev) | 1994 | if (!pdev) |
1977 | return; | 1995 | return; |
1978 | 1996 | ||
1979 | printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n"); | 1997 | printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); |
1980 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); | 1998 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); |
1981 | 1999 | ||
1982 | if (ret) | 2000 | if (ret) |
1983 | printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, " | 2001 | printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " |
1984 | "floppy might not work\n"); | 2002 | "floppy might not work\n"); |
1985 | 2003 | ||
1986 | } | 2004 | } |
1987 | #else | 2005 | #else |
@@ -2009,16 +2027,30 @@ static int __init init_context_pass_through(void) | |||
2009 | } | 2027 | } |
2010 | 2028 | ||
2011 | static int md_domain_init(struct dmar_domain *domain, int guest_width); | 2029 | static int md_domain_init(struct dmar_domain *domain, int guest_width); |
2030 | |||
2031 | static int __init si_domain_work_fn(unsigned long start_pfn, | ||
2032 | unsigned long end_pfn, void *datax) | ||
2033 | { | ||
2034 | int *ret = datax; | ||
2035 | |||
2036 | *ret = iommu_domain_identity_map(si_domain, | ||
2037 | (uint64_t)start_pfn << PAGE_SHIFT, | ||
2038 | (uint64_t)end_pfn << PAGE_SHIFT); | ||
2039 | return *ret; | ||
2040 | |||
2041 | } | ||
2042 | |||
2012 | static int si_domain_init(void) | 2043 | static int si_domain_init(void) |
2013 | { | 2044 | { |
2014 | struct dmar_drhd_unit *drhd; | 2045 | struct dmar_drhd_unit *drhd; |
2015 | struct intel_iommu *iommu; | 2046 | struct intel_iommu *iommu; |
2016 | int ret = 0; | 2047 | int nid, ret = 0; |
2017 | 2048 | ||
2018 | si_domain = alloc_domain(); | 2049 | si_domain = alloc_domain(); |
2019 | if (!si_domain) | 2050 | if (!si_domain) |
2020 | return -EFAULT; | 2051 | return -EFAULT; |
2021 | 2052 | ||
2053 | pr_debug("Identity mapping domain is domain %d\n", si_domain->id); | ||
2022 | 2054 | ||
2023 | for_each_active_iommu(iommu, drhd) { | 2055 | for_each_active_iommu(iommu, drhd) { |
2024 | ret = iommu_attach_domain(si_domain, iommu); | 2056 | ret = iommu_attach_domain(si_domain, iommu); |
@@ -2035,6 +2067,12 @@ static int si_domain_init(void) | |||
2035 | 2067 | ||
2036 | si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY; | 2068 | si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY; |
2037 | 2069 | ||
2070 | for_each_online_node(nid) { | ||
2071 | work_with_active_regions(nid, si_domain_work_fn, &ret); | ||
2072 | if (ret) | ||
2073 | return ret; | ||
2074 | } | ||
2075 | |||
2038 | return 0; | 2076 | return 0; |
2039 | } | 2077 | } |
2040 | 2078 | ||
@@ -2079,9 +2117,49 @@ static int domain_add_dev_info(struct dmar_domain *domain, | |||
2079 | return 0; | 2117 | return 0; |
2080 | } | 2118 | } |
2081 | 2119 | ||
2120 | static int iommu_should_identity_map(struct pci_dev *pdev, int startup) | ||
2121 | { | ||
2122 | if (iommu_identity_mapping == 2) | ||
2123 | return IS_GFX_DEVICE(pdev); | ||
2124 | |||
2125 | /* | ||
2126 | * We want to start off with all devices in the 1:1 domain, and | ||
2127 | * take them out later if we find they can't access all of memory. | ||
2128 | * | ||
2129 | * However, we can't do this for PCI devices behind bridges, | ||
2130 | * because all PCI devices behind the same bridge will end up | ||
2131 | * with the same source-id on their transactions. | ||
2132 | * | ||
2133 | * Practically speaking, we can't change things around for these | ||
2134 | * devices at run-time, because we can't be sure there'll be no | ||
2135 | * DMA transactions in flight for any of their siblings. | ||
2136 | * | ||
2137 | * So PCI devices (unless they're on the root bus) as well as | ||
2138 | * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of | ||
2139 | * the 1:1 domain, just in _case_ one of their siblings turns out | ||
2140 | * not to be able to map all of memory. | ||
2141 | */ | ||
2142 | if (!pdev->is_pcie) { | ||
2143 | if (!pci_is_root_bus(pdev->bus)) | ||
2144 | return 0; | ||
2145 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) | ||
2146 | return 0; | ||
2147 | } else if (pdev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | ||
2148 | return 0; | ||
2149 | |||
2150 | /* | ||
2151 | * At boot time, we don't yet know if devices will be 64-bit capable. | ||
2152 | * Assume that they will -- if they turn out not to be, then we can | ||
2153 | * take them out of the 1:1 domain later. | ||
2154 | */ | ||
2155 | if (!startup) | ||
2156 | return pdev->dma_mask > DMA_BIT_MASK(32); | ||
2157 | |||
2158 | return 1; | ||
2159 | } | ||
2160 | |||
2082 | static int iommu_prepare_static_identity_mapping(void) | 2161 | static int iommu_prepare_static_identity_mapping(void) |
2083 | { | 2162 | { |
2084 | int i; | ||
2085 | struct pci_dev *pdev = NULL; | 2163 | struct pci_dev *pdev = NULL; |
2086 | int ret; | 2164 | int ret; |
2087 | 2165 | ||
@@ -2089,23 +2167,19 @@ static int iommu_prepare_static_identity_mapping(void) | |||
2089 | if (ret) | 2167 | if (ret) |
2090 | return -EFAULT; | 2168 | return -EFAULT; |
2091 | 2169 | ||
2092 | printk(KERN_INFO "IOMMU: Setting identity map:\n"); | ||
2093 | for_each_pci_dev(pdev) { | 2170 | for_each_pci_dev(pdev) { |
2094 | for (i = 0; i < e820.nr_map; i++) { | 2171 | if (iommu_should_identity_map(pdev, 1)) { |
2095 | struct e820entry *ei = &e820.map[i]; | 2172 | printk(KERN_INFO "IOMMU: identity mapping for device %s\n", |
2096 | 2173 | pci_name(pdev)); | |
2097 | if (ei->type == E820_RAM) { | 2174 | |
2098 | ret = iommu_prepare_identity_map(pdev, | 2175 | ret = domain_context_mapping(si_domain, pdev, |
2099 | ei->addr, ei->addr + ei->size); | 2176 | CONTEXT_TT_MULTI_LEVEL); |
2100 | if (ret) { | 2177 | if (ret) |
2101 | printk(KERN_INFO "1:1 mapping to one domain failed.\n"); | 2178 | return ret; |
2102 | return -EFAULT; | 2179 | ret = domain_add_dev_info(si_domain, pdev); |
2103 | } | 2180 | if (ret) |
2104 | } | 2181 | return ret; |
2105 | } | 2182 | } |
2106 | ret = domain_add_dev_info(si_domain, pdev); | ||
2107 | if (ret) | ||
2108 | return ret; | ||
2109 | } | 2183 | } |
2110 | 2184 | ||
2111 | return 0; | 2185 | return 0; |
@@ -2260,6 +2334,10 @@ int __init init_dmars(void) | |||
2260 | * identity mapping if iommu_identity_mapping is set. | 2334 | * identity mapping if iommu_identity_mapping is set. |
2261 | */ | 2335 | */ |
2262 | if (!iommu_pass_through) { | 2336 | if (!iommu_pass_through) { |
2337 | #ifdef CONFIG_DMAR_BROKEN_GFX_WA | ||
2338 | if (!iommu_identity_mapping) | ||
2339 | iommu_identity_mapping = 2; | ||
2340 | #endif | ||
2263 | if (iommu_identity_mapping) | 2341 | if (iommu_identity_mapping) |
2264 | iommu_prepare_static_identity_mapping(); | 2342 | iommu_prepare_static_identity_mapping(); |
2265 | /* | 2343 | /* |
@@ -2293,8 +2371,6 @@ int __init init_dmars(void) | |||
2293 | } | 2371 | } |
2294 | } | 2372 | } |
2295 | 2373 | ||
2296 | iommu_prepare_gfx_mapping(); | ||
2297 | |||
2298 | iommu_prepare_isa(); | 2374 | iommu_prepare_isa(); |
2299 | } | 2375 | } |
2300 | 2376 | ||
@@ -2339,50 +2415,40 @@ error: | |||
2339 | return ret; | 2415 | return ret; |
2340 | } | 2416 | } |
2341 | 2417 | ||
2342 | static inline u64 aligned_size(u64 host_addr, size_t size) | 2418 | /* Returns a number of VTD pages, but aligned to MM page size */ |
2419 | static inline unsigned long aligned_nrpages(unsigned long host_addr, | ||
2420 | size_t size) | ||
2343 | { | 2421 | { |
2344 | u64 addr; | 2422 | host_addr &= ~PAGE_MASK; |
2345 | addr = (host_addr & (~PAGE_MASK)) + size; | 2423 | return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT; |
2346 | return PAGE_ALIGN(addr); | ||
2347 | } | ||
2348 | |||
2349 | struct iova * | ||
2350 | iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end) | ||
2351 | { | ||
2352 | struct iova *piova; | ||
2353 | |||
2354 | /* Make sure it's in range */ | ||
2355 | end = min_t(u64, DOMAIN_MAX_ADDR(domain->gaw), end); | ||
2356 | if (!size || (IOVA_START_ADDR + size > end)) | ||
2357 | return NULL; | ||
2358 | |||
2359 | piova = alloc_iova(&domain->iovad, | ||
2360 | size >> PAGE_SHIFT, IOVA_PFN(end), 1); | ||
2361 | return piova; | ||
2362 | } | 2424 | } |
2363 | 2425 | ||
2364 | static struct iova * | 2426 | /* This takes a number of _MM_ pages, not VTD pages */ |
2365 | __intel_alloc_iova(struct device *dev, struct dmar_domain *domain, | 2427 | static struct iova *intel_alloc_iova(struct device *dev, |
2366 | size_t size, u64 dma_mask) | 2428 | struct dmar_domain *domain, |
2429 | unsigned long nrpages, uint64_t dma_mask) | ||
2367 | { | 2430 | { |
2368 | struct pci_dev *pdev = to_pci_dev(dev); | 2431 | struct pci_dev *pdev = to_pci_dev(dev); |
2369 | struct iova *iova = NULL; | 2432 | struct iova *iova = NULL; |
2370 | 2433 | ||
2371 | if (dma_mask <= DMA_BIT_MASK(32) || dmar_forcedac) | 2434 | /* Restrict dma_mask to the width that the iommu can handle */ |
2372 | iova = iommu_alloc_iova(domain, size, dma_mask); | 2435 | dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask); |
2373 | else { | 2436 | |
2437 | if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) { | ||
2374 | /* | 2438 | /* |
2375 | * First try to allocate an io virtual address in | 2439 | * First try to allocate an io virtual address in |
2376 | * DMA_BIT_MASK(32) and if that fails then try allocating | 2440 | * DMA_BIT_MASK(32) and if that fails then try allocating |
2377 | * from higher range | 2441 | * from higher range |
2378 | */ | 2442 | */ |
2379 | iova = iommu_alloc_iova(domain, size, DMA_BIT_MASK(32)); | 2443 | iova = alloc_iova(&domain->iovad, nrpages, |
2380 | if (!iova) | 2444 | IOVA_PFN(DMA_BIT_MASK(32)), 1); |
2381 | iova = iommu_alloc_iova(domain, size, dma_mask); | 2445 | if (iova) |
2382 | } | 2446 | return iova; |
2383 | 2447 | } | |
2384 | if (!iova) { | 2448 | iova = alloc_iova(&domain->iovad, nrpages, IOVA_PFN(dma_mask), 1); |
2385 | printk(KERN_ERR"Allocating iova for %s failed", pci_name(pdev)); | 2449 | if (unlikely(!iova)) { |
2450 | printk(KERN_ERR "Allocating %ld-page iova for %s failed", | ||
2451 | nrpages, pci_name(pdev)); | ||
2386 | return NULL; | 2452 | return NULL; |
2387 | } | 2453 | } |
2388 | 2454 | ||
@@ -2424,16 +2490,24 @@ static int iommu_dummy(struct pci_dev *pdev) | |||
2424 | } | 2490 | } |
2425 | 2491 | ||
2426 | /* Check if the pdev needs to go through non-identity map and unmap process.*/ | 2492 | /* Check if the pdev needs to go through non-identity map and unmap process.*/ |
2427 | static int iommu_no_mapping(struct pci_dev *pdev) | 2493 | static int iommu_no_mapping(struct device *dev) |
2428 | { | 2494 | { |
2495 | struct pci_dev *pdev; | ||
2429 | int found; | 2496 | int found; |
2430 | 2497 | ||
2498 | if (unlikely(dev->bus != &pci_bus_type)) | ||
2499 | return 1; | ||
2500 | |||
2501 | pdev = to_pci_dev(dev); | ||
2502 | if (iommu_dummy(pdev)) | ||
2503 | return 1; | ||
2504 | |||
2431 | if (!iommu_identity_mapping) | 2505 | if (!iommu_identity_mapping) |
2432 | return iommu_dummy(pdev); | 2506 | return 0; |
2433 | 2507 | ||
2434 | found = identity_mapping(pdev); | 2508 | found = identity_mapping(pdev); |
2435 | if (found) { | 2509 | if (found) { |
2436 | if (pdev->dma_mask > DMA_BIT_MASK(32)) | 2510 | if (iommu_should_identity_map(pdev, 0)) |
2437 | return 1; | 2511 | return 1; |
2438 | else { | 2512 | else { |
2439 | /* | 2513 | /* |
@@ -2450,9 +2524,12 @@ static int iommu_no_mapping(struct pci_dev *pdev) | |||
2450 | * In case of a detached 64 bit DMA device from vm, the device | 2524 | * In case of a detached 64 bit DMA device from vm, the device |
2451 | * is put into si_domain for identity mapping. | 2525 | * is put into si_domain for identity mapping. |
2452 | */ | 2526 | */ |
2453 | if (pdev->dma_mask > DMA_BIT_MASK(32)) { | 2527 | if (iommu_should_identity_map(pdev, 0)) { |
2454 | int ret; | 2528 | int ret; |
2455 | ret = domain_add_dev_info(si_domain, pdev); | 2529 | ret = domain_add_dev_info(si_domain, pdev); |
2530 | if (ret) | ||
2531 | return 0; | ||
2532 | ret = domain_context_mapping(si_domain, pdev, CONTEXT_TT_MULTI_LEVEL); | ||
2456 | if (!ret) { | 2533 | if (!ret) { |
2457 | printk(KERN_INFO "64bit %s uses identity mapping\n", | 2534 | printk(KERN_INFO "64bit %s uses identity mapping\n", |
2458 | pci_name(pdev)); | 2535 | pci_name(pdev)); |
@@ -2461,7 +2538,7 @@ static int iommu_no_mapping(struct pci_dev *pdev) | |||
2461 | } | 2538 | } |
2462 | } | 2539 | } |
2463 | 2540 | ||
2464 | return iommu_dummy(pdev); | 2541 | return 0; |
2465 | } | 2542 | } |
2466 | 2543 | ||
2467 | static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | 2544 | static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, |
@@ -2477,7 +2554,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
2477 | 2554 | ||
2478 | BUG_ON(dir == DMA_NONE); | 2555 | BUG_ON(dir == DMA_NONE); |
2479 | 2556 | ||
2480 | if (iommu_no_mapping(pdev)) | 2557 | if (iommu_no_mapping(hwdev)) |
2481 | return paddr; | 2558 | return paddr; |
2482 | 2559 | ||
2483 | domain = get_valid_domain_for_dev(pdev); | 2560 | domain = get_valid_domain_for_dev(pdev); |
@@ -2485,14 +2562,13 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
2485 | return 0; | 2562 | return 0; |
2486 | 2563 | ||
2487 | iommu = domain_get_iommu(domain); | 2564 | iommu = domain_get_iommu(domain); |
2488 | size = aligned_size((u64)paddr, size); | 2565 | size = aligned_nrpages(paddr, size); |
2489 | 2566 | ||
2490 | iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); | 2567 | iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), |
2568 | pdev->dma_mask); | ||
2491 | if (!iova) | 2569 | if (!iova) |
2492 | goto error; | 2570 | goto error; |
2493 | 2571 | ||
2494 | start_paddr = (phys_addr_t)iova->pfn_lo << PAGE_SHIFT; | ||
2495 | |||
2496 | /* | 2572 | /* |
2497 | * Check if DMAR supports zero-length reads on write only | 2573 | * Check if DMAR supports zero-length reads on write only |
2498 | * mappings.. | 2574 | * mappings.. |
@@ -2508,20 +2584,20 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
2508 | * might have two guest_addr mapping to the same host paddr, but this | 2584 | * might have two guest_addr mapping to the same host paddr, but this |
2509 | * is not a big problem | 2585 | * is not a big problem |
2510 | */ | 2586 | */ |
2511 | ret = domain_page_mapping(domain, start_paddr, | 2587 | ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova->pfn_lo), |
2512 | ((u64)paddr) & PHYSICAL_PAGE_MASK, | 2588 | paddr >> VTD_PAGE_SHIFT, size, prot); |
2513 | size, prot); | ||
2514 | if (ret) | 2589 | if (ret) |
2515 | goto error; | 2590 | goto error; |
2516 | 2591 | ||
2517 | /* it's a non-present to present mapping. Only flush if caching mode */ | 2592 | /* it's a non-present to present mapping. Only flush if caching mode */ |
2518 | if (cap_caching_mode(iommu->cap)) | 2593 | if (cap_caching_mode(iommu->cap)) |
2519 | iommu_flush_iotlb_psi(iommu, 0, start_paddr, | 2594 | iommu_flush_iotlb_psi(iommu, 0, mm_to_dma_pfn(iova->pfn_lo), size); |
2520 | size >> VTD_PAGE_SHIFT); | ||
2521 | else | 2595 | else |
2522 | iommu_flush_write_buffer(iommu); | 2596 | iommu_flush_write_buffer(iommu); |
2523 | 2597 | ||
2524 | return start_paddr + ((u64)paddr & (~PAGE_MASK)); | 2598 | start_paddr = (phys_addr_t)iova->pfn_lo << PAGE_SHIFT; |
2599 | start_paddr += paddr & ~PAGE_MASK; | ||
2600 | return start_paddr; | ||
2525 | 2601 | ||
2526 | error: | 2602 | error: |
2527 | if (iova) | 2603 | if (iova) |
@@ -2614,11 +2690,11 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, | |||
2614 | { | 2690 | { |
2615 | struct pci_dev *pdev = to_pci_dev(dev); | 2691 | struct pci_dev *pdev = to_pci_dev(dev); |
2616 | struct dmar_domain *domain; | 2692 | struct dmar_domain *domain; |
2617 | unsigned long start_addr; | 2693 | unsigned long start_pfn, last_pfn; |
2618 | struct iova *iova; | 2694 | struct iova *iova; |
2619 | struct intel_iommu *iommu; | 2695 | struct intel_iommu *iommu; |
2620 | 2696 | ||
2621 | if (iommu_no_mapping(pdev)) | 2697 | if (iommu_no_mapping(dev)) |
2622 | return; | 2698 | return; |
2623 | 2699 | ||
2624 | domain = find_domain(pdev); | 2700 | domain = find_domain(pdev); |
@@ -2627,22 +2703,25 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, | |||
2627 | iommu = domain_get_iommu(domain); | 2703 | iommu = domain_get_iommu(domain); |
2628 | 2704 | ||
2629 | iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr)); | 2705 | iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr)); |
2630 | if (!iova) | 2706 | if (WARN_ONCE(!iova, "Driver unmaps unmatched page at PFN %llx\n", |
2707 | (unsigned long long)dev_addr)) | ||
2631 | return; | 2708 | return; |
2632 | 2709 | ||
2633 | start_addr = iova->pfn_lo << PAGE_SHIFT; | 2710 | start_pfn = mm_to_dma_pfn(iova->pfn_lo); |
2634 | size = aligned_size((u64)dev_addr, size); | 2711 | last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1; |
2635 | 2712 | ||
2636 | pr_debug("Device %s unmapping: %zx@%llx\n", | 2713 | pr_debug("Device %s unmapping: pfn %lx-%lx\n", |
2637 | pci_name(pdev), size, (unsigned long long)start_addr); | 2714 | pci_name(pdev), start_pfn, last_pfn); |
2638 | 2715 | ||
2639 | /* clear the whole page */ | 2716 | /* clear the whole page */ |
2640 | dma_pte_clear_range(domain, start_addr, start_addr + size); | 2717 | dma_pte_clear_range(domain, start_pfn, last_pfn); |
2718 | |||
2641 | /* free page tables */ | 2719 | /* free page tables */ |
2642 | dma_pte_free_pagetable(domain, start_addr, start_addr + size); | 2720 | dma_pte_free_pagetable(domain, start_pfn, last_pfn); |
2721 | |||
2643 | if (intel_iommu_strict) { | 2722 | if (intel_iommu_strict) { |
2644 | iommu_flush_iotlb_psi(iommu, domain->id, start_addr, | 2723 | iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, |
2645 | size >> VTD_PAGE_SHIFT); | 2724 | last_pfn - start_pfn + 1); |
2646 | /* free iova */ | 2725 | /* free iova */ |
2647 | __free_iova(&domain->iovad, iova); | 2726 | __free_iova(&domain->iovad, iova); |
2648 | } else { | 2727 | } else { |
@@ -2700,17 +2779,13 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | |||
2700 | int nelems, enum dma_data_direction dir, | 2779 | int nelems, enum dma_data_direction dir, |
2701 | struct dma_attrs *attrs) | 2780 | struct dma_attrs *attrs) |
2702 | { | 2781 | { |
2703 | int i; | ||
2704 | struct pci_dev *pdev = to_pci_dev(hwdev); | 2782 | struct pci_dev *pdev = to_pci_dev(hwdev); |
2705 | struct dmar_domain *domain; | 2783 | struct dmar_domain *domain; |
2706 | unsigned long start_addr; | 2784 | unsigned long start_pfn, last_pfn; |
2707 | struct iova *iova; | 2785 | struct iova *iova; |
2708 | size_t size = 0; | ||
2709 | phys_addr_t addr; | ||
2710 | struct scatterlist *sg; | ||
2711 | struct intel_iommu *iommu; | 2786 | struct intel_iommu *iommu; |
2712 | 2787 | ||
2713 | if (iommu_no_mapping(pdev)) | 2788 | if (iommu_no_mapping(hwdev)) |
2714 | return; | 2789 | return; |
2715 | 2790 | ||
2716 | domain = find_domain(pdev); | 2791 | domain = find_domain(pdev); |
@@ -2719,22 +2794,21 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | |||
2719 | iommu = domain_get_iommu(domain); | 2794 | iommu = domain_get_iommu(domain); |
2720 | 2795 | ||
2721 | iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address)); | 2796 | iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address)); |
2722 | if (!iova) | 2797 | if (WARN_ONCE(!iova, "Driver unmaps unmatched sglist at PFN %llx\n", |
2798 | (unsigned long long)sglist[0].dma_address)) | ||
2723 | return; | 2799 | return; |
2724 | for_each_sg(sglist, sg, nelems, i) { | ||
2725 | addr = page_to_phys(sg_page(sg)) + sg->offset; | ||
2726 | size += aligned_size((u64)addr, sg->length); | ||
2727 | } | ||
2728 | 2800 | ||
2729 | start_addr = iova->pfn_lo << PAGE_SHIFT; | 2801 | start_pfn = mm_to_dma_pfn(iova->pfn_lo); |
2802 | last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1; | ||
2730 | 2803 | ||
2731 | /* clear the whole page */ | 2804 | /* clear the whole page */ |
2732 | dma_pte_clear_range(domain, start_addr, start_addr + size); | 2805 | dma_pte_clear_range(domain, start_pfn, last_pfn); |
2806 | |||
2733 | /* free page tables */ | 2807 | /* free page tables */ |
2734 | dma_pte_free_pagetable(domain, start_addr, start_addr + size); | 2808 | dma_pte_free_pagetable(domain, start_pfn, last_pfn); |
2735 | 2809 | ||
2736 | iommu_flush_iotlb_psi(iommu, domain->id, start_addr, | 2810 | iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, |
2737 | size >> VTD_PAGE_SHIFT); | 2811 | (last_pfn - start_pfn + 1)); |
2738 | 2812 | ||
2739 | /* free iova */ | 2813 | /* free iova */ |
2740 | __free_iova(&domain->iovad, iova); | 2814 | __free_iova(&domain->iovad, iova); |
@@ -2757,21 +2831,20 @@ static int intel_nontranslate_map_sg(struct device *hddev, | |||
2757 | static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | 2831 | static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, |
2758 | enum dma_data_direction dir, struct dma_attrs *attrs) | 2832 | enum dma_data_direction dir, struct dma_attrs *attrs) |
2759 | { | 2833 | { |
2760 | phys_addr_t addr; | ||
2761 | int i; | 2834 | int i; |
2762 | struct pci_dev *pdev = to_pci_dev(hwdev); | 2835 | struct pci_dev *pdev = to_pci_dev(hwdev); |
2763 | struct dmar_domain *domain; | 2836 | struct dmar_domain *domain; |
2764 | size_t size = 0; | 2837 | size_t size = 0; |
2765 | int prot = 0; | 2838 | int prot = 0; |
2766 | size_t offset = 0; | 2839 | size_t offset_pfn = 0; |
2767 | struct iova *iova = NULL; | 2840 | struct iova *iova = NULL; |
2768 | int ret; | 2841 | int ret; |
2769 | struct scatterlist *sg; | 2842 | struct scatterlist *sg; |
2770 | unsigned long start_addr; | 2843 | unsigned long start_vpfn; |
2771 | struct intel_iommu *iommu; | 2844 | struct intel_iommu *iommu; |
2772 | 2845 | ||
2773 | BUG_ON(dir == DMA_NONE); | 2846 | BUG_ON(dir == DMA_NONE); |
2774 | if (iommu_no_mapping(pdev)) | 2847 | if (iommu_no_mapping(hwdev)) |
2775 | return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir); | 2848 | return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir); |
2776 | 2849 | ||
2777 | domain = get_valid_domain_for_dev(pdev); | 2850 | domain = get_valid_domain_for_dev(pdev); |
@@ -2780,12 +2853,11 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne | |||
2780 | 2853 | ||
2781 | iommu = domain_get_iommu(domain); | 2854 | iommu = domain_get_iommu(domain); |
2782 | 2855 | ||
2783 | for_each_sg(sglist, sg, nelems, i) { | 2856 | for_each_sg(sglist, sg, nelems, i) |
2784 | addr = page_to_phys(sg_page(sg)) + sg->offset; | 2857 | size += aligned_nrpages(sg->offset, sg->length); |
2785 | size += aligned_size((u64)addr, sg->length); | ||
2786 | } | ||
2787 | 2858 | ||
2788 | iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); | 2859 | iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), |
2860 | pdev->dma_mask); | ||
2789 | if (!iova) { | 2861 | if (!iova) { |
2790 | sglist->dma_length = 0; | 2862 | sglist->dma_length = 0; |
2791 | return 0; | 2863 | return 0; |
@@ -2801,35 +2873,24 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne | |||
2801 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) | 2873 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) |
2802 | prot |= DMA_PTE_WRITE; | 2874 | prot |= DMA_PTE_WRITE; |
2803 | 2875 | ||
2804 | start_addr = iova->pfn_lo << PAGE_SHIFT; | 2876 | start_vpfn = mm_to_dma_pfn(iova->pfn_lo); |
2805 | offset = 0; | 2877 | |
2806 | for_each_sg(sglist, sg, nelems, i) { | 2878 | ret = domain_sg_mapping(domain, start_vpfn, sglist, mm_to_dma_pfn(size), prot); |
2807 | addr = page_to_phys(sg_page(sg)) + sg->offset; | 2879 | if (unlikely(ret)) { |
2808 | size = aligned_size((u64)addr, sg->length); | 2880 | /* clear the page */ |
2809 | ret = domain_page_mapping(domain, start_addr + offset, | 2881 | dma_pte_clear_range(domain, start_vpfn, |
2810 | ((u64)addr) & PHYSICAL_PAGE_MASK, | 2882 | start_vpfn + size - 1); |
2811 | size, prot); | 2883 | /* free page tables */ |
2812 | if (ret) { | 2884 | dma_pte_free_pagetable(domain, start_vpfn, |
2813 | /* clear the page */ | 2885 | start_vpfn + size - 1); |
2814 | dma_pte_clear_range(domain, start_addr, | 2886 | /* free iova */ |
2815 | start_addr + offset); | 2887 | __free_iova(&domain->iovad, iova); |
2816 | /* free page tables */ | 2888 | return 0; |
2817 | dma_pte_free_pagetable(domain, start_addr, | ||
2818 | start_addr + offset); | ||
2819 | /* free iova */ | ||
2820 | __free_iova(&domain->iovad, iova); | ||
2821 | return 0; | ||
2822 | } | ||
2823 | sg->dma_address = start_addr + offset + | ||
2824 | ((u64)addr & (~PAGE_MASK)); | ||
2825 | sg->dma_length = sg->length; | ||
2826 | offset += size; | ||
2827 | } | 2889 | } |
2828 | 2890 | ||
2829 | /* it's a non-present to present mapping. Only flush if caching mode */ | 2891 | /* it's a non-present to present mapping. Only flush if caching mode */ |
2830 | if (cap_caching_mode(iommu->cap)) | 2892 | if (cap_caching_mode(iommu->cap)) |
2831 | iommu_flush_iotlb_psi(iommu, 0, start_addr, | 2893 | iommu_flush_iotlb_psi(iommu, 0, start_vpfn, offset_pfn); |
2832 | offset >> VTD_PAGE_SHIFT); | ||
2833 | else | 2894 | else |
2834 | iommu_flush_write_buffer(iommu); | 2895 | iommu_flush_write_buffer(iommu); |
2835 | 2896 | ||
@@ -3334,7 +3395,6 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) | |||
3334 | int adjust_width; | 3395 | int adjust_width; |
3335 | 3396 | ||
3336 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); | 3397 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); |
3337 | spin_lock_init(&domain->mapping_lock); | ||
3338 | spin_lock_init(&domain->iommu_lock); | 3398 | spin_lock_init(&domain->iommu_lock); |
3339 | 3399 | ||
3340 | domain_reserve_special_ranges(domain); | 3400 | domain_reserve_special_ranges(domain); |
@@ -3388,8 +3448,6 @@ static void iommu_free_vm_domain(struct dmar_domain *domain) | |||
3388 | 3448 | ||
3389 | static void vm_domain_exit(struct dmar_domain *domain) | 3449 | static void vm_domain_exit(struct dmar_domain *domain) |
3390 | { | 3450 | { |
3391 | u64 end; | ||
3392 | |||
3393 | /* Domain 0 is reserved, so dont process it */ | 3451 | /* Domain 0 is reserved, so dont process it */ |
3394 | if (!domain) | 3452 | if (!domain) |
3395 | return; | 3453 | return; |
@@ -3397,14 +3455,12 @@ static void vm_domain_exit(struct dmar_domain *domain) | |||
3397 | vm_domain_remove_all_dev_info(domain); | 3455 | vm_domain_remove_all_dev_info(domain); |
3398 | /* destroy iovas */ | 3456 | /* destroy iovas */ |
3399 | put_iova_domain(&domain->iovad); | 3457 | put_iova_domain(&domain->iovad); |
3400 | end = DOMAIN_MAX_ADDR(domain->gaw); | ||
3401 | end = end & (~VTD_PAGE_MASK); | ||
3402 | 3458 | ||
3403 | /* clear ptes */ | 3459 | /* clear ptes */ |
3404 | dma_pte_clear_range(domain, 0, end); | 3460 | dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); |
3405 | 3461 | ||
3406 | /* free page tables */ | 3462 | /* free page tables */ |
3407 | dma_pte_free_pagetable(domain, 0, end); | 3463 | dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); |
3408 | 3464 | ||
3409 | iommu_free_vm_domain(domain); | 3465 | iommu_free_vm_domain(domain); |
3410 | free_domain_mem(domain); | 3466 | free_domain_mem(domain); |
@@ -3513,7 +3569,7 @@ static int intel_iommu_map_range(struct iommu_domain *domain, | |||
3513 | if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) | 3569 | if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) |
3514 | prot |= DMA_PTE_SNP; | 3570 | prot |= DMA_PTE_SNP; |
3515 | 3571 | ||
3516 | max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); | 3572 | max_addr = iova + size; |
3517 | if (dmar_domain->max_addr < max_addr) { | 3573 | if (dmar_domain->max_addr < max_addr) { |
3518 | int min_agaw; | 3574 | int min_agaw; |
3519 | u64 end; | 3575 | u64 end; |
@@ -3531,8 +3587,11 @@ static int intel_iommu_map_range(struct iommu_domain *domain, | |||
3531 | } | 3587 | } |
3532 | dmar_domain->max_addr = max_addr; | 3588 | dmar_domain->max_addr = max_addr; |
3533 | } | 3589 | } |
3534 | 3590 | /* Round up size to next multiple of PAGE_SIZE, if it and | |
3535 | ret = domain_page_mapping(dmar_domain, iova, hpa, size, prot); | 3591 | the low bits of hpa would take us onto the next page */ |
3592 | size = aligned_nrpages(hpa, size); | ||
3593 | ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT, | ||
3594 | hpa >> VTD_PAGE_SHIFT, size, prot); | ||
3536 | return ret; | 3595 | return ret; |
3537 | } | 3596 | } |
3538 | 3597 | ||
@@ -3540,15 +3599,15 @@ static void intel_iommu_unmap_range(struct iommu_domain *domain, | |||
3540 | unsigned long iova, size_t size) | 3599 | unsigned long iova, size_t size) |
3541 | { | 3600 | { |
3542 | struct dmar_domain *dmar_domain = domain->priv; | 3601 | struct dmar_domain *dmar_domain = domain->priv; |
3543 | dma_addr_t base; | ||
3544 | 3602 | ||
3545 | /* The address might not be aligned */ | 3603 | if (!size) |
3546 | base = iova & VTD_PAGE_MASK; | 3604 | return; |
3547 | size = VTD_PAGE_ALIGN(size); | 3605 | |
3548 | dma_pte_clear_range(dmar_domain, base, base + size); | 3606 | dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT, |
3607 | (iova + size - 1) >> VTD_PAGE_SHIFT); | ||
3549 | 3608 | ||
3550 | if (dmar_domain->max_addr == base + size) | 3609 | if (dmar_domain->max_addr == iova + size) |
3551 | dmar_domain->max_addr = base; | 3610 | dmar_domain->max_addr = iova; |
3552 | } | 3611 | } |
3553 | 3612 | ||
3554 | static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, | 3613 | static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, |
@@ -3558,7 +3617,7 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, | |||
3558 | struct dma_pte *pte; | 3617 | struct dma_pte *pte; |
3559 | u64 phys = 0; | 3618 | u64 phys = 0; |
3560 | 3619 | ||
3561 | pte = addr_to_dma_pte(dmar_domain, iova); | 3620 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT); |
3562 | if (pte) | 3621 | if (pte) |
3563 | phys = dma_pte_addr(pte); | 3622 | phys = dma_pte_addr(pte); |
3564 | 3623 | ||
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c index 2287116e9822..46dd440e2315 100644 --- a/drivers/pci/iova.c +++ b/drivers/pci/iova.c | |||
@@ -1,9 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006, Intel Corporation. | 2 | * Copyright © 2006-2009, Intel Corporation. |
3 | * | 3 | * |
4 | * This file is released under the GPLv2. | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along with | ||
14 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
15 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
5 | * | 16 | * |
6 | * Copyright (C) 2006-2008 Intel Corporation | ||
7 | * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> | 17 | * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> |
8 | */ | 18 | */ |
9 | 19 | ||
@@ -123,7 +133,15 @@ move_left: | |||
123 | /* Insert the new_iova into domain rbtree by holding writer lock */ | 133 | /* Insert the new_iova into domain rbtree by holding writer lock */ |
124 | /* Add new node and rebalance tree. */ | 134 | /* Add new node and rebalance tree. */ |
125 | { | 135 | { |
126 | struct rb_node **entry = &((prev)), *parent = NULL; | 136 | struct rb_node **entry, *parent = NULL; |
137 | |||
138 | /* If we have 'prev', it's a valid place to start the | ||
139 | insertion. Otherwise, start from the root. */ | ||
140 | if (prev) | ||
141 | entry = &prev; | ||
142 | else | ||
143 | entry = &iovad->rbroot.rb_node; | ||
144 | |||
127 | /* Figure out where to put new node */ | 145 | /* Figure out where to put new node */ |
128 | while (*entry) { | 146 | while (*entry) { |
129 | struct iova *this = container_of(*entry, | 147 | struct iova *this = container_of(*entry, |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index d9f06fbfa0bf..d986afb7032b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -127,17 +127,23 @@ static inline __attribute_const__ u32 msi_enabled_mask(u16 control) | |||
127 | * reliably as devices without an INTx disable bit will then generate a | 127 | * reliably as devices without an INTx disable bit will then generate a |
128 | * level IRQ which will never be cleared. | 128 | * level IRQ which will never be cleared. |
129 | */ | 129 | */ |
130 | static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) | 130 | static u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) |
131 | { | 131 | { |
132 | u32 mask_bits = desc->masked; | 132 | u32 mask_bits = desc->masked; |
133 | 133 | ||
134 | if (!desc->msi_attrib.maskbit) | 134 | if (!desc->msi_attrib.maskbit) |
135 | return; | 135 | return 0; |
136 | 136 | ||
137 | mask_bits &= ~mask; | 137 | mask_bits &= ~mask; |
138 | mask_bits |= flag; | 138 | mask_bits |= flag; |
139 | pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits); | 139 | pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits); |
140 | desc->masked = mask_bits; | 140 | |
141 | return mask_bits; | ||
142 | } | ||
143 | |||
144 | static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) | ||
145 | { | ||
146 | desc->masked = __msi_mask_irq(desc, mask, flag); | ||
141 | } | 147 | } |
142 | 148 | ||
143 | /* | 149 | /* |
@@ -147,15 +153,21 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) | |||
147 | * file. This saves a few milliseconds when initialising devices with lots | 153 | * file. This saves a few milliseconds when initialising devices with lots |
148 | * of MSI-X interrupts. | 154 | * of MSI-X interrupts. |
149 | */ | 155 | */ |
150 | static void msix_mask_irq(struct msi_desc *desc, u32 flag) | 156 | static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag) |
151 | { | 157 | { |
152 | u32 mask_bits = desc->masked; | 158 | u32 mask_bits = desc->masked; |
153 | unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | 159 | unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + |
154 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; | 160 | PCI_MSIX_ENTRY_VECTOR_CTRL; |
155 | mask_bits &= ~1; | 161 | mask_bits &= ~1; |
156 | mask_bits |= flag; | 162 | mask_bits |= flag; |
157 | writel(mask_bits, desc->mask_base + offset); | 163 | writel(mask_bits, desc->mask_base + offset); |
158 | desc->masked = mask_bits; | 164 | |
165 | return mask_bits; | ||
166 | } | ||
167 | |||
168 | static void msix_mask_irq(struct msi_desc *desc, u32 flag) | ||
169 | { | ||
170 | desc->masked = __msix_mask_irq(desc, flag); | ||
159 | } | 171 | } |
160 | 172 | ||
161 | static void msi_set_mask_bit(unsigned irq, u32 flag) | 173 | static void msi_set_mask_bit(unsigned irq, u32 flag) |
@@ -188,9 +200,9 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) | |||
188 | void __iomem *base = entry->mask_base + | 200 | void __iomem *base = entry->mask_base + |
189 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | 201 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; |
190 | 202 | ||
191 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | 203 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); |
192 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | 204 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); |
193 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET); | 205 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); |
194 | } else { | 206 | } else { |
195 | struct pci_dev *dev = entry->dev; | 207 | struct pci_dev *dev = entry->dev; |
196 | int pos = entry->msi_attrib.pos; | 208 | int pos = entry->msi_attrib.pos; |
@@ -225,11 +237,9 @@ void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) | |||
225 | base = entry->mask_base + | 237 | base = entry->mask_base + |
226 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | 238 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; |
227 | 239 | ||
228 | writel(msg->address_lo, | 240 | writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); |
229 | base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | 241 | writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); |
230 | writel(msg->address_hi, | 242 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); |
231 | base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
232 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET); | ||
233 | } else { | 243 | } else { |
234 | struct pci_dev *dev = entry->dev; | 244 | struct pci_dev *dev = entry->dev; |
235 | int pos = entry->msi_attrib.pos; | 245 | int pos = entry->msi_attrib.pos; |
@@ -385,6 +395,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
385 | /* Configure MSI capability structure */ | 395 | /* Configure MSI capability structure */ |
386 | ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); | 396 | ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); |
387 | if (ret) { | 397 | if (ret) { |
398 | msi_mask_irq(entry, mask, ~mask); | ||
388 | msi_free_irqs(dev); | 399 | msi_free_irqs(dev); |
389 | return ret; | 400 | return ret; |
390 | } | 401 | } |
@@ -439,8 +450,14 @@ static int msix_capability_init(struct pci_dev *dev, | |||
439 | 450 | ||
440 | for (i = 0; i < nvec; i++) { | 451 | for (i = 0; i < nvec; i++) { |
441 | entry = alloc_msi_entry(dev); | 452 | entry = alloc_msi_entry(dev); |
442 | if (!entry) | 453 | if (!entry) { |
443 | break; | 454 | if (!i) |
455 | iounmap(base); | ||
456 | else | ||
457 | msi_free_irqs(dev); | ||
458 | /* No enough memory. Don't try again */ | ||
459 | return -ENOMEM; | ||
460 | } | ||
444 | 461 | ||
445 | j = entries[i].entry; | 462 | j = entries[i].entry; |
446 | entry->msi_attrib.is_msix = 1; | 463 | entry->msi_attrib.is_msix = 1; |
@@ -487,7 +504,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
487 | set_irq_msi(entry->irq, entry); | 504 | set_irq_msi(entry->irq, entry); |
488 | j = entries[i].entry; | 505 | j = entries[i].entry; |
489 | entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE + | 506 | entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE + |
490 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); | 507 | PCI_MSIX_ENTRY_VECTOR_CTRL); |
491 | msix_mask_irq(entry, 1); | 508 | msix_mask_irq(entry, 1); |
492 | i++; | 509 | i++; |
493 | } | 510 | } |
@@ -611,9 +628,11 @@ void pci_msi_shutdown(struct pci_dev *dev) | |||
611 | pci_intx_for_msi(dev, 1); | 628 | pci_intx_for_msi(dev, 1); |
612 | dev->msi_enabled = 0; | 629 | dev->msi_enabled = 0; |
613 | 630 | ||
631 | /* Return the device with MSI unmasked as initial states */ | ||
614 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl); | 632 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl); |
615 | mask = msi_capable_mask(ctrl); | 633 | mask = msi_capable_mask(ctrl); |
616 | msi_mask_irq(desc, mask, ~mask); | 634 | /* Keep cached state to be restored */ |
635 | __msi_mask_irq(desc, mask, ~mask); | ||
617 | 636 | ||
618 | /* Restore dev->irq to its default pin-assertion irq */ | 637 | /* Restore dev->irq to its default pin-assertion irq */ |
619 | dev->irq = desc->msi_attrib.default_irq; | 638 | dev->irq = desc->msi_attrib.default_irq; |
@@ -653,7 +672,6 @@ static int msi_free_irqs(struct pci_dev* dev) | |||
653 | 672 | ||
654 | list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { | 673 | list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { |
655 | if (entry->msi_attrib.is_msix) { | 674 | if (entry->msi_attrib.is_msix) { |
656 | msix_mask_irq(entry, 1); | ||
657 | if (list_is_last(&entry->list, &dev->msi_list)) | 675 | if (list_is_last(&entry->list, &dev->msi_list)) |
658 | iounmap(entry->mask_base); | 676 | iounmap(entry->mask_base); |
659 | } | 677 | } |
@@ -741,9 +759,17 @@ static void msix_free_all_irqs(struct pci_dev *dev) | |||
741 | 759 | ||
742 | void pci_msix_shutdown(struct pci_dev* dev) | 760 | void pci_msix_shutdown(struct pci_dev* dev) |
743 | { | 761 | { |
762 | struct msi_desc *entry; | ||
763 | |||
744 | if (!pci_msi_enable || !dev || !dev->msix_enabled) | 764 | if (!pci_msi_enable || !dev || !dev->msix_enabled) |
745 | return; | 765 | return; |
746 | 766 | ||
767 | /* Return the device with MSI-X masked as initial states */ | ||
768 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
769 | /* Keep cached states to be restored */ | ||
770 | __msix_mask_irq(entry, 1); | ||
771 | } | ||
772 | |||
747 | msix_set_enable(dev, 0); | 773 | msix_set_enable(dev, 0); |
748 | pci_intx_for_msi(dev, 1); | 774 | pci_intx_for_msi(dev, 1); |
749 | dev->msix_enabled = 0; | 775 | dev->msix_enabled = 0; |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index a0662842550b..de27c1cb5a2b 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h | |||
@@ -6,11 +6,11 @@ | |||
6 | #ifndef MSI_H | 6 | #ifndef MSI_H |
7 | #define MSI_H | 7 | #define MSI_H |
8 | 8 | ||
9 | #define PCI_MSIX_ENTRY_SIZE 16 | 9 | #define PCI_MSIX_ENTRY_SIZE 16 |
10 | #define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 | 10 | #define PCI_MSIX_ENTRY_LOWER_ADDR 0 |
11 | #define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 | 11 | #define PCI_MSIX_ENTRY_UPPER_ADDR 4 |
12 | #define PCI_MSIX_ENTRY_DATA_OFFSET 8 | 12 | #define PCI_MSIX_ENTRY_DATA 8 |
13 | #define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12 | 13 | #define PCI_MSIX_ENTRY_VECTOR_CTRL 12 |
14 | 14 | ||
15 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | 15 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) |
16 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) | 16 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6c93af5ced18..dbd0f947f497 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1517,11 +1517,20 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1517 | * | 1517 | * |
1518 | * Perform INTx swizzling for a device behind one level of bridge. This is | 1518 | * Perform INTx swizzling for a device behind one level of bridge. This is |
1519 | * required by section 9.1 of the PCI-to-PCI bridge specification for devices | 1519 | * required by section 9.1 of the PCI-to-PCI bridge specification for devices |
1520 | * behind bridges on add-in cards. | 1520 | * behind bridges on add-in cards. For devices with ARI enabled, the slot |
1521 | * number is always 0 (see the Implementation Note in section 2.2.8.1 of | ||
1522 | * the PCI Express Base Specification, Revision 2.1) | ||
1521 | */ | 1523 | */ |
1522 | u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin) | 1524 | u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin) |
1523 | { | 1525 | { |
1524 | return (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1; | 1526 | int slot; |
1527 | |||
1528 | if (pci_ari_enabled(dev->bus)) | ||
1529 | slot = 0; | ||
1530 | else | ||
1531 | slot = PCI_SLOT(dev->devfn); | ||
1532 | |||
1533 | return (((pin - 1) + slot) % 4) + 1; | ||
1525 | } | 1534 | } |
1526 | 1535 | ||
1527 | int | 1536 | int |
@@ -2171,7 +2180,7 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) | |||
2171 | u16 ctrl; | 2180 | u16 ctrl; |
2172 | struct pci_dev *pdev; | 2181 | struct pci_dev *pdev; |
2173 | 2182 | ||
2174 | if (dev->subordinate) | 2183 | if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self) |
2175 | return -ENOTTY; | 2184 | return -ENOTTY; |
2176 | 2185 | ||
2177 | list_for_each_entry(pdev, &dev->bus->devices, bus_list) | 2186 | list_for_each_entry(pdev, &dev->bus->devices, bus_list) |
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c index ece97df4df6d..a928d8ab6bda 100644 --- a/drivers/pci/pcie/aer/ecrc.c +++ b/drivers/pci/pcie/aer/ecrc.c | |||
@@ -106,7 +106,7 @@ void pcie_set_ecrc_checking(struct pci_dev *dev) | |||
106 | disable_ecrc_checking(dev); | 106 | disable_ecrc_checking(dev); |
107 | break; | 107 | break; |
108 | case ECRC_POLICY_ON: | 108 | case ECRC_POLICY_ON: |
109 | enable_ecrc_checking(dev);; | 109 | enable_ecrc_checking(dev); |
110 | break; | 110 | break; |
111 | default: | 111 | default: |
112 | return; | 112 | return; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 56552d74abea..06b965623962 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1058,6 +1058,11 @@ static void __devinit quirk_no_ata_d3(struct pci_dev *pdev) | |||
1058 | } | 1058 | } |
1059 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3); | 1059 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3); |
1060 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3); | 1060 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3); |
1061 | /* ALi loses some register settings that we cannot then restore */ | ||
1062 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, quirk_no_ata_d3); | ||
1063 | /* VIA comes back fine but we need to keep it alive or ACPI GTM failures | ||
1064 | occur when mode detecting */ | ||
1065 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_no_ata_d3); | ||
1061 | 1066 | ||
1062 | /* This was originally an Alpha specific thing, but it really fits here. | 1067 | /* This was originally an Alpha specific thing, but it really fits here. |
1063 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. | 1068 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index eddb0748b0ea..8c02b6c53bdb 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -311,7 +311,7 @@ EXPORT_SYMBOL_GPL(pci_destroy_slot); | |||
311 | #include <linux/pci_hotplug.h> | 311 | #include <linux/pci_hotplug.h> |
312 | /** | 312 | /** |
313 | * pci_hp_create_link - create symbolic link to the hotplug driver module. | 313 | * pci_hp_create_link - create symbolic link to the hotplug driver module. |
314 | * @slot: struct pci_slot | 314 | * @pci_slot: struct pci_slot |
315 | * | 315 | * |
316 | * Helper function for pci_hotplug_core.c to create symbolic link to | 316 | * Helper function for pci_hotplug_core.c to create symbolic link to |
317 | * the hotplug driver module. | 317 | * the hotplug driver module. |
@@ -334,7 +334,7 @@ EXPORT_SYMBOL_GPL(pci_hp_create_module_link); | |||
334 | 334 | ||
335 | /** | 335 | /** |
336 | * pci_hp_remove_link - remove symbolic link to the hotplug driver module. | 336 | * pci_hp_remove_link - remove symbolic link to the hotplug driver module. |
337 | * @slot: struct pci_slot | 337 | * @pci_slot: struct pci_slot |
338 | * | 338 | * |
339 | * Helper function for pci_hotplug_core.c to remove symbolic link to | 339 | * Helper function for pci_hotplug_core.c to remove symbolic link to |
340 | * the hotplug driver module. | 340 | * the hotplug driver module. |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 9ad97ea836e8..8eb04230fec7 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -472,7 +472,8 @@ static int __init init_tcic(void) | |||
472 | init_timer(&poll_timer); | 472 | init_timer(&poll_timer); |
473 | 473 | ||
474 | /* Build interrupt mask */ | 474 | /* Build interrupt mask */ |
475 | printk(", %d sockets\n" KERN_INFO " irq list (", sockets); | 475 | printk(KERN_CONT ", %d sockets\n", sockets); |
476 | printk(KERN_INFO " irq list ("); | ||
476 | if (irq_list_count == 0) | 477 | if (irq_list_count == 0) |
477 | mask = irq_mask; | 478 | mask = irq_mask; |
478 | else | 479 | else |
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 659421d0ca46..d4ad50d737b0 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services. | 2 | * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services. |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -32,7 +32,7 @@ | |||
32 | #include "i82365.h" | 32 | #include "i82365.h" |
33 | 33 | ||
34 | MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services"); | 34 | MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services"); |
35 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | 35 | MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); |
36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
37 | 37 | ||
38 | #define CARD_MAX_SLOTS 2 | 38 | #define CARD_MAX_SLOTS 2 |
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index 812f038e9bda..9b3c15827e5c 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * NEC VRC4173 CARDU driver for Socket Services | 6 | * NEC VRC4173 CARDU driver for Socket Services |
7 | * (This device doesn't support CardBus. it is supporting only 16bit PC Card.) | 7 | * (This device doesn't support CardBus. it is supporting only 16bit PC Card.) |
8 | * | 8 | * |
9 | * Copyright 2002,2003 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 9 | * Copyright 2002,2003 Yoichi Yuasa <yuasa@linux-mips.org> |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
@@ -41,7 +41,7 @@ | |||
41 | #include "vrc4173_cardu.h" | 41 | #include "vrc4173_cardu.h" |
42 | 42 | ||
43 | MODULE_DESCRIPTION("NEC VRC4173 CARDU driver for Socket Services"); | 43 | MODULE_DESCRIPTION("NEC VRC4173 CARDU driver for Socket Services"); |
44 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | 44 | MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); |
45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
46 | 46 | ||
47 | static int vrc4173_cardu_slots; | 47 | static int vrc4173_cardu_slots; |
diff --git a/drivers/pcmcia/vrc4173_cardu.h b/drivers/pcmcia/vrc4173_cardu.h index 7d77c74120c1..a7d96018ed8d 100644 --- a/drivers/pcmcia/vrc4173_cardu.h +++ b/drivers/pcmcia/vrc4173_cardu.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * BRIEF MODULE DESCRIPTION | 5 | * BRIEF MODULE DESCRIPTION |
6 | * Include file for NEC VRC4173 CARDU. | 6 | * Include file for NEC VRC4173 CARDU. |
7 | * | 7 | * |
8 | * Copyright 2002 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 8 | * Copyright 2002 Yoichi Yuasa <yuasa@linux-mips.org> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
11 | * under the terms of the GNU General Public License as published by the | 11 | * under the terms of the GNU General Public License as published by the |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 7232fe7104aa..46dad12f952f 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -355,6 +355,7 @@ config EEEPC_LAPTOP | |||
355 | depends on INPUT | 355 | depends on INPUT |
356 | depends on EXPERIMENTAL | 356 | depends on EXPERIMENTAL |
357 | depends on RFKILL || RFKILL = n | 357 | depends on RFKILL || RFKILL = n |
358 | depends on HOTPLUG_PCI | ||
358 | select BACKLIGHT_CLASS_DEVICE | 359 | select BACKLIGHT_CLASS_DEVICE |
359 | select HWMON | 360 | select HWMON |
360 | ---help--- | 361 | ---help--- |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 4207b26ff990..ec560f16d720 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
19 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 22 | #include <linux/module.h> |
21 | #include <linux/init.h> | 23 | #include <linux/init.h> |
@@ -31,6 +33,7 @@ | |||
31 | #include <linux/input.h> | 33 | #include <linux/input.h> |
32 | #include <linux/rfkill.h> | 34 | #include <linux/rfkill.h> |
33 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
34 | 37 | ||
35 | #define EEEPC_LAPTOP_VERSION "0.1" | 38 | #define EEEPC_LAPTOP_VERSION "0.1" |
36 | 39 | ||
@@ -40,11 +43,6 @@ | |||
40 | #define EEEPC_HOTK_DEVICE_NAME "Hotkey" | 43 | #define EEEPC_HOTK_DEVICE_NAME "Hotkey" |
41 | #define EEEPC_HOTK_HID "ASUS010" | 44 | #define EEEPC_HOTK_HID "ASUS010" |
42 | 45 | ||
43 | #define EEEPC_LOG EEEPC_HOTK_FILE ": " | ||
44 | #define EEEPC_ERR KERN_ERR EEEPC_LOG | ||
45 | #define EEEPC_WARNING KERN_WARNING EEEPC_LOG | ||
46 | #define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG | ||
47 | #define EEEPC_INFO KERN_INFO EEEPC_LOG | ||
48 | 46 | ||
49 | /* | 47 | /* |
50 | * Definitions for Asus EeePC | 48 | * Definitions for Asus EeePC |
@@ -141,8 +139,10 @@ struct eeepc_hotk { | |||
141 | u16 event_count[128]; /* count for each event */ | 139 | u16 event_count[128]; /* count for each event */ |
142 | struct input_dev *inputdev; | 140 | struct input_dev *inputdev; |
143 | u16 *keycode_map; | 141 | u16 *keycode_map; |
144 | struct rfkill *eeepc_wlan_rfkill; | 142 | struct rfkill *wlan_rfkill; |
145 | struct rfkill *eeepc_bluetooth_rfkill; | 143 | struct rfkill *bluetooth_rfkill; |
144 | struct rfkill *wwan3g_rfkill; | ||
145 | struct hotplug_slot *hotplug_slot; | ||
146 | }; | 146 | }; |
147 | 147 | ||
148 | /* The actual device the driver binds to */ | 148 | /* The actual device the driver binds to */ |
@@ -213,6 +213,15 @@ static struct acpi_driver eeepc_hotk_driver = { | |||
213 | }, | 213 | }, |
214 | }; | 214 | }; |
215 | 215 | ||
216 | /* PCI hotplug ops */ | ||
217 | static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value); | ||
218 | |||
219 | static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { | ||
220 | .owner = THIS_MODULE, | ||
221 | .get_adapter_status = eeepc_get_adapter_status, | ||
222 | .get_power_status = eeepc_get_adapter_status, | ||
223 | }; | ||
224 | |||
216 | /* The backlight device /sys/class/backlight */ | 225 | /* The backlight device /sys/class/backlight */ |
217 | static struct backlight_device *eeepc_backlight_device; | 226 | static struct backlight_device *eeepc_backlight_device; |
218 | 227 | ||
@@ -274,20 +283,20 @@ static int set_acpi(int cm, int value) | |||
274 | if (method == NULL) | 283 | if (method == NULL) |
275 | return -ENODEV; | 284 | return -ENODEV; |
276 | if (write_acpi_int(ehotk->handle, method, value, NULL)) | 285 | if (write_acpi_int(ehotk->handle, method, value, NULL)) |
277 | printk(EEEPC_WARNING "Error writing %s\n", method); | 286 | pr_warning("Error writing %s\n", method); |
278 | } | 287 | } |
279 | return 0; | 288 | return 0; |
280 | } | 289 | } |
281 | 290 | ||
282 | static int get_acpi(int cm) | 291 | static int get_acpi(int cm) |
283 | { | 292 | { |
284 | int value = -1; | 293 | int value = -ENODEV; |
285 | if ((ehotk->cm_supported & (0x1 << cm))) { | 294 | if ((ehotk->cm_supported & (0x1 << cm))) { |
286 | const char *method = cm_getv[cm]; | 295 | const char *method = cm_getv[cm]; |
287 | if (method == NULL) | 296 | if (method == NULL) |
288 | return -ENODEV; | 297 | return -ENODEV; |
289 | if (read_acpi_int(ehotk->handle, method, &value)) | 298 | if (read_acpi_int(ehotk->handle, method, &value)) |
290 | printk(EEEPC_WARNING "Error reading %s\n", method); | 299 | pr_warning("Error reading %s\n", method); |
291 | } | 300 | } |
292 | return value; | 301 | return value; |
293 | } | 302 | } |
@@ -359,13 +368,19 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) | |||
359 | 368 | ||
360 | rv = parse_arg(buf, count, &value); | 369 | rv = parse_arg(buf, count, &value); |
361 | if (rv > 0) | 370 | if (rv > 0) |
362 | set_acpi(cm, value); | 371 | value = set_acpi(cm, value); |
372 | if (value < 0) | ||
373 | return value; | ||
363 | return rv; | 374 | return rv; |
364 | } | 375 | } |
365 | 376 | ||
366 | static ssize_t show_sys_acpi(int cm, char *buf) | 377 | static ssize_t show_sys_acpi(int cm, char *buf) |
367 | { | 378 | { |
368 | return sprintf(buf, "%d\n", get_acpi(cm)); | 379 | int value = get_acpi(cm); |
380 | |||
381 | if (value < 0) | ||
382 | return value; | ||
383 | return sprintf(buf, "%d\n", value); | ||
369 | } | 384 | } |
370 | 385 | ||
371 | #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ | 386 | #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ |
@@ -539,6 +554,28 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) | |||
539 | return -EINVAL; | 554 | return -EINVAL; |
540 | } | 555 | } |
541 | 556 | ||
557 | static void cmsg_quirk(int cm, const char *name) | ||
558 | { | ||
559 | int dummy; | ||
560 | |||
561 | /* Some BIOSes do not report cm although it is avaliable. | ||
562 | Check if cm_getv[cm] works and, if yes, assume cm should be set. */ | ||
563 | if (!(ehotk->cm_supported & (1 << cm)) | ||
564 | && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) { | ||
565 | pr_info("%s (%x) not reported by BIOS," | ||
566 | " enabling anyway\n", name, 1 << cm); | ||
567 | ehotk->cm_supported |= 1 << cm; | ||
568 | } | ||
569 | } | ||
570 | |||
571 | static void cmsg_quirks(void) | ||
572 | { | ||
573 | cmsg_quirk(CM_ASL_LID, "LID"); | ||
574 | cmsg_quirk(CM_ASL_TYPE, "TYPE"); | ||
575 | cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER"); | ||
576 | cmsg_quirk(CM_ASL_TPD, "TPD"); | ||
577 | } | ||
578 | |||
542 | static int eeepc_hotk_check(void) | 579 | static int eeepc_hotk_check(void) |
543 | { | 580 | { |
544 | const struct key_entry *key; | 581 | const struct key_entry *key; |
@@ -551,26 +588,24 @@ static int eeepc_hotk_check(void) | |||
551 | if (ehotk->device->status.present) { | 588 | if (ehotk->device->status.present) { |
552 | if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, | 589 | if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, |
553 | &buffer)) { | 590 | &buffer)) { |
554 | printk(EEEPC_ERR "Hotkey initialization failed\n"); | 591 | pr_err("Hotkey initialization failed\n"); |
555 | return -ENODEV; | 592 | return -ENODEV; |
556 | } else { | 593 | } else { |
557 | printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", | 594 | pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag); |
558 | ehotk->init_flag); | ||
559 | } | 595 | } |
560 | /* get control methods supported */ | 596 | /* get control methods supported */ |
561 | if (read_acpi_int(ehotk->handle, "CMSG" | 597 | if (read_acpi_int(ehotk->handle, "CMSG" |
562 | , &ehotk->cm_supported)) { | 598 | , &ehotk->cm_supported)) { |
563 | printk(EEEPC_ERR | 599 | pr_err("Get control methods supported failed\n"); |
564 | "Get control methods supported failed\n"); | ||
565 | return -ENODEV; | 600 | return -ENODEV; |
566 | } else { | 601 | } else { |
567 | printk(EEEPC_INFO | 602 | cmsg_quirks(); |
568 | "Get control methods supported: 0x%x\n", | 603 | pr_info("Get control methods supported: 0x%x\n", |
569 | ehotk->cm_supported); | 604 | ehotk->cm_supported); |
570 | } | 605 | } |
571 | ehotk->inputdev = input_allocate_device(); | 606 | ehotk->inputdev = input_allocate_device(); |
572 | if (!ehotk->inputdev) { | 607 | if (!ehotk->inputdev) { |
573 | printk(EEEPC_INFO "Unable to allocate input device\n"); | 608 | pr_info("Unable to allocate input device\n"); |
574 | return 0; | 609 | return 0; |
575 | } | 610 | } |
576 | ehotk->inputdev->name = "Asus EeePC extra buttons"; | 611 | ehotk->inputdev->name = "Asus EeePC extra buttons"; |
@@ -589,12 +624,12 @@ static int eeepc_hotk_check(void) | |||
589 | } | 624 | } |
590 | result = input_register_device(ehotk->inputdev); | 625 | result = input_register_device(ehotk->inputdev); |
591 | if (result) { | 626 | if (result) { |
592 | printk(EEEPC_INFO "Unable to register input device\n"); | 627 | pr_info("Unable to register input device\n"); |
593 | input_free_device(ehotk->inputdev); | 628 | input_free_device(ehotk->inputdev); |
594 | return 0; | 629 | return 0; |
595 | } | 630 | } |
596 | } else { | 631 | } else { |
597 | printk(EEEPC_ERR "Hotkey device not present, aborting\n"); | 632 | pr_err("Hotkey device not present, aborting\n"); |
598 | return -EINVAL; | 633 | return -EINVAL; |
599 | } | 634 | } |
600 | return 0; | 635 | return 0; |
@@ -612,6 +647,19 @@ static int notify_brn(void) | |||
612 | return -1; | 647 | return -1; |
613 | } | 648 | } |
614 | 649 | ||
650 | static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, | ||
651 | u8 *value) | ||
652 | { | ||
653 | int val = get_acpi(CM_ASL_WLAN); | ||
654 | |||
655 | if (val == 1 || val == 0) | ||
656 | *value = val; | ||
657 | else | ||
658 | return -EINVAL; | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
615 | static void eeepc_rfkill_hotplug(void) | 663 | static void eeepc_rfkill_hotplug(void) |
616 | { | 664 | { |
617 | struct pci_dev *dev; | 665 | struct pci_dev *dev; |
@@ -619,7 +667,7 @@ static void eeepc_rfkill_hotplug(void) | |||
619 | bool blocked; | 667 | bool blocked; |
620 | 668 | ||
621 | if (!bus) { | 669 | if (!bus) { |
622 | printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); | 670 | pr_warning("Unable to find PCI bus 1?\n"); |
623 | return; | 671 | return; |
624 | } | 672 | } |
625 | 673 | ||
@@ -635,7 +683,7 @@ static void eeepc_rfkill_hotplug(void) | |||
635 | if (dev) { | 683 | if (dev) { |
636 | pci_bus_assign_resources(bus); | 684 | pci_bus_assign_resources(bus); |
637 | if (pci_bus_add_device(dev)) | 685 | if (pci_bus_add_device(dev)) |
638 | printk(EEEPC_ERR "Unable to hotplug wifi\n"); | 686 | pr_err("Unable to hotplug wifi\n"); |
639 | } | 687 | } |
640 | } else { | 688 | } else { |
641 | dev = pci_get_slot(bus, 0); | 689 | dev = pci_get_slot(bus, 0); |
@@ -645,7 +693,7 @@ static void eeepc_rfkill_hotplug(void) | |||
645 | } | 693 | } |
646 | } | 694 | } |
647 | 695 | ||
648 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); | 696 | rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); |
649 | } | 697 | } |
650 | 698 | ||
651 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 699 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
@@ -718,8 +766,7 @@ static int eeepc_register_rfkill_notifier(char *node) | |||
718 | eeepc_rfkill_notify, | 766 | eeepc_rfkill_notify, |
719 | NULL); | 767 | NULL); |
720 | if (ACPI_FAILURE(status)) | 768 | if (ACPI_FAILURE(status)) |
721 | printk(EEEPC_WARNING | 769 | pr_warning("Failed to register notify on %s\n", node); |
722 | "Failed to register notify on %s\n", node); | ||
723 | } else | 770 | } else |
724 | return -ENODEV; | 771 | return -ENODEV; |
725 | 772 | ||
@@ -738,19 +785,66 @@ static void eeepc_unregister_rfkill_notifier(char *node) | |||
738 | ACPI_SYSTEM_NOTIFY, | 785 | ACPI_SYSTEM_NOTIFY, |
739 | eeepc_rfkill_notify); | 786 | eeepc_rfkill_notify); |
740 | if (ACPI_FAILURE(status)) | 787 | if (ACPI_FAILURE(status)) |
741 | printk(EEEPC_ERR | 788 | pr_err("Error removing rfkill notify handler %s\n", |
742 | "Error removing rfkill notify handler %s\n", | ||
743 | node); | 789 | node); |
744 | } | 790 | } |
745 | } | 791 | } |
746 | 792 | ||
793 | static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) | ||
794 | { | ||
795 | kfree(hotplug_slot->info); | ||
796 | kfree(hotplug_slot); | ||
797 | } | ||
798 | |||
799 | static int eeepc_setup_pci_hotplug(void) | ||
800 | { | ||
801 | int ret = -ENOMEM; | ||
802 | struct pci_bus *bus = pci_find_bus(0, 1); | ||
803 | |||
804 | if (!bus) { | ||
805 | pr_err("Unable to find wifi PCI bus\n"); | ||
806 | return -ENODEV; | ||
807 | } | ||
808 | |||
809 | ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); | ||
810 | if (!ehotk->hotplug_slot) | ||
811 | goto error_slot; | ||
812 | |||
813 | ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), | ||
814 | GFP_KERNEL); | ||
815 | if (!ehotk->hotplug_slot->info) | ||
816 | goto error_info; | ||
817 | |||
818 | ehotk->hotplug_slot->private = ehotk; | ||
819 | ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; | ||
820 | ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops; | ||
821 | eeepc_get_adapter_status(ehotk->hotplug_slot, | ||
822 | &ehotk->hotplug_slot->info->adapter_status); | ||
823 | |||
824 | ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi"); | ||
825 | if (ret) { | ||
826 | pr_err("Unable to register hotplug slot - %d\n", ret); | ||
827 | goto error_register; | ||
828 | } | ||
829 | |||
830 | return 0; | ||
831 | |||
832 | error_register: | ||
833 | kfree(ehotk->hotplug_slot->info); | ||
834 | error_info: | ||
835 | kfree(ehotk->hotplug_slot); | ||
836 | ehotk->hotplug_slot = NULL; | ||
837 | error_slot: | ||
838 | return ret; | ||
839 | } | ||
840 | |||
747 | static int eeepc_hotk_add(struct acpi_device *device) | 841 | static int eeepc_hotk_add(struct acpi_device *device) |
748 | { | 842 | { |
749 | int result; | 843 | int result; |
750 | 844 | ||
751 | if (!device) | 845 | if (!device) |
752 | return -EINVAL; | 846 | return -EINVAL; |
753 | printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); | 847 | pr_notice(EEEPC_HOTK_NAME "\n"); |
754 | ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); | 848 | ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); |
755 | if (!ehotk) | 849 | if (!ehotk) |
756 | return -ENOMEM; | 850 | return -ENOMEM; |
@@ -764,53 +858,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
764 | if (result) | 858 | if (result) |
765 | goto ehotk_fail; | 859 | goto ehotk_fail; |
766 | 860 | ||
767 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
768 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
769 | |||
770 | if (get_acpi(CM_ASL_WLAN) != -1) { | ||
771 | ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan", | ||
772 | &device->dev, | ||
773 | RFKILL_TYPE_WLAN, | ||
774 | &eeepc_rfkill_ops, | ||
775 | (void *)CM_ASL_WLAN); | ||
776 | |||
777 | if (!ehotk->eeepc_wlan_rfkill) | ||
778 | goto wlan_fail; | ||
779 | |||
780 | rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill, | ||
781 | get_acpi(CM_ASL_WLAN) != 1); | ||
782 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); | ||
783 | if (result) | ||
784 | goto wlan_fail; | ||
785 | } | ||
786 | |||
787 | if (get_acpi(CM_ASL_BLUETOOTH) != -1) { | ||
788 | ehotk->eeepc_bluetooth_rfkill = | ||
789 | rfkill_alloc("eeepc-bluetooth", | ||
790 | &device->dev, | ||
791 | RFKILL_TYPE_BLUETOOTH, | ||
792 | &eeepc_rfkill_ops, | ||
793 | (void *)CM_ASL_BLUETOOTH); | ||
794 | |||
795 | if (!ehotk->eeepc_bluetooth_rfkill) | ||
796 | goto bluetooth_fail; | ||
797 | |||
798 | rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill, | ||
799 | get_acpi(CM_ASL_BLUETOOTH) != 1); | ||
800 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); | ||
801 | if (result) | ||
802 | goto bluetooth_fail; | ||
803 | } | ||
804 | |||
805 | return 0; | 861 | return 0; |
806 | 862 | ||
807 | bluetooth_fail: | ||
808 | rfkill_destroy(ehotk->eeepc_bluetooth_rfkill); | ||
809 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | ||
810 | wlan_fail: | ||
811 | rfkill_destroy(ehotk->eeepc_wlan_rfkill); | ||
812 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
813 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
814 | ehotk_fail: | 863 | ehotk_fail: |
815 | kfree(ehotk); | 864 | kfree(ehotk); |
816 | ehotk = NULL; | 865 | ehotk = NULL; |
@@ -823,16 +872,13 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) | |||
823 | if (!device || !acpi_driver_data(device)) | 872 | if (!device || !acpi_driver_data(device)) |
824 | return -EINVAL; | 873 | return -EINVAL; |
825 | 874 | ||
826 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
827 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
828 | |||
829 | kfree(ehotk); | 875 | kfree(ehotk); |
830 | return 0; | 876 | return 0; |
831 | } | 877 | } |
832 | 878 | ||
833 | static int eeepc_hotk_resume(struct acpi_device *device) | 879 | static int eeepc_hotk_resume(struct acpi_device *device) |
834 | { | 880 | { |
835 | if (ehotk->eeepc_wlan_rfkill) { | 881 | if (ehotk->wlan_rfkill) { |
836 | bool wlan; | 882 | bool wlan; |
837 | 883 | ||
838 | /* Workaround - it seems that _PTS disables the wireless | 884 | /* Workaround - it seems that _PTS disables the wireless |
@@ -844,14 +890,13 @@ static int eeepc_hotk_resume(struct acpi_device *device) | |||
844 | wlan = get_acpi(CM_ASL_WLAN); | 890 | wlan = get_acpi(CM_ASL_WLAN); |
845 | set_acpi(CM_ASL_WLAN, wlan); | 891 | set_acpi(CM_ASL_WLAN, wlan); |
846 | 892 | ||
847 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, | 893 | rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); |
848 | wlan != 1); | ||
849 | 894 | ||
850 | eeepc_rfkill_hotplug(); | 895 | eeepc_rfkill_hotplug(); |
851 | } | 896 | } |
852 | 897 | ||
853 | if (ehotk->eeepc_bluetooth_rfkill) | 898 | if (ehotk->bluetooth_rfkill) |
854 | rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, | 899 | rfkill_set_sw_state(ehotk->bluetooth_rfkill, |
855 | get_acpi(CM_ASL_BLUETOOTH) != 1); | 900 | get_acpi(CM_ASL_BLUETOOTH) != 1); |
856 | 901 | ||
857 | return 0; | 902 | return 0; |
@@ -973,10 +1018,16 @@ static void eeepc_backlight_exit(void) | |||
973 | 1018 | ||
974 | static void eeepc_rfkill_exit(void) | 1019 | static void eeepc_rfkill_exit(void) |
975 | { | 1020 | { |
976 | if (ehotk->eeepc_wlan_rfkill) | 1021 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); |
977 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | 1022 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); |
978 | if (ehotk->eeepc_bluetooth_rfkill) | 1023 | if (ehotk->wlan_rfkill) |
979 | rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); | 1024 | rfkill_unregister(ehotk->wlan_rfkill); |
1025 | if (ehotk->bluetooth_rfkill) | ||
1026 | rfkill_unregister(ehotk->bluetooth_rfkill); | ||
1027 | if (ehotk->wwan3g_rfkill) | ||
1028 | rfkill_unregister(ehotk->wwan3g_rfkill); | ||
1029 | if (ehotk->hotplug_slot) | ||
1030 | pci_hp_deregister(ehotk->hotplug_slot); | ||
980 | } | 1031 | } |
981 | 1032 | ||
982 | static void eeepc_input_exit(void) | 1033 | static void eeepc_input_exit(void) |
@@ -1011,6 +1062,75 @@ static void __exit eeepc_laptop_exit(void) | |||
1011 | platform_driver_unregister(&platform_driver); | 1062 | platform_driver_unregister(&platform_driver); |
1012 | } | 1063 | } |
1013 | 1064 | ||
1065 | static int eeepc_new_rfkill(struct rfkill **rfkill, | ||
1066 | const char *name, struct device *dev, | ||
1067 | enum rfkill_type type, int cm) | ||
1068 | { | ||
1069 | int result; | ||
1070 | |||
1071 | result = get_acpi(cm); | ||
1072 | if (result < 0) | ||
1073 | return result; | ||
1074 | |||
1075 | *rfkill = rfkill_alloc(name, dev, type, | ||
1076 | &eeepc_rfkill_ops, (void *)(unsigned long)cm); | ||
1077 | |||
1078 | if (!*rfkill) | ||
1079 | return -EINVAL; | ||
1080 | |||
1081 | rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); | ||
1082 | result = rfkill_register(*rfkill); | ||
1083 | if (result) { | ||
1084 | rfkill_destroy(*rfkill); | ||
1085 | *rfkill = NULL; | ||
1086 | return result; | ||
1087 | } | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | |||
1092 | static int eeepc_rfkill_init(struct device *dev) | ||
1093 | { | ||
1094 | int result = 0; | ||
1095 | |||
1096 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
1097 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
1098 | |||
1099 | result = eeepc_new_rfkill(&ehotk->wlan_rfkill, | ||
1100 | "eeepc-wlan", dev, | ||
1101 | RFKILL_TYPE_WLAN, CM_ASL_WLAN); | ||
1102 | |||
1103 | if (result && result != -ENODEV) | ||
1104 | goto exit; | ||
1105 | |||
1106 | result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, | ||
1107 | "eeepc-bluetooth", dev, | ||
1108 | RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); | ||
1109 | |||
1110 | if (result && result != -ENODEV) | ||
1111 | goto exit; | ||
1112 | |||
1113 | result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, | ||
1114 | "eeepc-wwan3g", dev, | ||
1115 | RFKILL_TYPE_WWAN, CM_ASL_3G); | ||
1116 | |||
1117 | if (result && result != -ENODEV) | ||
1118 | goto exit; | ||
1119 | |||
1120 | result = eeepc_setup_pci_hotplug(); | ||
1121 | /* | ||
1122 | * If we get -EBUSY then something else is handling the PCI hotplug - | ||
1123 | * don't fail in this case | ||
1124 | */ | ||
1125 | if (result == -EBUSY) | ||
1126 | result = 0; | ||
1127 | |||
1128 | exit: | ||
1129 | if (result && result != -ENODEV) | ||
1130 | eeepc_rfkill_exit(); | ||
1131 | return result; | ||
1132 | } | ||
1133 | |||
1014 | static int eeepc_backlight_init(struct device *dev) | 1134 | static int eeepc_backlight_init(struct device *dev) |
1015 | { | 1135 | { |
1016 | struct backlight_device *bd; | 1136 | struct backlight_device *bd; |
@@ -1018,8 +1138,7 @@ static int eeepc_backlight_init(struct device *dev) | |||
1018 | bd = backlight_device_register(EEEPC_HOTK_FILE, dev, | 1138 | bd = backlight_device_register(EEEPC_HOTK_FILE, dev, |
1019 | NULL, &eeepcbl_ops); | 1139 | NULL, &eeepcbl_ops); |
1020 | if (IS_ERR(bd)) { | 1140 | if (IS_ERR(bd)) { |
1021 | printk(EEEPC_ERR | 1141 | pr_err("Could not register eeepc backlight device\n"); |
1022 | "Could not register eeepc backlight device\n"); | ||
1023 | eeepc_backlight_device = NULL; | 1142 | eeepc_backlight_device = NULL; |
1024 | return PTR_ERR(bd); | 1143 | return PTR_ERR(bd); |
1025 | } | 1144 | } |
@@ -1038,8 +1157,7 @@ static int eeepc_hwmon_init(struct device *dev) | |||
1038 | 1157 | ||
1039 | hwmon = hwmon_device_register(dev); | 1158 | hwmon = hwmon_device_register(dev); |
1040 | if (IS_ERR(hwmon)) { | 1159 | if (IS_ERR(hwmon)) { |
1041 | printk(EEEPC_ERR | 1160 | pr_err("Could not register eeepc hwmon device\n"); |
1042 | "Could not register eeepc hwmon device\n"); | ||
1043 | eeepc_hwmon_device = NULL; | 1161 | eeepc_hwmon_device = NULL; |
1044 | return PTR_ERR(hwmon); | 1162 | return PTR_ERR(hwmon); |
1045 | } | 1163 | } |
@@ -1065,19 +1183,6 @@ static int __init eeepc_laptop_init(void) | |||
1065 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | 1183 | acpi_bus_unregister_driver(&eeepc_hotk_driver); |
1066 | return -ENODEV; | 1184 | return -ENODEV; |
1067 | } | 1185 | } |
1068 | dev = acpi_get_physical_device(ehotk->device->handle); | ||
1069 | |||
1070 | if (!acpi_video_backlight_support()) { | ||
1071 | result = eeepc_backlight_init(dev); | ||
1072 | if (result) | ||
1073 | goto fail_backlight; | ||
1074 | } else | ||
1075 | printk(EEEPC_INFO "Backlight controlled by ACPI video " | ||
1076 | "driver\n"); | ||
1077 | |||
1078 | result = eeepc_hwmon_init(dev); | ||
1079 | if (result) | ||
1080 | goto fail_hwmon; | ||
1081 | 1186 | ||
1082 | eeepc_enable_camera(); | 1187 | eeepc_enable_camera(); |
1083 | 1188 | ||
@@ -1097,7 +1202,33 @@ static int __init eeepc_laptop_init(void) | |||
1097 | &platform_attribute_group); | 1202 | &platform_attribute_group); |
1098 | if (result) | 1203 | if (result) |
1099 | goto fail_sysfs; | 1204 | goto fail_sysfs; |
1205 | |||
1206 | dev = &platform_device->dev; | ||
1207 | |||
1208 | if (!acpi_video_backlight_support()) { | ||
1209 | result = eeepc_backlight_init(dev); | ||
1210 | if (result) | ||
1211 | goto fail_backlight; | ||
1212 | } else | ||
1213 | pr_info("Backlight controlled by ACPI video " | ||
1214 | "driver\n"); | ||
1215 | |||
1216 | result = eeepc_hwmon_init(dev); | ||
1217 | if (result) | ||
1218 | goto fail_hwmon; | ||
1219 | |||
1220 | result = eeepc_rfkill_init(dev); | ||
1221 | if (result) | ||
1222 | goto fail_rfkill; | ||
1223 | |||
1100 | return 0; | 1224 | return 0; |
1225 | fail_rfkill: | ||
1226 | eeepc_hwmon_exit(); | ||
1227 | fail_hwmon: | ||
1228 | eeepc_backlight_exit(); | ||
1229 | fail_backlight: | ||
1230 | sysfs_remove_group(&platform_device->dev.kobj, | ||
1231 | &platform_attribute_group); | ||
1101 | fail_sysfs: | 1232 | fail_sysfs: |
1102 | platform_device_del(platform_device); | 1233 | platform_device_del(platform_device); |
1103 | fail_platform_device2: | 1234 | fail_platform_device2: |
@@ -1105,12 +1236,7 @@ fail_platform_device2: | |||
1105 | fail_platform_device1: | 1236 | fail_platform_device1: |
1106 | platform_driver_unregister(&platform_driver); | 1237 | platform_driver_unregister(&platform_driver); |
1107 | fail_platform_driver: | 1238 | fail_platform_driver: |
1108 | eeepc_hwmon_exit(); | ||
1109 | fail_hwmon: | ||
1110 | eeepc_backlight_exit(); | ||
1111 | fail_backlight: | ||
1112 | eeepc_input_exit(); | 1239 | eeepc_input_exit(); |
1113 | eeepc_rfkill_exit(); | ||
1114 | return result; | 1240 | return result; |
1115 | } | 1241 | } |
1116 | 1242 | ||
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 4ac2311c00af..ca508564a181 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -171,7 +171,7 @@ static int hp_wmi_tablet_state(void) | |||
171 | static int hp_wmi_set_block(void *data, bool blocked) | 171 | static int hp_wmi_set_block(void *data, bool blocked) |
172 | { | 172 | { |
173 | unsigned long b = (unsigned long) data; | 173 | unsigned long b = (unsigned long) data; |
174 | int query = BIT(b + 8) | ((!!blocked) << b); | 174 | int query = BIT(b + 8) | ((!blocked) << b); |
175 | 175 | ||
176 | return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); | 176 | return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); |
177 | } | 177 | } |
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index aafd3e6ebb0d..a118eb0f1e67 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Real Time Clock Driver | 2 | * Blackfin On-Chip Real Time Clock Driver |
3 | * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789] | 3 | * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x |
4 | * | 4 | * |
5 | * Copyright 2004-2008 Analog Devices Inc. | 5 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * | 6 | * |
7 | * Enter bugs at http://blackfin.uclinux.org/ | 7 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * | 8 | * |
@@ -363,7 +363,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
363 | struct bfin_rtc *rtc; | 363 | struct bfin_rtc *rtc; |
364 | struct device *dev = &pdev->dev; | 364 | struct device *dev = &pdev->dev; |
365 | int ret = 0; | 365 | int ret = 0; |
366 | unsigned long timeout; | 366 | unsigned long timeout = jiffies + HZ; |
367 | 367 | ||
368 | dev_dbg_stamp(dev); | 368 | dev_dbg_stamp(dev); |
369 | 369 | ||
@@ -374,32 +374,32 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
374 | platform_set_drvdata(pdev, rtc); | 374 | platform_set_drvdata(pdev, rtc); |
375 | device_init_wakeup(dev, 1); | 375 | device_init_wakeup(dev, 1); |
376 | 376 | ||
377 | /* Register our RTC with the RTC framework */ | ||
378 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, | ||
379 | THIS_MODULE); | ||
380 | if (unlikely(IS_ERR(rtc->rtc_dev))) { | ||
381 | ret = PTR_ERR(rtc->rtc_dev); | ||
382 | goto err; | ||
383 | } | ||
384 | |||
377 | /* Grab the IRQ and init the hardware */ | 385 | /* Grab the IRQ and init the hardware */ |
378 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev); | 386 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev); |
379 | if (unlikely(ret)) | 387 | if (unlikely(ret)) |
380 | goto err; | 388 | goto err_reg; |
381 | /* sometimes the bootloader touched things, but the write complete was not | 389 | /* sometimes the bootloader touched things, but the write complete was not |
382 | * enabled, so let's just do a quick timeout here since the IRQ will not fire ... | 390 | * enabled, so let's just do a quick timeout here since the IRQ will not fire ... |
383 | */ | 391 | */ |
384 | timeout = jiffies + HZ; | ||
385 | while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) | 392 | while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) |
386 | if (time_after(jiffies, timeout)) | 393 | if (time_after(jiffies, timeout)) |
387 | break; | 394 | break; |
388 | bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE); | 395 | bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE); |
389 | bfin_write_RTC_SWCNT(0); | 396 | bfin_write_RTC_SWCNT(0); |
390 | 397 | ||
391 | /* Register our RTC with the RTC framework */ | ||
392 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); | ||
393 | if (unlikely(IS_ERR(rtc->rtc_dev))) { | ||
394 | ret = PTR_ERR(rtc->rtc_dev); | ||
395 | goto err_irq; | ||
396 | } | ||
397 | |||
398 | return 0; | 398 | return 0; |
399 | 399 | ||
400 | err_irq: | 400 | err_reg: |
401 | free_irq(IRQ_RTC, dev); | 401 | rtc_device_unregister(rtc->rtc_dev); |
402 | err: | 402 | err: |
403 | kfree(rtc); | 403 | kfree(rtc); |
404 | return ret; | 404 | return ret; |
405 | } | 405 | } |
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 32b27739ec2a..713f7bf5afb3 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -283,7 +283,7 @@ static void ds1374_work(struct work_struct *work) | |||
283 | 283 | ||
284 | stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR); | 284 | stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR); |
285 | if (stat < 0) | 285 | if (stat < 0) |
286 | return; | 286 | goto unlock; |
287 | 287 | ||
288 | if (stat & DS1374_REG_SR_AF) { | 288 | if (stat & DS1374_REG_SR_AF) { |
289 | stat &= ~DS1374_REG_SR_AF; | 289 | stat &= ~DS1374_REG_SR_AF; |
@@ -302,7 +302,7 @@ static void ds1374_work(struct work_struct *work) | |||
302 | out: | 302 | out: |
303 | if (!ds1374->exiting) | 303 | if (!ds1374->exiting) |
304 | enable_irq(client->irq); | 304 | enable_irq(client->irq); |
305 | 305 | unlock: | |
306 | mutex_unlock(&ds1374->mutex); | 306 | mutex_unlock(&ds1374->mutex); |
307 | } | 307 | } |
308 | 308 | ||
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index f11297aff854..2c839d0d21bd 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Real Time Clock unit. | 2 | * Driver for NEC VR4100 series Real Time Clock unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2003-2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -33,7 +33,7 @@ | |||
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | 35 | ||
36 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | 36 | MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); |
37 | MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); | 37 | MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); |
38 | MODULE_LICENSE("GPL v2"); | 38 | MODULE_LICENSE("GPL v2"); |
39 | 39 | ||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index f8b1f04f26b8..c11770f5b368 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1696,8 +1696,7 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device, | |||
1696 | DBF_DEV_EVENT(DBF_ERR, device, "%s", | 1696 | DBF_DEV_EVENT(DBF_ERR, device, "%s", |
1697 | "unsolicited interrupt received " | 1697 | "unsolicited interrupt received " |
1698 | "(sense available)"); | 1698 | "(sense available)"); |
1699 | device->discipline->dump_sense_dbf(device, NULL, irb, | 1699 | device->discipline->dump_sense_dbf(device, irb, "unsolicited"); |
1700 | "unsolicited"); | ||
1701 | } | 1700 | } |
1702 | 1701 | ||
1703 | dasd_schedule_device_bh(device); | 1702 | dasd_schedule_device_bh(device); |
@@ -2941,42 +2940,20 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) | |||
2941 | } | 2940 | } |
2942 | 2941 | ||
2943 | static void | 2942 | static void |
2944 | dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, | 2943 | dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb, |
2945 | struct irb *irb, char *reason) | 2944 | char *reason) |
2946 | { | 2945 | { |
2947 | u64 *sense; | 2946 | u64 *sense; |
2948 | int sl; | ||
2949 | struct tsb *tsb; | ||
2950 | 2947 | ||
2951 | sense = NULL; | 2948 | sense = (u64 *) dasd_get_sense(irb); |
2952 | tsb = NULL; | ||
2953 | if (req && scsw_is_tm(&req->irb.scsw)) { | ||
2954 | if (irb->scsw.tm.tcw) | ||
2955 | tsb = tcw_get_tsb( | ||
2956 | (struct tcw *)(unsigned long)irb->scsw.tm.tcw); | ||
2957 | if (tsb && (irb->scsw.tm.fcxs == 0x01)) { | ||
2958 | switch (tsb->flags & 0x07) { | ||
2959 | case 1: /* tsa_iostat */ | ||
2960 | sense = (u64 *)tsb->tsa.iostat.sense; | ||
2961 | break; | ||
2962 | case 2: /* ts_ddpc */ | ||
2963 | sense = (u64 *)tsb->tsa.ddpc.sense; | ||
2964 | break; | ||
2965 | case 3: /* tsa_intrg */ | ||
2966 | break; | ||
2967 | } | ||
2968 | } | ||
2969 | } else { | ||
2970 | if (irb->esw.esw0.erw.cons) | ||
2971 | sense = (u64 *)irb->ecw; | ||
2972 | } | ||
2973 | if (sense) { | 2949 | if (sense) { |
2974 | for (sl = 0; sl < 4; sl++) { | 2950 | DBF_DEV_EVENT(DBF_EMERG, device, |
2975 | DBF_DEV_EVENT(DBF_EMERG, device, | 2951 | "%s: %s %02x%02x%02x %016llx %016llx %016llx " |
2976 | "%s: %016llx %016llx %016llx %016llx", | 2952 | "%016llx", reason, |
2977 | reason, sense[0], sense[1], sense[2], | 2953 | scsw_is_tm(&irb->scsw) ? "t" : "c", |
2978 | sense[3]); | 2954 | scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), |
2979 | } | 2955 | scsw_dstat(&irb->scsw), sense[0], sense[1], |
2956 | sense[2], sense[3]); | ||
2980 | } else { | 2957 | } else { |
2981 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", | 2958 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", |
2982 | "SORRY - NO VALID SENSE AVAILABLE\n"); | 2959 | "SORRY - NO VALID SENSE AVAILABLE\n"); |
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index d970ce2814be..cb8f9cef7429 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c | |||
@@ -172,7 +172,7 @@ dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb) | |||
172 | device = cqr->startdev; | 172 | device = cqr->startdev; |
173 | /* dump sense data to s390 debugfeature*/ | 173 | /* dump sense data to s390 debugfeature*/ |
174 | if (device->discipline && device->discipline->dump_sense_dbf) | 174 | if (device->discipline && device->discipline->dump_sense_dbf) |
175 | device->discipline->dump_sense_dbf(device, cqr, irb, "log"); | 175 | device->discipline->dump_sense_dbf(device, irb, "log"); |
176 | } | 176 | } |
177 | EXPORT_SYMBOL(dasd_log_sense_dbf); | 177 | EXPORT_SYMBOL(dasd_log_sense_dbf); |
178 | 178 | ||
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index e21ee735f926..31849ad5e59f 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -241,7 +241,7 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device, | |||
241 | /* check for unsolicited interrupts */ | 241 | /* check for unsolicited interrupts */ |
242 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | 242 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", |
243 | "unsolicited interrupt received"); | 243 | "unsolicited interrupt received"); |
244 | device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited"); | 244 | device->discipline->dump_sense_dbf(device, irb, "unsolicited"); |
245 | dasd_schedule_device_bh(device); | 245 | dasd_schedule_device_bh(device); |
246 | return; | 246 | return; |
247 | }; | 247 | }; |
@@ -444,17 +444,20 @@ dasd_fba_fill_info(struct dasd_device * device, | |||
444 | } | 444 | } |
445 | 445 | ||
446 | static void | 446 | static void |
447 | dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, | 447 | dasd_fba_dump_sense_dbf(struct dasd_device *device, struct irb *irb, |
448 | struct irb *irb, char *reason) | 448 | char *reason) |
449 | { | 449 | { |
450 | int sl; | 450 | u64 *sense; |
451 | if (irb->esw.esw0.erw.cons) { | 451 | |
452 | for (sl = 0; sl < 4; sl++) { | 452 | sense = (u64 *) dasd_get_sense(irb); |
453 | DBF_DEV_EVENT(DBF_EMERG, device, | 453 | if (sense) { |
454 | "%s: %08x %08x %08x %08x", | 454 | DBF_DEV_EVENT(DBF_EMERG, device, |
455 | reason, irb->ecw[8 * 0], irb->ecw[8 * 1], | 455 | "%s: %s %02x%02x%02x %016llx %016llx %016llx " |
456 | irb->ecw[8 * 2], irb->ecw[8 * 3]); | 456 | "%016llx", reason, |
457 | } | 457 | scsw_is_tm(&irb->scsw) ? "t" : "c", |
458 | scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), | ||
459 | scsw_dstat(&irb->scsw), sense[0], sense[1], | ||
460 | sense[2], sense[3]); | ||
458 | } else { | 461 | } else { |
459 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", | 462 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", |
460 | "SORRY - NO VALID SENSE AVAILABLE\n"); | 463 | "SORRY - NO VALID SENSE AVAILABLE\n"); |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index fd63b2f2bda9..b699ca356ac5 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -284,8 +284,7 @@ struct dasd_discipline { | |||
284 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); | 284 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); |
285 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, | 285 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, |
286 | struct irb *); | 286 | struct irb *); |
287 | void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *, | 287 | void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *); |
288 | struct irb *, char *); | ||
289 | 288 | ||
290 | void (*handle_unsolicited_interrupt) (struct dasd_device *, | 289 | void (*handle_unsolicited_interrupt) (struct dasd_device *, |
291 | struct irb *); | 290 | struct irb *); |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 016f9e9d2591..d34617682a62 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -964,7 +964,8 @@ static int dcssblk_freeze(struct device *dev) | |||
964 | break; | 964 | break; |
965 | } | 965 | } |
966 | if (rc) | 966 | if (rc) |
967 | pr_err("Suspend failed because device %s is writeable.\n", | 967 | pr_err("Suspending the system failed because DCSS device %s " |
968 | "is writable\n", | ||
968 | dev_info->segment_name); | 969 | dev_info->segment_name); |
969 | return rc; | 970 | return rc; |
970 | } | 971 | } |
@@ -987,8 +988,8 @@ static int dcssblk_restore(struct device *dev) | |||
987 | goto out_panic; | 988 | goto out_panic; |
988 | } | 989 | } |
989 | if (start != entry->start || end != entry->end) { | 990 | if (start != entry->start || end != entry->end) { |
990 | pr_err("Mismatch of start / end address after " | 991 | pr_err("The address range of DCSS %s changed " |
991 | "resuming device %s\n", | 992 | "while the system was suspended\n", |
992 | entry->segment_name); | 993 | entry->segment_name); |
993 | goto out_panic; | 994 | goto out_panic; |
994 | } | 995 | } |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 2e9e1ecd6d82..db442cd6621e 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -443,7 +443,7 @@ fail: | |||
443 | */ | 443 | */ |
444 | static void xpram_resume_error(const char *message) | 444 | static void xpram_resume_error(const char *message) |
445 | { | 445 | { |
446 | pr_err("Resume error: %s\n", message); | 446 | pr_err("Resuming the system failed: %s\n", message); |
447 | panic("xpram resume error\n"); | 447 | panic("xpram resume error\n"); |
448 | } | 448 | } |
449 | 449 | ||
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 7892550d7932..3234e90bd7f9 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c | |||
@@ -320,7 +320,7 @@ static int mon_open(struct inode *inode, struct file *filp) | |||
320 | goto out_path; | 320 | goto out_path; |
321 | } | 321 | } |
322 | filp->private_data = monpriv; | 322 | filp->private_data = monpriv; |
323 | dev_set_drvdata(&monreader_device, monpriv); | 323 | dev_set_drvdata(monreader_device, monpriv); |
324 | unlock_kernel(); | 324 | unlock_kernel(); |
325 | return nonseekable_open(inode, filp); | 325 | return nonseekable_open(inode, filp); |
326 | 326 | ||
@@ -463,7 +463,7 @@ static struct miscdevice mon_dev = { | |||
463 | *****************************************************************************/ | 463 | *****************************************************************************/ |
464 | static int monreader_freeze(struct device *dev) | 464 | static int monreader_freeze(struct device *dev) |
465 | { | 465 | { |
466 | struct mon_private *monpriv = dev_get_drvdata(&dev); | 466 | struct mon_private *monpriv = dev_get_drvdata(dev); |
467 | int rc; | 467 | int rc; |
468 | 468 | ||
469 | if (!monpriv) | 469 | if (!monpriv) |
diff --git a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h index 85f491ea929c..7a7bfc947d97 100644 --- a/drivers/s390/char/sclp_rw.h +++ b/drivers/s390/char/sclp_rw.h | |||
@@ -92,5 +92,10 @@ void sclp_set_columns(struct sclp_buffer *, unsigned short); | |||
92 | void sclp_set_htab(struct sclp_buffer *, unsigned short); | 92 | void sclp_set_htab(struct sclp_buffer *, unsigned short); |
93 | int sclp_chars_in_buffer(struct sclp_buffer *); | 93 | int sclp_chars_in_buffer(struct sclp_buffer *); |
94 | 94 | ||
95 | #ifdef CONFIG_SCLP_CONSOLE | ||
95 | void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); | 96 | void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); |
97 | #else | ||
98 | static inline void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event) { } | ||
99 | #endif | ||
100 | |||
96 | #endif /* __SCLP_RW_H__ */ | 101 | #endif /* __SCLP_RW_H__ */ |
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index cb7854c10c04..f2bc287b69e4 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c | |||
@@ -250,14 +250,14 @@ static int vmwdt_resume(void) | |||
250 | static int vmwdt_suspend(void) | 250 | static int vmwdt_suspend(void) |
251 | { | 251 | { |
252 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { | 252 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { |
253 | pr_err("The watchdog is in use. " | 253 | pr_err("The system cannot be suspended while the watchdog" |
254 | "This prevents hibernation or suspend.\n"); | 254 | " is in use\n"); |
255 | return NOTIFY_BAD; | 255 | return NOTIFY_BAD; |
256 | } | 256 | } |
257 | if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) { | 257 | if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) { |
258 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | 258 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); |
259 | pr_err("The watchdog is running. " | 259 | pr_err("The system cannot be suspended while the watchdog" |
260 | "This prevents hibernation or suspend.\n"); | 260 | " is running\n"); |
261 | return NOTIFY_BAD; | 261 | return NOTIFY_BAD; |
262 | } | 262 | } |
263 | return NOTIFY_DONE; | 263 | return NOTIFY_DONE; |
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 0471f8800483..4240b05aef6d 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c | |||
@@ -2826,8 +2826,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd) | |||
2826 | */ | 2826 | */ |
2827 | 2827 | ||
2828 | local_irq_restore(flags); | 2828 | local_irq_restore(flags); |
2829 | printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully\n" | 2829 | printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO); |
2830 | KERN_INFO " before abortion\n", HOSTNO); | ||
2831 | 2830 | ||
2832 | /* Maybe it is sufficient just to release the ST-DMA lock... (if | 2831 | /* Maybe it is sufficient just to release the ST-DMA lock... (if |
2833 | * possible at all) At least, we should check if the lock could be | 2832 | * possible at all) At least, we should check if the lock could be |
diff --git a/drivers/scsi/cxgb3i/Kbuild b/drivers/scsi/cxgb3i/Kbuild index 25a2032bfa26..70d060b7ff4f 100644 --- a/drivers/scsi/cxgb3i/Kbuild +++ b/drivers/scsi/cxgb3i/Kbuild | |||
@@ -1,4 +1,4 @@ | |||
1 | EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3 | 1 | EXTRA_CFLAGS += -I$(srctree)/drivers/net/cxgb3 |
2 | 2 | ||
3 | cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o cxgb3i_ddp.o | 3 | cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o cxgb3i_ddp.o |
4 | obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o | 4 | obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index 74369a3f963b..c399f485aa7d 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/inet.h> | 14 | #include <linux/inet.h> |
15 | #include <linux/crypto.h> | 15 | #include <linux/crypto.h> |
16 | #include <linux/if_vlan.h> | ||
16 | #include <net/dst.h> | 17 | #include <net/dst.h> |
17 | #include <net/tcp.h> | 18 | #include <net/tcp.h> |
18 | #include <scsi/scsi_cmnd.h> | 19 | #include <scsi/scsi_cmnd.h> |
@@ -184,6 +185,9 @@ static struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *ndev) | |||
184 | struct cxgb3i_adapter *snic; | 185 | struct cxgb3i_adapter *snic; |
185 | int i; | 186 | int i; |
186 | 187 | ||
188 | if (ndev->priv_flags & IFF_802_1Q_VLAN) | ||
189 | ndev = vlan_dev_real_dev(ndev); | ||
190 | |||
187 | read_lock(&cxgb3i_snic_rwlock); | 191 | read_lock(&cxgb3i_snic_rwlock); |
188 | list_for_each_entry(snic, &cxgb3i_snic_list, list_head) { | 192 | list_for_each_entry(snic, &cxgb3i_snic_list, list_head) { |
189 | for (i = 0; i < snic->hba_cnt; i++) { | 193 | for (i = 0; i < snic->hba_cnt; i++) { |
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index a84072865fc2..2c266c01dc5a 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c | |||
@@ -473,16 +473,16 @@ static int __devinit fnic_probe(struct pci_dev *pdev, | |||
473 | * limitation for the device. Try 40-bit first, and | 473 | * limitation for the device. Try 40-bit first, and |
474 | * fail to 32-bit. | 474 | * fail to 32-bit. |
475 | */ | 475 | */ |
476 | err = pci_set_dma_mask(pdev, DMA_40BIT_MASK); | 476 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40)); |
477 | if (err) { | 477 | if (err) { |
478 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 478 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
479 | if (err) { | 479 | if (err) { |
480 | shost_printk(KERN_ERR, fnic->lport->host, | 480 | shost_printk(KERN_ERR, fnic->lport->host, |
481 | "No usable DMA configuration " | 481 | "No usable DMA configuration " |
482 | "aborting\n"); | 482 | "aborting\n"); |
483 | goto err_out_release_regions; | 483 | goto err_out_release_regions; |
484 | } | 484 | } |
485 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 485 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
486 | if (err) { | 486 | if (err) { |
487 | shost_printk(KERN_ERR, fnic->lport->host, | 487 | shost_printk(KERN_ERR, fnic->lport->host, |
488 | "Unable to obtain 32-bit DMA " | 488 | "Unable to obtain 32-bit DMA " |
@@ -490,7 +490,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev, | |||
490 | goto err_out_release_regions; | 490 | goto err_out_release_regions; |
491 | } | 491 | } |
492 | } else { | 492 | } else { |
493 | err = pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK); | 493 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)); |
494 | if (err) { | 494 | if (err) { |
495 | shost_printk(KERN_ERR, fnic->lport->host, | 495 | shost_printk(KERN_ERR, fnic->lport->host, |
496 | "Unable to obtain 40-bit DMA " | 496 | "Unable to obtain 40-bit DMA " |
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index eabf36502856..bfc996971b81 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c | |||
@@ -245,7 +245,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, | |||
245 | struct vnic_wq_copy *wq, | 245 | struct vnic_wq_copy *wq, |
246 | struct fnic_io_req *io_req, | 246 | struct fnic_io_req *io_req, |
247 | struct scsi_cmnd *sc, | 247 | struct scsi_cmnd *sc, |
248 | u32 sg_count) | 248 | int sg_count) |
249 | { | 249 | { |
250 | struct scatterlist *sg; | 250 | struct scatterlist *sg; |
251 | struct fc_rport *rport = starget_to_rport(scsi_target(sc->device)); | 251 | struct fc_rport *rport = starget_to_rport(scsi_target(sc->device)); |
@@ -260,9 +260,6 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, | |||
260 | char msg[2]; | 260 | char msg[2]; |
261 | 261 | ||
262 | if (sg_count) { | 262 | if (sg_count) { |
263 | BUG_ON(sg_count < 0); | ||
264 | BUG_ON(sg_count > FNIC_MAX_SG_DESC_CNT); | ||
265 | |||
266 | /* For each SGE, create a device desc entry */ | 263 | /* For each SGE, create a device desc entry */ |
267 | desc = io_req->sgl_list; | 264 | desc = io_req->sgl_list; |
268 | for_each_sg(scsi_sglist(sc), sg, sg_count, i) { | 265 | for_each_sg(scsi_sglist(sc), sg, sg_count, i) { |
@@ -344,7 +341,7 @@ int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
344 | struct fnic *fnic; | 341 | struct fnic *fnic; |
345 | struct vnic_wq_copy *wq; | 342 | struct vnic_wq_copy *wq; |
346 | int ret; | 343 | int ret; |
347 | u32 sg_count; | 344 | int sg_count; |
348 | unsigned long flags; | 345 | unsigned long flags; |
349 | unsigned long ptr; | 346 | unsigned long ptr; |
350 | 347 | ||
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 869a11bdccbd..9928704e235f 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -1095,9 +1095,14 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct) | |||
1095 | MAX_INDIRECT_BUFS); | 1095 | MAX_INDIRECT_BUFS); |
1096 | hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS; | 1096 | hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS; |
1097 | } | 1097 | } |
1098 | |||
1099 | if (hostdata->madapter_info.os_type == 3) { | ||
1100 | enable_fast_fail(hostdata); | ||
1101 | return; | ||
1102 | } | ||
1098 | } | 1103 | } |
1099 | 1104 | ||
1100 | enable_fast_fail(hostdata); | 1105 | send_srp_login(hostdata); |
1101 | } | 1106 | } |
1102 | 1107 | ||
1103 | /** | 1108 | /** |
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index b12ad7c7c673..18735b39b3d3 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c | |||
@@ -75,8 +75,9 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd * | |||
75 | int i; | 75 | int i; |
76 | printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd); | 76 | printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd); |
77 | for (i = 0; i < cmd->cmd_len; ++i) | 77 | for (i = 0; i < cmd->cmd_len; ++i) |
78 | printk(" %.2x", cmd->cmnd[i]); | 78 | printk(KERN_CONT " %.2x", cmd->cmnd[i]); |
79 | printk("\n" KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n", | 79 | printk(KERN_CONT "\n"); |
80 | printk(KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n", | ||
80 | scsi_sg_count(cmd), scsi_bufflen(cmd), scsi_sglist(cmd)); | 81 | scsi_sg_count(cmd), scsi_bufflen(cmd), scsi_sglist(cmd)); |
81 | } | 82 | } |
82 | #endif | 83 | #endif |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 2eee9e6e4fe8..292c02f810d0 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -3670,13 +3670,14 @@ static void | |||
3670 | fc_bsg_goose_queue(struct fc_rport *rport) | 3670 | fc_bsg_goose_queue(struct fc_rport *rport) |
3671 | { | 3671 | { |
3672 | int flagset; | 3672 | int flagset; |
3673 | unsigned long flags; | ||
3673 | 3674 | ||
3674 | if (!rport->rqst_q) | 3675 | if (!rport->rqst_q) |
3675 | return; | 3676 | return; |
3676 | 3677 | ||
3677 | get_device(&rport->dev); | 3678 | get_device(&rport->dev); |
3678 | 3679 | ||
3679 | spin_lock(rport->rqst_q->queue_lock); | 3680 | spin_lock_irqsave(rport->rqst_q->queue_lock, flags); |
3680 | flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) && | 3681 | flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) && |
3681 | !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); | 3682 | !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); |
3682 | if (flagset) | 3683 | if (flagset) |
@@ -3684,7 +3685,7 @@ fc_bsg_goose_queue(struct fc_rport *rport) | |||
3684 | __blk_run_queue(rport->rqst_q); | 3685 | __blk_run_queue(rport->rqst_q); |
3685 | if (flagset) | 3686 | if (flagset) |
3686 | queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); | 3687 | queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); |
3687 | spin_unlock(rport->rqst_q->queue_lock); | 3688 | spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); |
3688 | 3689 | ||
3689 | put_device(&rport->dev); | 3690 | put_device(&rport->dev); |
3690 | } | 3691 | } |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 8201387b4daa..9230402c45af 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -210,13 +210,11 @@ static void sg_put_dev(Sg_device *sdp); | |||
210 | static int sg_allow_access(struct file *filp, unsigned char *cmd) | 210 | static int sg_allow_access(struct file *filp, unsigned char *cmd) |
211 | { | 211 | { |
212 | struct sg_fd *sfp = (struct sg_fd *)filp->private_data; | 212 | struct sg_fd *sfp = (struct sg_fd *)filp->private_data; |
213 | struct request_queue *q = sfp->parentdp->device->request_queue; | ||
214 | 213 | ||
215 | if (sfp->parentdp->device->type == TYPE_SCANNER) | 214 | if (sfp->parentdp->device->type == TYPE_SCANNER) |
216 | return 0; | 215 | return 0; |
217 | 216 | ||
218 | return blk_verify_command(&q->cmd_filter, | 217 | return blk_verify_command(cmd, filp->f_mode & FMODE_WRITE); |
219 | cmd, filp->f_mode & FMODE_WRITE); | ||
220 | } | 218 | } |
221 | 219 | ||
222 | static int | 220 | static int |
@@ -621,7 +619,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
621 | if (strcmp(current->comm, cmd) && printk_ratelimit()) { | 619 | if (strcmp(current->comm, cmd) && printk_ratelimit()) { |
622 | printk(KERN_WARNING | 620 | printk(KERN_WARNING |
623 | "sg_write: data in/out %d/%d bytes for SCSI command 0x%x--" | 621 | "sg_write: data in/out %d/%d bytes for SCSI command 0x%x--" |
624 | "guessing data in;\n" KERN_WARNING " " | 622 | "guessing data in;\n " |
625 | "program %s not setting count and/or reply_len properly\n", | 623 | "program %s not setting count and/or reply_len properly\n", |
626 | old_hdr.reply_len - (int)SZ_SG_HEADER, | 624 | old_hdr.reply_len - (int)SZ_SG_HEADER, |
627 | input_size, (unsigned int) cmnd[0], | 625 | input_size, (unsigned int) cmnd[0], |
@@ -1658,6 +1656,10 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd) | |||
1658 | md->nr_entries = req_schp->k_use_sg; | 1656 | md->nr_entries = req_schp->k_use_sg; |
1659 | md->offset = 0; | 1657 | md->offset = 0; |
1660 | md->null_mapped = hp->dxferp ? 0 : 1; | 1658 | md->null_mapped = hp->dxferp ? 0 : 1; |
1659 | if (dxfer_dir == SG_DXFER_TO_FROM_DEV) | ||
1660 | md->from_user = 1; | ||
1661 | else | ||
1662 | md->from_user = 0; | ||
1661 | } | 1663 | } |
1662 | 1664 | ||
1663 | if (iov_count) { | 1665 | if (iov_count) { |
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index bcaba86060ab..75da6e58ce55 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c | |||
@@ -2860,8 +2860,7 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) | |||
2860 | */ | 2860 | */ |
2861 | 2861 | ||
2862 | local_irq_restore(flags); | 2862 | local_irq_restore(flags); |
2863 | printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully\n" | 2863 | printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO); |
2864 | KERN_INFO " before abortion\n", HOSTNO); | ||
2865 | 2864 | ||
2866 | return SCSI_ABORT_NOT_RUNNING; | 2865 | return SCSI_ABORT_NOT_RUNNING; |
2867 | } | 2866 | } |
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c index 97f3158fa7b5..27e84e4b1fa9 100644 --- a/drivers/scsi/zalon.c +++ b/drivers/scsi/zalon.c | |||
@@ -134,7 +134,7 @@ zalon_probe(struct parisc_device *dev) | |||
134 | 134 | ||
135 | host = ncr_attach(&zalon7xx_template, unit, &device); | 135 | host = ncr_attach(&zalon7xx_template, unit, &device); |
136 | if (!host) | 136 | if (!host) |
137 | goto fail; | 137 | return -ENODEV; |
138 | 138 | ||
139 | if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) { | 139 | if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) { |
140 | dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching\n ", | 140 | dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching\n ", |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index a07015d646dd..e7108e75653d 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -60,11 +60,12 @@ struct serial_private { | |||
60 | 60 | ||
61 | static void moan_device(const char *str, struct pci_dev *dev) | 61 | static void moan_device(const char *str, struct pci_dev *dev) |
62 | { | 62 | { |
63 | printk(KERN_WARNING "%s: %s\n" | 63 | printk(KERN_WARNING |
64 | KERN_WARNING "Please send the output of lspci -vv, this\n" | 64 | "%s: %s\n" |
65 | KERN_WARNING "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" | 65 | "Please send the output of lspci -vv, this\n" |
66 | KERN_WARNING "manufacturer and name of serial board or\n" | 66 | "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" |
67 | KERN_WARNING "modem board to rmk+serial@arm.linux.org.uk.\n", | 67 | "manufacturer and name of serial board or\n" |
68 | "modem board to rmk+serial@arm.linux.org.uk.\n", | ||
68 | pci_name(dev), str, dev->vendor, dev->device, | 69 | pci_name(dev), str, dev->vendor, dev->device, |
69 | dev->subsystem_vendor, dev->subsystem_device); | 70 | dev->subsystem_vendor, dev->subsystem_device); |
70 | } | 71 | } |
@@ -759,6 +760,8 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
759 | /* subdevice 0x00PS means <P> parallel, <S> serial */ | 760 | /* subdevice 0x00PS means <P> parallel, <S> serial */ |
760 | unsigned int num_serial = dev->subsystem_device & 0xf; | 761 | unsigned int num_serial = dev->subsystem_device & 0xf; |
761 | 762 | ||
763 | if (dev->device == PCI_DEVICE_ID_NETMOS_9901) | ||
764 | return 0; | ||
762 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 765 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
763 | dev->subsystem_device == 0x0299) | 766 | dev->subsystem_device == 0x0299) |
764 | return 0; | 767 | return 0; |
@@ -3557,6 +3560,10 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3557 | PCI_VENDOR_ID_IBM, 0x0299, | 3560 | PCI_VENDOR_ID_IBM, 0x0299, |
3558 | 0, 0, pbn_b0_bt_2_115200 }, | 3561 | 0, 0, pbn_b0_bt_2_115200 }, |
3559 | 3562 | ||
3563 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, | ||
3564 | 0xA000, 0x1000, | ||
3565 | 0, 0, pbn_b0_1_115200 }, | ||
3566 | |||
3560 | /* | 3567 | /* |
3561 | * These entries match devices with class COMMUNICATION_SERIAL, | 3568 | * These entries match devices with class COMMUNICATION_SERIAL, |
3562 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 3569 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 66f52674ca0c..8e2feb563347 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -707,24 +707,25 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) | |||
707 | 707 | ||
708 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | 708 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) |
709 | { | 709 | { |
710 | unsigned short ssr_status, scr_status; | 710 | unsigned short ssr_status, scr_status, err_enabled; |
711 | struct uart_port *port = ptr; | 711 | struct uart_port *port = ptr; |
712 | irqreturn_t ret = IRQ_NONE; | 712 | irqreturn_t ret = IRQ_NONE; |
713 | 713 | ||
714 | ssr_status = sci_in(port, SCxSR); | 714 | ssr_status = sci_in(port, SCxSR); |
715 | scr_status = sci_in(port, SCSCR); | 715 | scr_status = sci_in(port, SCSCR); |
716 | err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE); | ||
716 | 717 | ||
717 | /* Tx Interrupt */ | 718 | /* Tx Interrupt */ |
718 | if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE)) | 719 | if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE)) |
719 | ret = sci_tx_interrupt(irq, ptr); | 720 | ret = sci_tx_interrupt(irq, ptr); |
720 | /* Rx Interrupt */ | 721 | /* Rx Interrupt */ |
721 | if ((ssr_status & 0x0002) && (scr_status & SCI_CTRL_FLAGS_RIE)) | 722 | if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE)) |
722 | ret = sci_rx_interrupt(irq, ptr); | 723 | ret = sci_rx_interrupt(irq, ptr); |
723 | /* Error Interrupt */ | 724 | /* Error Interrupt */ |
724 | if ((ssr_status & 0x0080) && (scr_status & SCI_CTRL_FLAGS_REIE)) | 725 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) |
725 | ret = sci_er_interrupt(irq, ptr); | 726 | ret = sci_er_interrupt(irq, ptr); |
726 | /* Break Interrupt */ | 727 | /* Break Interrupt */ |
727 | if ((ssr_status & 0x0010) && (scr_status & SCI_CTRL_FLAGS_REIE)) | 728 | if ((ssr_status & SCxSR_BRK(port)) && err_enabled) |
728 | ret = sci_br_interrupt(irq, ptr); | 729 | ret = sci_br_interrupt(irq, ptr); |
729 | 730 | ||
730 | return ret; | 731 | return ret; |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 0573f3b5175e..dac550e57c29 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Serial Interface Unit. | 2 | * Driver for NEC VR4100 series Serial Interface Unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2004-2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * Based on drivers/serial/8250.c, by Russell King. | 6 | * Based on drivers/serial/8250.c, by Russell King. |
7 | * | 7 | * |
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index da76797ce8b9..c0f950a7cbec 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -38,14 +38,12 @@ | |||
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/spi/spi.h> | 39 | #include <linux/spi/spi.h> |
40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
41 | #include <linux/errno.h> | ||
42 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
43 | #include <linux/clk.h> | 42 | #include <linux/clk.h> |
44 | #include <linux/err.h> | 43 | #include <linux/err.h> |
45 | #include <linux/amba/bus.h> | 44 | #include <linux/amba/bus.h> |
46 | #include <linux/amba/pl022.h> | 45 | #include <linux/amba/pl022.h> |
47 | #include <linux/io.h> | 46 | #include <linux/io.h> |
48 | #include <linux/delay.h> | ||
49 | 47 | ||
50 | /* | 48 | /* |
51 | * This macro is used to define some register default values. | 49 | * This macro is used to define some register default values. |
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c index aa90ddb37066..8980a5640bd9 100644 --- a/drivers/spi/omap_uwire.c +++ b/drivers/spi/omap_uwire.c | |||
@@ -514,6 +514,8 @@ static int __init uwire_probe(struct platform_device *pdev) | |||
514 | /* the spi->mode bits understood by this driver: */ | 514 | /* the spi->mode bits understood by this driver: */ |
515 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 515 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
516 | 516 | ||
517 | master->flags = SPI_MASTER_HALF_DUPLEX; | ||
518 | |||
517 | master->bus_num = 2; /* "official" */ | 519 | master->bus_num = 2; /* "official" */ |
518 | master->num_chipselect = 4; | 520 | master->num_chipselect = 4; |
519 | master->setup = uwire_setup; | 521 | master->setup = uwire_setup; |
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 2a5abc08e857..f1db395dd889 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c | |||
@@ -258,6 +258,11 @@ static void bitbang_work(struct work_struct *work) | |||
258 | struct spi_bitbang *bitbang = | 258 | struct spi_bitbang *bitbang = |
259 | container_of(work, struct spi_bitbang, work); | 259 | container_of(work, struct spi_bitbang, work); |
260 | unsigned long flags; | 260 | unsigned long flags; |
261 | int do_setup = -1; | ||
262 | int (*setup_transfer)(struct spi_device *, | ||
263 | struct spi_transfer *); | ||
264 | |||
265 | setup_transfer = bitbang->setup_transfer; | ||
261 | 266 | ||
262 | spin_lock_irqsave(&bitbang->lock, flags); | 267 | spin_lock_irqsave(&bitbang->lock, flags); |
263 | bitbang->busy = 1; | 268 | bitbang->busy = 1; |
@@ -269,8 +274,6 @@ static void bitbang_work(struct work_struct *work) | |||
269 | unsigned tmp; | 274 | unsigned tmp; |
270 | unsigned cs_change; | 275 | unsigned cs_change; |
271 | int status; | 276 | int status; |
272 | int (*setup_transfer)(struct spi_device *, | ||
273 | struct spi_transfer *); | ||
274 | 277 | ||
275 | m = container_of(bitbang->queue.next, struct spi_message, | 278 | m = container_of(bitbang->queue.next, struct spi_message, |
276 | queue); | 279 | queue); |
@@ -287,19 +290,19 @@ static void bitbang_work(struct work_struct *work) | |||
287 | tmp = 0; | 290 | tmp = 0; |
288 | cs_change = 1; | 291 | cs_change = 1; |
289 | status = 0; | 292 | status = 0; |
290 | setup_transfer = NULL; | ||
291 | 293 | ||
292 | list_for_each_entry (t, &m->transfers, transfer_list) { | 294 | list_for_each_entry (t, &m->transfers, transfer_list) { |
293 | 295 | ||
294 | /* override or restore speed and wordsize */ | 296 | /* override speed or wordsize? */ |
295 | if (t->speed_hz || t->bits_per_word) { | 297 | if (t->speed_hz || t->bits_per_word) |
296 | setup_transfer = bitbang->setup_transfer; | 298 | do_setup = 1; |
299 | |||
300 | /* init (-1) or override (1) transfer params */ | ||
301 | if (do_setup != 0) { | ||
297 | if (!setup_transfer) { | 302 | if (!setup_transfer) { |
298 | status = -ENOPROTOOPT; | 303 | status = -ENOPROTOOPT; |
299 | break; | 304 | break; |
300 | } | 305 | } |
301 | } | ||
302 | if (setup_transfer) { | ||
303 | status = setup_transfer(spi, t); | 306 | status = setup_transfer(spi, t); |
304 | if (status < 0) | 307 | if (status < 0) |
305 | break; | 308 | break; |
@@ -363,9 +366,10 @@ static void bitbang_work(struct work_struct *work) | |||
363 | m->status = status; | 366 | m->status = status; |
364 | m->complete(m->context); | 367 | m->complete(m->context); |
365 | 368 | ||
366 | /* restore speed and wordsize */ | 369 | /* restore speed and wordsize if it was overridden */ |
367 | if (setup_transfer) | 370 | if (do_setup == 1) |
368 | setup_transfer(spi, NULL); | 371 | setup_transfer(spi, NULL); |
372 | do_setup = 0; | ||
369 | 373 | ||
370 | /* normally deactivate chipselect ... unless no error and | 374 | /* normally deactivate chipselect ... unless no error and |
371 | * cs_change has hinted that the next message will probably | 375 | * cs_change has hinted that the next message will probably |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 5d869c4d3eb2..606e7a40a8da 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
@@ -58,15 +58,20 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; | |||
58 | 58 | ||
59 | 59 | ||
60 | /* Bit masks for spi_device.mode management. Note that incorrect | 60 | /* Bit masks for spi_device.mode management. Note that incorrect |
61 | * settings for CS_HIGH and 3WIRE can cause *lots* of trouble for other | 61 | * settings for some settings can cause *lots* of trouble for other |
62 | * devices on a shared bus: CS_HIGH, because this device will be | 62 | * devices on a shared bus: |
63 | * active when it shouldn't be; 3WIRE, because when active it won't | ||
64 | * behave as it should. | ||
65 | * | 63 | * |
66 | * REVISIT should changing those two modes be privileged? | 64 | * - CS_HIGH ... this device will be active when it shouldn't be |
65 | * - 3WIRE ... when active, it won't behave as it should | ||
66 | * - NO_CS ... there will be no explicit message boundaries; this | ||
67 | * is completely incompatible with the shared bus model | ||
68 | * - READY ... transfers may proceed when they shouldn't. | ||
69 | * | ||
70 | * REVISIT should changing those flags be privileged? | ||
67 | */ | 71 | */ |
68 | #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ | 72 | #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ |
69 | | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) | 73 | | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ |
74 | | SPI_NO_CS | SPI_READY) | ||
70 | 75 | ||
71 | struct spidev_data { | 76 | struct spidev_data { |
72 | dev_t devt; | 77 | dev_t devt; |
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index 3fd3e3b412b6..3c6feed46f6e 100644 --- a/drivers/ssb/driver_mipscore.c +++ b/drivers/ssb/driver_mipscore.c | |||
@@ -49,29 +49,54 @@ static const u32 ipsflag_irq_shift[] = { | |||
49 | 49 | ||
50 | static inline u32 ssb_irqflag(struct ssb_device *dev) | 50 | static inline u32 ssb_irqflag(struct ssb_device *dev) |
51 | { | 51 | { |
52 | return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG; | 52 | u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG); |
53 | if (tpsflag) | ||
54 | return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG; | ||
55 | else | ||
56 | /* not irq supported */ | ||
57 | return 0x3f; | ||
58 | } | ||
59 | |||
60 | static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag) | ||
61 | { | ||
62 | struct ssb_bus *bus = rdev->bus; | ||
63 | int i; | ||
64 | for (i = 0; i < bus->nr_devices; i++) { | ||
65 | struct ssb_device *dev; | ||
66 | dev = &(bus->devices[i]); | ||
67 | if (ssb_irqflag(dev) == irqflag) | ||
68 | return dev; | ||
69 | } | ||
70 | return NULL; | ||
53 | } | 71 | } |
54 | 72 | ||
55 | /* Get the MIPS IRQ assignment for a specified device. | 73 | /* Get the MIPS IRQ assignment for a specified device. |
56 | * If unassigned, 0 is returned. | 74 | * If unassigned, 0 is returned. |
75 | * If disabled, 5 is returned. | ||
76 | * If not supported, 6 is returned. | ||
57 | */ | 77 | */ |
58 | unsigned int ssb_mips_irq(struct ssb_device *dev) | 78 | unsigned int ssb_mips_irq(struct ssb_device *dev) |
59 | { | 79 | { |
60 | struct ssb_bus *bus = dev->bus; | 80 | struct ssb_bus *bus = dev->bus; |
81 | struct ssb_device *mdev = bus->mipscore.dev; | ||
61 | u32 irqflag; | 82 | u32 irqflag; |
62 | u32 ipsflag; | 83 | u32 ipsflag; |
63 | u32 tmp; | 84 | u32 tmp; |
64 | unsigned int irq; | 85 | unsigned int irq; |
65 | 86 | ||
66 | irqflag = ssb_irqflag(dev); | 87 | irqflag = ssb_irqflag(dev); |
88 | if (irqflag == 0x3f) | ||
89 | return 6; | ||
67 | ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG); | 90 | ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG); |
68 | for (irq = 1; irq <= 4; irq++) { | 91 | for (irq = 1; irq <= 4; irq++) { |
69 | tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]); | 92 | tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]); |
70 | if (tmp == irqflag) | 93 | if (tmp == irqflag) |
71 | break; | 94 | break; |
72 | } | 95 | } |
73 | if (irq == 5) | 96 | if (irq == 5) { |
74 | irq = 0; | 97 | if ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)) |
98 | irq = 0; | ||
99 | } | ||
75 | 100 | ||
76 | return irq; | 101 | return irq; |
77 | } | 102 | } |
@@ -97,25 +122,56 @@ static void set_irq(struct ssb_device *dev, unsigned int irq) | |||
97 | struct ssb_device *mdev = bus->mipscore.dev; | 122 | struct ssb_device *mdev = bus->mipscore.dev; |
98 | u32 irqflag = ssb_irqflag(dev); | 123 | u32 irqflag = ssb_irqflag(dev); |
99 | 124 | ||
125 | BUG_ON(oldirq == 6); | ||
126 | |||
100 | dev->irq = irq + 2; | 127 | dev->irq = irq + 2; |
101 | 128 | ||
102 | ssb_dprintk(KERN_INFO PFX | ||
103 | "set_irq: core 0x%04x, irq %d => %d\n", | ||
104 | dev->id.coreid, oldirq, irq); | ||
105 | /* clear the old irq */ | 129 | /* clear the old irq */ |
106 | if (oldirq == 0) | 130 | if (oldirq == 0) |
107 | ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))); | 131 | ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))); |
108 | else | 132 | else if (oldirq != 5) |
109 | clear_irq(bus, oldirq); | 133 | clear_irq(bus, oldirq); |
110 | 134 | ||
111 | /* assign the new one */ | 135 | /* assign the new one */ |
112 | if (irq == 0) { | 136 | if (irq == 0) { |
113 | ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC))); | 137 | ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC))); |
114 | } else { | 138 | } else { |
139 | u32 ipsflag = ssb_read32(mdev, SSB_IPSFLAG); | ||
140 | if ((ipsflag & ipsflag_irq_mask[irq]) != ipsflag_irq_mask[irq]) { | ||
141 | u32 oldipsflag = (ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]; | ||
142 | struct ssb_device *olddev = find_device(dev, oldipsflag); | ||
143 | if (olddev) | ||
144 | set_irq(olddev, 0); | ||
145 | } | ||
115 | irqflag <<= ipsflag_irq_shift[irq]; | 146 | irqflag <<= ipsflag_irq_shift[irq]; |
116 | irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]); | 147 | irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]); |
117 | ssb_write32(mdev, SSB_IPSFLAG, irqflag); | 148 | ssb_write32(mdev, SSB_IPSFLAG, irqflag); |
118 | } | 149 | } |
150 | ssb_dprintk(KERN_INFO PFX | ||
151 | "set_irq: core 0x%04x, irq %d => %d\n", | ||
152 | dev->id.coreid, oldirq+2, irq+2); | ||
153 | } | ||
154 | |||
155 | static void print_irq(struct ssb_device *dev, unsigned int irq) | ||
156 | { | ||
157 | int i; | ||
158 | static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; | ||
159 | ssb_dprintk(KERN_INFO PFX | ||
160 | "core 0x%04x, irq :", dev->id.coreid); | ||
161 | for (i = 0; i <= 6; i++) { | ||
162 | ssb_dprintk(" %s%s", irq_name[i], i==irq?"*":" "); | ||
163 | } | ||
164 | ssb_dprintk("\n"); | ||
165 | } | ||
166 | |||
167 | static void dump_irq(struct ssb_bus *bus) | ||
168 | { | ||
169 | int i; | ||
170 | for (i = 0; i < bus->nr_devices; i++) { | ||
171 | struct ssb_device *dev; | ||
172 | dev = &(bus->devices[i]); | ||
173 | print_irq(dev, ssb_mips_irq(dev)); | ||
174 | } | ||
119 | } | 175 | } |
120 | 176 | ||
121 | static void ssb_mips_serial_init(struct ssb_mipscore *mcore) | 177 | static void ssb_mips_serial_init(struct ssb_mipscore *mcore) |
@@ -197,16 +253,23 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) | |||
197 | 253 | ||
198 | /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ | 254 | /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ |
199 | for (irq = 2, i = 0; i < bus->nr_devices; i++) { | 255 | for (irq = 2, i = 0; i < bus->nr_devices; i++) { |
256 | int mips_irq; | ||
200 | dev = &(bus->devices[i]); | 257 | dev = &(bus->devices[i]); |
201 | dev->irq = ssb_mips_irq(dev) + 2; | 258 | mips_irq = ssb_mips_irq(dev); |
259 | if (mips_irq > 4) | ||
260 | dev->irq = 0; | ||
261 | else | ||
262 | dev->irq = mips_irq + 2; | ||
263 | if (dev->irq > 5) | ||
264 | continue; | ||
202 | switch (dev->id.coreid) { | 265 | switch (dev->id.coreid) { |
203 | case SSB_DEV_USB11_HOST: | 266 | case SSB_DEV_USB11_HOST: |
204 | /* shouldn't need a separate irq line for non-4710, most of them have a proper | 267 | /* shouldn't need a separate irq line for non-4710, most of them have a proper |
205 | * external usb controller on the pci */ | 268 | * external usb controller on the pci */ |
206 | if ((bus->chip_id == 0x4710) && (irq <= 4)) { | 269 | if ((bus->chip_id == 0x4710) && (irq <= 4)) { |
207 | set_irq(dev, irq++); | 270 | set_irq(dev, irq++); |
208 | break; | ||
209 | } | 271 | } |
272 | break; | ||
210 | /* fallthrough */ | 273 | /* fallthrough */ |
211 | case SSB_DEV_PCI: | 274 | case SSB_DEV_PCI: |
212 | case SSB_DEV_ETHERNET: | 275 | case SSB_DEV_ETHERNET: |
@@ -220,6 +283,8 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) | |||
220 | } | 283 | } |
221 | } | 284 | } |
222 | } | 285 | } |
286 | ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n"); | ||
287 | dump_irq(bus); | ||
223 | 288 | ||
224 | ssb_mips_serial_init(mcore); | 289 | ssb_mips_serial_init(mcore); |
225 | ssb_mips_flash_detect(mcore); | 290 | ssb_mips_flash_detect(mcore); |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index fbfadbac67e8..100e7a5c5ea1 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
@@ -583,7 +583,7 @@ static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom) | |||
583 | ssb_printk("."); | 583 | ssb_printk("."); |
584 | err = ssb_pcmcia_sprom_write(bus, i, sprom[i]); | 584 | err = ssb_pcmcia_sprom_write(bus, i, sprom[i]); |
585 | if (err) { | 585 | if (err) { |
586 | ssb_printk("\n" KERN_NOTICE PFX | 586 | ssb_printk(KERN_NOTICE PFX |
587 | "Failed to write to SPROM.\n"); | 587 | "Failed to write to SPROM.\n"); |
588 | failed = 1; | 588 | failed = 1; |
589 | break; | 589 | break; |
@@ -591,7 +591,7 @@ static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom) | |||
591 | } | 591 | } |
592 | err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS); | 592 | err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS); |
593 | if (err) { | 593 | if (err) { |
594 | ssb_printk("\n" KERN_NOTICE PFX | 594 | ssb_printk(KERN_NOTICE PFX |
595 | "Could not disable SPROM write access.\n"); | 595 | "Could not disable SPROM write access.\n"); |
596 | failed = 1; | 596 | failed = 1; |
597 | } | 597 | } |
@@ -678,7 +678,8 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, | |||
678 | sprom->board_rev = tuple.TupleData[1]; | 678 | sprom->board_rev = tuple.TupleData[1]; |
679 | break; | 679 | break; |
680 | case SSB_PCMCIA_CIS_PA: | 680 | case SSB_PCMCIA_CIS_PA: |
681 | GOTO_ERROR_ON(tuple.TupleDataLen != 9, | 681 | GOTO_ERROR_ON((tuple.TupleDataLen != 9) && |
682 | (tuple.TupleDataLen != 10), | ||
682 | "pa tpl size"); | 683 | "pa tpl size"); |
683 | sprom->pa0b0 = tuple.TupleData[1] | | 684 | sprom->pa0b0 = tuple.TupleData[1] | |
684 | ((u16)tuple.TupleData[2] << 8); | 685 | ((u16)tuple.TupleData[2] << 8); |
@@ -718,7 +719,8 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, | |||
718 | sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1]; | 719 | sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1]; |
719 | break; | 720 | break; |
720 | case SSB_PCMCIA_CIS_BFLAGS: | 721 | case SSB_PCMCIA_CIS_BFLAGS: |
721 | GOTO_ERROR_ON(tuple.TupleDataLen != 3, | 722 | GOTO_ERROR_ON((tuple.TupleDataLen != 3) && |
723 | (tuple.TupleDataLen != 5), | ||
722 | "bfl tpl size"); | 724 | "bfl tpl size"); |
723 | sprom->boardflags_lo = tuple.TupleData[1] | | 725 | sprom->boardflags_lo = tuple.TupleData[1] | |
724 | ((u16)tuple.TupleData[2] << 8); | 726 | ((u16)tuple.TupleData[2] << 8); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 38bfdb0f6660..3f1045993474 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -550,7 +550,7 @@ static void acm_waker(struct work_struct *waker) | |||
550 | static int acm_tty_open(struct tty_struct *tty, struct file *filp) | 550 | static int acm_tty_open(struct tty_struct *tty, struct file *filp) |
551 | { | 551 | { |
552 | struct acm *acm; | 552 | struct acm *acm; |
553 | int rv = -EINVAL; | 553 | int rv = -ENODEV; |
554 | int i; | 554 | int i; |
555 | dbg("Entering acm_tty_open."); | 555 | dbg("Entering acm_tty_open."); |
556 | 556 | ||
@@ -677,7 +677,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
677 | 677 | ||
678 | /* Perform the closing process and see if we need to do the hardware | 678 | /* Perform the closing process and see if we need to do the hardware |
679 | shutdown */ | 679 | shutdown */ |
680 | if (tty_port_close_start(&acm->port, tty, filp) == 0) | 680 | if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0) |
681 | return; | 681 | return; |
682 | acm_port_down(acm, 0); | 682 | acm_port_down(acm, 0); |
683 | tty_port_close_end(&acm->port, tty); | 683 | tty_port_close_end(&acm->port, tty); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ce3f453f02ef..95ccfa0b9fc5 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -648,7 +648,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
648 | struct urb *urb; | 648 | struct urb *urb; |
649 | int length; | 649 | int length; |
650 | unsigned long flags; | 650 | unsigned long flags; |
651 | char buffer[4]; /* Any root hubs with > 31 ports? */ | 651 | char buffer[6]; /* Any root hubs with > 31 ports? */ |
652 | 652 | ||
653 | if (unlikely(!hcd->rh_registered)) | 653 | if (unlikely(!hcd->rh_registered)) |
654 | return; | 654 | return; |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 1576a0520adf..0c03471f0d41 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -337,10 +337,10 @@ config USB_R8A66597_HCD | |||
337 | 337 | ||
338 | config SUPERH_ON_CHIP_R8A66597 | 338 | config SUPERH_ON_CHIP_R8A66597 |
339 | boolean "Enable SuperH on-chip R8A66597 USB" | 339 | boolean "Enable SuperH on-chip R8A66597 USB" |
340 | depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723) | 340 | depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724) |
341 | help | 341 | help |
342 | This driver enables support for the on-chip R8A66597 in the | 342 | This driver enables support for the on-chip R8A66597 in the |
343 | SH7366 and SH7723 processors. | 343 | SH7366, SH7723 and SH7724 processors. |
344 | 344 | ||
345 | config USB_WHCI_HCD | 345 | config USB_WHCI_HCD |
346 | tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)" | 346 | tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)" |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index f8d9045d668a..0f7a30b7d2d1 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -1261,7 +1261,7 @@ static int mon_alloc_buff(struct mon_pgmap *map, int npages) | |||
1261 | return -ENOMEM; | 1261 | return -ENOMEM; |
1262 | } | 1262 | } |
1263 | map[n].ptr = (unsigned char *) vaddr; | 1263 | map[n].ptr = (unsigned char *) vaddr; |
1264 | map[n].pg = virt_to_page(vaddr); | 1264 | map[n].pg = virt_to_page((void *) vaddr); |
1265 | } | 1265 | } |
1266 | return 0; | 1266 | return 0; |
1267 | } | 1267 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3dc3768ca71c..5f08702f672f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -2121,7 +2121,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
2121 | /* Note that the error flag is duplicated for | 2121 | /* Note that the error flag is duplicated for |
2122 | every character received since we don't know | 2122 | every character received since we don't know |
2123 | which character it applied to */ | 2123 | which character it applied to */ |
2124 | if (!usb_serial_handle_sysrq_char(port, | 2124 | if (!usb_serial_handle_sysrq_char(tty, port, |
2125 | data[packet_offset + i])) | 2125 | data[packet_offset + i])) |
2126 | tty_insert_flip_char(tty, | 2126 | tty_insert_flip_char(tty, |
2127 | data[packet_offset + i], | 2127 | data[packet_offset + i], |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 932d6241b787..ce57f6a32bdf 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -424,10 +424,17 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | |||
424 | if (!tty) | 424 | if (!tty) |
425 | goto done; | 425 | goto done; |
426 | 426 | ||
427 | /* Push data to tty */ | 427 | /* The per character mucking around with sysrq path it too slow for |
428 | for (i = 0; i < urb->actual_length; i++, ch++) { | 428 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases |
429 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 429 | where the USB serial is not a console anyway */ |
430 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 430 | if (!port->console || !port->sysrq) |
431 | tty_insert_flip_string(tty, ch, urb->actual_length); | ||
432 | else { | ||
433 | /* Push data to tty */ | ||
434 | for (i = 0; i < urb->actual_length; i++, ch++) { | ||
435 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | ||
436 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | ||
437 | } | ||
431 | } | 438 | } |
432 | tty_flip_buffer_push(tty); | 439 | tty_flip_buffer_push(tty); |
433 | tty_kref_put(tty); | 440 | tty_kref_put(tty); |
@@ -527,11 +534,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
527 | } | 534 | } |
528 | } | 535 | } |
529 | 536 | ||
530 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | 537 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, |
538 | struct usb_serial_port *port, unsigned int ch) | ||
531 | { | 539 | { |
532 | if (port->sysrq && port->console) { | 540 | if (port->sysrq && port->console) { |
533 | if (ch && time_before(jiffies, port->sysrq)) { | 541 | if (ch && time_before(jiffies, port->sysrq)) { |
534 | handle_sysrq(ch, tty_port_tty_get(&port->port)); | 542 | handle_sysrq(ch, tty); |
535 | port->sysrq = 0; | 543 | port->sysrq = 0; |
536 | return 1; | 544 | return 1; |
537 | } | 545 | } |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ec6c132a25b5..efaf59c4f5d0 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -971,18 +971,46 @@ exit: | |||
971 | __func__, retval); | 971 | __func__, retval); |
972 | } | 972 | } |
973 | 973 | ||
974 | static void pl2303_push_data(struct tty_struct *tty, | ||
975 | struct usb_serial_port *port, struct urb *urb, | ||
976 | u8 line_status) | ||
977 | { | ||
978 | unsigned char *data = urb->transfer_buffer; | ||
979 | /* get tty_flag from status */ | ||
980 | char tty_flag = TTY_NORMAL; | ||
981 | /* break takes precedence over parity, */ | ||
982 | /* which takes precedence over framing errors */ | ||
983 | if (line_status & UART_BREAK_ERROR) | ||
984 | tty_flag = TTY_BREAK; | ||
985 | else if (line_status & UART_PARITY_ERROR) | ||
986 | tty_flag = TTY_PARITY; | ||
987 | else if (line_status & UART_FRAME_ERROR) | ||
988 | tty_flag = TTY_FRAME; | ||
989 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
990 | |||
991 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
992 | /* overrun is special, not associated with a char */ | ||
993 | if (line_status & UART_OVERRUN_ERROR) | ||
994 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
995 | if (port->console && port->sysrq) { | ||
996 | int i; | ||
997 | for (i = 0; i < urb->actual_length; ++i) | ||
998 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | ||
999 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1000 | } else | ||
1001 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1002 | tty_flip_buffer_push(tty); | ||
1003 | } | ||
1004 | |||
974 | static void pl2303_read_bulk_callback(struct urb *urb) | 1005 | static void pl2303_read_bulk_callback(struct urb *urb) |
975 | { | 1006 | { |
976 | struct usb_serial_port *port = urb->context; | 1007 | struct usb_serial_port *port = urb->context; |
977 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 1008 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
978 | struct tty_struct *tty; | 1009 | struct tty_struct *tty; |
979 | unsigned char *data = urb->transfer_buffer; | ||
980 | unsigned long flags; | 1010 | unsigned long flags; |
981 | int i; | ||
982 | int result; | 1011 | int result; |
983 | int status = urb->status; | 1012 | int status = urb->status; |
984 | u8 line_status; | 1013 | u8 line_status; |
985 | char tty_flag; | ||
986 | 1014 | ||
987 | dbg("%s - port %d", __func__, port->number); | 1015 | dbg("%s - port %d", __func__, port->number); |
988 | 1016 | ||
@@ -1010,10 +1038,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1010 | } | 1038 | } |
1011 | 1039 | ||
1012 | usb_serial_debug_data(debug, &port->dev, __func__, | 1040 | usb_serial_debug_data(debug, &port->dev, __func__, |
1013 | urb->actual_length, data); | 1041 | urb->actual_length, urb->transfer_buffer); |
1014 | |||
1015 | /* get tty_flag from status */ | ||
1016 | tty_flag = TTY_NORMAL; | ||
1017 | 1042 | ||
1018 | spin_lock_irqsave(&priv->lock, flags); | 1043 | spin_lock_irqsave(&priv->lock, flags); |
1019 | line_status = priv->line_status; | 1044 | line_status = priv->line_status; |
@@ -1021,26 +1046,9 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1021 | spin_unlock_irqrestore(&priv->lock, flags); | 1046 | spin_unlock_irqrestore(&priv->lock, flags); |
1022 | wake_up_interruptible(&priv->delta_msr_wait); | 1047 | wake_up_interruptible(&priv->delta_msr_wait); |
1023 | 1048 | ||
1024 | /* break takes precedence over parity, */ | ||
1025 | /* which takes precedence over framing errors */ | ||
1026 | if (line_status & UART_BREAK_ERROR) | ||
1027 | tty_flag = TTY_BREAK; | ||
1028 | else if (line_status & UART_PARITY_ERROR) | ||
1029 | tty_flag = TTY_PARITY; | ||
1030 | else if (line_status & UART_FRAME_ERROR) | ||
1031 | tty_flag = TTY_FRAME; | ||
1032 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
1033 | |||
1034 | tty = tty_port_tty_get(&port->port); | 1049 | tty = tty_port_tty_get(&port->port); |
1035 | if (tty && urb->actual_length) { | 1050 | if (tty && urb->actual_length) { |
1036 | tty_buffer_request_room(tty, urb->actual_length + 1); | 1051 | pl2303_push_data(tty, port, urb, line_status); |
1037 | /* overrun is special, not associated with a char */ | ||
1038 | if (line_status & UART_OVERRUN_ERROR) | ||
1039 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1040 | for (i = 0; i < urb->actual_length; ++i) | ||
1041 | if (!usb_serial_handle_sysrq_char(port, data[i])) | ||
1042 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1043 | tty_flip_buffer_push(tty); | ||
1044 | } | 1052 | } |
1045 | tty_kref_put(tty); | 1053 | tty_kref_put(tty); |
1046 | /* Schedule the next read _if_ we are still open */ | 1054 | /* Schedule the next read _if_ we are still open */ |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index d595aa5586a7..a84216464ca0 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -333,6 +333,9 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
333 | { | 333 | { |
334 | struct usb_serial_port *port = tty->driver_data; | 334 | struct usb_serial_port *port = tty->driver_data; |
335 | 335 | ||
336 | if (!port) | ||
337 | return; | ||
338 | |||
336 | dbg("%s - port %d", __func__, port->number); | 339 | dbg("%s - port %d", __func__, port->number); |
337 | 340 | ||
338 | 341 | ||
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d6d65ef85f54..41296a6807e2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -616,6 +616,8 @@ config FB_STI | |||
616 | select FB_CFB_FILLRECT | 616 | select FB_CFB_FILLRECT |
617 | select FB_CFB_COPYAREA | 617 | select FB_CFB_COPYAREA |
618 | select FB_CFB_IMAGEBLIT | 618 | select FB_CFB_IMAGEBLIT |
619 | select STI_CONSOLE | ||
620 | select VT | ||
619 | default y | 621 | default y |
620 | ---help--- | 622 | ---help--- |
621 | STI refers to the HP "Standard Text Interface" which is a set of | 623 | STI refers to the HP "Standard Text Interface" which is a set of |
@@ -933,7 +935,7 @@ config FB_S1D13XXX | |||
933 | 935 | ||
934 | config FB_ATMEL | 936 | config FB_ATMEL |
935 | tristate "AT91/AT32 LCD Controller support" | 937 | tristate "AT91/AT32 LCD Controller support" |
936 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32) | 938 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9G10 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32) |
937 | select FB_CFB_FILLRECT | 939 | select FB_CFB_FILLRECT |
938 | select FB_CFB_COPYAREA | 940 | select FB_CFB_COPYAREA |
939 | select FB_CFB_IMAGEBLIT | 941 | select FB_CFB_IMAGEBLIT |
@@ -949,7 +951,7 @@ config FB_INTSRAM | |||
949 | 951 | ||
950 | config FB_ATMEL_STN | 952 | config FB_ATMEL_STN |
951 | bool "Use a STN display with AT91/AT32 LCD Controller" | 953 | bool "Use a STN display with AT91/AT32 LCD Controller" |
952 | depends on FB_ATMEL && MACH_AT91SAM9261EK | 954 | depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK) |
953 | default n | 955 | default n |
954 | help | 956 | help |
955 | Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD | 957 | Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index fb8163d181ab..a21efcd10b78 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -226,9 +226,10 @@ static int clcdfb_set_par(struct fb_info *info) | |||
226 | clcdfb_enable(fb, regs.cntl); | 226 | clcdfb_enable(fb, regs.cntl); |
227 | 227 | ||
228 | #ifdef DEBUG | 228 | #ifdef DEBUG |
229 | printk(KERN_INFO "CLCD: Registers set to\n" | 229 | printk(KERN_INFO |
230 | KERN_INFO " %08x %08x %08x %08x\n" | 230 | "CLCD: Registers set to\n" |
231 | KERN_INFO " %08x %08x %08x %08x\n", | 231 | " %08x %08x %08x %08x\n" |
232 | " %08x %08x %08x %08x\n", | ||
232 | readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), | 233 | readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), |
233 | readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), | 234 | readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), |
234 | readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), | 235 | readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), |
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index 018850c116c6..8cd279be74e5 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c | |||
@@ -2405,6 +2405,9 @@ static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) | |||
2405 | return 0; | 2405 | return 0; |
2406 | } | 2406 | } |
2407 | 2407 | ||
2408 | /* fbhw->encode_fix() must be called with fb_info->mm_lock held | ||
2409 | * if it is called after the register_framebuffer() - not a case here | ||
2410 | */ | ||
2408 | static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | 2411 | static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) |
2409 | { | 2412 | { |
2410 | struct atafb_par par; | 2413 | struct atafb_par par; |
@@ -2414,7 +2417,8 @@ static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | |||
2414 | if (err) | 2417 | if (err) |
2415 | return err; | 2418 | return err; |
2416 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | 2419 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); |
2417 | return fbhw->encode_fix(fix, &par); | 2420 | err = fbhw->encode_fix(fix, &par); |
2421 | return err; | ||
2418 | } | 2422 | } |
2419 | 2423 | ||
2420 | static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info) | 2424 | static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info) |
@@ -2743,7 +2747,9 @@ static int atafb_set_par(struct fb_info *info) | |||
2743 | 2747 | ||
2744 | /* Decode wanted screen parameters */ | 2748 | /* Decode wanted screen parameters */ |
2745 | fbhw->decode_var(&info->var, par); | 2749 | fbhw->decode_var(&info->var, par); |
2750 | mutex_lock(&info->mm_lock); | ||
2746 | fbhw->encode_fix(&info->fix, par); | 2751 | fbhw->encode_fix(&info->fix, par); |
2752 | mutex_unlock(&info->mm_lock); | ||
2747 | 2753 | ||
2748 | /* Set new videomode */ | 2754 | /* Set new videomode */ |
2749 | ata_set_par(par); | 2755 | ata_set_par(par); |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 5afd64482f55..2830ffd72976 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -182,7 +182,8 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) | |||
182 | { | 182 | { |
183 | unsigned long value; | 183 | unsigned long value; |
184 | 184 | ||
185 | if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000())) | 185 | if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() |
186 | || cpu_is_at32ap7000())) | ||
186 | return xres; | 187 | return xres; |
187 | 188 | ||
188 | value = xres; | 189 | value = xres; |
@@ -261,6 +262,9 @@ static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo) | |||
261 | /** | 262 | /** |
262 | * atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory | 263 | * atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory |
263 | * @sinfo: the frame buffer to allocate memory for | 264 | * @sinfo: the frame buffer to allocate memory for |
265 | * | ||
266 | * This function is called only from the atmel_lcdfb_probe() | ||
267 | * so no locking by fb_info->mm_lock around smem_len setting is needed. | ||
264 | */ | 268 | */ |
265 | static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) | 269 | static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) |
266 | { | 270 | { |
@@ -821,7 +825,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) | |||
821 | info->fix = atmel_lcdfb_fix; | 825 | info->fix = atmel_lcdfb_fix; |
822 | 826 | ||
823 | /* Enable LCDC Clocks */ | 827 | /* Enable LCDC Clocks */ |
824 | if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) { | 828 | if (cpu_is_at91sam9261() || cpu_is_at91sam9g10() |
829 | || cpu_is_at32ap7000()) { | ||
825 | sinfo->bus_clk = clk_get(dev, "hck1"); | 830 | sinfo->bus_clk = clk_get(dev, "hck1"); |
826 | if (IS_ERR(sinfo->bus_clk)) { | 831 | if (IS_ERR(sinfo->bus_clk)) { |
827 | ret = PTR_ERR(sinfo->bus_clk); | 832 | ret = PTR_ERR(sinfo->bus_clk); |
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index 7691e73823d3..1f39a62f899b 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h | |||
@@ -187,6 +187,8 @@ struct atyfb_par { | |||
187 | int mtrr_reg; | 187 | int mtrr_reg; |
188 | #endif | 188 | #endif |
189 | u32 mem_cntl; | 189 | u32 mem_cntl; |
190 | struct crtc saved_crtc; | ||
191 | union aty_pll saved_pll; | ||
190 | }; | 192 | }; |
191 | 193 | ||
192 | /* | 194 | /* |
@@ -217,6 +219,7 @@ struct atyfb_par { | |||
217 | #define M64F_XL_DLL 0x00080000 | 219 | #define M64F_XL_DLL 0x00080000 |
218 | #define M64F_MFB_FORCE_4 0x00100000 | 220 | #define M64F_MFB_FORCE_4 0x00100000 |
219 | #define M64F_HW_TRIPLE 0x00200000 | 221 | #define M64F_HW_TRIPLE 0x00200000 |
222 | #define M64F_XL_MEM 0x00400000 | ||
220 | /* | 223 | /* |
221 | * Register access | 224 | * Register access |
222 | */ | 225 | */ |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 1207c208a30b..63d3739d43a8 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -66,6 +66,8 @@ | |||
66 | #include <linux/spinlock.h> | 66 | #include <linux/spinlock.h> |
67 | #include <linux/wait.h> | 67 | #include <linux/wait.h> |
68 | #include <linux/backlight.h> | 68 | #include <linux/backlight.h> |
69 | #include <linux/reboot.h> | ||
70 | #include <linux/dmi.h> | ||
69 | 71 | ||
70 | #include <asm/io.h> | 72 | #include <asm/io.h> |
71 | #include <linux/uaccess.h> | 73 | #include <linux/uaccess.h> |
@@ -249,8 +251,6 @@ static int aty_init(struct fb_info *info); | |||
249 | static int store_video_par(char *videopar, unsigned char m64_num); | 251 | static int store_video_par(char *videopar, unsigned char m64_num); |
250 | #endif | 252 | #endif |
251 | 253 | ||
252 | static struct crtc saved_crtc; | ||
253 | static union aty_pll saved_pll; | ||
254 | static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); | 254 | static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); |
255 | 255 | ||
256 | static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); | 256 | static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); |
@@ -261,6 +261,8 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); | |||
261 | static int read_aty_sense(const struct atyfb_par *par); | 261 | static int read_aty_sense(const struct atyfb_par *par); |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | static DEFINE_MUTEX(reboot_lock); | ||
265 | static struct fb_info *reboot_info; | ||
264 | 266 | ||
265 | /* | 267 | /* |
266 | * Interface used by the world | 268 | * Interface used by the world |
@@ -361,8 +363,8 @@ static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, }; | |||
361 | #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) | 363 | #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) |
362 | #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) | 364 | #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) |
363 | 365 | ||
364 | #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4) | 366 | #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM) |
365 | #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS) | 367 | #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS) |
366 | 368 | ||
367 | static struct { | 369 | static struct { |
368 | u16 pci_id; | 370 | u16 pci_id; |
@@ -539,6 +541,7 @@ static char ram_edo[] __devinitdata = "EDO"; | |||
539 | static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; | 541 | static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; |
540 | static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; | 542 | static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; |
541 | static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; | 543 | static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; |
544 | static char ram_wram[] __devinitdata = "WRAM"; | ||
542 | static char ram_off[] __devinitdata = "OFF"; | 545 | static char ram_off[] __devinitdata = "OFF"; |
543 | #endif /* CONFIG_FB_ATY_CT */ | 546 | #endif /* CONFIG_FB_ATY_CT */ |
544 | 547 | ||
@@ -553,6 +556,10 @@ static char *aty_gx_ram[8] __devinitdata = { | |||
553 | #ifdef CONFIG_FB_ATY_CT | 556 | #ifdef CONFIG_FB_ATY_CT |
554 | static char *aty_ct_ram[8] __devinitdata = { | 557 | static char *aty_ct_ram[8] __devinitdata = { |
555 | ram_off, ram_dram, ram_edo, ram_edo, | 558 | ram_off, ram_dram, ram_edo, ram_edo, |
559 | ram_sdram, ram_sgram, ram_wram, ram_resv | ||
560 | }; | ||
561 | static char *aty_xl_ram[8] __devinitdata = { | ||
562 | ram_off, ram_dram, ram_edo, ram_edo, | ||
556 | ram_sdram, ram_sgram, ram_sdram32, ram_resv | 563 | ram_sdram, ram_sgram, ram_sdram32, ram_resv |
557 | }; | 564 | }; |
558 | #endif /* CONFIG_FB_ATY_CT */ | 565 | #endif /* CONFIG_FB_ATY_CT */ |
@@ -760,6 +767,17 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) | |||
760 | #endif /* CONFIG_FB_ATY_GENERIC_LCD */ | 767 | #endif /* CONFIG_FB_ATY_GENERIC_LCD */ |
761 | } | 768 | } |
762 | 769 | ||
770 | static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp) | ||
771 | { | ||
772 | u32 line_length = vxres * bpp / 8; | ||
773 | |||
774 | if (par->ram_type == SGRAM || | ||
775 | (!M64_HAS(XL_MEM) && par->ram_type == WRAM)) | ||
776 | line_length = (line_length + 63) & ~63; | ||
777 | |||
778 | return line_length; | ||
779 | } | ||
780 | |||
763 | static int aty_var_to_crtc(const struct fb_info *info, | 781 | static int aty_var_to_crtc(const struct fb_info *info, |
764 | const struct fb_var_screeninfo *var, struct crtc *crtc) | 782 | const struct fb_var_screeninfo *var, struct crtc *crtc) |
765 | { | 783 | { |
@@ -769,13 +787,14 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
769 | u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; | 787 | u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; |
770 | u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; | 788 | u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; |
771 | u32 pix_width, dp_pix_width, dp_chain_mask; | 789 | u32 pix_width, dp_pix_width, dp_chain_mask; |
790 | u32 line_length; | ||
772 | 791 | ||
773 | /* input */ | 792 | /* input */ |
774 | xres = var->xres; | 793 | xres = (var->xres + 7) & ~7; |
775 | yres = var->yres; | 794 | yres = var->yres; |
776 | vxres = var->xres_virtual; | 795 | vxres = (var->xres_virtual + 7) & ~7; |
777 | vyres = var->yres_virtual; | 796 | vyres = var->yres_virtual; |
778 | xoffset = var->xoffset; | 797 | xoffset = (var->xoffset + 7) & ~7; |
779 | yoffset = var->yoffset; | 798 | yoffset = var->yoffset; |
780 | bpp = var->bits_per_pixel; | 799 | bpp = var->bits_per_pixel; |
781 | if (bpp == 16) | 800 | if (bpp == 16) |
@@ -827,7 +846,9 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
827 | } else | 846 | } else |
828 | FAIL("invalid bpp"); | 847 | FAIL("invalid bpp"); |
829 | 848 | ||
830 | if (vxres * vyres * bpp / 8 > info->fix.smem_len) | 849 | line_length = calc_line_length(par, vxres, bpp); |
850 | |||
851 | if (vyres * line_length > info->fix.smem_len) | ||
831 | FAIL("not enough video RAM"); | 852 | FAIL("not enough video RAM"); |
832 | 853 | ||
833 | h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; | 854 | h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; |
@@ -969,7 +990,9 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
969 | crtc->xoffset = xoffset; | 990 | crtc->xoffset = xoffset; |
970 | crtc->yoffset = yoffset; | 991 | crtc->yoffset = yoffset; |
971 | crtc->bpp = bpp; | 992 | crtc->bpp = bpp; |
972 | crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19); | 993 | crtc->off_pitch = |
994 | ((yoffset * line_length + xoffset * bpp / 8) / 8) | | ||
995 | ((line_length / bpp) << 22); | ||
973 | crtc->vline_crnt_vline = 0; | 996 | crtc->vline_crnt_vline = 0; |
974 | 997 | ||
975 | crtc->h_tot_disp = h_total | (h_disp<<16); | 998 | crtc->h_tot_disp = h_total | (h_disp<<16); |
@@ -1394,7 +1417,9 @@ static int atyfb_set_par(struct fb_info *info) | |||
1394 | } | 1417 | } |
1395 | aty_st_8(DAC_MASK, 0xff, par); | 1418 | aty_st_8(DAC_MASK, 0xff, par); |
1396 | 1419 | ||
1397 | info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8; | 1420 | info->fix.line_length = calc_line_length(par, var->xres_virtual, |
1421 | var->bits_per_pixel); | ||
1422 | |||
1398 | info->fix.visual = var->bits_per_pixel <= 8 ? | 1423 | info->fix.visual = var->bits_per_pixel <= 8 ? |
1399 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; | 1424 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; |
1400 | 1425 | ||
@@ -1505,10 +1530,12 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info) | |||
1505 | { | 1530 | { |
1506 | u32 xoffset = info->var.xoffset; | 1531 | u32 xoffset = info->var.xoffset; |
1507 | u32 yoffset = info->var.yoffset; | 1532 | u32 yoffset = info->var.yoffset; |
1508 | u32 vxres = par->crtc.vxres; | 1533 | u32 line_length = info->fix.line_length; |
1509 | u32 bpp = info->var.bits_per_pixel; | 1534 | u32 bpp = info->var.bits_per_pixel; |
1510 | 1535 | ||
1511 | par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19); | 1536 | par->crtc.off_pitch = |
1537 | ((yoffset * line_length + xoffset * bpp / 8) / 8) | | ||
1538 | ((line_length / bpp) << 22); | ||
1512 | } | 1539 | } |
1513 | 1540 | ||
1514 | 1541 | ||
@@ -2201,7 +2228,7 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) | |||
2201 | const int *refresh_tbl; | 2228 | const int *refresh_tbl; |
2202 | int i, size; | 2229 | int i, size; |
2203 | 2230 | ||
2204 | if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { | 2231 | if (M64_HAS(XL_MEM)) { |
2205 | refresh_tbl = ragexl_tbl; | 2232 | refresh_tbl = ragexl_tbl; |
2206 | size = ARRAY_SIZE(ragexl_tbl); | 2233 | size = ARRAY_SIZE(ragexl_tbl); |
2207 | } else { | 2234 | } else { |
@@ -2335,7 +2362,10 @@ static int __devinit aty_init(struct fb_info *info) | |||
2335 | par->pll_ops = &aty_pll_ct; | 2362 | par->pll_ops = &aty_pll_ct; |
2336 | par->bus_type = PCI; | 2363 | par->bus_type = PCI; |
2337 | par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); | 2364 | par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); |
2338 | ramname = aty_ct_ram[par->ram_type]; | 2365 | if (M64_HAS(XL_MEM)) |
2366 | ramname = aty_xl_ram[par->ram_type]; | ||
2367 | else | ||
2368 | ramname = aty_ct_ram[par->ram_type]; | ||
2339 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ | 2369 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ |
2340 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) | 2370 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) |
2341 | par->pll_limits.mclk = 63; | 2371 | par->pll_limits.mclk = 63; |
@@ -2390,9 +2420,9 @@ static int __devinit aty_init(struct fb_info *info) | |||
2390 | #endif /* CONFIG_FB_ATY_CT */ | 2420 | #endif /* CONFIG_FB_ATY_CT */ |
2391 | 2421 | ||
2392 | /* save previous video mode */ | 2422 | /* save previous video mode */ |
2393 | aty_get_crtc(par, &saved_crtc); | 2423 | aty_get_crtc(par, &par->saved_crtc); |
2394 | if(par->pll_ops->get_pll) | 2424 | if(par->pll_ops->get_pll) |
2395 | par->pll_ops->get_pll(info, &saved_pll); | 2425 | par->pll_ops->get_pll(info, &par->saved_pll); |
2396 | 2426 | ||
2397 | par->mem_cntl = aty_ld_le32(MEM_CNTL, par); | 2427 | par->mem_cntl = aty_ld_le32(MEM_CNTL, par); |
2398 | gtb_memsize = M64_HAS(GTB_DSP); | 2428 | gtb_memsize = M64_HAS(GTB_DSP); |
@@ -2667,8 +2697,8 @@ static int __devinit aty_init(struct fb_info *info) | |||
2667 | 2697 | ||
2668 | aty_init_exit: | 2698 | aty_init_exit: |
2669 | /* restore video mode */ | 2699 | /* restore video mode */ |
2670 | aty_set_crtc(par, &saved_crtc); | 2700 | aty_set_crtc(par, &par->saved_crtc); |
2671 | par->pll_ops->set_pll(info, &saved_pll); | 2701 | par->pll_ops->set_pll(info, &par->saved_pll); |
2672 | 2702 | ||
2673 | #ifdef CONFIG_MTRR | 2703 | #ifdef CONFIG_MTRR |
2674 | if (par->mtrr_reg >= 0) { | 2704 | if (par->mtrr_reg >= 0) { |
@@ -3502,6 +3532,11 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi | |||
3502 | par->mmap_map[1].prot_flag = _PAGE_E; | 3532 | par->mmap_map[1].prot_flag = _PAGE_E; |
3503 | #endif /* __sparc__ */ | 3533 | #endif /* __sparc__ */ |
3504 | 3534 | ||
3535 | mutex_lock(&reboot_lock); | ||
3536 | if (!reboot_info) | ||
3537 | reboot_info = info; | ||
3538 | mutex_unlock(&reboot_lock); | ||
3539 | |||
3505 | return 0; | 3540 | return 0; |
3506 | 3541 | ||
3507 | err_release_io: | 3542 | err_release_io: |
@@ -3614,8 +3649,8 @@ static void __devexit atyfb_remove(struct fb_info *info) | |||
3614 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 3649 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
3615 | 3650 | ||
3616 | /* restore video mode */ | 3651 | /* restore video mode */ |
3617 | aty_set_crtc(par, &saved_crtc); | 3652 | aty_set_crtc(par, &par->saved_crtc); |
3618 | par->pll_ops->set_pll(info, &saved_pll); | 3653 | par->pll_ops->set_pll(info, &par->saved_pll); |
3619 | 3654 | ||
3620 | unregister_framebuffer(info); | 3655 | unregister_framebuffer(info); |
3621 | 3656 | ||
@@ -3661,6 +3696,11 @@ static void __devexit atyfb_pci_remove(struct pci_dev *pdev) | |||
3661 | { | 3696 | { |
3662 | struct fb_info *info = pci_get_drvdata(pdev); | 3697 | struct fb_info *info = pci_get_drvdata(pdev); |
3663 | 3698 | ||
3699 | mutex_lock(&reboot_lock); | ||
3700 | if (reboot_info == info) | ||
3701 | reboot_info = NULL; | ||
3702 | mutex_unlock(&reboot_lock); | ||
3703 | |||
3664 | atyfb_remove(info); | 3704 | atyfb_remove(info); |
3665 | } | 3705 | } |
3666 | 3706 | ||
@@ -3808,6 +3848,56 @@ static int __init atyfb_setup(char *options) | |||
3808 | } | 3848 | } |
3809 | #endif /* MODULE */ | 3849 | #endif /* MODULE */ |
3810 | 3850 | ||
3851 | static int atyfb_reboot_notify(struct notifier_block *nb, | ||
3852 | unsigned long code, void *unused) | ||
3853 | { | ||
3854 | struct atyfb_par *par; | ||
3855 | |||
3856 | if (code != SYS_RESTART) | ||
3857 | return NOTIFY_DONE; | ||
3858 | |||
3859 | mutex_lock(&reboot_lock); | ||
3860 | |||
3861 | if (!reboot_info) | ||
3862 | goto out; | ||
3863 | |||
3864 | if (!lock_fb_info(reboot_info)) | ||
3865 | goto out; | ||
3866 | |||
3867 | par = reboot_info->par; | ||
3868 | |||
3869 | /* | ||
3870 | * HP OmniBook 500's BIOS doesn't like the state of the | ||
3871 | * hardware after atyfb has been used. Restore the hardware | ||
3872 | * to the original state to allow successful reboots. | ||
3873 | */ | ||
3874 | aty_set_crtc(par, &par->saved_crtc); | ||
3875 | par->pll_ops->set_pll(reboot_info, &par->saved_pll); | ||
3876 | |||
3877 | unlock_fb_info(reboot_info); | ||
3878 | out: | ||
3879 | mutex_unlock(&reboot_lock); | ||
3880 | |||
3881 | return NOTIFY_DONE; | ||
3882 | } | ||
3883 | |||
3884 | static struct notifier_block atyfb_reboot_notifier = { | ||
3885 | .notifier_call = atyfb_reboot_notify, | ||
3886 | }; | ||
3887 | |||
3888 | static const struct dmi_system_id atyfb_reboot_ids[] = { | ||
3889 | { | ||
3890 | .ident = "HP OmniBook 500", | ||
3891 | .matches = { | ||
3892 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
3893 | DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"), | ||
3894 | DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"), | ||
3895 | }, | ||
3896 | }, | ||
3897 | |||
3898 | { } | ||
3899 | }; | ||
3900 | |||
3811 | static int __init atyfb_init(void) | 3901 | static int __init atyfb_init(void) |
3812 | { | 3902 | { |
3813 | int err1 = 1, err2 = 1; | 3903 | int err1 = 1, err2 = 1; |
@@ -3826,11 +3916,20 @@ static int __init atyfb_init(void) | |||
3826 | err2 = atyfb_atari_probe(); | 3916 | err2 = atyfb_atari_probe(); |
3827 | #endif | 3917 | #endif |
3828 | 3918 | ||
3829 | return (err1 && err2) ? -ENODEV : 0; | 3919 | if (err1 && err2) |
3920 | return -ENODEV; | ||
3921 | |||
3922 | if (dmi_check_system(atyfb_reboot_ids)) | ||
3923 | register_reboot_notifier(&atyfb_reboot_notifier); | ||
3924 | |||
3925 | return 0; | ||
3830 | } | 3926 | } |
3831 | 3927 | ||
3832 | static void __exit atyfb_exit(void) | 3928 | static void __exit atyfb_exit(void) |
3833 | { | 3929 | { |
3930 | if (dmi_check_system(atyfb_reboot_ids)) | ||
3931 | unregister_reboot_notifier(&atyfb_reboot_notifier); | ||
3932 | |||
3834 | #ifdef CONFIG_PCI | 3933 | #ifdef CONFIG_PCI |
3835 | pci_unregister_driver(&atyfb_driver); | 3934 | pci_unregister_driver(&atyfb_driver); |
3836 | #endif | 3935 | #endif |
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c index 0cc9724e61a2..51fcc0a2c94a 100644 --- a/drivers/video/aty/mach64_accel.c +++ b/drivers/video/aty/mach64_accel.c | |||
@@ -63,14 +63,17 @@ static void reset_GTC_3D_engine(const struct atyfb_par *par) | |||
63 | void aty_init_engine(struct atyfb_par *par, struct fb_info *info) | 63 | void aty_init_engine(struct atyfb_par *par, struct fb_info *info) |
64 | { | 64 | { |
65 | u32 pitch_value; | 65 | u32 pitch_value; |
66 | u32 vxres; | ||
66 | 67 | ||
67 | /* determine modal information from global mode structure */ | 68 | /* determine modal information from global mode structure */ |
68 | pitch_value = info->var.xres_virtual; | 69 | pitch_value = info->fix.line_length / (info->var.bits_per_pixel / 8); |
70 | vxres = info->var.xres_virtual; | ||
69 | 71 | ||
70 | if (info->var.bits_per_pixel == 24) { | 72 | if (info->var.bits_per_pixel == 24) { |
71 | /* In 24 bpp, the engine is in 8 bpp - this requires that all */ | 73 | /* In 24 bpp, the engine is in 8 bpp - this requires that all */ |
72 | /* horizontal coordinates and widths must be adjusted */ | 74 | /* horizontal coordinates and widths must be adjusted */ |
73 | pitch_value *= 3; | 75 | pitch_value *= 3; |
76 | vxres *= 3; | ||
74 | } | 77 | } |
75 | 78 | ||
76 | /* On GTC (RagePro), we need to reset the 3D engine before */ | 79 | /* On GTC (RagePro), we need to reset the 3D engine before */ |
@@ -133,7 +136,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) | |||
133 | aty_st_le32(SC_LEFT, 0, par); | 136 | aty_st_le32(SC_LEFT, 0, par); |
134 | aty_st_le32(SC_TOP, 0, par); | 137 | aty_st_le32(SC_TOP, 0, par); |
135 | aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); | 138 | aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); |
136 | aty_st_le32(SC_RIGHT, pitch_value - 1, par); | 139 | aty_st_le32(SC_RIGHT, vxres - 1, par); |
137 | 140 | ||
138 | /* set background color to minimum value (usually BLACK) */ | 141 | /* set background color to minimum value (usually BLACK) */ |
139 | aty_st_le32(DP_BKGD_CLR, 0, par); | 142 | aty_st_le32(DP_BKGD_CLR, 0, par); |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index f9d19be05540..90861cd93165 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -110,7 +110,7 @@ config BACKLIGHT_CLASS_DEVICE | |||
110 | config BACKLIGHT_ATMEL_LCDC | 110 | config BACKLIGHT_ATMEL_LCDC |
111 | bool "Atmel LCDC Contrast-as-Backlight control" | 111 | bool "Atmel LCDC Contrast-as-Backlight control" |
112 | depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL | 112 | depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL |
113 | default y if MACH_SAM9261EK || MACH_SAM9263EK | 113 | default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK |
114 | help | 114 | help |
115 | This provides a backlight control internal to the Atmel LCDC | 115 | This provides a backlight control internal to the Atmel LCDC |
116 | driver. If the LCD "contrast control" on your board is wired | 116 | driver. If the LCD "contrast control" on your board is wired |
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index 1dae7f8f3c6b..51422fc4f606 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c | |||
@@ -356,7 +356,7 @@ static int __devinit tdo24m_probe(struct spi_device *spi) | |||
356 | lcd->power = FB_BLANK_POWERDOWN; | 356 | lcd->power = FB_BLANK_POWERDOWN; |
357 | lcd->mode = MODE_VGA; /* default to VGA */ | 357 | lcd->mode = MODE_VGA; /* default to VGA */ |
358 | 358 | ||
359 | lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL)); | 359 | lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, GFP_KERNEL); |
360 | if (lcd->buf == NULL) { | 360 | if (lcd->buf == NULL) { |
361 | kfree(lcd); | 361 | kfree(lcd); |
362 | return -ENOMEM; | 362 | return -ENOMEM; |
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c index 7bad24ed04ef..108b89e09a80 100644 --- a/drivers/video/cobalt_lcdfb.c +++ b/drivers/video/cobalt_lcdfb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Cobalt server LCD frame buffer driver. | 2 | * Cobalt server LCD frame buffer driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index f8a09bf8d0cd..53ea05645ff8 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1310,8 +1310,6 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, | |||
1310 | 1310 | ||
1311 | static int | 1311 | static int |
1312 | fb_mmap(struct file *file, struct vm_area_struct * vma) | 1312 | fb_mmap(struct file *file, struct vm_area_struct * vma) |
1313 | __acquires(&info->lock) | ||
1314 | __releases(&info->lock) | ||
1315 | { | 1313 | { |
1316 | int fbidx = iminor(file->f_path.dentry->d_inode); | 1314 | int fbidx = iminor(file->f_path.dentry->d_inode); |
1317 | struct fb_info *info = registered_fb[fbidx]; | 1315 | struct fb_info *info = registered_fb[fbidx]; |
@@ -1325,16 +1323,14 @@ __releases(&info->lock) | |||
1325 | off = vma->vm_pgoff << PAGE_SHIFT; | 1323 | off = vma->vm_pgoff << PAGE_SHIFT; |
1326 | if (!fb) | 1324 | if (!fb) |
1327 | return -ENODEV; | 1325 | return -ENODEV; |
1326 | mutex_lock(&info->mm_lock); | ||
1328 | if (fb->fb_mmap) { | 1327 | if (fb->fb_mmap) { |
1329 | int res; | 1328 | int res; |
1330 | mutex_lock(&info->lock); | ||
1331 | res = fb->fb_mmap(info, vma); | 1329 | res = fb->fb_mmap(info, vma); |
1332 | mutex_unlock(&info->lock); | 1330 | mutex_unlock(&info->mm_lock); |
1333 | return res; | 1331 | return res; |
1334 | } | 1332 | } |
1335 | 1333 | ||
1336 | mutex_lock(&info->lock); | ||
1337 | |||
1338 | /* frame buffer memory */ | 1334 | /* frame buffer memory */ |
1339 | start = info->fix.smem_start; | 1335 | start = info->fix.smem_start; |
1340 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); | 1336 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); |
@@ -1342,13 +1338,13 @@ __releases(&info->lock) | |||
1342 | /* memory mapped io */ | 1338 | /* memory mapped io */ |
1343 | off -= len; | 1339 | off -= len; |
1344 | if (info->var.accel_flags) { | 1340 | if (info->var.accel_flags) { |
1345 | mutex_unlock(&info->lock); | 1341 | mutex_unlock(&info->mm_lock); |
1346 | return -EINVAL; | 1342 | return -EINVAL; |
1347 | } | 1343 | } |
1348 | start = info->fix.mmio_start; | 1344 | start = info->fix.mmio_start; |
1349 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); | 1345 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); |
1350 | } | 1346 | } |
1351 | mutex_unlock(&info->lock); | 1347 | mutex_unlock(&info->mm_lock); |
1352 | start &= PAGE_MASK; | 1348 | start &= PAGE_MASK; |
1353 | if ((vma->vm_end - vma->vm_start + off) > len) | 1349 | if ((vma->vm_end - vma->vm_start + off) > len) |
1354 | return -EINVAL; | 1350 | return -EINVAL; |
@@ -1518,6 +1514,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1518 | break; | 1514 | break; |
1519 | fb_info->node = i; | 1515 | fb_info->node = i; |
1520 | mutex_init(&fb_info->lock); | 1516 | mutex_init(&fb_info->lock); |
1517 | mutex_init(&fb_info->mm_lock); | ||
1521 | 1518 | ||
1522 | fb_info->dev = device_create(fb_class, fb_info->device, | 1519 | fb_info->dev = device_create(fb_class, fb_info->device, |
1523 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); | 1520 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); |
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index f153c581cbd7..72d68b3dc478 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -750,24 +750,26 @@ static void update_lcdc(struct fb_info *info) | |||
750 | static int map_video_memory(struct fb_info *info) | 750 | static int map_video_memory(struct fb_info *info) |
751 | { | 751 | { |
752 | phys_addr_t phys; | 752 | phys_addr_t phys; |
753 | u32 smem_len = info->fix.line_length * info->var.yres_virtual; | ||
753 | 754 | ||
754 | pr_debug("info->var.xres_virtual = %d\n", info->var.xres_virtual); | 755 | pr_debug("info->var.xres_virtual = %d\n", info->var.xres_virtual); |
755 | pr_debug("info->var.yres_virtual = %d\n", info->var.yres_virtual); | 756 | pr_debug("info->var.yres_virtual = %d\n", info->var.yres_virtual); |
756 | pr_debug("info->fix.line_length = %d\n", info->fix.line_length); | 757 | pr_debug("info->fix.line_length = %d\n", info->fix.line_length); |
758 | pr_debug("MAP_VIDEO_MEMORY: smem_len = %u\n", smem_len); | ||
757 | 759 | ||
758 | info->fix.smem_len = info->fix.line_length * info->var.yres_virtual; | 760 | info->screen_base = fsl_diu_alloc(smem_len, &phys); |
759 | pr_debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->fix.smem_len); | ||
760 | info->screen_base = fsl_diu_alloc(info->fix.smem_len, &phys); | ||
761 | if (info->screen_base == NULL) { | 761 | if (info->screen_base == NULL) { |
762 | printk(KERN_ERR "Unable to allocate fb memory\n"); | 762 | printk(KERN_ERR "Unable to allocate fb memory\n"); |
763 | return -ENOMEM; | 763 | return -ENOMEM; |
764 | } | 764 | } |
765 | mutex_lock(&info->mm_lock); | ||
765 | info->fix.smem_start = (unsigned long) phys; | 766 | info->fix.smem_start = (unsigned long) phys; |
767 | info->fix.smem_len = smem_len; | ||
768 | mutex_unlock(&info->mm_lock); | ||
766 | info->screen_size = info->fix.smem_len; | 769 | info->screen_size = info->fix.smem_len; |
767 | 770 | ||
768 | pr_debug("Allocated fb @ paddr=0x%08lx, size=%d.\n", | 771 | pr_debug("Allocated fb @ paddr=0x%08lx, size=%d.\n", |
769 | info->fix.smem_start, | 772 | info->fix.smem_start, info->fix.smem_len); |
770 | info->fix.smem_len); | ||
771 | pr_debug("screen base %p\n", info->screen_base); | 773 | pr_debug("screen base %p\n", info->screen_base); |
772 | 774 | ||
773 | return 0; | 775 | return 0; |
@@ -776,9 +778,11 @@ static int map_video_memory(struct fb_info *info) | |||
776 | static void unmap_video_memory(struct fb_info *info) | 778 | static void unmap_video_memory(struct fb_info *info) |
777 | { | 779 | { |
778 | fsl_diu_free(info->screen_base, info->fix.smem_len); | 780 | fsl_diu_free(info->screen_base, info->fix.smem_len); |
781 | mutex_lock(&info->mm_lock); | ||
779 | info->screen_base = NULL; | 782 | info->screen_base = NULL; |
780 | info->fix.smem_start = 0; | 783 | info->fix.smem_start = 0; |
781 | info->fix.smem_len = 0; | 784 | info->fix.smem_len = 0; |
785 | mutex_unlock(&info->mm_lock); | ||
782 | } | 786 | } |
783 | 787 | ||
784 | /* | 788 | /* |
@@ -1219,12 +1223,6 @@ static int __devinit install_fb(struct fb_info *info) | |||
1219 | return -EINVAL; | 1223 | return -EINVAL; |
1220 | } | 1224 | } |
1221 | 1225 | ||
1222 | if (fsl_diu_set_par(info)) { | ||
1223 | printk(KERN_ERR "fb_set_par failed"); | ||
1224 | fb_dealloc_cmap(&info->cmap); | ||
1225 | return -EINVAL; | ||
1226 | } | ||
1227 | |||
1228 | if (register_framebuffer(info) < 0) { | 1226 | if (register_framebuffer(info) < 0) { |
1229 | printk(KERN_ERR "register_framebuffer failed"); | 1227 | printk(KERN_ERR "register_framebuffer failed"); |
1230 | unmap_video_memory(info); | 1228 | unmap_video_memory(info); |
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 020db7fc9153..e7116a6d82d3 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c | |||
@@ -44,9 +44,6 @@ static struct fb_fix_screeninfo hitfb_fix __initdata = { | |||
44 | .accel = FB_ACCEL_NONE, | 44 | .accel = FB_ACCEL_NONE, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static u32 pseudo_palette[16]; | ||
48 | static struct fb_info fb_info; | ||
49 | |||
50 | static inline void hitfb_accel_wait(void) | 47 | static inline void hitfb_accel_wait(void) |
51 | { | 48 | { |
52 | while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ; | 49 | while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ; |
@@ -331,6 +328,8 @@ static struct fb_ops hitfb_ops = { | |||
331 | static int __init hitfb_probe(struct platform_device *dev) | 328 | static int __init hitfb_probe(struct platform_device *dev) |
332 | { | 329 | { |
333 | unsigned short lcdclor, ldr3, ldvndr; | 330 | unsigned short lcdclor, ldr3, ldvndr; |
331 | struct fb_info *info; | ||
332 | int ret; | ||
334 | 333 | ||
335 | if (fb_get_options("hitfb", NULL)) | 334 | if (fb_get_options("hitfb", NULL)) |
336 | return -ENODEV; | 335 | return -ENODEV; |
@@ -384,32 +383,53 @@ static int __init hitfb_probe(struct platform_device *dev) | |||
384 | break; | 383 | break; |
385 | } | 384 | } |
386 | 385 | ||
387 | fb_info.fbops = &hitfb_ops; | 386 | info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); |
388 | fb_info.var = hitfb_var; | 387 | if (unlikely(!info)) |
389 | fb_info.fix = hitfb_fix; | 388 | return -ENOMEM; |
390 | fb_info.pseudo_palette = pseudo_palette; | 389 | |
391 | fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | | 390 | info->fbops = &hitfb_ops; |
391 | info->var = hitfb_var; | ||
392 | info->fix = hitfb_fix; | ||
393 | info->pseudo_palette = info->par; | ||
394 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | | ||
392 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; | 395 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; |
393 | 396 | ||
394 | fb_info.screen_base = (void *)hitfb_fix.smem_start; | 397 | info->screen_base = (void *)hitfb_fix.smem_start; |
395 | 398 | ||
396 | fb_alloc_cmap(&fb_info.cmap, 256, 0); | 399 | ret = fb_alloc_cmap(&info->cmap, 256, 0); |
400 | if (unlikely(ret < 0)) | ||
401 | goto err_fb; | ||
397 | 402 | ||
398 | if (register_framebuffer(&fb_info) < 0) | 403 | ret = register_framebuffer(info); |
399 | return -EINVAL; | 404 | if (unlikely(ret < 0)) |
405 | goto err; | ||
406 | |||
407 | platform_set_drvdata(dev, info); | ||
400 | 408 | ||
401 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | 409 | printk(KERN_INFO "fb%d: %s frame buffer device\n", |
402 | fb_info.node, fb_info.fix.id); | 410 | info->node, info->fix.id); |
411 | |||
403 | return 0; | 412 | return 0; |
413 | |||
414 | err: | ||
415 | fb_dealloc_cmap(&info->cmap); | ||
416 | err_fb: | ||
417 | framebuffer_release(info); | ||
418 | return ret; | ||
404 | } | 419 | } |
405 | 420 | ||
406 | static int __exit hitfb_remove(struct platform_device *dev) | 421 | static int __exit hitfb_remove(struct platform_device *dev) |
407 | { | 422 | { |
408 | return unregister_framebuffer(&fb_info); | 423 | struct fb_info *info = platform_get_drvdata(dev); |
424 | |||
425 | unregister_framebuffer(info); | ||
426 | fb_dealloc_cmap(&info->cmap); | ||
427 | framebuffer_release(info); | ||
428 | |||
429 | return 0; | ||
409 | } | 430 | } |
410 | 431 | ||
411 | #ifdef CONFIG_PM | 432 | static int hitfb_suspend(struct device *dev) |
412 | static int hitfb_suspend(struct platform_device *dev, pm_message_t state) | ||
413 | { | 433 | { |
414 | u16 v; | 434 | u16 v; |
415 | 435 | ||
@@ -421,7 +441,7 @@ static int hitfb_suspend(struct platform_device *dev, pm_message_t state) | |||
421 | return 0; | 441 | return 0; |
422 | } | 442 | } |
423 | 443 | ||
424 | static int hitfb_resume(struct platform_device *dev) | 444 | static int hitfb_resume(struct device *dev) |
425 | { | 445 | { |
426 | u16 v; | 446 | u16 v; |
427 | 447 | ||
@@ -435,17 +455,19 @@ static int hitfb_resume(struct platform_device *dev) | |||
435 | 455 | ||
436 | return 0; | 456 | return 0; |
437 | } | 457 | } |
438 | #endif | 458 | |
459 | static struct dev_pm_ops hitfb_dev_pm_ops = { | ||
460 | .suspend = hitfb_suspend, | ||
461 | .resume = hitfb_resume, | ||
462 | }; | ||
439 | 463 | ||
440 | static struct platform_driver hitfb_driver = { | 464 | static struct platform_driver hitfb_driver = { |
441 | .probe = hitfb_probe, | 465 | .probe = hitfb_probe, |
442 | .remove = __exit_p(hitfb_remove), | 466 | .remove = __exit_p(hitfb_remove), |
443 | #ifdef CONFIG_PM | ||
444 | .suspend = hitfb_suspend, | ||
445 | .resume = hitfb_resume, | ||
446 | #endif | ||
447 | .driver = { | 467 | .driver = { |
448 | .name = "hitfb", | 468 | .name = "hitfb", |
469 | .owner = THIS_MODULE, | ||
470 | .pm = &hitfb_dev_pm_ops, | ||
449 | }, | 471 | }, |
450 | }; | 472 | }; |
451 | 473 | ||
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 2e940199fc89..5743ea25e818 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -1090,8 +1090,10 @@ static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | |||
1090 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | 1090 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); |
1091 | 1091 | ||
1092 | strcpy(fix->id, "I810"); | 1092 | strcpy(fix->id, "I810"); |
1093 | mutex_lock(&info->mm_lock); | ||
1093 | fix->smem_start = par->fb.physical; | 1094 | fix->smem_start = par->fb.physical; |
1094 | fix->smem_len = par->fb.size; | 1095 | fix->smem_len = par->fb.size; |
1096 | mutex_unlock(&info->mm_lock); | ||
1095 | fix->type = FB_TYPE_PACKED_PIXELS; | 1097 | fix->type = FB_TYPE_PACKED_PIXELS; |
1096 | fix->type_aux = 0; | 1098 | fix->type_aux = 0; |
1097 | fix->xpanstep = 8; | 1099 | fix->xpanstep = 8; |
@@ -2058,8 +2060,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev, | |||
2058 | 2060 | ||
2059 | fb_var_to_videomode(&mode, &info->var); | 2061 | fb_var_to_videomode(&mode, &info->var); |
2060 | fb_add_videomode(&mode, &info->modelist); | 2062 | fb_add_videomode(&mode, &info->modelist); |
2061 | encode_fix(&info->fix, info); | 2063 | |
2062 | |||
2063 | i810fb_init_ringbuffer(info); | 2064 | i810fb_init_ringbuffer(info); |
2064 | err = register_framebuffer(info); | 2065 | err = register_framebuffer(info); |
2065 | 2066 | ||
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c index 0ce3b0a89798..a74e5da17aa0 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/matrox/matroxfb_DAC1064.c | |||
@@ -454,9 +454,9 @@ static void DAC1064_restore_2(WPMINFO2) { | |||
454 | dprintk(KERN_DEBUG "DAC1064regs "); | 454 | dprintk(KERN_DEBUG "DAC1064regs "); |
455 | for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { | 455 | for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) { |
456 | dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]); | 456 | dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]); |
457 | if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... "); | 457 | if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... "); |
458 | } | 458 | } |
459 | dprintk("\n" KERN_DEBUG "DAC1064clk "); | 459 | dprintk(KERN_DEBUG "DAC1064clk "); |
460 | for (i = 0; i < 6; i++) | 460 | for (i = 0; i < 6; i++) |
461 | dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]); | 461 | dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]); |
462 | dprintk("\n"); | 462 | dprintk("\n"); |
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c index 13524821e242..4e825112a601 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.c +++ b/drivers/video/matrox/matroxfb_Ti3026.c | |||
@@ -651,9 +651,9 @@ static void Ti3026_restore(WPMINFO2) { | |||
651 | dprintk(KERN_DEBUG "3026DACregs "); | 651 | dprintk(KERN_DEBUG "3026DACregs "); |
652 | for (i = 0; i < 21; i++) { | 652 | for (i = 0; i < 21; i++) { |
653 | dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]); | 653 | dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]); |
654 | if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... "); | 654 | if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... "); |
655 | } | 655 | } |
656 | dprintk("\n" KERN_DEBUG "DACclk "); | 656 | dprintk(KERN_DEBUG "DACclk "); |
657 | for (i = 0; i < 6; i++) | 657 | for (i = 0; i < 6; i++) |
658 | dprintk("C%02X=%02X ", i, hw->DACclk[i]); | 658 | dprintk("C%02X=%02X ", i, hw->DACclk[i]); |
659 | dprintk("\n"); | 659 | dprintk("\n"); |
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 8e7a275df50c..0c1049b308bf 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c | |||
@@ -724,8 +724,10 @@ static void matroxfb_update_fix(WPMINFO2) | |||
724 | struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; | 724 | struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; |
725 | DBG(__func__) | 725 | DBG(__func__) |
726 | 726 | ||
727 | mutex_lock(&ACCESS_FBINFO(fbcon).mm_lock); | ||
727 | fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); | 728 | fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); |
728 | fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); | 729 | fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); |
730 | mutex_unlock(&ACCESS_FBINFO(fbcon).mm_lock); | ||
729 | } | 731 | } |
730 | 732 | ||
731 | static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 733 | static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
@@ -1874,7 +1876,6 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1874 | } | 1876 | } |
1875 | matroxfb_init_fix(PMINFO2); | 1877 | matroxfb_init_fix(PMINFO2); |
1876 | ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)); | 1878 | ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)); |
1877 | matroxfb_update_fix(PMINFO2); | ||
1878 | /* Normalize values (namely yres_virtual) */ | 1879 | /* Normalize values (namely yres_virtual) */ |
1879 | matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon)); | 1880 | matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon)); |
1880 | /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over | 1881 | /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over |
@@ -2081,6 +2082,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm | |||
2081 | spin_lock_init(&ACCESS_FBINFO(lock.accel)); | 2082 | spin_lock_init(&ACCESS_FBINFO(lock.accel)); |
2082 | init_rwsem(&ACCESS_FBINFO(crtc2.lock)); | 2083 | init_rwsem(&ACCESS_FBINFO(crtc2.lock)); |
2083 | init_rwsem(&ACCESS_FBINFO(altout.lock)); | 2084 | init_rwsem(&ACCESS_FBINFO(altout.lock)); |
2085 | mutex_init(&ACCESS_FBINFO(fbcon).mm_lock); | ||
2084 | ACCESS_FBINFO(irq_flags) = 0; | 2086 | ACCESS_FBINFO(irq_flags) = 0; |
2085 | init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); | 2087 | init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); |
2086 | init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); | 2088 | init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); |
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c index 7ac4c5f6145d..ebcb5c6b4962 100644 --- a/drivers/video/matrox/matroxfb_crtc2.c +++ b/drivers/video/matrox/matroxfb_crtc2.c | |||
@@ -289,7 +289,12 @@ static int matroxfb_dh_release(struct fb_info* info, int user) { | |||
289 | #undef m2info | 289 | #undef m2info |
290 | } | 290 | } |
291 | 291 | ||
292 | static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) { | 292 | /* |
293 | * This function is called before the register_framebuffer so | ||
294 | * no locking is needed. | ||
295 | */ | ||
296 | static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) | ||
297 | { | ||
293 | struct fb_fix_screeninfo *fix = &m2info->fbcon.fix; | 298 | struct fb_fix_screeninfo *fix = &m2info->fbcon.fix; |
294 | 299 | ||
295 | strcpy(fix->id, "MATROX DH"); | 300 | strcpy(fix->id, "MATROX DH"); |
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index b7af5256e887..f8778cde2183 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c | |||
@@ -669,7 +669,7 @@ static uint32_t bpp_to_pixfmt(int bpp) | |||
669 | } | 669 | } |
670 | 670 | ||
671 | static int mx3fb_blank(int blank, struct fb_info *fbi); | 671 | static int mx3fb_blank(int blank, struct fb_info *fbi); |
672 | static int mx3fb_map_video_memory(struct fb_info *fbi); | 672 | static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len); |
673 | static int mx3fb_unmap_video_memory(struct fb_info *fbi); | 673 | static int mx3fb_unmap_video_memory(struct fb_info *fbi); |
674 | 674 | ||
675 | /** | 675 | /** |
@@ -742,8 +742,7 @@ static int mx3fb_set_par(struct fb_info *fbi) | |||
742 | if (fbi->fix.smem_start) | 742 | if (fbi->fix.smem_start) |
743 | mx3fb_unmap_video_memory(fbi); | 743 | mx3fb_unmap_video_memory(fbi); |
744 | 744 | ||
745 | fbi->fix.smem_len = mem_len; | 745 | if (mx3fb_map_video_memory(fbi, mem_len) < 0) { |
746 | if (mx3fb_map_video_memory(fbi) < 0) { | ||
747 | mutex_unlock(&mx3_fbi->mutex); | 746 | mutex_unlock(&mx3_fbi->mutex); |
748 | return -ENOMEM; | 747 | return -ENOMEM; |
749 | } | 748 | } |
@@ -1198,6 +1197,7 @@ static int mx3fb_resume(struct platform_device *pdev) | |||
1198 | /** | 1197 | /** |
1199 | * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. | 1198 | * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. |
1200 | * @fbi: framebuffer information pointer | 1199 | * @fbi: framebuffer information pointer |
1200 | * @mem_len: length of mapped memory | ||
1201 | * @return: Error code indicating success or failure | 1201 | * @return: Error code indicating success or failure |
1202 | * | 1202 | * |
1203 | * This buffer is remapped into a non-cached, non-buffered, memory region to | 1203 | * This buffer is remapped into a non-cached, non-buffered, memory region to |
@@ -1205,23 +1205,26 @@ static int mx3fb_resume(struct platform_device *pdev) | |||
1205 | * area is remapped, all virtual memory access to the video memory should occur | 1205 | * area is remapped, all virtual memory access to the video memory should occur |
1206 | * at the new region. | 1206 | * at the new region. |
1207 | */ | 1207 | */ |
1208 | static int mx3fb_map_video_memory(struct fb_info *fbi) | 1208 | static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len) |
1209 | { | 1209 | { |
1210 | int retval = 0; | 1210 | int retval = 0; |
1211 | dma_addr_t addr; | 1211 | dma_addr_t addr; |
1212 | 1212 | ||
1213 | fbi->screen_base = dma_alloc_writecombine(fbi->device, | 1213 | fbi->screen_base = dma_alloc_writecombine(fbi->device, |
1214 | fbi->fix.smem_len, | 1214 | mem_len, |
1215 | &addr, GFP_DMA); | 1215 | &addr, GFP_DMA); |
1216 | 1216 | ||
1217 | if (!fbi->screen_base) { | 1217 | if (!fbi->screen_base) { |
1218 | dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", | 1218 | dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", |
1219 | fbi->fix.smem_len); | 1219 | mem_len); |
1220 | retval = -EBUSY; | 1220 | retval = -EBUSY; |
1221 | goto err0; | 1221 | goto err0; |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | mutex_lock(&fbi->mm_lock); | ||
1224 | fbi->fix.smem_start = addr; | 1225 | fbi->fix.smem_start = addr; |
1226 | fbi->fix.smem_len = mem_len; | ||
1227 | mutex_unlock(&fbi->mm_lock); | ||
1225 | 1228 | ||
1226 | dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", | 1229 | dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", |
1227 | (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); | 1230 | (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); |
@@ -1251,8 +1254,10 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi) | |||
1251 | fbi->screen_base, fbi->fix.smem_start); | 1254 | fbi->screen_base, fbi->fix.smem_start); |
1252 | 1255 | ||
1253 | fbi->screen_base = 0; | 1256 | fbi->screen_base = 0; |
1257 | mutex_lock(&fbi->mm_lock); | ||
1254 | fbi->fix.smem_start = 0; | 1258 | fbi->fix.smem_start = 0; |
1255 | fbi->fix.smem_len = 0; | 1259 | fbi->fix.smem_len = 0; |
1260 | mutex_unlock(&fbi->mm_lock); | ||
1256 | return 0; | 1261 | return 0; |
1257 | } | 1262 | } |
1258 | 1263 | ||
@@ -1360,11 +1365,6 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) | |||
1360 | init_completion(&mx3fbi->flip_cmpl); | 1365 | init_completion(&mx3fbi->flip_cmpl); |
1361 | disable_irq(ichan->eof_irq); | 1366 | disable_irq(ichan->eof_irq); |
1362 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); | 1367 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); |
1363 | ret = mx3fb_set_par(fbi); | ||
1364 | if (ret < 0) | ||
1365 | goto esetpar; | ||
1366 | |||
1367 | mx3fb_blank(FB_BLANK_UNBLANK, fbi); | ||
1368 | 1368 | ||
1369 | dev_info(dev, "registered, using mode %s\n", fb_mode); | 1369 | dev_info(dev, "registered, using mode %s\n", fb_mode); |
1370 | 1370 | ||
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 060d72fe57cb..4ea99bfc37b4 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
@@ -393,8 +393,10 @@ static void set_fb_fix(struct fb_info *fbi) | |||
393 | 393 | ||
394 | rg = &plane->fbdev->mem_desc.region[plane->idx]; | 394 | rg = &plane->fbdev->mem_desc.region[plane->idx]; |
395 | fbi->screen_base = rg->vaddr; | 395 | fbi->screen_base = rg->vaddr; |
396 | mutex_lock(&fbi->mm_lock); | ||
396 | fix->smem_start = rg->paddr; | 397 | fix->smem_start = rg->paddr; |
397 | fix->smem_len = rg->size; | 398 | fix->smem_len = rg->size; |
399 | mutex_unlock(&fbi->mm_lock); | ||
398 | 400 | ||
399 | fix->type = FB_TYPE_PACKED_PIXELS; | 401 | fix->type = FB_TYPE_PACKED_PIXELS; |
400 | bpp = var->bits_per_pixel; | 402 | bpp = var->bits_per_pixel; |
@@ -886,8 +888,10 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) | |||
886 | * plane memory is dealloce'd, the other | 888 | * plane memory is dealloce'd, the other |
887 | * screen parameters in var / fix are invalid. | 889 | * screen parameters in var / fix are invalid. |
888 | */ | 890 | */ |
891 | mutex_lock(&fbi->mm_lock); | ||
889 | fbi->fix.smem_start = 0; | 892 | fbi->fix.smem_start = 0; |
890 | fbi->fix.smem_len = 0; | 893 | fbi->fix.smem_len = 0; |
894 | mutex_unlock(&fbi->mm_lock); | ||
891 | } | 895 | } |
892 | } | 896 | } |
893 | } | 897 | } |
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 03b3670130a0..bacfabd9ce16 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
@@ -141,7 +141,9 @@ static int platinumfb_set_par (struct fb_info *info) | |||
141 | offset = 0x10; | 141 | offset = 0x10; |
142 | 142 | ||
143 | info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; | 143 | info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; |
144 | mutex_lock(&info->mm_lock); | ||
144 | info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; | 145 | info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; |
146 | mutex_unlock(&info->mm_lock); | ||
145 | info->fix.visual = (pinfo->cmode == CMODE_8) ? | 147 | info->fix.visual = (pinfo->cmode == CMODE_8) ? |
146 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; | 148 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; |
147 | info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode) | 149 | info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode) |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 0889d50c3288..6506117c134b 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -815,8 +815,10 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) | |||
815 | ofb->video_mem_phys = virt_to_phys(ofb->video_mem); | 815 | ofb->video_mem_phys = virt_to_phys(ofb->video_mem); |
816 | ofb->video_mem_size = size; | 816 | ofb->video_mem_size = size; |
817 | 817 | ||
818 | mutex_lock(&ofb->fb.mm_lock); | ||
818 | ofb->fb.fix.smem_start = ofb->video_mem_phys; | 819 | ofb->fb.fix.smem_start = ofb->video_mem_phys; |
819 | ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; | 820 | ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; |
821 | mutex_unlock(&ofb->fb.mm_lock); | ||
820 | ofb->fb.screen_base = ofb->video_mem; | 822 | ofb->fb.screen_base = ofb->video_mem; |
821 | return 0; | 823 | return 0; |
822 | } | 824 | } |
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 43680e545427..bb63c07e13de 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -211,23 +211,21 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, | |||
211 | 211 | ||
212 | /** | 212 | /** |
213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. | 213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. |
214 | * @id: window id. | ||
214 | * @sfb: The hardware state. | 215 | * @sfb: The hardware state. |
215 | * @pixclock: The pixel clock wanted, in picoseconds. | 216 | * @pixclock: The pixel clock wanted, in picoseconds. |
216 | * | 217 | * |
217 | * Given the specified pixel clock, work out the necessary divider to get | 218 | * Given the specified pixel clock, work out the necessary divider to get |
218 | * close to the output frequency. | 219 | * close to the output frequency. |
219 | */ | 220 | */ |
220 | static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) | 221 | static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk) |
221 | { | 222 | { |
223 | struct s3c_fb_pd_win *win = sfb->pdata->win[id]; | ||
222 | unsigned long clk = clk_get_rate(sfb->bus_clk); | 224 | unsigned long clk = clk_get_rate(sfb->bus_clk); |
223 | unsigned long long tmp; | ||
224 | unsigned int result; | 225 | unsigned int result; |
225 | 226 | ||
226 | tmp = (unsigned long long)clk; | 227 | pixclk *= win->win_mode.refresh; |
227 | tmp *= pixclk; | 228 | result = clk / pixclk; |
228 | |||
229 | do_div(tmp, 1000000000UL); | ||
230 | result = (unsigned int)tmp / 1000; | ||
231 | 229 | ||
232 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", | 230 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", |
233 | pixclk, clk, result, clk / result); | 231 | pixclk, clk, result, clk / result); |
@@ -267,6 +265,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
267 | struct s3c_fb *sfb = win->parent; | 265 | struct s3c_fb *sfb = win->parent; |
268 | void __iomem *regs = sfb->regs; | 266 | void __iomem *regs = sfb->regs; |
269 | int win_no = win->index; | 267 | int win_no = win->index; |
268 | u32 osdc_data = 0; | ||
270 | u32 data; | 269 | u32 data; |
271 | u32 pagewidth; | 270 | u32 pagewidth; |
272 | int clkdiv; | 271 | int clkdiv; |
@@ -302,7 +301,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
302 | /* use window 0 as the basis for the lcd output timings */ | 301 | /* use window 0 as the basis for the lcd output timings */ |
303 | 302 | ||
304 | if (win_no == 0) { | 303 | if (win_no == 0) { |
305 | clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); | 304 | clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock); |
306 | 305 | ||
307 | data = sfb->pdata->vidcon0; | 306 | data = sfb->pdata->vidcon0; |
308 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); | 307 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); |
@@ -359,8 +358,6 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
359 | 358 | ||
360 | data = var->xres * var->yres; | 359 | data = var->xres * var->yres; |
361 | 360 | ||
362 | u32 osdc_data = 0; | ||
363 | |||
364 | osdc_data = VIDISD14C_ALPHA1_R(0xf) | | 361 | osdc_data = VIDISD14C_ALPHA1_R(0xf) | |
365 | VIDISD14C_ALPHA1_G(0xf) | | 362 | VIDISD14C_ALPHA1_G(0xf) | |
366 | VIDISD14C_ALPHA1_B(0xf); | 363 | VIDISD14C_ALPHA1_B(0xf); |
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c index 653bdfee3057..9f6d6e61f0cc 100644 --- a/drivers/video/sh7760fb.c +++ b/drivers/video/sh7760fb.c | |||
@@ -120,18 +120,6 @@ static int sh7760_setcolreg (u_int regno, | |||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, | ||
124 | unsigned long stride) | ||
125 | { | ||
126 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | ||
127 | strcpy(fix->id, "sh7760-lcdc"); | ||
128 | |||
129 | fix->smem_start = (unsigned long)info->screen_base; | ||
130 | fix->smem_len = info->screen_size; | ||
131 | |||
132 | fix->line_length = stride; | ||
133 | } | ||
134 | |||
135 | static int sh7760fb_get_color_info(struct device *dev, | 123 | static int sh7760fb_get_color_info(struct device *dev, |
136 | u16 lddfr, int *bpp, int *gray) | 124 | u16 lddfr, int *bpp, int *gray) |
137 | { | 125 | { |
@@ -334,7 +322,8 @@ static int sh7760fb_set_par(struct fb_info *info) | |||
334 | 322 | ||
335 | iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */ | 323 | iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */ |
336 | 324 | ||
337 | encode_fix(&info->fix, info, stride); | 325 | info->fix.line_length = stride; |
326 | |||
338 | sh7760fb_check_var(&info->var, info); | 327 | sh7760fb_check_var(&info->var, info); |
339 | 328 | ||
340 | sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */ | 329 | sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */ |
@@ -435,6 +424,8 @@ static int sh7760fb_alloc_mem(struct fb_info *info) | |||
435 | 424 | ||
436 | info->screen_base = fbmem; | 425 | info->screen_base = fbmem; |
437 | info->screen_size = vram; | 426 | info->screen_size = vram; |
427 | info->fix.smem_start = (unsigned long)info->screen_base; | ||
428 | info->fix.smem_len = info->screen_size; | ||
438 | 429 | ||
439 | return 0; | 430 | return 0; |
440 | } | 431 | } |
@@ -520,6 +511,8 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev) | |||
520 | info->var.transp.length = 0; | 511 | info->var.transp.length = 0; |
521 | info->var.transp.msb_right = 0; | 512 | info->var.transp.msb_right = 0; |
522 | 513 | ||
514 | strcpy(info->fix.id, "sh7760-lcdc"); | ||
515 | |||
523 | /* set the DON2 bit now, before cmap allocation, as it will randomize | 516 | /* set the DON2 bit now, before cmap allocation, as it will randomize |
524 | * palette memory. | 517 | * palette memory. |
525 | */ | 518 | */ |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index f10d2fbeda06..8f24564f77b0 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/vmalloc.h> | ||
20 | #include <video/sh_mobile_lcdc.h> | 21 | #include <video/sh_mobile_lcdc.h> |
21 | #include <asm/atomic.h> | 22 | #include <asm/atomic.h> |
22 | 23 | ||
@@ -30,9 +31,10 @@ struct sh_mobile_lcdc_chan { | |||
30 | unsigned long enabled; /* ME and SE in LDCNT2R */ | 31 | unsigned long enabled; /* ME and SE in LDCNT2R */ |
31 | struct sh_mobile_lcdc_chan_cfg cfg; | 32 | struct sh_mobile_lcdc_chan_cfg cfg; |
32 | u32 pseudo_palette[PALETTE_NR]; | 33 | u32 pseudo_palette[PALETTE_NR]; |
33 | struct fb_info info; | 34 | struct fb_info *info; |
34 | dma_addr_t dma_handle; | 35 | dma_addr_t dma_handle; |
35 | struct fb_deferred_io defio; | 36 | struct fb_deferred_io defio; |
37 | struct scatterlist *sglist; | ||
36 | unsigned long frame_end; | 38 | unsigned long frame_end; |
37 | wait_queue_head_t frame_end_wait; | 39 | wait_queue_head_t frame_end_wait; |
38 | }; | 40 | }; |
@@ -206,16 +208,38 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {} | |||
206 | static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {} | 208 | static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {} |
207 | #endif | 209 | #endif |
208 | 210 | ||
211 | static int sh_mobile_lcdc_sginit(struct fb_info *info, | ||
212 | struct list_head *pagelist) | ||
213 | { | ||
214 | struct sh_mobile_lcdc_chan *ch = info->par; | ||
215 | unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT; | ||
216 | struct page *page; | ||
217 | int nr_pages = 0; | ||
218 | |||
219 | sg_init_table(ch->sglist, nr_pages_max); | ||
220 | |||
221 | list_for_each_entry(page, pagelist, lru) | ||
222 | sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0); | ||
223 | |||
224 | return nr_pages; | ||
225 | } | ||
226 | |||
209 | static void sh_mobile_lcdc_deferred_io(struct fb_info *info, | 227 | static void sh_mobile_lcdc_deferred_io(struct fb_info *info, |
210 | struct list_head *pagelist) | 228 | struct list_head *pagelist) |
211 | { | 229 | { |
212 | struct sh_mobile_lcdc_chan *ch = info->par; | 230 | struct sh_mobile_lcdc_chan *ch = info->par; |
231 | unsigned int nr_pages; | ||
213 | 232 | ||
214 | /* enable clocks before accessing hardware */ | 233 | /* enable clocks before accessing hardware */ |
215 | sh_mobile_lcdc_clk_on(ch->lcdc); | 234 | sh_mobile_lcdc_clk_on(ch->lcdc); |
216 | 235 | ||
236 | nr_pages = sh_mobile_lcdc_sginit(info, pagelist); | ||
237 | dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | ||
238 | |||
217 | /* trigger panel update */ | 239 | /* trigger panel update */ |
218 | lcdc_write_chan(ch, LDSM2R, 1); | 240 | lcdc_write_chan(ch, LDSM2R, 1); |
241 | |||
242 | dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | ||
219 | } | 243 | } |
220 | 244 | ||
221 | static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) | 245 | static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) |
@@ -418,22 +442,22 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
418 | /* set bpp format in PKF[4:0] */ | 442 | /* set bpp format in PKF[4:0] */ |
419 | tmp = lcdc_read_chan(ch, LDDFR); | 443 | tmp = lcdc_read_chan(ch, LDDFR); |
420 | tmp &= ~(0x0001001f); | 444 | tmp &= ~(0x0001001f); |
421 | tmp |= (priv->ch[k].info.var.bits_per_pixel == 16) ? 3 : 0; | 445 | tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0; |
422 | lcdc_write_chan(ch, LDDFR, tmp); | 446 | lcdc_write_chan(ch, LDDFR, tmp); |
423 | 447 | ||
424 | /* point out our frame buffer */ | 448 | /* point out our frame buffer */ |
425 | lcdc_write_chan(ch, LDSA1R, ch->info.fix.smem_start); | 449 | lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start); |
426 | 450 | ||
427 | /* set line size */ | 451 | /* set line size */ |
428 | lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length); | 452 | lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length); |
429 | 453 | ||
430 | /* setup deferred io if SYS bus */ | 454 | /* setup deferred io if SYS bus */ |
431 | tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; | 455 | tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; |
432 | if (ch->ldmt1r_value & (1 << 12) && tmp) { | 456 | if (ch->ldmt1r_value & (1 << 12) && tmp) { |
433 | ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; | 457 | ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; |
434 | ch->defio.delay = msecs_to_jiffies(tmp); | 458 | ch->defio.delay = msecs_to_jiffies(tmp); |
435 | ch->info.fbdefio = &ch->defio; | 459 | ch->info->fbdefio = &ch->defio; |
436 | fb_deferred_io_init(&ch->info); | 460 | fb_deferred_io_init(ch->info); |
437 | 461 | ||
438 | /* one-shot mode */ | 462 | /* one-shot mode */ |
439 | lcdc_write_chan(ch, LDSM1R, 1); | 463 | lcdc_write_chan(ch, LDSM1R, 1); |
@@ -479,12 +503,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
479 | * flush frame, and wait for frame end interrupt | 503 | * flush frame, and wait for frame end interrupt |
480 | * clean up deferred io and enable clock | 504 | * clean up deferred io and enable clock |
481 | */ | 505 | */ |
482 | if (ch->info.fbdefio) { | 506 | if (ch->info->fbdefio) { |
483 | ch->frame_end = 0; | 507 | ch->frame_end = 0; |
484 | schedule_delayed_work(&ch->info.deferred_work, 0); | 508 | schedule_delayed_work(&ch->info->deferred_work, 0); |
485 | wait_event(ch->frame_end_wait, ch->frame_end); | 509 | wait_event(ch->frame_end_wait, ch->frame_end); |
486 | fb_deferred_io_cleanup(&ch->info); | 510 | fb_deferred_io_cleanup(ch->info); |
487 | ch->info.fbdefio = NULL; | 511 | ch->info->fbdefio = NULL; |
488 | sh_mobile_lcdc_clk_on(priv); | 512 | sh_mobile_lcdc_clk_on(priv); |
489 | } | 513 | } |
490 | 514 | ||
@@ -793,9 +817,16 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
793 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); | 817 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); |
794 | 818 | ||
795 | for (i = 0; i < j; i++) { | 819 | for (i = 0; i < j; i++) { |
796 | info = &priv->ch[i].info; | ||
797 | cfg = &priv->ch[i].cfg; | 820 | cfg = &priv->ch[i].cfg; |
798 | 821 | ||
822 | priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); | ||
823 | if (!priv->ch[i].info) { | ||
824 | dev_err(&pdev->dev, "unable to allocate fb_info\n"); | ||
825 | error = -ENOMEM; | ||
826 | break; | ||
827 | } | ||
828 | |||
829 | info = priv->ch[i].info; | ||
799 | info->fbops = &sh_mobile_lcdc_ops; | 830 | info->fbops = &sh_mobile_lcdc_ops; |
800 | info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; | 831 | info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; |
801 | info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres; | 832 | info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres; |
@@ -846,21 +877,31 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
846 | } | 877 | } |
847 | 878 | ||
848 | for (i = 0; i < j; i++) { | 879 | for (i = 0; i < j; i++) { |
849 | error = register_framebuffer(&priv->ch[i].info); | 880 | struct sh_mobile_lcdc_chan *ch = priv->ch + i; |
881 | |||
882 | info = ch->info; | ||
883 | |||
884 | if (info->fbdefio) { | ||
885 | priv->ch->sglist = vmalloc(sizeof(struct scatterlist) * | ||
886 | info->fix.smem_len >> PAGE_SHIFT); | ||
887 | if (!priv->ch->sglist) { | ||
888 | dev_err(&pdev->dev, "cannot allocate sglist\n"); | ||
889 | goto err1; | ||
890 | } | ||
891 | } | ||
892 | |||
893 | error = register_framebuffer(info); | ||
850 | if (error < 0) | 894 | if (error < 0) |
851 | goto err1; | 895 | goto err1; |
852 | } | ||
853 | 896 | ||
854 | for (i = 0; i < j; i++) { | ||
855 | info = &priv->ch[i].info; | ||
856 | dev_info(info->dev, | 897 | dev_info(info->dev, |
857 | "registered %s/%s as %dx%d %dbpp.\n", | 898 | "registered %s/%s as %dx%d %dbpp.\n", |
858 | pdev->name, | 899 | pdev->name, |
859 | (priv->ch[i].cfg.chan == LCDC_CHAN_MAINLCD) ? | 900 | (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? |
860 | "mainlcd" : "sublcd", | 901 | "mainlcd" : "sublcd", |
861 | (int) priv->ch[i].cfg.lcd_cfg.xres, | 902 | (int) ch->cfg.lcd_cfg.xres, |
862 | (int) priv->ch[i].cfg.lcd_cfg.yres, | 903 | (int) ch->cfg.lcd_cfg.yres, |
863 | priv->ch[i].cfg.bpp); | 904 | ch->cfg.bpp); |
864 | 905 | ||
865 | /* deferred io mode: disable clock to save power */ | 906 | /* deferred io mode: disable clock to save power */ |
866 | if (info->fbdefio) | 907 | if (info->fbdefio) |
@@ -881,20 +922,24 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
881 | int i; | 922 | int i; |
882 | 923 | ||
883 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) | 924 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) |
884 | if (priv->ch[i].info.dev) | 925 | if (priv->ch[i].info->dev) |
885 | unregister_framebuffer(&priv->ch[i].info); | 926 | unregister_framebuffer(priv->ch[i].info); |
886 | 927 | ||
887 | sh_mobile_lcdc_stop(priv); | 928 | sh_mobile_lcdc_stop(priv); |
888 | 929 | ||
889 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { | 930 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { |
890 | info = &priv->ch[i].info; | 931 | info = priv->ch[i].info; |
891 | 932 | ||
892 | if (!info->device) | 933 | if (!info || !info->device) |
893 | continue; | 934 | continue; |
894 | 935 | ||
936 | if (priv->ch[i].sglist) | ||
937 | vfree(priv->ch[i].sglist); | ||
938 | |||
895 | dma_free_coherent(&pdev->dev, info->fix.smem_len, | 939 | dma_free_coherent(&pdev->dev, info->fix.smem_len, |
896 | info->screen_base, priv->ch[i].dma_handle); | 940 | info->screen_base, priv->ch[i].dma_handle); |
897 | fb_dealloc_cmap(&info->cmap); | 941 | fb_dealloc_cmap(&info->cmap); |
942 | framebuffer_release(info); | ||
898 | } | 943 | } |
899 | 944 | ||
900 | #ifdef CONFIG_HAVE_CLK | 945 | #ifdef CONFIG_HAVE_CLK |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 7072d19080d5..4a067f0d0ceb 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -1847,8 +1847,10 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) | |||
1847 | 1847 | ||
1848 | strcpy(fix->id, ivideo->myid); | 1848 | strcpy(fix->id, ivideo->myid); |
1849 | 1849 | ||
1850 | mutex_lock(&info->mm_lock); | ||
1850 | fix->smem_start = ivideo->video_base + ivideo->video_offset; | 1851 | fix->smem_start = ivideo->video_base + ivideo->video_offset; |
1851 | fix->smem_len = ivideo->sisfb_mem; | 1852 | fix->smem_len = ivideo->sisfb_mem; |
1853 | mutex_unlock(&info->mm_lock); | ||
1852 | fix->type = FB_TYPE_PACKED_PIXELS; | 1854 | fix->type = FB_TYPE_PACKED_PIXELS; |
1853 | fix->type_aux = 0; | 1855 | fix->type_aux = 0; |
1854 | fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | 1856 | fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; |
@@ -6365,7 +6367,6 @@ error_3: vfree(ivideo->bios_abase); | |||
6365 | sis_fb_info->fix = ivideo->sisfb_fix; | 6367 | sis_fb_info->fix = ivideo->sisfb_fix; |
6366 | sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; | 6368 | sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; |
6367 | sis_fb_info->fbops = &sisfb_ops; | 6369 | sis_fb_info->fbops = &sisfb_ops; |
6368 | sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info); | ||
6369 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; | 6370 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; |
6370 | 6371 | ||
6371 | fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); | 6372 | fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index eb5d73a06702..924d79462780 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -145,7 +145,7 @@ static inline void sm501fb_sync_regs(struct sm501fb_info *info) | |||
145 | #define SM501_MEMF_ACCEL (8) | 145 | #define SM501_MEMF_ACCEL (8) |
146 | 146 | ||
147 | static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | 147 | static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, |
148 | unsigned int why, size_t size) | 148 | unsigned int why, size_t size, u32 smem_len) |
149 | { | 149 | { |
150 | struct sm501fb_par *par; | 150 | struct sm501fb_par *par; |
151 | struct fb_info *fbi; | 151 | struct fb_info *fbi; |
@@ -172,7 +172,7 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | |||
172 | if (ptr > 0) | 172 | if (ptr > 0) |
173 | ptr &= ~(PAGE_SIZE - 1); | 173 | ptr &= ~(PAGE_SIZE - 1); |
174 | 174 | ||
175 | if (fbi && ptr < fbi->fix.smem_len) | 175 | if (fbi && ptr < smem_len) |
176 | return -ENOMEM; | 176 | return -ENOMEM; |
177 | 177 | ||
178 | break; | 178 | break; |
@@ -197,7 +197,7 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | |||
197 | 197 | ||
198 | case SM501_MEMF_ACCEL: | 198 | case SM501_MEMF_ACCEL: |
199 | fbi = inf->fb[HEAD_CRT]; | 199 | fbi = inf->fb[HEAD_CRT]; |
200 | ptr = fbi ? fbi->fix.smem_len : 0; | 200 | ptr = fbi ? smem_len : 0; |
201 | 201 | ||
202 | fbi = inf->fb[HEAD_PANEL]; | 202 | fbi = inf->fb[HEAD_PANEL]; |
203 | if (fbi) { | 203 | if (fbi) { |
@@ -413,6 +413,7 @@ static int sm501fb_set_par_common(struct fb_info *info, | |||
413 | unsigned int mem_type; | 413 | unsigned int mem_type; |
414 | unsigned int clock_type; | 414 | unsigned int clock_type; |
415 | unsigned int head_addr; | 415 | unsigned int head_addr; |
416 | unsigned int smem_len; | ||
416 | 417 | ||
417 | dev_dbg(fbi->dev, "%s: %dx%d, bpp = %d, virtual %dx%d\n", | 418 | dev_dbg(fbi->dev, "%s: %dx%d, bpp = %d, virtual %dx%d\n", |
418 | __func__, var->xres, var->yres, var->bits_per_pixel, | 419 | __func__, var->xres, var->yres, var->bits_per_pixel, |
@@ -453,18 +454,20 @@ static int sm501fb_set_par_common(struct fb_info *info, | |||
453 | 454 | ||
454 | /* allocate fb memory within 501 */ | 455 | /* allocate fb memory within 501 */ |
455 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel)/8; | 456 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel)/8; |
456 | info->fix.smem_len = info->fix.line_length * var->yres_virtual; | 457 | smem_len = info->fix.line_length * var->yres_virtual; |
457 | 458 | ||
458 | dev_dbg(fbi->dev, "%s: line length = %u\n", __func__, | 459 | dev_dbg(fbi->dev, "%s: line length = %u\n", __func__, |
459 | info->fix.line_length); | 460 | info->fix.line_length); |
460 | 461 | ||
461 | if (sm501_alloc_mem(fbi, &par->screen, mem_type, | 462 | if (sm501_alloc_mem(fbi, &par->screen, mem_type, smem_len, smem_len)) { |
462 | info->fix.smem_len)) { | ||
463 | dev_err(fbi->dev, "no memory available\n"); | 463 | dev_err(fbi->dev, "no memory available\n"); |
464 | return -ENOMEM; | 464 | return -ENOMEM; |
465 | } | 465 | } |
466 | 466 | ||
467 | mutex_lock(&info->mm_lock); | ||
467 | info->fix.smem_start = fbi->fbmem_res->start + par->screen.sm_addr; | 468 | info->fix.smem_start = fbi->fbmem_res->start + par->screen.sm_addr; |
469 | info->fix.smem_len = smem_len; | ||
470 | mutex_unlock(&info->mm_lock); | ||
468 | 471 | ||
469 | info->screen_base = fbi->fbmem + par->screen.sm_addr; | 472 | info->screen_base = fbi->fbmem + par->screen.sm_addr; |
470 | info->screen_size = info->fix.smem_len; | 473 | info->screen_size = info->fix.smem_len; |
@@ -637,7 +640,8 @@ static int sm501fb_set_par_crt(struct fb_info *info) | |||
637 | if ((control & SM501_DC_CRT_CONTROL_SEL) == 0) { | 640 | if ((control & SM501_DC_CRT_CONTROL_SEL) == 0) { |
638 | /* the head is displaying panel data... */ | 641 | /* the head is displaying panel data... */ |
639 | 642 | ||
640 | sm501_alloc_mem(fbi, &par->screen, SM501_MEMF_CRT, 0); | 643 | sm501_alloc_mem(fbi, &par->screen, SM501_MEMF_CRT, 0, |
644 | info->fix.smem_len); | ||
641 | goto out_update; | 645 | goto out_update; |
642 | } | 646 | } |
643 | 647 | ||
@@ -1289,7 +1293,8 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base) | |||
1289 | 1293 | ||
1290 | par->cursor_regs = info->regs + reg_base; | 1294 | par->cursor_regs = info->regs + reg_base; |
1291 | 1295 | ||
1292 | ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024); | 1296 | ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024, |
1297 | fbi->fix.smem_len); | ||
1293 | if (ret < 0) | 1298 | if (ret < 0) |
1294 | return ret; | 1299 | return ret; |
1295 | 1300 | ||
@@ -1535,9 +1540,6 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1535 | if (ret) | 1540 | if (ret) |
1536 | dev_err(info->dev, "check_var() failed on initial setup?\n"); | 1541 | dev_err(info->dev, "check_var() failed on initial setup?\n"); |
1537 | 1542 | ||
1538 | /* ensure we've activated our new configuration */ | ||
1539 | (fb->fbops->fb_set_par)(fb); | ||
1540 | |||
1541 | return 0; | 1543 | return 0; |
1542 | } | 1544 | } |
1543 | 1545 | ||
@@ -1619,6 +1621,8 @@ static int __devinit sm501fb_start_one(struct sm501fb_info *info, | |||
1619 | if (!fbi) | 1621 | if (!fbi) |
1620 | return 0; | 1622 | return 0; |
1621 | 1623 | ||
1624 | mutex_init(&info->fb[head]->mm_lock); | ||
1625 | |||
1622 | ret = sm501fb_init_fb(info->fb[head], head, drvname); | 1626 | ret = sm501fb_init_fb(info->fb[head], head, drvname); |
1623 | if (ret) { | 1627 | if (ret) { |
1624 | dev_err(info->dev, "cannot initialise fb %s\n", drvname); | 1628 | dev_err(info->dev, "cannot initialise fb %s\n", drvname); |
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index eec9dcb7f599..6120f0c526fe 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c | |||
@@ -1115,10 +1115,9 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) | |||
1115 | if the device name contains the string "DX" and tell the | 1115 | if the device name contains the string "DX" and tell the |
1116 | user how to reconfigure the card. */ | 1116 | user how to reconfigure the card. */ |
1117 | if (strstr(sti->outptr.dev_name, "DX")) { | 1117 | if (strstr(sti->outptr.dev_name, "DX")) { |
1118 | printk(KERN_WARNING "WARNING: stifb framebuffer driver does not " | 1118 | printk(KERN_WARNING |
1119 | "support '%s' in double-buffer mode.\n" | 1119 | "WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n" |
1120 | KERN_WARNING "WARNING: Please disable the double-buffer mode " | 1120 | "WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n", |
1121 | "in IPL menu (the PARISC-BIOS).\n", | ||
1122 | sti->outptr.dev_name); | 1121 | sti->outptr.dev_name); |
1123 | goto out_err0; | 1122 | goto out_err0; |
1124 | } | 1123 | } |
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index d0674f1e3f10..2376f688ec8b 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c | |||
@@ -523,6 +523,7 @@ static int w100fb_set_par(struct fb_info *info) | |||
523 | info->fix.ywrapstep = 0; | 523 | info->fix.ywrapstep = 0; |
524 | info->fix.line_length = par->xres * BITS_PER_PIXEL / 8; | 524 | info->fix.line_length = par->xres * BITS_PER_PIXEL / 8; |
525 | 525 | ||
526 | mutex_lock(&info->mm_lock); | ||
526 | if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) { | 527 | if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) { |
527 | par->extmem_active = 1; | 528 | par->extmem_active = 1; |
528 | info->fix.smem_len = par->mach->mem->size+1; | 529 | info->fix.smem_len = par->mach->mem->size+1; |
@@ -530,6 +531,7 @@ static int w100fb_set_par(struct fb_info *info) | |||
530 | par->extmem_active = 0; | 531 | par->extmem_active = 0; |
531 | info->fix.smem_len = MEM_INT_SIZE+1; | 532 | info->fix.smem_len = MEM_INT_SIZE+1; |
532 | } | 533 | } |
534 | mutex_unlock(&info->mm_lock); | ||
533 | 535 | ||
534 | w100fb_activate_var(par); | 536 | w100fb_activate_var(par); |
535 | } | 537 | } |
@@ -746,8 +748,6 @@ int __init w100fb_probe(struct platform_device *pdev) | |||
746 | goto out; | 748 | goto out; |
747 | } | 749 | } |
748 | 750 | ||
749 | w100fb_set_par(info); | ||
750 | |||
751 | if (register_framebuffer(info) < 0) { | 751 | if (register_framebuffer(info) < 0) { |
752 | err = -EINVAL; | 752 | err = -EINVAL; |
753 | goto out; | 753 | goto out; |
diff --git a/drivers/vlynq/Kconfig b/drivers/vlynq/Kconfig index f6542211db48..a9efb1625321 100644 --- a/drivers/vlynq/Kconfig +++ b/drivers/vlynq/Kconfig | |||
@@ -13,7 +13,7 @@ config VLYNQ | |||
13 | 13 | ||
14 | config VLYNQ_DEBUG | 14 | config VLYNQ_DEBUG |
15 | bool "VLYNQ bus debug" | 15 | bool "VLYNQ bus debug" |
16 | depends on VLYNQ && KERNEL_DEBUG | 16 | depends on VLYNQ && DEBUG_KERNEL |
17 | help | 17 | help |
18 | Turn on VLYNQ bus debugging. | 18 | Turn on VLYNQ bus debugging. |
19 | 19 | ||
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c index 7335433b067b..f05d2a368367 100644 --- a/drivers/vlynq/vlynq.c +++ b/drivers/vlynq/vlynq.c | |||
@@ -76,7 +76,7 @@ struct vlynq_regs { | |||
76 | u32 int_device[8]; | 76 | u32 int_device[8]; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | #ifdef VLYNQ_DEBUG | 79 | #ifdef CONFIG_VLYNQ_DEBUG |
80 | static void vlynq_dump_regs(struct vlynq_device *dev) | 80 | static void vlynq_dump_regs(struct vlynq_device *dev) |
81 | { | 81 | { |
82 | int i; | 82 | int i; |
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index 5c7011cda6a6..751c003864ad 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c | |||
@@ -161,7 +161,7 @@ static long bcm47xx_wdt_ioctl(struct file *file, | |||
161 | { | 161 | { |
162 | void __user *argp = (void __user *)arg; | 162 | void __user *argp = (void __user *)arg; |
163 | int __user *p = argp; | 163 | int __user *p = argp; |
164 | int new_value, retval = -EINVAL;; | 164 | int new_value, retval = -EINVAL; |
165 | 165 | ||
166 | switch (cmd) { | 166 | switch (cmd) { |
167 | case WDIOC_GETSUPPORT: | 167 | case WDIOC_GETSUPPORT: |
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index ee1caae4d33b..016245419fad 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | static unsigned long oscr_freq; | 39 | static unsigned long oscr_freq; |
40 | static unsigned long sa1100wdt_users; | 40 | static unsigned long sa1100wdt_users; |
41 | static int pre_margin; | 41 | static unsigned int pre_margin; |
42 | static int boot_status; | 42 | static int boot_status; |
43 | 43 | ||
44 | /* | 44 | /* |
@@ -84,6 +84,7 @@ static const struct watchdog_info ident = { | |||
84 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | 84 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
85 | | WDIOF_KEEPALIVEPING, | 85 | | WDIOF_KEEPALIVEPING, |
86 | .identity = "SA1100/PXA255 Watchdog", | 86 | .identity = "SA1100/PXA255 Watchdog", |
87 | .firmware_version = 1, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, | 90 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, |
@@ -118,7 +119,7 @@ static long sa1100dog_ioctl(struct file *file, unsigned int cmd, | |||
118 | if (ret) | 119 | if (ret) |
119 | break; | 120 | break; |
120 | 121 | ||
121 | if (time <= 0 || time > 255) { | 122 | if (time <= 0 || (oscr_freq * (long long)time >= 0xffffffff)) { |
122 | ret = -EINVAL; | 123 | ret = -EINVAL; |
123 | break; | 124 | break; |
124 | } | 125 | } |
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index 916890abffdd..f201accc4e3d 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c | |||
@@ -89,6 +89,11 @@ static void w83627hf_select_wd_register(void) | |||
89 | c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ | 89 | c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ |
90 | outb_p(0x2b, WDT_EFER); | 90 | outb_p(0x2b, WDT_EFER); |
91 | outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */ | 91 | outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */ |
92 | } else if (c == 0x88) { /* W83627EHF */ | ||
93 | outb_p(0x2d, WDT_EFER); /* select GPIO5 */ | ||
94 | c = inb_p(WDT_EFDR) & ~0x01; /* PIN77 -> WDT0# */ | ||
95 | outb_p(0x2d, WDT_EFER); | ||
96 | outb_p(c, WDT_EFDR); /* set GPIO5 to WDT0 */ | ||
92 | } | 97 | } |
93 | 98 | ||
94 | outb_p(0x07, WDT_EFER); /* point to logical device number reg */ | 99 | outb_p(0x07, WDT_EFER); /* point to logical device number reg */ |
diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c index 883b5f79673a..a6c12dec91a1 100644 --- a/drivers/watchdog/w83697ug_wdt.c +++ b/drivers/watchdog/w83697ug_wdt.c | |||
@@ -149,8 +149,10 @@ static void wdt_ctrl(int timeout) | |||
149 | { | 149 | { |
150 | spin_lock(&io_lock); | 150 | spin_lock(&io_lock); |
151 | 151 | ||
152 | if (w83697ug_select_wd_register() < 0) | 152 | if (w83697ug_select_wd_register() < 0) { |
153 | spin_unlock(&io_lock); | ||
153 | return; | 154 | return; |
155 | } | ||
154 | 156 | ||
155 | outb_p(0xF4, WDT_EFER); /* Select CRF4 */ | 157 | outb_p(0xF4, WDT_EFER); /* Select CRF4 */ |
156 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ | 158 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ |
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index a4fe7a38d9b0..3bde56bce63a 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
@@ -218,16 +218,14 @@ static void wdrtas_timer_keepalive(void) | |||
218 | */ | 218 | */ |
219 | static int wdrtas_get_temperature(void) | 219 | static int wdrtas_get_temperature(void) |
220 | { | 220 | { |
221 | long result; | 221 | int result; |
222 | int temperature = 0; | 222 | int temperature = 0; |
223 | 223 | ||
224 | result = rtas_call(wdrtas_token_get_sensor_state, 2, 2, | 224 | result = rtas_get_sensor(WDRTAS_THERMAL_SENSOR, 0, &temperature); |
225 | (void *)__pa(&temperature), | ||
226 | WDRTAS_THERMAL_SENSOR, 0); | ||
227 | 225 | ||
228 | if (result < 0) | 226 | if (result < 0) |
229 | printk(KERN_WARNING "wdrtas: reading the thermal sensor " | 227 | printk(KERN_WARNING "wdrtas: reading the thermal sensor " |
230 | "faild: %li\n", result); | 228 | "failed: %i\n", result); |
231 | else | 229 | else |
232 | temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */ | 230 | temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */ |
233 | 231 | ||
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 891d2e90753a..abad71b1632b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -927,9 +927,9 @@ static struct irq_chip xen_dynamic_chip __read_mostly = { | |||
927 | void __init xen_init_IRQ(void) | 927 | void __init xen_init_IRQ(void) |
928 | { | 928 | { |
929 | int i; | 929 | int i; |
930 | size_t size = nr_cpu_ids * sizeof(struct cpu_evtchn_s); | ||
931 | 930 | ||
932 | cpu_evtchn_mask_p = alloc_bootmem(size); | 931 | cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s), |
932 | GFP_KERNEL); | ||
933 | BUG_ON(cpu_evtchn_mask_p == NULL); | 933 | BUG_ON(cpu_evtchn_mask_p == NULL); |
934 | 934 | ||
935 | init_evtchn_cpu_bindings(); | 935 | init_evtchn_cpu_bindings(); |