diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-08-26 23:12:40 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-08-26 23:12:40 -0400 |
commit | f480fe3916de2e2cbb6e384cb685f0f1d8272188 (patch) | |
tree | 141c60a2a263f1c01907e692d4aef1e6b699d8c7 /drivers | |
parent | 4f0dbc2781b9dc457159b676289f874ab2dc3560 (diff) | |
parent | f415c413f458837bd0c27086b79aca889f9435e4 (diff) |
Merge commit 'origin/master' into next
Diffstat (limited to 'drivers')
61 files changed, 1015 insertions, 598 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0efa59e7e3af..66393d5c4c7c 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -162,8 +162,9 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, | |||
162 | pr->power.timer_broadcast_on_state = state; | 162 | pr->power.timer_broadcast_on_state = state; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) | 165 | static void lapic_timer_propagate_broadcast(void *arg) |
166 | { | 166 | { |
167 | struct acpi_processor *pr = (struct acpi_processor *) arg; | ||
167 | unsigned long reason; | 168 | unsigned long reason; |
168 | 169 | ||
169 | reason = pr->power.timer_broadcast_on_state < INT_MAX ? | 170 | reason = pr->power.timer_broadcast_on_state < INT_MAX ? |
@@ -635,7 +636,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
635 | working++; | 636 | working++; |
636 | } | 637 | } |
637 | 638 | ||
638 | lapic_timer_propagate_broadcast(pr); | 639 | smp_call_function_single(pr->id, lapic_timer_propagate_broadcast, |
640 | pr, 1); | ||
639 | 641 | ||
640 | return (working); | 642 | return (working); |
641 | } | 643 | } |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 1733d3439ad2..e48af9f79219 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -508,8 +508,9 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
508 | * be obtained while the delayed work queue halt ensures that no more | 508 | * be obtained while the delayed work queue halt ensures that no more |
509 | * data is fed to the ldisc. | 509 | * data is fed to the ldisc. |
510 | * | 510 | * |
511 | * In order to wait for any existing references to complete see | 511 | * You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex) |
512 | * tty_ldisc_wait_idle. | 512 | * in order to make sure any currently executing ldisc work is also |
513 | * flushed. | ||
513 | */ | 514 | */ |
514 | 515 | ||
515 | static int tty_ldisc_halt(struct tty_struct *tty) | 516 | static int tty_ldisc_halt(struct tty_struct *tty) |
@@ -753,11 +754,14 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
753 | * N_TTY. | 754 | * N_TTY. |
754 | */ | 755 | */ |
755 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 756 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { |
757 | /* Make sure the old ldisc is quiescent */ | ||
758 | tty_ldisc_halt(tty); | ||
759 | flush_scheduled_work(); | ||
760 | |||
756 | /* Avoid racing set_ldisc or tty_ldisc_release */ | 761 | /* Avoid racing set_ldisc or tty_ldisc_release */ |
757 | mutex_lock(&tty->ldisc_mutex); | 762 | mutex_lock(&tty->ldisc_mutex); |
758 | if (tty->ldisc) { /* Not yet closed */ | 763 | if (tty->ldisc) { /* Not yet closed */ |
759 | /* Switch back to N_TTY */ | 764 | /* Switch back to N_TTY */ |
760 | tty_ldisc_halt(tty); | ||
761 | tty_ldisc_reinit(tty); | 765 | tty_ldisc_reinit(tty); |
762 | /* At this point we have a closed ldisc and we want to | 766 | /* At this point we have a closed ldisc and we want to |
763 | reopen it. We could defer this to the next open but | 767 | reopen it. We could defer this to the next open but |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 33be210d6723..2f631c75f704 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -258,31 +258,6 @@ void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) | |||
258 | EXPORT_SYMBOL(drm_mode_object_find); | 258 | EXPORT_SYMBOL(drm_mode_object_find); |
259 | 259 | ||
260 | /** | 260 | /** |
261 | * drm_crtc_from_fb - find the CRTC structure associated with an fb | ||
262 | * @dev: DRM device | ||
263 | * @fb: framebuffer in question | ||
264 | * | ||
265 | * LOCKING: | ||
266 | * Caller must hold mode_config lock. | ||
267 | * | ||
268 | * Find CRTC in the mode_config structure that matches @fb. | ||
269 | * | ||
270 | * RETURNS: | ||
271 | * Pointer to the CRTC or NULL if it wasn't found. | ||
272 | */ | ||
273 | struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev, | ||
274 | struct drm_framebuffer *fb) | ||
275 | { | ||
276 | struct drm_crtc *crtc; | ||
277 | |||
278 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
279 | if (crtc->fb == fb) | ||
280 | return crtc; | ||
281 | } | ||
282 | return NULL; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * drm_framebuffer_init - initialize a framebuffer | 261 | * drm_framebuffer_init - initialize a framebuffer |
287 | * @dev: DRM device | 262 | * @dev: DRM device |
288 | * | 263 | * |
@@ -328,11 +303,20 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) | |||
328 | { | 303 | { |
329 | struct drm_device *dev = fb->dev; | 304 | struct drm_device *dev = fb->dev; |
330 | struct drm_crtc *crtc; | 305 | struct drm_crtc *crtc; |
306 | struct drm_mode_set set; | ||
307 | int ret; | ||
331 | 308 | ||
332 | /* remove from any CRTC */ | 309 | /* remove from any CRTC */ |
333 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 310 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
334 | if (crtc->fb == fb) | 311 | if (crtc->fb == fb) { |
335 | crtc->fb = NULL; | 312 | /* should turn off the crtc */ |
313 | memset(&set, 0, sizeof(struct drm_mode_set)); | ||
314 | set.crtc = crtc; | ||
315 | set.fb = NULL; | ||
316 | ret = crtc->funcs->set_config(&set); | ||
317 | if (ret) | ||
318 | DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); | ||
319 | } | ||
336 | } | 320 | } |
337 | 321 | ||
338 | drm_mode_object_put(dev, &fb->base); | 322 | drm_mode_object_put(dev, &fb->base); |
@@ -1511,7 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
1511 | set.mode = mode; | 1495 | set.mode = mode; |
1512 | set.connectors = connector_set; | 1496 | set.connectors = connector_set; |
1513 | set.num_connectors = crtc_req->count_connectors; | 1497 | set.num_connectors = crtc_req->count_connectors; |
1514 | set.fb =fb; | 1498 | set.fb = fb; |
1515 | ret = crtc->funcs->set_config(&set); | 1499 | ret = crtc->funcs->set_config(&set); |
1516 | 1500 | ||
1517 | out: | 1501 | out: |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 80cc6d06d61b..7f2728bbc16c 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -502,12 +502,40 @@ static int add_detailed_info(struct drm_connector *connector, | |||
502 | struct detailed_non_pixel *data = &timing->data.other_data; | 502 | struct detailed_non_pixel *data = &timing->data.other_data; |
503 | struct drm_display_mode *newmode; | 503 | struct drm_display_mode *newmode; |
504 | 504 | ||
505 | /* EDID up to and including 1.2 may put monitor info here */ | 505 | /* X server check is version 1.1 or higher */ |
506 | if (edid->version == 1 && edid->revision < 3) | 506 | if (edid->version == 1 && edid->revision >= 1 && |
507 | continue; | 507 | !timing->pixel_clock) { |
508 | 508 | /* Other timing or info */ | |
509 | /* Detailed mode timing */ | 509 | switch (data->type) { |
510 | if (timing->pixel_clock) { | 510 | case EDID_DETAIL_MONITOR_SERIAL: |
511 | break; | ||
512 | case EDID_DETAIL_MONITOR_STRING: | ||
513 | break; | ||
514 | case EDID_DETAIL_MONITOR_RANGE: | ||
515 | /* Get monitor range data */ | ||
516 | break; | ||
517 | case EDID_DETAIL_MONITOR_NAME: | ||
518 | break; | ||
519 | case EDID_DETAIL_MONITOR_CPDATA: | ||
520 | break; | ||
521 | case EDID_DETAIL_STD_MODES: | ||
522 | /* Five modes per detailed section */ | ||
523 | for (j = 0; j < 5; i++) { | ||
524 | struct std_timing *std; | ||
525 | struct drm_display_mode *newmode; | ||
526 | |||
527 | std = &data->data.timings[j]; | ||
528 | newmode = drm_mode_std(dev, std); | ||
529 | if (newmode) { | ||
530 | drm_mode_probed_add(connector, newmode); | ||
531 | modes++; | ||
532 | } | ||
533 | } | ||
534 | break; | ||
535 | default: | ||
536 | break; | ||
537 | } | ||
538 | } else { | ||
511 | newmode = drm_mode_detailed(dev, edid, timing, quirks); | 539 | newmode = drm_mode_detailed(dev, edid, timing, quirks); |
512 | if (!newmode) | 540 | if (!newmode) |
513 | continue; | 541 | continue; |
@@ -518,38 +546,6 @@ static int add_detailed_info(struct drm_connector *connector, | |||
518 | drm_mode_probed_add(connector, newmode); | 546 | drm_mode_probed_add(connector, newmode); |
519 | 547 | ||
520 | modes++; | 548 | modes++; |
521 | continue; | ||
522 | } | ||
523 | |||
524 | /* Other timing or info */ | ||
525 | switch (data->type) { | ||
526 | case EDID_DETAIL_MONITOR_SERIAL: | ||
527 | break; | ||
528 | case EDID_DETAIL_MONITOR_STRING: | ||
529 | break; | ||
530 | case EDID_DETAIL_MONITOR_RANGE: | ||
531 | /* Get monitor range data */ | ||
532 | break; | ||
533 | case EDID_DETAIL_MONITOR_NAME: | ||
534 | break; | ||
535 | case EDID_DETAIL_MONITOR_CPDATA: | ||
536 | break; | ||
537 | case EDID_DETAIL_STD_MODES: | ||
538 | /* Five modes per detailed section */ | ||
539 | for (j = 0; j < 5; i++) { | ||
540 | struct std_timing *std; | ||
541 | struct drm_display_mode *newmode; | ||
542 | |||
543 | std = &data->data.timings[j]; | ||
544 | newmode = drm_mode_std(dev, std); | ||
545 | if (newmode) { | ||
546 | drm_mode_probed_add(connector, newmode); | ||
547 | modes++; | ||
548 | } | ||
549 | } | ||
550 | break; | ||
551 | default: | ||
552 | break; | ||
553 | } | 549 | } |
554 | } | 550 | } |
555 | 551 | ||
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 85ec31b3ff00..f7a615b80c70 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -22,44 +22,50 @@ | |||
22 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) | 22 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) |
23 | #define to_drm_connector(d) container_of(d, struct drm_connector, kdev) | 23 | #define to_drm_connector(d) container_of(d, struct drm_connector, kdev) |
24 | 24 | ||
25 | static struct device_type drm_sysfs_device_minor = { | ||
26 | .name = "drm_minor" | ||
27 | }; | ||
28 | |||
25 | /** | 29 | /** |
26 | * drm_sysfs_suspend - DRM class suspend hook | 30 | * drm_class_suspend - DRM class suspend hook |
27 | * @dev: Linux device to suspend | 31 | * @dev: Linux device to suspend |
28 | * @state: power state to enter | 32 | * @state: power state to enter |
29 | * | 33 | * |
30 | * Just figures out what the actual struct drm_device associated with | 34 | * Just figures out what the actual struct drm_device associated with |
31 | * @dev is and calls its suspend hook, if present. | 35 | * @dev is and calls its suspend hook, if present. |
32 | */ | 36 | */ |
33 | static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | 37 | static int drm_class_suspend(struct device *dev, pm_message_t state) |
34 | { | 38 | { |
35 | struct drm_minor *drm_minor = to_drm_minor(dev); | 39 | if (dev->type == &drm_sysfs_device_minor) { |
36 | struct drm_device *drm_dev = drm_minor->dev; | 40 | struct drm_minor *drm_minor = to_drm_minor(dev); |
37 | 41 | struct drm_device *drm_dev = drm_minor->dev; | |
38 | if (drm_minor->type == DRM_MINOR_LEGACY && | 42 | |
39 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | 43 | if (drm_minor->type == DRM_MINOR_LEGACY && |
40 | drm_dev->driver->suspend) | 44 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && |
41 | return drm_dev->driver->suspend(drm_dev, state); | 45 | drm_dev->driver->suspend) |
42 | 46 | return drm_dev->driver->suspend(drm_dev, state); | |
47 | } | ||
43 | return 0; | 48 | return 0; |
44 | } | 49 | } |
45 | 50 | ||
46 | /** | 51 | /** |
47 | * drm_sysfs_resume - DRM class resume hook | 52 | * drm_class_resume - DRM class resume hook |
48 | * @dev: Linux device to resume | 53 | * @dev: Linux device to resume |
49 | * | 54 | * |
50 | * Just figures out what the actual struct drm_device associated with | 55 | * Just figures out what the actual struct drm_device associated with |
51 | * @dev is and calls its resume hook, if present. | 56 | * @dev is and calls its resume hook, if present. |
52 | */ | 57 | */ |
53 | static int drm_sysfs_resume(struct device *dev) | 58 | static int drm_class_resume(struct device *dev) |
54 | { | 59 | { |
55 | struct drm_minor *drm_minor = to_drm_minor(dev); | 60 | if (dev->type == &drm_sysfs_device_minor) { |
56 | struct drm_device *drm_dev = drm_minor->dev; | 61 | struct drm_minor *drm_minor = to_drm_minor(dev); |
57 | 62 | struct drm_device *drm_dev = drm_minor->dev; | |
58 | if (drm_minor->type == DRM_MINOR_LEGACY && | 63 | |
59 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | 64 | if (drm_minor->type == DRM_MINOR_LEGACY && |
60 | drm_dev->driver->resume) | 65 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && |
61 | return drm_dev->driver->resume(drm_dev); | 66 | drm_dev->driver->resume) |
62 | 67 | return drm_dev->driver->resume(drm_dev); | |
68 | } | ||
63 | return 0; | 69 | return 0; |
64 | } | 70 | } |
65 | 71 | ||
@@ -99,8 +105,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name) | |||
99 | goto err_out; | 105 | goto err_out; |
100 | } | 106 | } |
101 | 107 | ||
102 | class->suspend = drm_sysfs_suspend; | 108 | class->suspend = drm_class_suspend; |
103 | class->resume = drm_sysfs_resume; | 109 | class->resume = drm_class_resume; |
104 | 110 | ||
105 | err = class_create_file(class, &class_attr_version); | 111 | err = class_create_file(class, &class_attr_version); |
106 | if (err) | 112 | if (err) |
@@ -480,6 +486,7 @@ int drm_sysfs_device_add(struct drm_minor *minor) | |||
480 | minor->kdev.class = drm_class; | 486 | minor->kdev.class = drm_class; |
481 | minor->kdev.release = drm_sysfs_device_release; | 487 | minor->kdev.release = drm_sysfs_device_release; |
482 | minor->kdev.devt = minor->device; | 488 | minor->kdev.devt = minor->device; |
489 | minor->kdev.type = &drm_sysfs_device_minor; | ||
483 | if (minor->type == DRM_MINOR_CONTROL) | 490 | if (minor->type == DRM_MINOR_CONTROL) |
484 | minor_str = "controlD%d"; | 491 | minor_str = "controlD%d"; |
485 | else if (minor->type == DRM_MINOR_RENDER) | 492 | else if (minor->type == DRM_MINOR_RENDER) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index f1ba8ff41130..68e728e8be4d 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -254,6 +254,72 @@ void r100_mc_fini(struct radeon_device *rdev) | |||
254 | 254 | ||
255 | 255 | ||
256 | /* | 256 | /* |
257 | * Interrupts | ||
258 | */ | ||
259 | int r100_irq_set(struct radeon_device *rdev) | ||
260 | { | ||
261 | uint32_t tmp = 0; | ||
262 | |||
263 | if (rdev->irq.sw_int) { | ||
264 | tmp |= RADEON_SW_INT_ENABLE; | ||
265 | } | ||
266 | if (rdev->irq.crtc_vblank_int[0]) { | ||
267 | tmp |= RADEON_CRTC_VBLANK_MASK; | ||
268 | } | ||
269 | if (rdev->irq.crtc_vblank_int[1]) { | ||
270 | tmp |= RADEON_CRTC2_VBLANK_MASK; | ||
271 | } | ||
272 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | ||
277 | { | ||
278 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | ||
279 | uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | | ||
280 | RADEON_CRTC2_VBLANK_STAT; | ||
281 | |||
282 | if (irqs) { | ||
283 | WREG32(RADEON_GEN_INT_STATUS, irqs); | ||
284 | } | ||
285 | return irqs & irq_mask; | ||
286 | } | ||
287 | |||
288 | int r100_irq_process(struct radeon_device *rdev) | ||
289 | { | ||
290 | uint32_t status; | ||
291 | |||
292 | status = r100_irq_ack(rdev); | ||
293 | if (!status) { | ||
294 | return IRQ_NONE; | ||
295 | } | ||
296 | while (status) { | ||
297 | /* SW interrupt */ | ||
298 | if (status & RADEON_SW_INT_TEST) { | ||
299 | radeon_fence_process(rdev); | ||
300 | } | ||
301 | /* Vertical blank interrupts */ | ||
302 | if (status & RADEON_CRTC_VBLANK_STAT) { | ||
303 | drm_handle_vblank(rdev->ddev, 0); | ||
304 | } | ||
305 | if (status & RADEON_CRTC2_VBLANK_STAT) { | ||
306 | drm_handle_vblank(rdev->ddev, 1); | ||
307 | } | ||
308 | status = r100_irq_ack(rdev); | ||
309 | } | ||
310 | return IRQ_HANDLED; | ||
311 | } | ||
312 | |||
313 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) | ||
314 | { | ||
315 | if (crtc == 0) | ||
316 | return RREG32(RADEON_CRTC_CRNT_FRAME); | ||
317 | else | ||
318 | return RREG32(RADEON_CRTC2_CRNT_FRAME); | ||
319 | } | ||
320 | |||
321 | |||
322 | /* | ||
257 | * Fence emission | 323 | * Fence emission |
258 | */ | 324 | */ |
259 | void r100_fence_ring_emit(struct radeon_device *rdev, | 325 | void r100_fence_ring_emit(struct radeon_device *rdev, |
@@ -1025,6 +1091,16 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1025 | tmp |= tile_flags; | 1091 | tmp |= tile_flags; |
1026 | ib[idx] = tmp; | 1092 | ib[idx] = tmp; |
1027 | break; | 1093 | break; |
1094 | case RADEON_RB3D_ZPASS_ADDR: | ||
1095 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1096 | if (r) { | ||
1097 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
1098 | idx, reg); | ||
1099 | r100_cs_dump_packet(p, pkt); | ||
1100 | return r; | ||
1101 | } | ||
1102 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | ||
1103 | break; | ||
1028 | default: | 1104 | default: |
1029 | /* FIXME: we don't want to allow anyothers packet */ | 1105 | /* FIXME: we don't want to allow anyothers packet */ |
1030 | break; | 1106 | break; |
@@ -1556,26 +1632,6 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
1556 | r100_pll_errata_after_data(rdev); | 1632 | r100_pll_errata_after_data(rdev); |
1557 | } | 1633 | } |
1558 | 1634 | ||
1559 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | ||
1560 | { | ||
1561 | if (reg < 0x10000) | ||
1562 | return readl(((void __iomem *)rdev->rmmio) + reg); | ||
1563 | else { | ||
1564 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
1565 | return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
1566 | } | ||
1567 | } | ||
1568 | |||
1569 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
1570 | { | ||
1571 | if (reg < 0x10000) | ||
1572 | writel(v, ((void __iomem *)rdev->rmmio) + reg); | ||
1573 | else { | ||
1574 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
1575 | writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
1576 | } | ||
1577 | } | ||
1578 | |||
1579 | int r100_init(struct radeon_device *rdev) | 1635 | int r100_init(struct radeon_device *rdev) |
1580 | { | 1636 | { |
1581 | return 0; | 1637 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 9c8d41534a5d..053f4ec397f7 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -83,8 +83,8 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
83 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB); | 83 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB); |
84 | (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); | 84 | (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); |
85 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); | 85 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); |
86 | mb(); | ||
87 | } | 86 | } |
87 | mb(); | ||
88 | } | 88 | } |
89 | 89 | ||
90 | int rv370_pcie_gart_enable(struct radeon_device *rdev) | 90 | int rv370_pcie_gart_enable(struct radeon_device *rdev) |
@@ -448,6 +448,7 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
448 | /* rv350,rv370,rv380 */ | 448 | /* rv350,rv370,rv380 */ |
449 | rdev->num_gb_pipes = 1; | 449 | rdev->num_gb_pipes = 1; |
450 | } | 450 | } |
451 | rdev->num_z_pipes = 1; | ||
451 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); | 452 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); |
452 | switch (rdev->num_gb_pipes) { | 453 | switch (rdev->num_gb_pipes) { |
453 | case 2: | 454 | case 2: |
@@ -486,7 +487,8 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
486 | printk(KERN_WARNING "Failed to wait MC idle while " | 487 | printk(KERN_WARNING "Failed to wait MC idle while " |
487 | "programming pipes. Bad things might happen.\n"); | 488 | "programming pipes. Bad things might happen.\n"); |
488 | } | 489 | } |
489 | DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes); | 490 | DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n", |
491 | rdev->num_gb_pipes, rdev->num_z_pipes); | ||
490 | } | 492 | } |
491 | 493 | ||
492 | int r300_ga_reset(struct radeon_device *rdev) | 494 | int r300_ga_reset(struct radeon_device *rdev) |
@@ -593,27 +595,6 @@ void r300_vram_info(struct radeon_device *rdev) | |||
593 | 595 | ||
594 | 596 | ||
595 | /* | 597 | /* |
596 | * Indirect registers accessor | ||
597 | */ | ||
598 | uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg) | ||
599 | { | ||
600 | uint32_t r; | ||
601 | |||
602 | WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff)); | ||
603 | (void)RREG32(RADEON_PCIE_INDEX); | ||
604 | r = RREG32(RADEON_PCIE_DATA); | ||
605 | return r; | ||
606 | } | ||
607 | |||
608 | void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
609 | { | ||
610 | WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff)); | ||
611 | (void)RREG32(RADEON_PCIE_INDEX); | ||
612 | WREG32(RADEON_PCIE_DATA, (v)); | ||
613 | (void)RREG32(RADEON_PCIE_DATA); | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * PCIE Lanes | 598 | * PCIE Lanes |
618 | */ | 599 | */ |
619 | 600 | ||
@@ -1403,6 +1384,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
1403 | tmp = (ib_chunk->kdata[idx] >> 22) & 0xF; | 1384 | tmp = (ib_chunk->kdata[idx] >> 22) & 0xF; |
1404 | track->textures[i].txdepth = tmp; | 1385 | track->textures[i].txdepth = tmp; |
1405 | break; | 1386 | break; |
1387 | case R300_ZB_ZPASS_ADDR: | ||
1388 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1389 | if (r) { | ||
1390 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
1391 | idx, reg); | ||
1392 | r100_cs_dump_packet(p, pkt); | ||
1393 | return r; | ||
1394 | } | ||
1395 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | ||
1396 | break; | ||
1397 | case 0x4be8: | ||
1398 | /* valid register only on RV530 */ | ||
1399 | if (p->rdev->family == CHIP_RV530) | ||
1400 | break; | ||
1401 | /* fallthrough do not move */ | ||
1406 | default: | 1402 | default: |
1407 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 1403 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
1408 | reg, idx); | 1404 | reg, idx); |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index dea497a979f2..97426a6f370f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -165,7 +165,18 @@ void r420_pipes_init(struct radeon_device *rdev) | |||
165 | printk(KERN_WARNING "Failed to wait GUI idle while " | 165 | printk(KERN_WARNING "Failed to wait GUI idle while " |
166 | "programming pipes. Bad things might happen.\n"); | 166 | "programming pipes. Bad things might happen.\n"); |
167 | } | 167 | } |
168 | DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes); | 168 | |
169 | if (rdev->family == CHIP_RV530) { | ||
170 | tmp = RREG32(RV530_GB_PIPE_SELECT2); | ||
171 | if ((tmp & 3) == 3) | ||
172 | rdev->num_z_pipes = 2; | ||
173 | else | ||
174 | rdev->num_z_pipes = 1; | ||
175 | } else | ||
176 | rdev->num_z_pipes = 1; | ||
177 | |||
178 | DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n", | ||
179 | rdev->num_gb_pipes, rdev->num_z_pipes); | ||
169 | } | 180 | } |
170 | 181 | ||
171 | void r420_gpu_init(struct radeon_device *rdev) | 182 | void r420_gpu_init(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 036691b38cb7..e1d5e0331e19 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -350,6 +350,7 @@ | |||
350 | #define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 | 350 | #define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 |
351 | #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 | 351 | #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 |
352 | #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c | 352 | #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c |
353 | #define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 | ||
353 | #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 | 354 | #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 |
354 | 355 | ||
355 | /* master controls */ | 356 | /* master controls */ |
@@ -438,14 +439,15 @@ | |||
438 | # define AVIVO_DC_LB_DISP1_END_ADR_SHIFT 4 | 439 | # define AVIVO_DC_LB_DISP1_END_ADR_SHIFT 4 |
439 | # define AVIVO_DC_LB_DISP1_END_ADR_MASK 0x7ff | 440 | # define AVIVO_DC_LB_DISP1_END_ADR_MASK 0x7ff |
440 | 441 | ||
441 | #define R500_DxMODE_INT_MASK 0x6540 | ||
442 | #define R500_D1MODE_INT_MASK (1<<0) | ||
443 | #define R500_D2MODE_INT_MASK (1<<8) | ||
444 | |||
445 | #define AVIVO_D1MODE_DATA_FORMAT 0x6528 | 442 | #define AVIVO_D1MODE_DATA_FORMAT 0x6528 |
446 | # define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) | 443 | # define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) |
447 | #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C | 444 | #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C |
445 | #define AVIVO_D1MODE_VBLANK_STATUS 0x6534 | ||
446 | # define AVIVO_VBLANK_ACK (1 << 4) | ||
448 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 | 447 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 |
448 | #define AVIVO_DxMODE_INT_MASK 0x6540 | ||
449 | # define AVIVO_D1MODE_INT_MASK (1 << 0) | ||
450 | # define AVIVO_D2MODE_INT_MASK (1 << 8) | ||
449 | #define AVIVO_D1MODE_VIEWPORT_START 0x6580 | 451 | #define AVIVO_D1MODE_VIEWPORT_START 0x6580 |
450 | #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 | 452 | #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 |
451 | #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 | 453 | #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 |
@@ -475,6 +477,7 @@ | |||
475 | #define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 | 477 | #define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 |
476 | #define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 | 478 | #define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 |
477 | #define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c | 479 | #define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c |
480 | #define AVIVO_D2CRTC_FRAME_COUNT 0x68a4 | ||
478 | #define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 | 481 | #define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 |
479 | 482 | ||
480 | #define AVIVO_D2GRPH_ENABLE 0x6900 | 483 | #define AVIVO_D2GRPH_ENABLE 0x6900 |
@@ -497,6 +500,7 @@ | |||
497 | #define AVIVO_D2CUR_SIZE 0x6c10 | 500 | #define AVIVO_D2CUR_SIZE 0x6c10 |
498 | #define AVIVO_D2CUR_POSITION 0x6c14 | 501 | #define AVIVO_D2CUR_POSITION 0x6c14 |
499 | 502 | ||
503 | #define AVIVO_D2MODE_VBLANK_STATUS 0x6d34 | ||
500 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 | 504 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 |
501 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 | 505 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 |
502 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 | 506 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 |
@@ -748,4 +752,8 @@ | |||
748 | # define AVIVO_I2C_EN (1 << 0) | 752 | # define AVIVO_I2C_EN (1 << 0) |
749 | # define AVIVO_I2C_RESET (1 << 8) | 753 | # define AVIVO_I2C_RESET (1 << 8) |
750 | 754 | ||
755 | #define AVIVO_DISP_INTERRUPT_STATUS 0x7edc | ||
756 | # define AVIVO_D1_VBLANK_INTERRUPT (1 << 4) | ||
757 | # define AVIVO_D2_VBLANK_INTERRUPT (1 << 5) | ||
758 | |||
751 | #endif | 759 | #endif |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 09fb0b6ec7dd..ebd6b0f7bdff 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -177,7 +177,6 @@ void r520_gpu_init(struct radeon_device *rdev) | |||
177 | */ | 177 | */ |
178 | /* workaround for RV530 */ | 178 | /* workaround for RV530 */ |
179 | if (rdev->family == CHIP_RV530) { | 179 | if (rdev->family == CHIP_RV530) { |
180 | WREG32(0x4124, 1); | ||
181 | WREG32(0x4128, 0xFF); | 180 | WREG32(0x4128, 0xFF); |
182 | } | 181 | } |
183 | r420_pipes_init(rdev); | 182 | r420_pipes_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b1d945b8ed6c..b519fb2fecbb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -242,6 +242,7 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
242 | uint64_t *gpu_addr); | 242 | uint64_t *gpu_addr); |
243 | void radeon_object_unpin(struct radeon_object *robj); | 243 | void radeon_object_unpin(struct radeon_object *robj); |
244 | int radeon_object_wait(struct radeon_object *robj); | 244 | int radeon_object_wait(struct radeon_object *robj); |
245 | int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement); | ||
245 | int radeon_object_evict_vram(struct radeon_device *rdev); | 246 | int radeon_object_evict_vram(struct radeon_device *rdev); |
246 | int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset); | 247 | int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset); |
247 | void radeon_object_force_delete(struct radeon_device *rdev); | 248 | void radeon_object_force_delete(struct radeon_device *rdev); |
@@ -574,6 +575,7 @@ struct radeon_asic { | |||
574 | void (*ring_start)(struct radeon_device *rdev); | 575 | void (*ring_start)(struct radeon_device *rdev); |
575 | int (*irq_set)(struct radeon_device *rdev); | 576 | int (*irq_set)(struct radeon_device *rdev); |
576 | int (*irq_process)(struct radeon_device *rdev); | 577 | int (*irq_process)(struct radeon_device *rdev); |
578 | u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); | ||
577 | void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence); | 579 | void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence); |
578 | int (*cs_parse)(struct radeon_cs_parser *p); | 580 | int (*cs_parse)(struct radeon_cs_parser *p); |
579 | int (*copy_blit)(struct radeon_device *rdev, | 581 | int (*copy_blit)(struct radeon_device *rdev, |
@@ -653,6 +655,7 @@ struct radeon_device { | |||
653 | int usec_timeout; | 655 | int usec_timeout; |
654 | enum radeon_pll_errata pll_errata; | 656 | enum radeon_pll_errata pll_errata; |
655 | int num_gb_pipes; | 657 | int num_gb_pipes; |
658 | int num_z_pipes; | ||
656 | int disp_priority; | 659 | int disp_priority; |
657 | /* BIOS */ | 660 | /* BIOS */ |
658 | uint8_t *bios; | 661 | uint8_t *bios; |
@@ -666,14 +669,11 @@ struct radeon_device { | |||
666 | resource_size_t rmmio_base; | 669 | resource_size_t rmmio_base; |
667 | resource_size_t rmmio_size; | 670 | resource_size_t rmmio_size; |
668 | void *rmmio; | 671 | void *rmmio; |
669 | radeon_rreg_t mm_rreg; | ||
670 | radeon_wreg_t mm_wreg; | ||
671 | radeon_rreg_t mc_rreg; | 672 | radeon_rreg_t mc_rreg; |
672 | radeon_wreg_t mc_wreg; | 673 | radeon_wreg_t mc_wreg; |
673 | radeon_rreg_t pll_rreg; | 674 | radeon_rreg_t pll_rreg; |
674 | radeon_wreg_t pll_wreg; | 675 | radeon_wreg_t pll_wreg; |
675 | radeon_rreg_t pcie_rreg; | 676 | uint32_t pcie_reg_mask; |
676 | radeon_wreg_t pcie_wreg; | ||
677 | radeon_rreg_t pciep_rreg; | 677 | radeon_rreg_t pciep_rreg; |
678 | radeon_wreg_t pciep_wreg; | 678 | radeon_wreg_t pciep_wreg; |
679 | struct radeon_clock clock; | 679 | struct radeon_clock clock; |
@@ -705,22 +705,42 @@ int radeon_device_init(struct radeon_device *rdev, | |||
705 | void radeon_device_fini(struct radeon_device *rdev); | 705 | void radeon_device_fini(struct radeon_device *rdev); |
706 | int radeon_gpu_wait_for_idle(struct radeon_device *rdev); | 706 | int radeon_gpu_wait_for_idle(struct radeon_device *rdev); |
707 | 707 | ||
708 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | ||
709 | { | ||
710 | if (reg < 0x10000) | ||
711 | return readl(((void __iomem *)rdev->rmmio) + reg); | ||
712 | else { | ||
713 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
714 | return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
715 | } | ||
716 | } | ||
717 | |||
718 | static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
719 | { | ||
720 | if (reg < 0x10000) | ||
721 | writel(v, ((void __iomem *)rdev->rmmio) + reg); | ||
722 | else { | ||
723 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | ||
724 | writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | ||
725 | } | ||
726 | } | ||
727 | |||
708 | 728 | ||
709 | /* | 729 | /* |
710 | * Registers read & write functions. | 730 | * Registers read & write functions. |
711 | */ | 731 | */ |
712 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) | 732 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) |
713 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) | 733 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) |
714 | #define RREG32(reg) rdev->mm_rreg(rdev, (reg)) | 734 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) |
715 | #define WREG32(reg, v) rdev->mm_wreg(rdev, (reg), (v)) | 735 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) |
716 | #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) | 736 | #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
717 | #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) | 737 | #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
718 | #define RREG32_PLL(reg) rdev->pll_rreg(rdev, (reg)) | 738 | #define RREG32_PLL(reg) rdev->pll_rreg(rdev, (reg)) |
719 | #define WREG32_PLL(reg, v) rdev->pll_wreg(rdev, (reg), (v)) | 739 | #define WREG32_PLL(reg, v) rdev->pll_wreg(rdev, (reg), (v)) |
720 | #define RREG32_MC(reg) rdev->mc_rreg(rdev, (reg)) | 740 | #define RREG32_MC(reg) rdev->mc_rreg(rdev, (reg)) |
721 | #define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v)) | 741 | #define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v)) |
722 | #define RREG32_PCIE(reg) rdev->pcie_rreg(rdev, (reg)) | 742 | #define RREG32_PCIE(reg) rv370_pcie_rreg(rdev, (reg)) |
723 | #define WREG32_PCIE(reg, v) rdev->pcie_wreg(rdev, (reg), (v)) | 743 | #define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v)) |
724 | #define WREG32_P(reg, val, mask) \ | 744 | #define WREG32_P(reg, val, mask) \ |
725 | do { \ | 745 | do { \ |
726 | uint32_t tmp_ = RREG32(reg); \ | 746 | uint32_t tmp_ = RREG32(reg); \ |
@@ -736,6 +756,24 @@ int radeon_gpu_wait_for_idle(struct radeon_device *rdev); | |||
736 | WREG32_PLL(reg, tmp_); \ | 756 | WREG32_PLL(reg, tmp_); \ |
737 | } while (0) | 757 | } while (0) |
738 | 758 | ||
759 | /* | ||
760 | * Indirect registers accessor | ||
761 | */ | ||
762 | static inline uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg) | ||
763 | { | ||
764 | uint32_t r; | ||
765 | |||
766 | WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); | ||
767 | r = RREG32(RADEON_PCIE_DATA); | ||
768 | return r; | ||
769 | } | ||
770 | |||
771 | static inline void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
772 | { | ||
773 | WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); | ||
774 | WREG32(RADEON_PCIE_DATA, (v)); | ||
775 | } | ||
776 | |||
739 | void r100_pll_errata_after_index(struct radeon_device *rdev); | 777 | void r100_pll_errata_after_index(struct radeon_device *rdev); |
740 | 778 | ||
741 | 779 | ||
@@ -862,6 +900,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
862 | #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) | 900 | #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) |
863 | #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) | 901 | #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) |
864 | #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) | 902 | #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) |
903 | #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) | ||
865 | #define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence)) | 904 | #define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence)) |
866 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) | 905 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) |
867 | #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) | 906 | #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 9a75876e0c3b..7ca6c13569b5 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -49,6 +49,7 @@ void r100_vram_info(struct radeon_device *rdev); | |||
49 | int r100_gpu_reset(struct radeon_device *rdev); | 49 | int r100_gpu_reset(struct radeon_device *rdev); |
50 | int r100_mc_init(struct radeon_device *rdev); | 50 | int r100_mc_init(struct radeon_device *rdev); |
51 | void r100_mc_fini(struct radeon_device *rdev); | 51 | void r100_mc_fini(struct radeon_device *rdev); |
52 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); | ||
52 | int r100_wb_init(struct radeon_device *rdev); | 53 | int r100_wb_init(struct radeon_device *rdev); |
53 | void r100_wb_fini(struct radeon_device *rdev); | 54 | void r100_wb_fini(struct radeon_device *rdev); |
54 | int r100_gart_enable(struct radeon_device *rdev); | 55 | int r100_gart_enable(struct radeon_device *rdev); |
@@ -96,6 +97,7 @@ static struct radeon_asic r100_asic = { | |||
96 | .ring_start = &r100_ring_start, | 97 | .ring_start = &r100_ring_start, |
97 | .irq_set = &r100_irq_set, | 98 | .irq_set = &r100_irq_set, |
98 | .irq_process = &r100_irq_process, | 99 | .irq_process = &r100_irq_process, |
100 | .get_vblank_counter = &r100_get_vblank_counter, | ||
99 | .fence_ring_emit = &r100_fence_ring_emit, | 101 | .fence_ring_emit = &r100_fence_ring_emit, |
100 | .cs_parse = &r100_cs_parse, | 102 | .cs_parse = &r100_cs_parse, |
101 | .copy_blit = &r100_copy_blit, | 103 | .copy_blit = &r100_copy_blit, |
@@ -156,6 +158,7 @@ static struct radeon_asic r300_asic = { | |||
156 | .ring_start = &r300_ring_start, | 158 | .ring_start = &r300_ring_start, |
157 | .irq_set = &r100_irq_set, | 159 | .irq_set = &r100_irq_set, |
158 | .irq_process = &r100_irq_process, | 160 | .irq_process = &r100_irq_process, |
161 | .get_vblank_counter = &r100_get_vblank_counter, | ||
159 | .fence_ring_emit = &r300_fence_ring_emit, | 162 | .fence_ring_emit = &r300_fence_ring_emit, |
160 | .cs_parse = &r300_cs_parse, | 163 | .cs_parse = &r300_cs_parse, |
161 | .copy_blit = &r100_copy_blit, | 164 | .copy_blit = &r100_copy_blit, |
@@ -196,6 +199,7 @@ static struct radeon_asic r420_asic = { | |||
196 | .ring_start = &r300_ring_start, | 199 | .ring_start = &r300_ring_start, |
197 | .irq_set = &r100_irq_set, | 200 | .irq_set = &r100_irq_set, |
198 | .irq_process = &r100_irq_process, | 201 | .irq_process = &r100_irq_process, |
202 | .get_vblank_counter = &r100_get_vblank_counter, | ||
199 | .fence_ring_emit = &r300_fence_ring_emit, | 203 | .fence_ring_emit = &r300_fence_ring_emit, |
200 | .cs_parse = &r300_cs_parse, | 204 | .cs_parse = &r300_cs_parse, |
201 | .copy_blit = &r100_copy_blit, | 205 | .copy_blit = &r100_copy_blit, |
@@ -243,6 +247,7 @@ static struct radeon_asic rs400_asic = { | |||
243 | .ring_start = &r300_ring_start, | 247 | .ring_start = &r300_ring_start, |
244 | .irq_set = &r100_irq_set, | 248 | .irq_set = &r100_irq_set, |
245 | .irq_process = &r100_irq_process, | 249 | .irq_process = &r100_irq_process, |
250 | .get_vblank_counter = &r100_get_vblank_counter, | ||
246 | .fence_ring_emit = &r300_fence_ring_emit, | 251 | .fence_ring_emit = &r300_fence_ring_emit, |
247 | .cs_parse = &r300_cs_parse, | 252 | .cs_parse = &r300_cs_parse, |
248 | .copy_blit = &r100_copy_blit, | 253 | .copy_blit = &r100_copy_blit, |
@@ -266,6 +271,8 @@ void rs600_vram_info(struct radeon_device *rdev); | |||
266 | int rs600_mc_init(struct radeon_device *rdev); | 271 | int rs600_mc_init(struct radeon_device *rdev); |
267 | void rs600_mc_fini(struct radeon_device *rdev); | 272 | void rs600_mc_fini(struct radeon_device *rdev); |
268 | int rs600_irq_set(struct radeon_device *rdev); | 273 | int rs600_irq_set(struct radeon_device *rdev); |
274 | int rs600_irq_process(struct radeon_device *rdev); | ||
275 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); | ||
269 | int rs600_gart_enable(struct radeon_device *rdev); | 276 | int rs600_gart_enable(struct radeon_device *rdev); |
270 | void rs600_gart_disable(struct radeon_device *rdev); | 277 | void rs600_gart_disable(struct radeon_device *rdev); |
271 | void rs600_gart_tlb_flush(struct radeon_device *rdev); | 278 | void rs600_gart_tlb_flush(struct radeon_device *rdev); |
@@ -291,7 +298,8 @@ static struct radeon_asic rs600_asic = { | |||
291 | .cp_disable = &r100_cp_disable, | 298 | .cp_disable = &r100_cp_disable, |
292 | .ring_start = &r300_ring_start, | 299 | .ring_start = &r300_ring_start, |
293 | .irq_set = &rs600_irq_set, | 300 | .irq_set = &rs600_irq_set, |
294 | .irq_process = &r100_irq_process, | 301 | .irq_process = &rs600_irq_process, |
302 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
295 | .fence_ring_emit = &r300_fence_ring_emit, | 303 | .fence_ring_emit = &r300_fence_ring_emit, |
296 | .cs_parse = &r300_cs_parse, | 304 | .cs_parse = &r300_cs_parse, |
297 | .copy_blit = &r100_copy_blit, | 305 | .copy_blit = &r100_copy_blit, |
@@ -308,6 +316,7 @@ static struct radeon_asic rs600_asic = { | |||
308 | /* | 316 | /* |
309 | * rs690,rs740 | 317 | * rs690,rs740 |
310 | */ | 318 | */ |
319 | int rs690_init(struct radeon_device *rdev); | ||
311 | void rs690_errata(struct radeon_device *rdev); | 320 | void rs690_errata(struct radeon_device *rdev); |
312 | void rs690_vram_info(struct radeon_device *rdev); | 321 | void rs690_vram_info(struct radeon_device *rdev); |
313 | int rs690_mc_init(struct radeon_device *rdev); | 322 | int rs690_mc_init(struct radeon_device *rdev); |
@@ -316,7 +325,7 @@ uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); | |||
316 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 325 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
317 | void rs690_bandwidth_update(struct radeon_device *rdev); | 326 | void rs690_bandwidth_update(struct radeon_device *rdev); |
318 | static struct radeon_asic rs690_asic = { | 327 | static struct radeon_asic rs690_asic = { |
319 | .init = &r300_init, | 328 | .init = &rs690_init, |
320 | .errata = &rs690_errata, | 329 | .errata = &rs690_errata, |
321 | .vram_info = &rs690_vram_info, | 330 | .vram_info = &rs690_vram_info, |
322 | .gpu_reset = &r300_gpu_reset, | 331 | .gpu_reset = &r300_gpu_reset, |
@@ -333,7 +342,8 @@ static struct radeon_asic rs690_asic = { | |||
333 | .cp_disable = &r100_cp_disable, | 342 | .cp_disable = &r100_cp_disable, |
334 | .ring_start = &r300_ring_start, | 343 | .ring_start = &r300_ring_start, |
335 | .irq_set = &rs600_irq_set, | 344 | .irq_set = &rs600_irq_set, |
336 | .irq_process = &r100_irq_process, | 345 | .irq_process = &rs600_irq_process, |
346 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
337 | .fence_ring_emit = &r300_fence_ring_emit, | 347 | .fence_ring_emit = &r300_fence_ring_emit, |
338 | .cs_parse = &r300_cs_parse, | 348 | .cs_parse = &r300_cs_parse, |
339 | .copy_blit = &r100_copy_blit, | 349 | .copy_blit = &r100_copy_blit, |
@@ -381,8 +391,9 @@ static struct radeon_asic rv515_asic = { | |||
381 | .cp_fini = &r100_cp_fini, | 391 | .cp_fini = &r100_cp_fini, |
382 | .cp_disable = &r100_cp_disable, | 392 | .cp_disable = &r100_cp_disable, |
383 | .ring_start = &rv515_ring_start, | 393 | .ring_start = &rv515_ring_start, |
384 | .irq_set = &r100_irq_set, | 394 | .irq_set = &rs600_irq_set, |
385 | .irq_process = &r100_irq_process, | 395 | .irq_process = &rs600_irq_process, |
396 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
386 | .fence_ring_emit = &r300_fence_ring_emit, | 397 | .fence_ring_emit = &r300_fence_ring_emit, |
387 | .cs_parse = &r300_cs_parse, | 398 | .cs_parse = &r300_cs_parse, |
388 | .copy_blit = &r100_copy_blit, | 399 | .copy_blit = &r100_copy_blit, |
@@ -423,8 +434,9 @@ static struct radeon_asic r520_asic = { | |||
423 | .cp_fini = &r100_cp_fini, | 434 | .cp_fini = &r100_cp_fini, |
424 | .cp_disable = &r100_cp_disable, | 435 | .cp_disable = &r100_cp_disable, |
425 | .ring_start = &rv515_ring_start, | 436 | .ring_start = &rv515_ring_start, |
426 | .irq_set = &r100_irq_set, | 437 | .irq_set = &rs600_irq_set, |
427 | .irq_process = &r100_irq_process, | 438 | .irq_process = &rs600_irq_process, |
439 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
428 | .fence_ring_emit = &r300_fence_ring_emit, | 440 | .fence_ring_emit = &r300_fence_ring_emit, |
429 | .cs_parse = &r300_cs_parse, | 441 | .cs_parse = &r300_cs_parse, |
430 | .copy_blit = &r100_copy_blit, | 442 | .copy_blit = &r100_copy_blit, |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index afc4db280b94..2a027e00762a 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -685,23 +685,15 @@ static const uint32_t default_tvdac_adj[CHIP_LAST] = { | |||
685 | 0x00780000, /* rs480 */ | 685 | 0x00780000, /* rs480 */ |
686 | }; | 686 | }; |
687 | 687 | ||
688 | static struct radeon_encoder_tv_dac | 688 | static void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev, |
689 | *radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev) | 689 | struct radeon_encoder_tv_dac *tv_dac) |
690 | { | 690 | { |
691 | struct radeon_encoder_tv_dac *tv_dac = NULL; | ||
692 | |||
693 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | ||
694 | |||
695 | if (!tv_dac) | ||
696 | return NULL; | ||
697 | |||
698 | tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family]; | 691 | tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family]; |
699 | if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250)) | 692 | if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250)) |
700 | tv_dac->ps2_tvdac_adj = 0x00880000; | 693 | tv_dac->ps2_tvdac_adj = 0x00880000; |
701 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 694 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
702 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 695 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
703 | 696 | return; | |
704 | return tv_dac; | ||
705 | } | 697 | } |
706 | 698 | ||
707 | struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | 699 | struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct |
@@ -713,19 +705,18 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
713 | uint16_t dac_info; | 705 | uint16_t dac_info; |
714 | uint8_t rev, bg, dac; | 706 | uint8_t rev, bg, dac; |
715 | struct radeon_encoder_tv_dac *tv_dac = NULL; | 707 | struct radeon_encoder_tv_dac *tv_dac = NULL; |
708 | int found = 0; | ||
709 | |||
710 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | ||
711 | if (!tv_dac) | ||
712 | return NULL; | ||
716 | 713 | ||
717 | if (rdev->bios == NULL) | 714 | if (rdev->bios == NULL) |
718 | return radeon_legacy_get_tv_dac_info_from_table(rdev); | 715 | goto out; |
719 | 716 | ||
720 | /* first check TV table */ | 717 | /* first check TV table */ |
721 | dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); | 718 | dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); |
722 | if (dac_info) { | 719 | if (dac_info) { |
723 | tv_dac = | ||
724 | kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | ||
725 | |||
726 | if (!tv_dac) | ||
727 | return NULL; | ||
728 | |||
729 | rev = RBIOS8(dac_info + 0x3); | 720 | rev = RBIOS8(dac_info + 0x3); |
730 | if (rev > 4) { | 721 | if (rev > 4) { |
731 | bg = RBIOS8(dac_info + 0xc) & 0xf; | 722 | bg = RBIOS8(dac_info + 0xc) & 0xf; |
@@ -739,6 +730,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
739 | bg = RBIOS8(dac_info + 0x10) & 0xf; | 730 | bg = RBIOS8(dac_info + 0x10) & 0xf; |
740 | dac = RBIOS8(dac_info + 0x11) & 0xf; | 731 | dac = RBIOS8(dac_info + 0x11) & 0xf; |
741 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 732 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
733 | found = 1; | ||
742 | } else if (rev > 1) { | 734 | } else if (rev > 1) { |
743 | bg = RBIOS8(dac_info + 0xc) & 0xf; | 735 | bg = RBIOS8(dac_info + 0xc) & 0xf; |
744 | dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; | 736 | dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; |
@@ -751,22 +743,15 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
751 | bg = RBIOS8(dac_info + 0xe) & 0xf; | 743 | bg = RBIOS8(dac_info + 0xe) & 0xf; |
752 | dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; | 744 | dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; |
753 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 745 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
746 | found = 1; | ||
754 | } | 747 | } |
755 | |||
756 | tv_dac->tv_std = radeon_combios_get_tv_info(encoder); | 748 | tv_dac->tv_std = radeon_combios_get_tv_info(encoder); |
757 | 749 | } | |
758 | } else { | 750 | if (!found) { |
759 | /* then check CRT table */ | 751 | /* then check CRT table */ |
760 | dac_info = | 752 | dac_info = |
761 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); | 753 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
762 | if (dac_info) { | 754 | if (dac_info) { |
763 | tv_dac = | ||
764 | kzalloc(sizeof(struct radeon_encoder_tv_dac), | ||
765 | GFP_KERNEL); | ||
766 | |||
767 | if (!tv_dac) | ||
768 | return NULL; | ||
769 | |||
770 | rev = RBIOS8(dac_info) & 0x3; | 755 | rev = RBIOS8(dac_info) & 0x3; |
771 | if (rev < 2) { | 756 | if (rev < 2) { |
772 | bg = RBIOS8(dac_info + 0x3) & 0xf; | 757 | bg = RBIOS8(dac_info + 0x3) & 0xf; |
@@ -775,6 +760,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
775 | (bg << 16) | (dac << 20); | 760 | (bg << 16) | (dac << 20); |
776 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 761 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
777 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 762 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
763 | found = 1; | ||
778 | } else { | 764 | } else { |
779 | bg = RBIOS8(dac_info + 0x4) & 0xf; | 765 | bg = RBIOS8(dac_info + 0x4) & 0xf; |
780 | dac = RBIOS8(dac_info + 0x5) & 0xf; | 766 | dac = RBIOS8(dac_info + 0x5) & 0xf; |
@@ -782,13 +768,17 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
782 | (bg << 16) | (dac << 20); | 768 | (bg << 16) | (dac << 20); |
783 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 769 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
784 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 770 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
771 | found = 1; | ||
785 | } | 772 | } |
786 | } else { | 773 | } else { |
787 | DRM_INFO("No TV DAC info found in BIOS\n"); | 774 | DRM_INFO("No TV DAC info found in BIOS\n"); |
788 | return radeon_legacy_get_tv_dac_info_from_table(rdev); | ||
789 | } | 775 | } |
790 | } | 776 | } |
791 | 777 | ||
778 | out: | ||
779 | if (!found) /* fallback to defaults */ | ||
780 | radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac); | ||
781 | |||
792 | return tv_dac; | 782 | return tv_dac; |
793 | } | 783 | } |
794 | 784 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index d8356827ef17..7a52c461145c 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -406,6 +406,15 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) | |||
406 | { | 406 | { |
407 | uint32_t gb_tile_config, gb_pipe_sel = 0; | 407 | uint32_t gb_tile_config, gb_pipe_sel = 0; |
408 | 408 | ||
409 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { | ||
410 | uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2); | ||
411 | if ((z_pipe_sel & 3) == 3) | ||
412 | dev_priv->num_z_pipes = 2; | ||
413 | else | ||
414 | dev_priv->num_z_pipes = 1; | ||
415 | } else | ||
416 | dev_priv->num_z_pipes = 1; | ||
417 | |||
409 | /* RS4xx/RS6xx/R4xx/R5xx */ | 418 | /* RS4xx/RS6xx/R4xx/R5xx */ |
410 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { | 419 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { |
411 | gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); | 420 | gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 9ff6dcb97f9d..7693f7c67bd3 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -225,25 +225,18 @@ void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
225 | 225 | ||
226 | void radeon_register_accessor_init(struct radeon_device *rdev) | 226 | void radeon_register_accessor_init(struct radeon_device *rdev) |
227 | { | 227 | { |
228 | rdev->mm_rreg = &r100_mm_rreg; | ||
229 | rdev->mm_wreg = &r100_mm_wreg; | ||
230 | rdev->mc_rreg = &radeon_invalid_rreg; | 228 | rdev->mc_rreg = &radeon_invalid_rreg; |
231 | rdev->mc_wreg = &radeon_invalid_wreg; | 229 | rdev->mc_wreg = &radeon_invalid_wreg; |
232 | rdev->pll_rreg = &radeon_invalid_rreg; | 230 | rdev->pll_rreg = &radeon_invalid_rreg; |
233 | rdev->pll_wreg = &radeon_invalid_wreg; | 231 | rdev->pll_wreg = &radeon_invalid_wreg; |
234 | rdev->pcie_rreg = &radeon_invalid_rreg; | ||
235 | rdev->pcie_wreg = &radeon_invalid_wreg; | ||
236 | rdev->pciep_rreg = &radeon_invalid_rreg; | 232 | rdev->pciep_rreg = &radeon_invalid_rreg; |
237 | rdev->pciep_wreg = &radeon_invalid_wreg; | 233 | rdev->pciep_wreg = &radeon_invalid_wreg; |
238 | 234 | ||
239 | /* Don't change order as we are overridding accessor. */ | 235 | /* Don't change order as we are overridding accessor. */ |
240 | if (rdev->family < CHIP_RV515) { | 236 | if (rdev->family < CHIP_RV515) { |
241 | rdev->pcie_rreg = &rv370_pcie_rreg; | 237 | rdev->pcie_reg_mask = 0xff; |
242 | rdev->pcie_wreg = &rv370_pcie_wreg; | 238 | } else { |
243 | } | 239 | rdev->pcie_reg_mask = 0x7ff; |
244 | if (rdev->family >= CHIP_RV515) { | ||
245 | rdev->pcie_rreg = &rv515_pcie_rreg; | ||
246 | rdev->pcie_wreg = &rv515_pcie_wreg; | ||
247 | } | 240 | } |
248 | /* FIXME: not sure here */ | 241 | /* FIXME: not sure here */ |
249 | if (rdev->family <= CHIP_R580) { | 242 | if (rdev->family <= CHIP_R580) { |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 3933f8216a34..6fa32dac4e97 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -100,9 +100,10 @@ | |||
100 | * 1.28- Add support for VBL on CRTC2 | 100 | * 1.28- Add support for VBL on CRTC2 |
101 | * 1.29- R500 3D cmd buffer support | 101 | * 1.29- R500 3D cmd buffer support |
102 | * 1.30- Add support for occlusion queries | 102 | * 1.30- Add support for occlusion queries |
103 | * 1.31- Add support for num Z pipes from GET_PARAM | ||
103 | */ | 104 | */ |
104 | #define DRIVER_MAJOR 1 | 105 | #define DRIVER_MAJOR 1 |
105 | #define DRIVER_MINOR 30 | 106 | #define DRIVER_MINOR 31 |
106 | #define DRIVER_PATCHLEVEL 0 | 107 | #define DRIVER_PATCHLEVEL 0 |
107 | 108 | ||
108 | /* | 109 | /* |
@@ -329,6 +330,7 @@ typedef struct drm_radeon_private { | |||
329 | resource_size_t fb_aper_offset; | 330 | resource_size_t fb_aper_offset; |
330 | 331 | ||
331 | int num_gb_pipes; | 332 | int num_gb_pipes; |
333 | int num_z_pipes; | ||
332 | int track_flush; | 334 | int track_flush; |
333 | drm_local_map_t *mmio; | 335 | drm_local_map_t *mmio; |
334 | 336 | ||
@@ -689,6 +691,7 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga | |||
689 | 691 | ||
690 | /* pipe config regs */ | 692 | /* pipe config regs */ |
691 | #define R400_GB_PIPE_SELECT 0x402c | 693 | #define R400_GB_PIPE_SELECT 0x402c |
694 | #define RV530_GB_PIPE_SELECT2 0x4124 | ||
692 | #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ | 695 | #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ |
693 | #define R300_GB_TILE_CONFIG 0x4018 | 696 | #define R300_GB_TILE_CONFIG 0x4018 |
694 | # define R300_ENABLE_TILING (1 << 0) | 697 | # define R300_ENABLE_TILING (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 3206c0ad7b6c..ec383edf5f38 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -574,6 +574,8 @@ int radeonfb_create(struct radeon_device *rdev, | |||
574 | goto out_unref; | 574 | goto out_unref; |
575 | } | 575 | } |
576 | 576 | ||
577 | memset_io(fbptr, 0, aligned_size); | ||
578 | |||
577 | strcpy(info->fix.id, "radeondrmfb"); | 579 | strcpy(info->fix.id, "radeondrmfb"); |
578 | info->fix.type = FB_TYPE_PACKED_PIXELS; | 580 | info->fix.type = FB_TYPE_PACKED_PIXELS; |
579 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 581 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index cded5180c752..d880edf254db 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -262,8 +262,34 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
262 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 262 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
263 | struct drm_file *filp) | 263 | struct drm_file *filp) |
264 | { | 264 | { |
265 | /* FIXME: implement */ | 265 | struct drm_radeon_gem_busy *args = data; |
266 | return 0; | 266 | struct drm_gem_object *gobj; |
267 | struct radeon_object *robj; | ||
268 | int r; | ||
269 | uint32_t cur_placement; | ||
270 | |||
271 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | ||
272 | if (gobj == NULL) { | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | robj = gobj->driver_private; | ||
276 | r = radeon_object_busy_domain(robj, &cur_placement); | ||
277 | switch (cur_placement) { | ||
278 | case TTM_PL_VRAM: | ||
279 | args->domain = RADEON_GEM_DOMAIN_VRAM; | ||
280 | break; | ||
281 | case TTM_PL_TT: | ||
282 | args->domain = RADEON_GEM_DOMAIN_GTT; | ||
283 | break; | ||
284 | case TTM_PL_SYSTEM: | ||
285 | args->domain = RADEON_GEM_DOMAIN_CPU; | ||
286 | default: | ||
287 | break; | ||
288 | } | ||
289 | mutex_lock(&dev->struct_mutex); | ||
290 | drm_gem_object_unreference(gobj); | ||
291 | mutex_unlock(&dev->struct_mutex); | ||
292 | return r; | ||
267 | } | 293 | } |
268 | 294 | ||
269 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | 295 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 491d569deb0e..9805e4b6ca1b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -32,60 +32,6 @@ | |||
32 | #include "radeon.h" | 32 | #include "radeon.h" |
33 | #include "atom.h" | 33 | #include "atom.h" |
34 | 34 | ||
35 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | ||
36 | { | ||
37 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | ||
38 | uint32_t irq_mask = RADEON_SW_INT_TEST; | ||
39 | |||
40 | if (irqs) { | ||
41 | WREG32(RADEON_GEN_INT_STATUS, irqs); | ||
42 | } | ||
43 | return irqs & irq_mask; | ||
44 | } | ||
45 | |||
46 | int r100_irq_set(struct radeon_device *rdev) | ||
47 | { | ||
48 | uint32_t tmp = 0; | ||
49 | |||
50 | if (rdev->irq.sw_int) { | ||
51 | tmp |= RADEON_SW_INT_ENABLE; | ||
52 | } | ||
53 | /* Todo go through CRTC and enable vblank int or not */ | ||
54 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | int r100_irq_process(struct radeon_device *rdev) | ||
59 | { | ||
60 | uint32_t status; | ||
61 | |||
62 | status = r100_irq_ack(rdev); | ||
63 | if (!status) { | ||
64 | return IRQ_NONE; | ||
65 | } | ||
66 | while (status) { | ||
67 | /* SW interrupt */ | ||
68 | if (status & RADEON_SW_INT_TEST) { | ||
69 | radeon_fence_process(rdev); | ||
70 | } | ||
71 | status = r100_irq_ack(rdev); | ||
72 | } | ||
73 | return IRQ_HANDLED; | ||
74 | } | ||
75 | |||
76 | int rs600_irq_set(struct radeon_device *rdev) | ||
77 | { | ||
78 | uint32_t tmp = 0; | ||
79 | |||
80 | if (rdev->irq.sw_int) { | ||
81 | tmp |= RADEON_SW_INT_ENABLE; | ||
82 | } | ||
83 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
84 | /* Todo go through CRTC and enable vblank int or not */ | ||
85 | WREG32(R500_DxMODE_INT_MASK, 0); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | 35 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) |
90 | { | 36 | { |
91 | struct drm_device *dev = (struct drm_device *) arg; | 37 | struct drm_device *dev = (struct drm_device *) arg; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 3357110e30ce..dce09ada32bc 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -95,6 +95,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
95 | case RADEON_INFO_NUM_GB_PIPES: | 95 | case RADEON_INFO_NUM_GB_PIPES: |
96 | value = rdev->num_gb_pipes; | 96 | value = rdev->num_gb_pipes; |
97 | break; | 97 | break; |
98 | case RADEON_INFO_NUM_Z_PIPES: | ||
99 | value = rdev->num_z_pipes; | ||
100 | break; | ||
98 | default: | 101 | default: |
99 | DRM_DEBUG("Invalid request %d\n", info->request); | 102 | DRM_DEBUG("Invalid request %d\n", info->request); |
100 | return -EINVAL; | 103 | return -EINVAL; |
@@ -141,19 +144,42 @@ void radeon_driver_preclose_kms(struct drm_device *dev, | |||
141 | */ | 144 | */ |
142 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) | 145 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) |
143 | { | 146 | { |
144 | /* FIXME: implement */ | 147 | struct radeon_device *rdev = dev->dev_private; |
145 | return 0; | 148 | |
149 | if (crtc < 0 || crtc > 1) { | ||
150 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | |||
154 | return radeon_get_vblank_counter(rdev, crtc); | ||
146 | } | 155 | } |
147 | 156 | ||
148 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) | 157 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) |
149 | { | 158 | { |
150 | /* FIXME: implement */ | 159 | struct radeon_device *rdev = dev->dev_private; |
151 | return 0; | 160 | |
161 | if (crtc < 0 || crtc > 1) { | ||
162 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
163 | return -EINVAL; | ||
164 | } | ||
165 | |||
166 | rdev->irq.crtc_vblank_int[crtc] = true; | ||
167 | |||
168 | return radeon_irq_set(rdev); | ||
152 | } | 169 | } |
153 | 170 | ||
154 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) | 171 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) |
155 | { | 172 | { |
156 | /* FIXME: implement */ | 173 | struct radeon_device *rdev = dev->dev_private; |
174 | |||
175 | if (crtc < 0 || crtc > 1) { | ||
176 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | rdev->irq.crtc_vblank_int[crtc] = false; | ||
181 | |||
182 | radeon_irq_set(rdev); | ||
157 | } | 183 | } |
158 | 184 | ||
159 | 185 | ||
@@ -295,5 +321,6 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = { | |||
295 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), | 321 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), |
296 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH), | 322 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH), |
297 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH), | 323 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH), |
324 | DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH), | ||
298 | }; | 325 | }; |
299 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); | 326 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 7d06dc98a42a..0da72f18fd3a 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -310,10 +310,13 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
310 | RADEON_CRTC_DISP_REQ_EN_B)); | 310 | RADEON_CRTC_DISP_REQ_EN_B)); |
311 | WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); | 311 | WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); |
312 | } | 312 | } |
313 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | ||
314 | radeon_crtc_load_lut(crtc); | ||
313 | break; | 315 | break; |
314 | case DRM_MODE_DPMS_STANDBY: | 316 | case DRM_MODE_DPMS_STANDBY: |
315 | case DRM_MODE_DPMS_SUSPEND: | 317 | case DRM_MODE_DPMS_SUSPEND: |
316 | case DRM_MODE_DPMS_OFF: | 318 | case DRM_MODE_DPMS_OFF: |
319 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | ||
317 | if (radeon_crtc->crtc_id) | 320 | if (radeon_crtc->crtc_id) |
318 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); | 321 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); |
319 | else { | 322 | else { |
@@ -323,10 +326,6 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
323 | } | 326 | } |
324 | break; | 327 | break; |
325 | } | 328 | } |
326 | |||
327 | if (mode != DRM_MODE_DPMS_OFF) { | ||
328 | radeon_crtc_load_lut(crtc); | ||
329 | } | ||
330 | } | 329 | } |
331 | 330 | ||
332 | /* properly set crtc bpp when using atombios */ | 331 | /* properly set crtc bpp when using atombios */ |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 34d0f58eb944..9322675ef6d0 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -1066,6 +1066,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1066 | 1066 | ||
1067 | switch (radeon_encoder->encoder_id) { | 1067 | switch (radeon_encoder->encoder_id) { |
1068 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | 1068 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: |
1069 | encoder->possible_crtcs = 0x1; | ||
1069 | drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); | 1070 | drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); |
1070 | drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); | 1071 | drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); |
1071 | if (rdev->is_atom_bios) | 1072 | if (rdev->is_atom_bios) |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index e98cae3bf4a6..b85fb83d7ae8 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -316,6 +316,25 @@ int radeon_object_wait(struct radeon_object *robj) | |||
316 | return r; | 316 | return r; |
317 | } | 317 | } |
318 | 318 | ||
319 | int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement) | ||
320 | { | ||
321 | int r = 0; | ||
322 | |||
323 | r = radeon_object_reserve(robj, true); | ||
324 | if (unlikely(r != 0)) { | ||
325 | DRM_ERROR("radeon: failed to reserve object for waiting.\n"); | ||
326 | return r; | ||
327 | } | ||
328 | spin_lock(&robj->tobj.lock); | ||
329 | *cur_placement = robj->tobj.mem.mem_type; | ||
330 | if (robj->tobj.sync_obj) { | ||
331 | r = ttm_bo_wait(&robj->tobj, true, true, true); | ||
332 | } | ||
333 | spin_unlock(&robj->tobj.lock); | ||
334 | radeon_object_unreserve(robj); | ||
335 | return r; | ||
336 | } | ||
337 | |||
319 | int radeon_object_evict_vram(struct radeon_device *rdev) | 338 | int radeon_object_evict_vram(struct radeon_device *rdev) |
320 | { | 339 | { |
321 | if (rdev->flags & RADEON_IS_IGP) { | 340 | if (rdev->flags & RADEON_IS_IGP) { |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index e1b618574461..4df43f62c678 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -982,12 +982,15 @@ | |||
982 | # define RS400_TMDS2_PLLRST (1 << 1) | 982 | # define RS400_TMDS2_PLLRST (1 << 1) |
983 | 983 | ||
984 | #define RADEON_GEN_INT_CNTL 0x0040 | 984 | #define RADEON_GEN_INT_CNTL 0x0040 |
985 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | ||
986 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | ||
985 | # define RADEON_SW_INT_ENABLE (1 << 25) | 987 | # define RADEON_SW_INT_ENABLE (1 << 25) |
986 | #define RADEON_GEN_INT_STATUS 0x0044 | 988 | #define RADEON_GEN_INT_STATUS 0x0044 |
987 | # define RADEON_VSYNC_INT_AK (1 << 2) | 989 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) |
988 | # define RADEON_VSYNC_INT (1 << 2) | 990 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) |
989 | # define RADEON_VSYNC2_INT_AK (1 << 6) | 991 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) |
990 | # define RADEON_VSYNC2_INT (1 << 6) | 992 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) |
993 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) | ||
991 | # define RADEON_SW_INT_FIRE (1 << 26) | 994 | # define RADEON_SW_INT_FIRE (1 << 26) |
992 | # define RADEON_SW_INT_TEST (1 << 25) | 995 | # define RADEON_SW_INT_TEST (1 << 25) |
993 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 996 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
@@ -2334,6 +2337,9 @@ | |||
2334 | # define RADEON_RE_WIDTH_SHIFT 0 | 2337 | # define RADEON_RE_WIDTH_SHIFT 0 |
2335 | # define RADEON_RE_HEIGHT_SHIFT 16 | 2338 | # define RADEON_RE_HEIGHT_SHIFT 16 |
2336 | 2339 | ||
2340 | #define RADEON_RB3D_ZPASS_DATA 0x3290 | ||
2341 | #define RADEON_RB3D_ZPASS_ADDR 0x3294 | ||
2342 | |||
2337 | #define RADEON_SE_CNTL 0x1c4c | 2343 | #define RADEON_SE_CNTL 0x1c4c |
2338 | # define RADEON_FFACE_CULL_CW (0 << 0) | 2344 | # define RADEON_FFACE_CULL_CW (0 << 0) |
2339 | # define RADEON_FFACE_CULL_CCW (1 << 0) | 2345 | # define RADEON_FFACE_CULL_CCW (1 << 0) |
@@ -3568,4 +3574,6 @@ | |||
3568 | #define RADEON_SCRATCH_REG4 0x15f0 | 3574 | #define RADEON_SCRATCH_REG4 0x15f0 |
3569 | #define RADEON_SCRATCH_REG5 0x15f4 | 3575 | #define RADEON_SCRATCH_REG5 0x15f4 |
3570 | 3576 | ||
3577 | #define RV530_GB_PIPE_SELECT2 0x4124 | ||
3578 | |||
3571 | #endif | 3579 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 46645f3e0328..2882f40d5ec5 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -3081,6 +3081,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil | |||
3081 | case RADEON_PARAM_NUM_GB_PIPES: | 3081 | case RADEON_PARAM_NUM_GB_PIPES: |
3082 | value = dev_priv->num_gb_pipes; | 3082 | value = dev_priv->num_gb_pipes; |
3083 | break; | 3083 | break; |
3084 | case RADEON_PARAM_NUM_Z_PIPES: | ||
3085 | value = dev_priv->num_z_pipes; | ||
3086 | break; | ||
3084 | default: | 3087 | default: |
3085 | DRM_DEBUG("Invalid parameter %d\n", param->param); | 3088 | DRM_DEBUG("Invalid parameter %d\n", param->param); |
3086 | return -EINVAL; | 3089 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index bbea6dee4a94..7e8ce983a908 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -240,6 +240,88 @@ void rs600_mc_fini(struct radeon_device *rdev) | |||
240 | 240 | ||
241 | 241 | ||
242 | /* | 242 | /* |
243 | * Interrupts | ||
244 | */ | ||
245 | int rs600_irq_set(struct radeon_device *rdev) | ||
246 | { | ||
247 | uint32_t tmp = 0; | ||
248 | uint32_t mode_int = 0; | ||
249 | |||
250 | if (rdev->irq.sw_int) { | ||
251 | tmp |= RADEON_SW_INT_ENABLE; | ||
252 | } | ||
253 | if (rdev->irq.crtc_vblank_int[0]) { | ||
254 | tmp |= AVIVO_DISPLAY_INT_STATUS; | ||
255 | mode_int |= AVIVO_D1MODE_INT_MASK; | ||
256 | } | ||
257 | if (rdev->irq.crtc_vblank_int[1]) { | ||
258 | tmp |= AVIVO_DISPLAY_INT_STATUS; | ||
259 | mode_int |= AVIVO_D2MODE_INT_MASK; | ||
260 | } | ||
261 | WREG32(RADEON_GEN_INT_CNTL, tmp); | ||
262 | WREG32(AVIVO_DxMODE_INT_MASK, mode_int); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) | ||
267 | { | ||
268 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | ||
269 | uint32_t irq_mask = RADEON_SW_INT_TEST; | ||
270 | |||
271 | if (irqs & AVIVO_DISPLAY_INT_STATUS) { | ||
272 | *r500_disp_int = RREG32(AVIVO_DISP_INTERRUPT_STATUS); | ||
273 | if (*r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) { | ||
274 | WREG32(AVIVO_D1MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK); | ||
275 | } | ||
276 | if (*r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) { | ||
277 | WREG32(AVIVO_D2MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK); | ||
278 | } | ||
279 | } else { | ||
280 | *r500_disp_int = 0; | ||
281 | } | ||
282 | |||
283 | if (irqs) { | ||
284 | WREG32(RADEON_GEN_INT_STATUS, irqs); | ||
285 | } | ||
286 | return irqs & irq_mask; | ||
287 | } | ||
288 | |||
289 | int rs600_irq_process(struct radeon_device *rdev) | ||
290 | { | ||
291 | uint32_t status; | ||
292 | uint32_t r500_disp_int; | ||
293 | |||
294 | status = rs600_irq_ack(rdev, &r500_disp_int); | ||
295 | if (!status && !r500_disp_int) { | ||
296 | return IRQ_NONE; | ||
297 | } | ||
298 | while (status || r500_disp_int) { | ||
299 | /* SW interrupt */ | ||
300 | if (status & RADEON_SW_INT_TEST) { | ||
301 | radeon_fence_process(rdev); | ||
302 | } | ||
303 | /* Vertical blank interrupts */ | ||
304 | if (r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) { | ||
305 | drm_handle_vblank(rdev->ddev, 0); | ||
306 | } | ||
307 | if (r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) { | ||
308 | drm_handle_vblank(rdev->ddev, 1); | ||
309 | } | ||
310 | status = rs600_irq_ack(rdev, &r500_disp_int); | ||
311 | } | ||
312 | return IRQ_HANDLED; | ||
313 | } | ||
314 | |||
315 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc) | ||
316 | { | ||
317 | if (crtc == 0) | ||
318 | return RREG32(AVIVO_D1CRTC_FRAME_COUNT); | ||
319 | else | ||
320 | return RREG32(AVIVO_D2CRTC_FRAME_COUNT); | ||
321 | } | ||
322 | |||
323 | |||
324 | /* | ||
243 | * Global GPU functions | 325 | * Global GPU functions |
244 | */ | 326 | */ |
245 | void rs600_disable_vga(struct radeon_device *rdev) | 327 | void rs600_disable_vga(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 839595b00728..bc6b7c5339bc 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -652,3 +652,68 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
652 | WREG32(RS690_MC_DATA, v); | 652 | WREG32(RS690_MC_DATA, v); |
653 | WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); | 653 | WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); |
654 | } | 654 | } |
655 | |||
656 | static const unsigned rs690_reg_safe_bm[219] = { | ||
657 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
658 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
659 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
660 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
661 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
662 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
663 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
664 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
665 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
666 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
667 | 0x17FF1FFF,0xFFFFFFFC,0xFFFFFFFF,0xFF30FFBF, | ||
668 | 0xFFFFFFF8,0xC3E6FFFF,0xFFFFF6DF,0xFFFFFFFF, | ||
669 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
670 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
671 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFF03F, | ||
672 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
673 | 0xFFFFFFFF,0xFFFFEFCE,0xF00EBFFF,0x007C0000, | ||
674 | 0xF0000078,0xFF000009,0xFFFFFFFF,0xFFFFFFFF, | ||
675 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
676 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
677 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
678 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
679 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
680 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
681 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
682 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
683 | 0xFFFFF7FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
684 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
685 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
686 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
687 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
688 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
689 | 0xFFFFFC78,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF, | ||
690 | 0x38FF8F50,0xFFF88082,0xF000000C,0xFAE009FF, | ||
691 | 0x0000FFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000, | ||
692 | 0x00000000,0x0000C100,0x00000000,0x00000000, | ||
693 | 0x00000000,0x00000000,0x00000000,0x00000000, | ||
694 | 0x00000000,0xFFFF0000,0xFFFFFFFF,0xFF80FFFF, | ||
695 | 0x00000000,0x00000000,0x00000000,0x00000000, | ||
696 | 0x0003FC01,0xFFFFFFF8,0xFE800B19,0xFFFFFFFF, | ||
697 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
698 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
699 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
700 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
701 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
702 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
703 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
704 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
705 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
706 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
707 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
708 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
709 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
710 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
711 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
712 | }; | ||
713 | |||
714 | int rs690_init(struct radeon_device *rdev) | ||
715 | { | ||
716 | rdev->config.r300.reg_safe_bm = rs690_reg_safe_bm; | ||
717 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs690_reg_safe_bm); | ||
718 | return 0; | ||
719 | } | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index fd8f3ca716ea..31a7f668ae5a 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -400,25 +400,6 @@ void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
400 | WREG32(MC_IND_INDEX, 0); | 400 | WREG32(MC_IND_INDEX, 0); |
401 | } | 401 | } |
402 | 402 | ||
403 | uint32_t rv515_pcie_rreg(struct radeon_device *rdev, uint32_t reg) | ||
404 | { | ||
405 | uint32_t r; | ||
406 | |||
407 | WREG32(PCIE_INDEX, ((reg) & 0x7ff)); | ||
408 | (void)RREG32(PCIE_INDEX); | ||
409 | r = RREG32(PCIE_DATA); | ||
410 | return r; | ||
411 | } | ||
412 | |||
413 | void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | ||
414 | { | ||
415 | WREG32(PCIE_INDEX, ((reg) & 0x7ff)); | ||
416 | (void)RREG32(PCIE_INDEX); | ||
417 | WREG32(PCIE_DATA, (v)); | ||
418 | (void)RREG32(PCIE_DATA); | ||
419 | } | ||
420 | |||
421 | |||
422 | /* | 403 | /* |
423 | * Debugfs info | 404 | * Debugfs info |
424 | */ | 405 | */ |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index d258b02aef44..827da0858136 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -674,7 +674,14 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
674 | 674 | ||
675 | err = 0; | 675 | err = 0; |
676 | complete: | 676 | complete: |
677 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat); | 677 | /* |
678 | * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be | ||
679 | * acked after the data operation is complete. | ||
680 | * Ref: TRM SWPU114Q Figure 18-31 | ||
681 | */ | ||
682 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat & | ||
683 | ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | | ||
684 | OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); | ||
678 | 685 | ||
679 | if (stat & OMAP_I2C_STAT_NACK) { | 686 | if (stat & OMAP_I2C_STAT_NACK) { |
680 | err |= OMAP_I2C_STAT_NACK; | 687 | err |= OMAP_I2C_STAT_NACK; |
@@ -687,6 +694,9 @@ complete: | |||
687 | } | 694 | } |
688 | if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | | 695 | if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | |
689 | OMAP_I2C_STAT_AL)) { | 696 | OMAP_I2C_STAT_AL)) { |
697 | omap_i2c_ack_stat(dev, stat & | ||
698 | (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | | ||
699 | OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); | ||
690 | omap_i2c_complete_cmd(dev, err); | 700 | omap_i2c_complete_cmd(dev, err); |
691 | return IRQ_HANDLED; | 701 | return IRQ_HANDLED; |
692 | } | 702 | } |
@@ -774,7 +784,7 @@ complete: | |||
774 | * memory to the I2C interface. | 784 | * memory to the I2C interface. |
775 | */ | 785 | */ |
776 | 786 | ||
777 | if (cpu_is_omap34xx()) { | 787 | if (dev->rev <= OMAP_I2C_REV_ON_3430) { |
778 | while (!(stat & OMAP_I2C_STAT_XUDF)) { | 788 | while (!(stat & OMAP_I2C_STAT_XUDF)) { |
779 | if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { | 789 | if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { |
780 | omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); | 790 | omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); |
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 182e711318ba..d2728a28a8db 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c | |||
@@ -117,7 +117,8 @@ enum stu300_error { | |||
117 | STU300_ERROR_NONE = 0, | 117 | STU300_ERROR_NONE = 0, |
118 | STU300_ERROR_ACKNOWLEDGE_FAILURE, | 118 | STU300_ERROR_ACKNOWLEDGE_FAILURE, |
119 | STU300_ERROR_BUS_ERROR, | 119 | STU300_ERROR_BUS_ERROR, |
120 | STU300_ERROR_ARBITRATION_LOST | 120 | STU300_ERROR_ARBITRATION_LOST, |
121 | STU300_ERROR_UNKNOWN | ||
121 | }; | 122 | }; |
122 | 123 | ||
123 | /* timeout waiting for the controller to respond */ | 124 | /* timeout waiting for the controller to respond */ |
@@ -127,7 +128,7 @@ enum stu300_error { | |||
127 | * The number of address send athemps tried before giving up. | 128 | * The number of address send athemps tried before giving up. |
128 | * If the first one failes it seems like 5 to 8 attempts are required. | 129 | * If the first one failes it seems like 5 to 8 attempts are required. |
129 | */ | 130 | */ |
130 | #define NUM_ADDR_RESEND_ATTEMPTS 10 | 131 | #define NUM_ADDR_RESEND_ATTEMPTS 12 |
131 | 132 | ||
132 | /* I2C clock speed, in Hz 0-400kHz*/ | 133 | /* I2C clock speed, in Hz 0-400kHz*/ |
133 | static unsigned int scl_frequency = 100000; | 134 | static unsigned int scl_frequency = 100000; |
@@ -149,6 +150,7 @@ module_param(scl_frequency, uint, 0644); | |||
149 | * @msg_index: index of current message | 150 | * @msg_index: index of current message |
150 | * @msg_len: length of current message | 151 | * @msg_len: length of current message |
151 | */ | 152 | */ |
153 | |||
152 | struct stu300_dev { | 154 | struct stu300_dev { |
153 | struct platform_device *pdev; | 155 | struct platform_device *pdev; |
154 | struct i2c_adapter adapter; | 156 | struct i2c_adapter adapter; |
@@ -188,6 +190,27 @@ static inline u32 stu300_r8(void __iomem *address) | |||
188 | return readl(address) & 0x000000FFU; | 190 | return readl(address) & 0x000000FFU; |
189 | } | 191 | } |
190 | 192 | ||
193 | static void stu300_irq_enable(struct stu300_dev *dev) | ||
194 | { | ||
195 | u32 val; | ||
196 | val = stu300_r8(dev->virtbase + I2C_CR); | ||
197 | val |= I2C_CR_INTERRUPT_ENABLE; | ||
198 | /* Twice paranoia (possible HW glitch) */ | ||
199 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
200 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
201 | } | ||
202 | |||
203 | static void stu300_irq_disable(struct stu300_dev *dev) | ||
204 | { | ||
205 | u32 val; | ||
206 | val = stu300_r8(dev->virtbase + I2C_CR); | ||
207 | val &= ~I2C_CR_INTERRUPT_ENABLE; | ||
208 | /* Twice paranoia (possible HW glitch) */ | ||
209 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
210 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
211 | } | ||
212 | |||
213 | |||
191 | /* | 214 | /* |
192 | * Tells whether a certain event or events occurred in | 215 | * Tells whether a certain event or events occurred in |
193 | * response to a command. The events represent states in | 216 | * response to a command. The events represent states in |
@@ -196,9 +219,10 @@ static inline u32 stu300_r8(void __iomem *address) | |||
196 | * documentation and can only be treated as abstract state | 219 | * documentation and can only be treated as abstract state |
197 | * machine states. | 220 | * machine states. |
198 | * | 221 | * |
199 | * @ret 0 = event has not occurred, any other value means | 222 | * @ret 0 = event has not occurred or unknown error, any |
200 | * the event occurred. | 223 | * other value means the correct event occurred or an error. |
201 | */ | 224 | */ |
225 | |||
202 | static int stu300_event_occurred(struct stu300_dev *dev, | 226 | static int stu300_event_occurred(struct stu300_dev *dev, |
203 | enum stu300_event mr_event) { | 227 | enum stu300_event mr_event) { |
204 | u32 status1; | 228 | u32 status1; |
@@ -206,11 +230,28 @@ static int stu300_event_occurred(struct stu300_dev *dev, | |||
206 | 230 | ||
207 | /* What event happened? */ | 231 | /* What event happened? */ |
208 | status1 = stu300_r8(dev->virtbase + I2C_SR1); | 232 | status1 = stu300_r8(dev->virtbase + I2C_SR1); |
233 | |||
209 | if (!(status1 & I2C_SR1_EVF_IND)) | 234 | if (!(status1 & I2C_SR1_EVF_IND)) |
210 | /* No event at all */ | 235 | /* No event at all */ |
211 | return 0; | 236 | return 0; |
237 | |||
212 | status2 = stu300_r8(dev->virtbase + I2C_SR2); | 238 | status2 = stu300_r8(dev->virtbase + I2C_SR2); |
213 | 239 | ||
240 | /* Block any multiple interrupts */ | ||
241 | stu300_irq_disable(dev); | ||
242 | |||
243 | /* Check for errors first */ | ||
244 | if (status2 & I2C_SR2_AF_IND) { | ||
245 | dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE; | ||
246 | return 1; | ||
247 | } else if (status2 & I2C_SR2_BERR_IND) { | ||
248 | dev->cmd_err = STU300_ERROR_BUS_ERROR; | ||
249 | return 1; | ||
250 | } else if (status2 & I2C_SR2_ARLO_IND) { | ||
251 | dev->cmd_err = STU300_ERROR_ARBITRATION_LOST; | ||
252 | return 1; | ||
253 | } | ||
254 | |||
214 | switch (mr_event) { | 255 | switch (mr_event) { |
215 | case STU300_EVENT_1: | 256 | case STU300_EVENT_1: |
216 | if (status1 & I2C_SR1_ADSL_IND) | 257 | if (status1 & I2C_SR1_ADSL_IND) |
@@ -221,10 +262,6 @@ static int stu300_event_occurred(struct stu300_dev *dev, | |||
221 | case STU300_EVENT_7: | 262 | case STU300_EVENT_7: |
222 | case STU300_EVENT_8: | 263 | case STU300_EVENT_8: |
223 | if (status1 & I2C_SR1_BTF_IND) { | 264 | if (status1 & I2C_SR1_BTF_IND) { |
224 | if (status2 & I2C_SR2_AF_IND) | ||
225 | dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE; | ||
226 | else if (status2 & I2C_SR2_BERR_IND) | ||
227 | dev->cmd_err = STU300_ERROR_BUS_ERROR; | ||
228 | return 1; | 265 | return 1; |
229 | } | 266 | } |
230 | break; | 267 | break; |
@@ -240,8 +277,6 @@ static int stu300_event_occurred(struct stu300_dev *dev, | |||
240 | case STU300_EVENT_6: | 277 | case STU300_EVENT_6: |
241 | if (status2 & I2C_SR2_ENDAD_IND) { | 278 | if (status2 & I2C_SR2_ENDAD_IND) { |
242 | /* First check for any errors */ | 279 | /* First check for any errors */ |
243 | if (status2 & I2C_SR2_AF_IND) | ||
244 | dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE; | ||
245 | return 1; | 280 | return 1; |
246 | } | 281 | } |
247 | break; | 282 | break; |
@@ -252,8 +287,15 @@ static int stu300_event_occurred(struct stu300_dev *dev, | |||
252 | default: | 287 | default: |
253 | break; | 288 | break; |
254 | } | 289 | } |
255 | if (status2 & I2C_SR2_ARLO_IND) | 290 | /* If we get here, we're on thin ice. |
256 | dev->cmd_err = STU300_ERROR_ARBITRATION_LOST; | 291 | * Here we are in a status where we have |
292 | * gotten a response that does not match | ||
293 | * what we requested. | ||
294 | */ | ||
295 | dev->cmd_err = STU300_ERROR_UNKNOWN; | ||
296 | dev_err(&dev->pdev->dev, | ||
297 | "Unhandled interrupt! %d sr1: 0x%x sr2: 0x%x\n", | ||
298 | mr_event, status1, status2); | ||
257 | return 0; | 299 | return 0; |
258 | } | 300 | } |
259 | 301 | ||
@@ -262,21 +304,20 @@ static irqreturn_t stu300_irh(int irq, void *data) | |||
262 | struct stu300_dev *dev = data; | 304 | struct stu300_dev *dev = data; |
263 | int res; | 305 | int res; |
264 | 306 | ||
307 | /* Just make sure that the block is clocked */ | ||
308 | clk_enable(dev->clk); | ||
309 | |||
265 | /* See if this was what we were waiting for */ | 310 | /* See if this was what we were waiting for */ |
266 | spin_lock(&dev->cmd_issue_lock); | 311 | spin_lock(&dev->cmd_issue_lock); |
267 | if (dev->cmd_event != STU300_EVENT_NONE) { | 312 | |
268 | res = stu300_event_occurred(dev, dev->cmd_event); | 313 | res = stu300_event_occurred(dev, dev->cmd_event); |
269 | if (res || dev->cmd_err != STU300_ERROR_NONE) { | 314 | if (res || dev->cmd_err != STU300_ERROR_NONE) |
270 | u32 val; | 315 | complete(&dev->cmd_complete); |
271 | 316 | ||
272 | complete(&dev->cmd_complete); | ||
273 | /* Block any multiple interrupts */ | ||
274 | val = stu300_r8(dev->virtbase + I2C_CR); | ||
275 | val &= ~I2C_CR_INTERRUPT_ENABLE; | ||
276 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
277 | } | ||
278 | } | ||
279 | spin_unlock(&dev->cmd_issue_lock); | 317 | spin_unlock(&dev->cmd_issue_lock); |
318 | |||
319 | clk_disable(dev->clk); | ||
320 | |||
280 | return IRQ_HANDLED; | 321 | return IRQ_HANDLED; |
281 | } | 322 | } |
282 | 323 | ||
@@ -308,7 +349,6 @@ static int stu300_start_and_await_event(struct stu300_dev *dev, | |||
308 | stu300_wr8(cr_value, dev->virtbase + I2C_CR); | 349 | stu300_wr8(cr_value, dev->virtbase + I2C_CR); |
309 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, | 350 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, |
310 | STU300_TIMEOUT); | 351 | STU300_TIMEOUT); |
311 | |||
312 | if (ret < 0) { | 352 | if (ret < 0) { |
313 | dev_err(&dev->pdev->dev, | 353 | dev_err(&dev->pdev->dev, |
314 | "wait_for_completion_interruptible_timeout() " | 354 | "wait_for_completion_interruptible_timeout() " |
@@ -342,7 +382,6 @@ static int stu300_await_event(struct stu300_dev *dev, | |||
342 | enum stu300_event mr_event) | 382 | enum stu300_event mr_event) |
343 | { | 383 | { |
344 | int ret; | 384 | int ret; |
345 | u32 val; | ||
346 | 385 | ||
347 | if (unlikely(irqs_disabled())) { | 386 | if (unlikely(irqs_disabled())) { |
348 | /* TODO: implement polling for this case if need be. */ | 387 | /* TODO: implement polling for this case if need be. */ |
@@ -354,36 +393,18 @@ static int stu300_await_event(struct stu300_dev *dev, | |||
354 | /* Is it already here? */ | 393 | /* Is it already here? */ |
355 | spin_lock_irq(&dev->cmd_issue_lock); | 394 | spin_lock_irq(&dev->cmd_issue_lock); |
356 | dev->cmd_err = STU300_ERROR_NONE; | 395 | dev->cmd_err = STU300_ERROR_NONE; |
357 | if (stu300_event_occurred(dev, mr_event)) { | ||
358 | spin_unlock_irq(&dev->cmd_issue_lock); | ||
359 | goto exit_await_check_err; | ||
360 | } | ||
361 | init_completion(&dev->cmd_complete); | ||
362 | dev->cmd_err = STU300_ERROR_NONE; | ||
363 | dev->cmd_event = mr_event; | 396 | dev->cmd_event = mr_event; |
364 | 397 | ||
365 | /* Turn on the I2C interrupt for current operation */ | 398 | init_completion(&dev->cmd_complete); |
366 | val = stu300_r8(dev->virtbase + I2C_CR); | ||
367 | val |= I2C_CR_INTERRUPT_ENABLE; | ||
368 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
369 | |||
370 | /* Twice paranoia (possible HW glitch) */ | ||
371 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
372 | 399 | ||
373 | /* Check again: is it already here? */ | 400 | /* Turn on the I2C interrupt for current operation */ |
374 | if (unlikely(stu300_event_occurred(dev, mr_event))) { | 401 | stu300_irq_enable(dev); |
375 | /* Disable IRQ again. */ | ||
376 | val &= ~I2C_CR_INTERRUPT_ENABLE; | ||
377 | stu300_wr8(val, dev->virtbase + I2C_CR); | ||
378 | spin_unlock_irq(&dev->cmd_issue_lock); | ||
379 | goto exit_await_check_err; | ||
380 | } | ||
381 | 402 | ||
382 | /* Unlock the command block and wait for the event to occur */ | 403 | /* Unlock the command block and wait for the event to occur */ |
383 | spin_unlock_irq(&dev->cmd_issue_lock); | 404 | spin_unlock_irq(&dev->cmd_issue_lock); |
405 | |||
384 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, | 406 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, |
385 | STU300_TIMEOUT); | 407 | STU300_TIMEOUT); |
386 | |||
387 | if (ret < 0) { | 408 | if (ret < 0) { |
388 | dev_err(&dev->pdev->dev, | 409 | dev_err(&dev->pdev->dev, |
389 | "wait_for_completion_interruptible_timeout()" | 410 | "wait_for_completion_interruptible_timeout()" |
@@ -401,7 +422,6 @@ static int stu300_await_event(struct stu300_dev *dev, | |||
401 | return -ETIMEDOUT; | 422 | return -ETIMEDOUT; |
402 | } | 423 | } |
403 | 424 | ||
404 | exit_await_check_err: | ||
405 | if (dev->cmd_err != STU300_ERROR_NONE) { | 425 | if (dev->cmd_err != STU300_ERROR_NONE) { |
406 | if (mr_event != STU300_EVENT_6) { | 426 | if (mr_event != STU300_EVENT_6) { |
407 | dev_err(&dev->pdev->dev, "controller " | 427 | dev_err(&dev->pdev->dev, "controller " |
@@ -457,18 +477,19 @@ struct stu300_clkset { | |||
457 | }; | 477 | }; |
458 | 478 | ||
459 | static const struct stu300_clkset stu300_clktable[] = { | 479 | static const struct stu300_clkset stu300_clktable[] = { |
460 | { 0, 0xFFU }, | 480 | { 0, 0xFFU }, |
461 | { 2500000, I2C_OAR2_FR_25_10MHZ }, | 481 | { 2500000, I2C_OAR2_FR_25_10MHZ }, |
462 | { 10000000, I2C_OAR2_FR_10_1667MHZ }, | 482 | { 10000000, I2C_OAR2_FR_10_1667MHZ }, |
463 | { 16670000, I2C_OAR2_FR_1667_2667MHZ }, | 483 | { 16670000, I2C_OAR2_FR_1667_2667MHZ }, |
464 | { 26670000, I2C_OAR2_FR_2667_40MHZ }, | 484 | { 26670000, I2C_OAR2_FR_2667_40MHZ }, |
465 | { 40000000, I2C_OAR2_FR_40_5333MHZ }, | 485 | { 40000000, I2C_OAR2_FR_40_5333MHZ }, |
466 | { 53330000, I2C_OAR2_FR_5333_66MHZ }, | 486 | { 53330000, I2C_OAR2_FR_5333_66MHZ }, |
467 | { 66000000, I2C_OAR2_FR_66_80MHZ }, | 487 | { 66000000, I2C_OAR2_FR_66_80MHZ }, |
468 | { 80000000, I2C_OAR2_FR_80_100MHZ }, | 488 | { 80000000, I2C_OAR2_FR_80_100MHZ }, |
469 | { 100000000, 0xFFU }, | 489 | { 100000000, 0xFFU }, |
470 | }; | 490 | }; |
471 | 491 | ||
492 | |||
472 | static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate) | 493 | static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate) |
473 | { | 494 | { |
474 | 495 | ||
@@ -494,10 +515,10 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate) | |||
494 | 515 | ||
495 | if (dev->speed > 100000) | 516 | if (dev->speed > 100000) |
496 | /* Fast Mode I2C */ | 517 | /* Fast Mode I2C */ |
497 | val = ((clkrate/dev->speed)-9)/3; | 518 | val = ((clkrate/dev->speed) - 9)/3 + 1; |
498 | else | 519 | else |
499 | /* Standard Mode I2C */ | 520 | /* Standard Mode I2C */ |
500 | val = ((clkrate/dev->speed)-7)/2; | 521 | val = ((clkrate/dev->speed) - 7)/2 + 1; |
501 | 522 | ||
502 | /* According to spec the divider must be > 2 */ | 523 | /* According to spec the divider must be > 2 */ |
503 | if (val < 0x002) { | 524 | if (val < 0x002) { |
@@ -557,6 +578,7 @@ static int stu300_init_hw(struct stu300_dev *dev) | |||
557 | */ | 578 | */ |
558 | clkrate = clk_get_rate(dev->clk); | 579 | clkrate = clk_get_rate(dev->clk); |
559 | ret = stu300_set_clk(dev, clkrate); | 580 | ret = stu300_set_clk(dev, clkrate); |
581 | |||
560 | if (ret) | 582 | if (ret) |
561 | return ret; | 583 | return ret; |
562 | /* | 584 | /* |
@@ -641,7 +663,6 @@ static int stu300_xfer_msg(struct i2c_adapter *adap, | |||
641 | int attempts = 0; | 663 | int attempts = 0; |
642 | struct stu300_dev *dev = i2c_get_adapdata(adap); | 664 | struct stu300_dev *dev = i2c_get_adapdata(adap); |
643 | 665 | ||
644 | |||
645 | clk_enable(dev->clk); | 666 | clk_enable(dev->clk); |
646 | 667 | ||
647 | /* Remove this if (0) to trace each and every message. */ | 668 | /* Remove this if (0) to trace each and every message. */ |
@@ -715,14 +736,15 @@ static int stu300_xfer_msg(struct i2c_adapter *adap, | |||
715 | 736 | ||
716 | if (attempts < NUM_ADDR_RESEND_ATTEMPTS && attempts > 0) { | 737 | if (attempts < NUM_ADDR_RESEND_ATTEMPTS && attempts > 0) { |
717 | dev_dbg(&dev->pdev->dev, "managed to get address " | 738 | dev_dbg(&dev->pdev->dev, "managed to get address " |
718 | "through after %d attempts\n", attempts); | 739 | "through after %d attempts\n", attempts); |
719 | } else if (attempts == NUM_ADDR_RESEND_ATTEMPTS) { | 740 | } else if (attempts == NUM_ADDR_RESEND_ATTEMPTS) { |
720 | dev_dbg(&dev->pdev->dev, "I give up, tried %d times " | 741 | dev_dbg(&dev->pdev->dev, "I give up, tried %d times " |
721 | "to resend address.\n", | 742 | "to resend address.\n", |
722 | NUM_ADDR_RESEND_ATTEMPTS); | 743 | NUM_ADDR_RESEND_ATTEMPTS); |
723 | goto exit_disable; | 744 | goto exit_disable; |
724 | } | 745 | } |
725 | 746 | ||
747 | |||
726 | if (msg->flags & I2C_M_RD) { | 748 | if (msg->flags & I2C_M_RD) { |
727 | /* READ: we read the actual bytes one at a time */ | 749 | /* READ: we read the actual bytes one at a time */ |
728 | for (i = 0; i < msg->len; i++) { | 750 | for (i = 0; i < msg->len; i++) { |
@@ -804,8 +826,10 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, | |||
804 | { | 826 | { |
805 | int ret = -1; | 827 | int ret = -1; |
806 | int i; | 828 | int i; |
829 | |||
807 | struct stu300_dev *dev = i2c_get_adapdata(adap); | 830 | struct stu300_dev *dev = i2c_get_adapdata(adap); |
808 | dev->msg_len = num; | 831 | dev->msg_len = num; |
832 | |||
809 | for (i = 0; i < num; i++) { | 833 | for (i = 0; i < num; i++) { |
810 | /* | 834 | /* |
811 | * Another driver appears to send stop for each message, | 835 | * Another driver appears to send stop for each message, |
@@ -817,6 +841,7 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, | |||
817 | dev->msg_index = i; | 841 | dev->msg_index = i; |
818 | 842 | ||
819 | ret = stu300_xfer_msg(adap, &msgs[i], (i == (num - 1))); | 843 | ret = stu300_xfer_msg(adap, &msgs[i], (i == (num - 1))); |
844 | |||
820 | if (ret != 0) { | 845 | if (ret != 0) { |
821 | num = ret; | 846 | num = ret; |
822 | break; | 847 | break; |
@@ -845,6 +870,7 @@ stu300_probe(struct platform_device *pdev) | |||
845 | struct resource *res; | 870 | struct resource *res; |
846 | int bus_nr; | 871 | int bus_nr; |
847 | int ret = 0; | 872 | int ret = 0; |
873 | char clk_name[] = "I2C0"; | ||
848 | 874 | ||
849 | dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL); | 875 | dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL); |
850 | if (!dev) { | 876 | if (!dev) { |
@@ -854,7 +880,8 @@ stu300_probe(struct platform_device *pdev) | |||
854 | } | 880 | } |
855 | 881 | ||
856 | bus_nr = pdev->id; | 882 | bus_nr = pdev->id; |
857 | dev->clk = clk_get(&pdev->dev, NULL); | 883 | clk_name[3] += (char)bus_nr; |
884 | dev->clk = clk_get(&pdev->dev, clk_name); | ||
858 | if (IS_ERR(dev->clk)) { | 885 | if (IS_ERR(dev->clk)) { |
859 | ret = PTR_ERR(dev->clk); | 886 | ret = PTR_ERR(dev->clk); |
860 | dev_err(&pdev->dev, "could not retrieve i2c bus clock\n"); | 887 | dev_err(&pdev->dev, "could not retrieve i2c bus clock\n"); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 4cfd084fa897..9a1d55b74d7a 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -456,8 +456,11 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
456 | unsigned int cmd, void __user *argp) | 456 | unsigned int cmd, void __user *argp) |
457 | { | 457 | { |
458 | struct input_dev *dev = joydev->handle.dev; | 458 | struct input_dev *dev = joydev->handle.dev; |
459 | size_t len; | ||
459 | int i, j; | 460 | int i, j; |
461 | const char *name; | ||
460 | 462 | ||
463 | /* Process fixed-sized commands. */ | ||
461 | switch (cmd) { | 464 | switch (cmd) { |
462 | 465 | ||
463 | case JS_SET_CAL: | 466 | case JS_SET_CAL: |
@@ -499,9 +502,22 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
499 | return copy_to_user(argp, joydev->corr, | 502 | return copy_to_user(argp, joydev->corr, |
500 | sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; | 503 | sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; |
501 | 504 | ||
502 | case JSIOCSAXMAP: | 505 | } |
503 | if (copy_from_user(joydev->abspam, argp, | 506 | |
504 | sizeof(__u8) * (ABS_MAX + 1))) | 507 | /* |
508 | * Process variable-sized commands (the axis and button map commands | ||
509 | * are considered variable-sized to decouple them from the values of | ||
510 | * ABS_MAX and KEY_MAX). | ||
511 | */ | ||
512 | switch (cmd & ~IOCSIZE_MASK) { | ||
513 | |||
514 | case (JSIOCSAXMAP & ~IOCSIZE_MASK): | ||
515 | len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam)); | ||
516 | /* | ||
517 | * FIXME: we should not copy into our axis map before | ||
518 | * validating the data. | ||
519 | */ | ||
520 | if (copy_from_user(joydev->abspam, argp, len)) | ||
505 | return -EFAULT; | 521 | return -EFAULT; |
506 | 522 | ||
507 | for (i = 0; i < joydev->nabs; i++) { | 523 | for (i = 0; i < joydev->nabs; i++) { |
@@ -511,13 +527,17 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
511 | } | 527 | } |
512 | return 0; | 528 | return 0; |
513 | 529 | ||
514 | case JSIOCGAXMAP: | 530 | case (JSIOCGAXMAP & ~IOCSIZE_MASK): |
515 | return copy_to_user(argp, joydev->abspam, | 531 | len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam)); |
516 | sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0; | 532 | return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0; |
517 | 533 | ||
518 | case JSIOCSBTNMAP: | 534 | case (JSIOCSBTNMAP & ~IOCSIZE_MASK): |
519 | if (copy_from_user(joydev->keypam, argp, | 535 | len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam)); |
520 | sizeof(__u16) * (KEY_MAX - BTN_MISC + 1))) | 536 | /* |
537 | * FIXME: we should not copy into our keymap before | ||
538 | * validating the data. | ||
539 | */ | ||
540 | if (copy_from_user(joydev->keypam, argp, len)) | ||
521 | return -EFAULT; | 541 | return -EFAULT; |
522 | 542 | ||
523 | for (i = 0; i < joydev->nkey; i++) { | 543 | for (i = 0; i < joydev->nkey; i++) { |
@@ -529,25 +549,19 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
529 | 549 | ||
530 | return 0; | 550 | return 0; |
531 | 551 | ||
532 | case JSIOCGBTNMAP: | 552 | case (JSIOCGBTNMAP & ~IOCSIZE_MASK): |
533 | return copy_to_user(argp, joydev->keypam, | 553 | len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam)); |
534 | sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0; | 554 | return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0; |
535 | 555 | ||
536 | default: | 556 | case JSIOCGNAME(0): |
537 | if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { | 557 | name = dev->name; |
538 | int len; | 558 | if (!name) |
539 | const char *name = dev->name; | 559 | return 0; |
540 | 560 | ||
541 | if (!name) | 561 | len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1); |
542 | return 0; | 562 | return copy_to_user(argp, name, len) ? -EFAULT : len; |
543 | len = strlen(name) + 1; | ||
544 | if (len > _IOC_SIZE(cmd)) | ||
545 | len = _IOC_SIZE(cmd); | ||
546 | if (copy_to_user(argp, name, len)) | ||
547 | return -EFAULT; | ||
548 | return len; | ||
549 | } | ||
550 | } | 563 | } |
564 | |||
551 | return -EINVAL; | 565 | return -EINVAL; |
552 | } | 566 | } |
553 | 567 | ||
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index baabf8302645..f6c688cae334 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -74,6 +74,7 @@ static struct iforce_device iforce_device[] = { | |||
74 | { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_avb_wheel, abs_wheel, ff_iforce }, | 74 | { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_avb_wheel, abs_wheel, ff_iforce }, |
75 | { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, //? | 75 | { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, //? |
76 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? | 76 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? |
77 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, | ||
77 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 78 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? |
78 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 79 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? |
79 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 80 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index f83185aeb511..9f289d8f52c6 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
@@ -223,6 +223,7 @@ static struct usb_device_id iforce_usb_ids [] = { | |||
223 | { USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */ | 223 | { USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */ |
224 | { USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */ | 224 | { USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */ |
225 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ | 225 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ |
226 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ | ||
226 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ | 227 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ |
227 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ | 228 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ |
228 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ | 229 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index a9d5031b855e..ea30c983a33e 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -388,6 +388,32 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
388 | return result; | 388 | return result; |
389 | } | 389 | } |
390 | 390 | ||
391 | static int wacom_query_tablet_data(struct usb_interface *intf) | ||
392 | { | ||
393 | unsigned char *rep_data; | ||
394 | int limit = 0; | ||
395 | int error; | ||
396 | |||
397 | rep_data = kmalloc(2, GFP_KERNEL); | ||
398 | if (!rep_data) | ||
399 | return -ENOMEM; | ||
400 | |||
401 | do { | ||
402 | rep_data[0] = 2; | ||
403 | rep_data[1] = 2; | ||
404 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
405 | 2, rep_data, 2); | ||
406 | if (error >= 0) | ||
407 | error = usb_get_report(intf, | ||
408 | WAC_HID_FEATURE_REPORT, 2, | ||
409 | rep_data, 2); | ||
410 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | ||
411 | |||
412 | kfree(rep_data); | ||
413 | |||
414 | return error < 0 ? error : 0; | ||
415 | } | ||
416 | |||
391 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 417 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
392 | { | 418 | { |
393 | struct usb_device *dev = interface_to_usbdev(intf); | 419 | struct usb_device *dev = interface_to_usbdev(intf); |
@@ -398,7 +424,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
398 | struct wacom_features *features; | 424 | struct wacom_features *features; |
399 | struct input_dev *input_dev; | 425 | struct input_dev *input_dev; |
400 | int error = -ENOMEM; | 426 | int error = -ENOMEM; |
401 | char rep_data[2], limit = 0; | ||
402 | struct hid_descriptor *hid_desc; | 427 | struct hid_descriptor *hid_desc; |
403 | 428 | ||
404 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 429 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
@@ -489,20 +514,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
489 | 514 | ||
490 | /* | 515 | /* |
491 | * Ask the tablet to report tablet data if it is not a Tablet PC. | 516 | * Ask the tablet to report tablet data if it is not a Tablet PC. |
492 | * Repeat until it succeeds | 517 | * Note that if query fails it is not a hard failure. |
493 | */ | 518 | */ |
494 | if (wacom_wac->features->type != TABLETPC) { | 519 | if (wacom_wac->features->type != TABLETPC) |
495 | do { | 520 | wacom_query_tablet_data(intf); |
496 | rep_data[0] = 2; | ||
497 | rep_data[1] = 2; | ||
498 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
499 | 2, rep_data, 2); | ||
500 | if (error >= 0) | ||
501 | error = usb_get_report(intf, | ||
502 | WAC_HID_FEATURE_REPORT, 2, | ||
503 | rep_data, 2); | ||
504 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | ||
505 | } | ||
506 | 521 | ||
507 | usb_set_intfdata(intf, wacom); | 522 | usb_set_intfdata(intf, wacom); |
508 | return 0; | 523 | return 0; |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 6954f5500108..3a7a58222f83 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -170,11 +170,11 @@ static void ucb1400_handle_pending_irq(struct ucb1400_ts *ucb) | |||
170 | ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr); | 170 | ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr); |
171 | ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0); | 171 | ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0); |
172 | 172 | ||
173 | if (isr & UCB_IE_TSPX) { | 173 | if (isr & UCB_IE_TSPX) |
174 | ucb1400_ts_irq_disable(ucb->ac97); | 174 | ucb1400_ts_irq_disable(ucb->ac97); |
175 | enable_irq(ucb->irq); | 175 | else |
176 | } else | 176 | dev_dbg(&ucb->ts_idev->dev, "ucb1400: unexpected IE_STATUS = %#x\n", isr); |
177 | printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr); | 177 | enable_irq(ucb->irq); |
178 | } | 178 | } |
179 | 179 | ||
180 | static int ucb1400_ts_thread(void *_ucb) | 180 | static int ucb1400_ts_thread(void *_ucb) |
@@ -345,6 +345,7 @@ static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb) | |||
345 | static int ucb1400_ts_probe(struct platform_device *dev) | 345 | static int ucb1400_ts_probe(struct platform_device *dev) |
346 | { | 346 | { |
347 | int error, x_res, y_res; | 347 | int error, x_res, y_res; |
348 | u16 fcsr; | ||
348 | struct ucb1400_ts *ucb = dev->dev.platform_data; | 349 | struct ucb1400_ts *ucb = dev->dev.platform_data; |
349 | 350 | ||
350 | ucb->ts_idev = input_allocate_device(); | 351 | ucb->ts_idev = input_allocate_device(); |
@@ -382,6 +383,14 @@ static int ucb1400_ts_probe(struct platform_device *dev) | |||
382 | ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); | 383 | ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); |
383 | ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 384 | ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
384 | 385 | ||
386 | /* | ||
387 | * Enable ADC filter to prevent horrible jitter on Colibri. | ||
388 | * This also further reduces jitter on boards where ADCSYNC | ||
389 | * pin is connected. | ||
390 | */ | ||
391 | fcsr = ucb1400_reg_read(ucb->ac97, UCB_FCSR); | ||
392 | ucb1400_reg_write(ucb->ac97, UCB_FCSR, fcsr | UCB_FCSR_AVE); | ||
393 | |||
385 | ucb1400_adc_enable(ucb->ac97); | 394 | ucb1400_adc_enable(ucb->ac97); |
386 | x_res = ucb1400_ts_read_xres(ucb); | 395 | x_res = ucb1400_ts_read_xres(ucb); |
387 | y_res = ucb1400_ts_read_yres(ucb); | 396 | y_res = ucb1400_ts_read_yres(ucb); |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 7ad972229db4..0d9d4bc9c762 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
61 | buf64 = (uint64_t *)buf; | 61 | buf64 = (uint64_t *)buf; |
62 | while (i < len/8) { | 62 | while (i < len/8) { |
63 | uint64_t x; | 63 | uint64_t x; |
64 | asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); | 64 | asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base)); |
65 | buf64[i++] = x; | 65 | buf64[i++] = x; |
66 | } | 66 | } |
67 | i *= 8; | 67 | i *= 8; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5f6509a5f640..5ce7cbabd7a7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1727,12 +1727,14 @@ config KS8842 | |||
1727 | tristate "Micrel KSZ8842" | 1727 | tristate "Micrel KSZ8842" |
1728 | depends on HAS_IOMEM | 1728 | depends on HAS_IOMEM |
1729 | help | 1729 | help |
1730 | This platform driver is for Micrel KSZ8842 chip. | 1730 | This platform driver is for Micrel KSZ8842 / KS8842 |
1731 | 2-port ethernet switch chip (managed, VLAN, QoS). | ||
1731 | 1732 | ||
1732 | config KS8851 | 1733 | config KS8851 |
1733 | tristate "Micrel KS8851 SPI" | 1734 | tristate "Micrel KS8851 SPI" |
1734 | depends on SPI | 1735 | depends on SPI |
1735 | select MII | 1736 | select MII |
1737 | select CRC32 | ||
1736 | help | 1738 | help |
1737 | SPI driver for Micrel KS8851 SPI attached network chip. | 1739 | SPI driver for Micrel KS8851 SPI attached network chip. |
1738 | 1740 | ||
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c index 616fb7985a34..ddd231cb54b7 100644 --- a/drivers/net/arm/w90p910_ether.c +++ b/drivers/net/arm/w90p910_ether.c | |||
@@ -1080,7 +1080,7 @@ static struct platform_driver w90p910_ether_driver = { | |||
1080 | .probe = w90p910_ether_probe, | 1080 | .probe = w90p910_ether_probe, |
1081 | .remove = __devexit_p(w90p910_ether_remove), | 1081 | .remove = __devexit_p(w90p910_ether_remove), |
1082 | .driver = { | 1082 | .driver = { |
1083 | .name = "w90p910-emc", | 1083 | .name = "nuc900-emc", |
1084 | .owner = THIS_MODULE, | 1084 | .owner = THIS_MODULE, |
1085 | }, | 1085 | }, |
1086 | }; | 1086 | }; |
@@ -1101,5 +1101,5 @@ module_exit(w90p910_ether_exit); | |||
1101 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | 1101 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); |
1102 | MODULE_DESCRIPTION("w90p910 MAC driver!"); | 1102 | MODULE_DESCRIPTION("w90p910 MAC driver!"); |
1103 | MODULE_LICENSE("GPL"); | 1103 | MODULE_LICENSE("GPL"); |
1104 | MODULE_ALIAS("platform:w90p910-emc"); | 1104 | MODULE_ALIAS("platform:nuc900-emc"); |
1105 | 1105 | ||
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 41b648a67fec..3a6735dc9f6a 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -1899,7 +1899,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
1899 | nic->ru_running = RU_SUSPENDED; | 1899 | nic->ru_running = RU_SUSPENDED; |
1900 | pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, | 1900 | pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, |
1901 | sizeof(struct rfd), | 1901 | sizeof(struct rfd), |
1902 | PCI_DMA_BIDIRECTIONAL); | 1902 | PCI_DMA_FROMDEVICE); |
1903 | return -ENODATA; | 1903 | return -ENODATA; |
1904 | } | 1904 | } |
1905 | 1905 | ||
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index cc786333d95c..c40113f58963 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c | |||
@@ -309,6 +309,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
309 | { | 309 | { |
310 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); | 310 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); |
311 | struct bcom_fec_bd *bd; | 311 | struct bcom_fec_bd *bd; |
312 | unsigned long flags; | ||
312 | 313 | ||
313 | if (bcom_queue_full(priv->tx_dmatsk)) { | 314 | if (bcom_queue_full(priv->tx_dmatsk)) { |
314 | if (net_ratelimit()) | 315 | if (net_ratelimit()) |
@@ -316,7 +317,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
316 | return NETDEV_TX_BUSY; | 317 | return NETDEV_TX_BUSY; |
317 | } | 318 | } |
318 | 319 | ||
319 | spin_lock_irq(&priv->lock); | 320 | spin_lock_irqsave(&priv->lock, flags); |
320 | dev->trans_start = jiffies; | 321 | dev->trans_start = jiffies; |
321 | 322 | ||
322 | bd = (struct bcom_fec_bd *) | 323 | bd = (struct bcom_fec_bd *) |
@@ -332,7 +333,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
332 | netif_stop_queue(dev); | 333 | netif_stop_queue(dev); |
333 | } | 334 | } |
334 | 335 | ||
335 | spin_unlock_irq(&priv->lock); | 336 | spin_unlock_irqrestore(&priv->lock, flags); |
336 | 337 | ||
337 | return NETDEV_TX_OK; | 338 | return NETDEV_TX_OK; |
338 | } | 339 | } |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index beb84213b671..f0f890803710 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -1305,6 +1305,8 @@ static int emac_close(struct net_device *ndev) | |||
1305 | 1305 | ||
1306 | free_irq(dev->emac_irq, dev); | 1306 | free_irq(dev->emac_irq, dev); |
1307 | 1307 | ||
1308 | netif_carrier_off(ndev); | ||
1309 | |||
1308 | return 0; | 1310 | return 0; |
1309 | } | 1311 | } |
1310 | 1312 | ||
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index c4361d466597..ee1cff5c9b21 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
26 | #include <linux/etherdevice.h> | ||
27 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
28 | #include <linux/rtnetlink.h> | 27 | #include <linux/rtnetlink.h> |
29 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
@@ -205,9 +204,6 @@ static const struct net_device_ops au1k_irda_netdev_ops = { | |||
205 | .ndo_start_xmit = au1k_irda_hard_xmit, | 204 | .ndo_start_xmit = au1k_irda_hard_xmit, |
206 | .ndo_tx_timeout = au1k_tx_timeout, | 205 | .ndo_tx_timeout = au1k_tx_timeout, |
207 | .ndo_do_ioctl = au1k_irda_ioctl, | 206 | .ndo_do_ioctl = au1k_irda_ioctl, |
208 | .ndo_change_mtu = eth_change_mtu, | ||
209 | .ndo_validate_addr = eth_validate_addr, | ||
210 | .ndo_set_mac_address = eth_mac_addr, | ||
211 | }; | 207 | }; |
212 | 208 | ||
213 | static int au1k_irda_net_init(struct net_device *dev) | 209 | static int au1k_irda_net_init(struct net_device *dev) |
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 3376a4f39e0a..77d10edefd25 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c | |||
@@ -803,9 +803,6 @@ static const struct net_device_ops pxa_irda_netdev_ops = { | |||
803 | .ndo_stop = pxa_irda_stop, | 803 | .ndo_stop = pxa_irda_stop, |
804 | .ndo_start_xmit = pxa_irda_hard_xmit, | 804 | .ndo_start_xmit = pxa_irda_hard_xmit, |
805 | .ndo_do_ioctl = pxa_irda_ioctl, | 805 | .ndo_do_ioctl = pxa_irda_ioctl, |
806 | .ndo_change_mtu = eth_change_mtu, | ||
807 | .ndo_validate_addr = eth_validate_addr, | ||
808 | .ndo_set_mac_address = eth_mac_addr, | ||
809 | }; | 806 | }; |
810 | 807 | ||
811 | static int pxa_irda_probe(struct platform_device *pdev) | 808 | static int pxa_irda_probe(struct platform_device *pdev) |
@@ -830,6 +827,7 @@ static int pxa_irda_probe(struct platform_device *pdev) | |||
830 | if (!dev) | 827 | if (!dev) |
831 | goto err_mem_3; | 828 | goto err_mem_3; |
832 | 829 | ||
830 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
833 | si = netdev_priv(dev); | 831 | si = netdev_priv(dev); |
834 | si->dev = &pdev->dev; | 832 | si->dev = &pdev->dev; |
835 | si->pdata = pdev->dev.platform_data; | 833 | si->pdata = pdev->dev.platform_data; |
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 2aeb2e6aec1b..b039cb081e94 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
29 | #include <linux/rtnetlink.h> | 28 | #include <linux/rtnetlink.h> |
30 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
@@ -881,9 +880,6 @@ static const struct net_device_ops sa1100_irda_netdev_ops = { | |||
881 | .ndo_stop = sa1100_irda_stop, | 880 | .ndo_stop = sa1100_irda_stop, |
882 | .ndo_start_xmit = sa1100_irda_hard_xmit, | 881 | .ndo_start_xmit = sa1100_irda_hard_xmit, |
883 | .ndo_do_ioctl = sa1100_irda_ioctl, | 882 | .ndo_do_ioctl = sa1100_irda_ioctl, |
884 | .ndo_change_mtu = eth_change_mtu, | ||
885 | .ndo_validate_addr = eth_validate_addr, | ||
886 | .ndo_set_mac_address = eth_mac_addr, | ||
887 | }; | 883 | }; |
888 | 884 | ||
889 | static int sa1100_irda_probe(struct platform_device *pdev) | 885 | static int sa1100_irda_probe(struct platform_device *pdev) |
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index 2a0174b62e96..92fb8235c766 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c | |||
@@ -41,6 +41,7 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
41 | struct ixpdev_priv *ip = netdev_priv(dev); | 41 | struct ixpdev_priv *ip = netdev_priv(dev); |
42 | struct ixpdev_tx_desc *desc; | 42 | struct ixpdev_tx_desc *desc; |
43 | int entry; | 43 | int entry; |
44 | unsigned long flags; | ||
44 | 45 | ||
45 | if (unlikely(skb->len > PAGE_SIZE)) { | 46 | if (unlikely(skb->len > PAGE_SIZE)) { |
46 | /* @@@ Count drops. */ | 47 | /* @@@ Count drops. */ |
@@ -63,11 +64,11 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
63 | 64 | ||
64 | dev->trans_start = jiffies; | 65 | dev->trans_start = jiffies; |
65 | 66 | ||
66 | local_irq_disable(); | 67 | local_irq_save(flags); |
67 | ip->tx_queue_entries++; | 68 | ip->tx_queue_entries++; |
68 | if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN) | 69 | if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN) |
69 | netif_stop_queue(dev); | 70 | netif_stop_queue(dev); |
70 | local_irq_enable(); | 71 | local_irq_restore(flags); |
71 | 72 | ||
72 | return 0; | 73 | return 0; |
73 | } | 74 | } |
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 5b5c25368d1e..e3601cf3f931 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c | |||
@@ -620,6 +620,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
620 | dma_addr_t mapping; | 620 | dma_addr_t mapping; |
621 | unsigned int len, entry; | 621 | unsigned int len, entry; |
622 | u32 ctrl; | 622 | u32 ctrl; |
623 | unsigned long flags; | ||
623 | 624 | ||
624 | #ifdef DEBUG | 625 | #ifdef DEBUG |
625 | int i; | 626 | int i; |
@@ -635,12 +636,12 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
635 | #endif | 636 | #endif |
636 | 637 | ||
637 | len = skb->len; | 638 | len = skb->len; |
638 | spin_lock_irq(&bp->lock); | 639 | spin_lock_irqsave(&bp->lock, flags); |
639 | 640 | ||
640 | /* This is a hard error, log it. */ | 641 | /* This is a hard error, log it. */ |
641 | if (TX_BUFFS_AVAIL(bp) < 1) { | 642 | if (TX_BUFFS_AVAIL(bp) < 1) { |
642 | netif_stop_queue(dev); | 643 | netif_stop_queue(dev); |
643 | spin_unlock_irq(&bp->lock); | 644 | spin_unlock_irqrestore(&bp->lock, flags); |
644 | dev_err(&bp->pdev->dev, | 645 | dev_err(&bp->pdev->dev, |
645 | "BUG! Tx Ring full when queue awake!\n"); | 646 | "BUG! Tx Ring full when queue awake!\n"); |
646 | dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n", | 647 | dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n", |
@@ -674,7 +675,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
674 | if (TX_BUFFS_AVAIL(bp) < 1) | 675 | if (TX_BUFFS_AVAIL(bp) < 1) |
675 | netif_stop_queue(dev); | 676 | netif_stop_queue(dev); |
676 | 677 | ||
677 | spin_unlock_irq(&bp->lock); | 678 | spin_unlock_irqrestore(&bp->lock, flags); |
678 | 679 | ||
679 | dev->trans_start = jiffies; | 680 | dev->trans_start = jiffies; |
680 | 681 | ||
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 5a88b3f57693..62208401c4df 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c | |||
@@ -437,6 +437,7 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind) | |||
437 | { | 437 | { |
438 | struct mlx4_en_cq *cq = &priv->tx_cq[tx_ind]; | 438 | struct mlx4_en_cq *cq = &priv->tx_cq[tx_ind]; |
439 | struct mlx4_en_tx_ring *ring = &priv->tx_ring[tx_ind]; | 439 | struct mlx4_en_tx_ring *ring = &priv->tx_ring[tx_ind]; |
440 | unsigned long flags; | ||
440 | 441 | ||
441 | /* If we don't have a pending timer, set one up to catch our recent | 442 | /* If we don't have a pending timer, set one up to catch our recent |
442 | post in case the interface becomes idle */ | 443 | post in case the interface becomes idle */ |
@@ -445,9 +446,9 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind) | |||
445 | 446 | ||
446 | /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */ | 447 | /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */ |
447 | if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0) | 448 | if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0) |
448 | if (spin_trylock_irq(&ring->comp_lock)) { | 449 | if (spin_trylock_irqsave(&ring->comp_lock, flags)) { |
449 | mlx4_en_process_tx_cq(priv->dev, cq); | 450 | mlx4_en_process_tx_cq(priv->dev, cq); |
450 | spin_unlock_irq(&ring->comp_lock); | 451 | spin_unlock_irqrestore(&ring->comp_lock, flags); |
451 | } | 452 | } |
452 | } | 453 | } |
453 | 454 | ||
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 1c70e999cc50..9da1fa12a67c 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -196,21 +196,23 @@ static void PRINT_PKT(u_char *buf, int length) | |||
196 | /* this enables an interrupt in the interrupt mask register */ | 196 | /* this enables an interrupt in the interrupt mask register */ |
197 | #define SMC_ENABLE_INT(lp, x) do { \ | 197 | #define SMC_ENABLE_INT(lp, x) do { \ |
198 | unsigned char mask; \ | 198 | unsigned char mask; \ |
199 | spin_lock_irq(&lp->lock); \ | 199 | unsigned long smc_enable_flags; \ |
200 | spin_lock_irqsave(&lp->lock, smc_enable_flags); \ | ||
200 | mask = SMC_GET_INT_MASK(lp); \ | 201 | mask = SMC_GET_INT_MASK(lp); \ |
201 | mask |= (x); \ | 202 | mask |= (x); \ |
202 | SMC_SET_INT_MASK(lp, mask); \ | 203 | SMC_SET_INT_MASK(lp, mask); \ |
203 | spin_unlock_irq(&lp->lock); \ | 204 | spin_unlock_irqrestore(&lp->lock, smc_enable_flags); \ |
204 | } while (0) | 205 | } while (0) |
205 | 206 | ||
206 | /* this disables an interrupt from the interrupt mask register */ | 207 | /* this disables an interrupt from the interrupt mask register */ |
207 | #define SMC_DISABLE_INT(lp, x) do { \ | 208 | #define SMC_DISABLE_INT(lp, x) do { \ |
208 | unsigned char mask; \ | 209 | unsigned char mask; \ |
209 | spin_lock_irq(&lp->lock); \ | 210 | unsigned long smc_disable_flags; \ |
211 | spin_lock_irqsave(&lp->lock, smc_disable_flags); \ | ||
210 | mask = SMC_GET_INT_MASK(lp); \ | 212 | mask = SMC_GET_INT_MASK(lp); \ |
211 | mask &= ~(x); \ | 213 | mask &= ~(x); \ |
212 | SMC_SET_INT_MASK(lp, mask); \ | 214 | SMC_SET_INT_MASK(lp, mask); \ |
213 | spin_unlock_irq(&lp->lock); \ | 215 | spin_unlock_irqrestore(&lp->lock, smc_disable_flags); \ |
214 | } while (0) | 216 | } while (0) |
215 | 217 | ||
216 | /* | 218 | /* |
@@ -520,21 +522,21 @@ static inline void smc_rcv(struct net_device *dev) | |||
520 | * any other concurrent access and C would always interrupt B. But life | 522 | * any other concurrent access and C would always interrupt B. But life |
521 | * isn't that easy in a SMP world... | 523 | * isn't that easy in a SMP world... |
522 | */ | 524 | */ |
523 | #define smc_special_trylock(lock) \ | 525 | #define smc_special_trylock(lock, flags) \ |
524 | ({ \ | 526 | ({ \ |
525 | int __ret; \ | 527 | int __ret; \ |
526 | local_irq_disable(); \ | 528 | local_irq_save(flags); \ |
527 | __ret = spin_trylock(lock); \ | 529 | __ret = spin_trylock(lock); \ |
528 | if (!__ret) \ | 530 | if (!__ret) \ |
529 | local_irq_enable(); \ | 531 | local_irq_restore(flags); \ |
530 | __ret; \ | 532 | __ret; \ |
531 | }) | 533 | }) |
532 | #define smc_special_lock(lock) spin_lock_irq(lock) | 534 | #define smc_special_lock(lock, flags) spin_lock_irq(lock, flags) |
533 | #define smc_special_unlock(lock) spin_unlock_irq(lock) | 535 | #define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) |
534 | #else | 536 | #else |
535 | #define smc_special_trylock(lock) (1) | 537 | #define smc_special_trylock(lock, flags) (1) |
536 | #define smc_special_lock(lock) do { } while (0) | 538 | #define smc_special_lock(lock, flags) do { } while (0) |
537 | #define smc_special_unlock(lock) do { } while (0) | 539 | #define smc_special_unlock(lock, flags) do { } while (0) |
538 | #endif | 540 | #endif |
539 | 541 | ||
540 | /* | 542 | /* |
@@ -548,10 +550,11 @@ static void smc_hardware_send_pkt(unsigned long data) | |||
548 | struct sk_buff *skb; | 550 | struct sk_buff *skb; |
549 | unsigned int packet_no, len; | 551 | unsigned int packet_no, len; |
550 | unsigned char *buf; | 552 | unsigned char *buf; |
553 | unsigned long flags; | ||
551 | 554 | ||
552 | DBG(3, "%s: %s\n", dev->name, __func__); | 555 | DBG(3, "%s: %s\n", dev->name, __func__); |
553 | 556 | ||
554 | if (!smc_special_trylock(&lp->lock)) { | 557 | if (!smc_special_trylock(&lp->lock, flags)) { |
555 | netif_stop_queue(dev); | 558 | netif_stop_queue(dev); |
556 | tasklet_schedule(&lp->tx_task); | 559 | tasklet_schedule(&lp->tx_task); |
557 | return; | 560 | return; |
@@ -559,7 +562,7 @@ static void smc_hardware_send_pkt(unsigned long data) | |||
559 | 562 | ||
560 | skb = lp->pending_tx_skb; | 563 | skb = lp->pending_tx_skb; |
561 | if (unlikely(!skb)) { | 564 | if (unlikely(!skb)) { |
562 | smc_special_unlock(&lp->lock); | 565 | smc_special_unlock(&lp->lock, flags); |
563 | return; | 566 | return; |
564 | } | 567 | } |
565 | lp->pending_tx_skb = NULL; | 568 | lp->pending_tx_skb = NULL; |
@@ -569,7 +572,7 @@ static void smc_hardware_send_pkt(unsigned long data) | |||
569 | printk("%s: Memory allocation failed.\n", dev->name); | 572 | printk("%s: Memory allocation failed.\n", dev->name); |
570 | dev->stats.tx_errors++; | 573 | dev->stats.tx_errors++; |
571 | dev->stats.tx_fifo_errors++; | 574 | dev->stats.tx_fifo_errors++; |
572 | smc_special_unlock(&lp->lock); | 575 | smc_special_unlock(&lp->lock, flags); |
573 | goto done; | 576 | goto done; |
574 | } | 577 | } |
575 | 578 | ||
@@ -608,7 +611,7 @@ static void smc_hardware_send_pkt(unsigned long data) | |||
608 | 611 | ||
609 | /* queue the packet for TX */ | 612 | /* queue the packet for TX */ |
610 | SMC_SET_MMU_CMD(lp, MC_ENQUEUE); | 613 | SMC_SET_MMU_CMD(lp, MC_ENQUEUE); |
611 | smc_special_unlock(&lp->lock); | 614 | smc_special_unlock(&lp->lock, flags); |
612 | 615 | ||
613 | dev->trans_start = jiffies; | 616 | dev->trans_start = jiffies; |
614 | dev->stats.tx_packets++; | 617 | dev->stats.tx_packets++; |
@@ -633,6 +636,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
633 | struct smc_local *lp = netdev_priv(dev); | 636 | struct smc_local *lp = netdev_priv(dev); |
634 | void __iomem *ioaddr = lp->base; | 637 | void __iomem *ioaddr = lp->base; |
635 | unsigned int numPages, poll_count, status; | 638 | unsigned int numPages, poll_count, status; |
639 | unsigned long flags; | ||
636 | 640 | ||
637 | DBG(3, "%s: %s\n", dev->name, __func__); | 641 | DBG(3, "%s: %s\n", dev->name, __func__); |
638 | 642 | ||
@@ -658,7 +662,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
658 | return 0; | 662 | return 0; |
659 | } | 663 | } |
660 | 664 | ||
661 | smc_special_lock(&lp->lock); | 665 | smc_special_lock(&lp->lock, flags); |
662 | 666 | ||
663 | /* now, try to allocate the memory */ | 667 | /* now, try to allocate the memory */ |
664 | SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages); | 668 | SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages); |
@@ -676,7 +680,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
676 | } | 680 | } |
677 | } while (--poll_count); | 681 | } while (--poll_count); |
678 | 682 | ||
679 | smc_special_unlock(&lp->lock); | 683 | smc_special_unlock(&lp->lock, flags); |
680 | 684 | ||
681 | lp->pending_tx_skb = skb; | 685 | lp->pending_tx_skb = skb; |
682 | if (!poll_count) { | 686 | if (!poll_count) { |
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 632fac86a308..b3946272c72e 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -70,7 +70,7 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc) | |||
70 | int err = 0; | 70 | int err = 0; |
71 | u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE]; | 71 | u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE]; |
72 | 72 | ||
73 | if ((key < 0) || (key > 4)) | 73 | if ((key < 0) || (key >= 4)) |
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | 75 | ||
76 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, | 76 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 294250e294dd..87a95588a8e3 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -869,6 +869,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) | |||
869 | priv->aifsn[3] = 3; /* AIFSN[AC_BE] */ | 869 | priv->aifsn[3] = 3; /* AIFSN[AC_BE] */ |
870 | rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0); | 870 | rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0); |
871 | 871 | ||
872 | /* ENEDCA flag must always be set, transmit issues? */ | ||
873 | rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA); | ||
874 | |||
872 | return 0; | 875 | return 0; |
873 | } | 876 | } |
874 | 877 | ||
@@ -1173,13 +1176,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, | |||
1173 | rtl818x_iowrite8(priv, &priv->map->BSSID[i], | 1176 | rtl818x_iowrite8(priv, &priv->map->BSSID[i], |
1174 | info->bssid[i]); | 1177 | info->bssid[i]); |
1175 | 1178 | ||
1179 | if (priv->is_rtl8187b) | ||
1180 | reg = RTL818X_MSR_ENEDCA; | ||
1181 | else | ||
1182 | reg = 0; | ||
1183 | |||
1176 | if (is_valid_ether_addr(info->bssid)) { | 1184 | if (is_valid_ether_addr(info->bssid)) { |
1177 | reg = RTL818X_MSR_INFRA; | 1185 | reg |= RTL818X_MSR_INFRA; |
1178 | if (priv->is_rtl8187b) | ||
1179 | reg |= RTL818X_MSR_ENEDCA; | ||
1180 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); | 1186 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); |
1181 | } else { | 1187 | } else { |
1182 | reg = RTL818X_MSR_NO_LINK; | 1188 | reg |= RTL818X_MSR_NO_LINK; |
1183 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); | 1189 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); |
1184 | } | 1190 | } |
1185 | 1191 | ||
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index a07580138e81..c2fd6187773f 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c | |||
@@ -346,7 +346,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | |||
346 | static int yellowfin_open(struct net_device *dev); | 346 | static int yellowfin_open(struct net_device *dev); |
347 | static void yellowfin_timer(unsigned long data); | 347 | static void yellowfin_timer(unsigned long data); |
348 | static void yellowfin_tx_timeout(struct net_device *dev); | 348 | static void yellowfin_tx_timeout(struct net_device *dev); |
349 | static void yellowfin_init_ring(struct net_device *dev); | 349 | static int yellowfin_init_ring(struct net_device *dev); |
350 | static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); | 350 | static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); |
351 | static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); | 351 | static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); |
352 | static int yellowfin_rx(struct net_device *dev); | 352 | static int yellowfin_rx(struct net_device *dev); |
@@ -573,19 +573,24 @@ static int yellowfin_open(struct net_device *dev) | |||
573 | { | 573 | { |
574 | struct yellowfin_private *yp = netdev_priv(dev); | 574 | struct yellowfin_private *yp = netdev_priv(dev); |
575 | void __iomem *ioaddr = yp->base; | 575 | void __iomem *ioaddr = yp->base; |
576 | int i; | 576 | int i, ret; |
577 | 577 | ||
578 | /* Reset the chip. */ | 578 | /* Reset the chip. */ |
579 | iowrite32(0x80000000, ioaddr + DMACtrl); | 579 | iowrite32(0x80000000, ioaddr + DMACtrl); |
580 | 580 | ||
581 | i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); | 581 | ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); |
582 | if (i) return i; | 582 | if (ret) |
583 | return ret; | ||
583 | 584 | ||
584 | if (yellowfin_debug > 1) | 585 | if (yellowfin_debug > 1) |
585 | printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", | 586 | printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", |
586 | dev->name, dev->irq); | 587 | dev->name, dev->irq); |
587 | 588 | ||
588 | yellowfin_init_ring(dev); | 589 | ret = yellowfin_init_ring(dev); |
590 | if (ret) { | ||
591 | free_irq(dev->irq, dev); | ||
592 | return ret; | ||
593 | } | ||
589 | 594 | ||
590 | iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); | 595 | iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); |
591 | iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); | 596 | iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); |
@@ -725,10 +730,10 @@ static void yellowfin_tx_timeout(struct net_device *dev) | |||
725 | } | 730 | } |
726 | 731 | ||
727 | /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ | 732 | /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ |
728 | static void yellowfin_init_ring(struct net_device *dev) | 733 | static int yellowfin_init_ring(struct net_device *dev) |
729 | { | 734 | { |
730 | struct yellowfin_private *yp = netdev_priv(dev); | 735 | struct yellowfin_private *yp = netdev_priv(dev); |
731 | int i; | 736 | int i, j; |
732 | 737 | ||
733 | yp->tx_full = 0; | 738 | yp->tx_full = 0; |
734 | yp->cur_rx = yp->cur_tx = 0; | 739 | yp->cur_rx = yp->cur_tx = 0; |
@@ -753,6 +758,11 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
753 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, | 758 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, |
754 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 759 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
755 | } | 760 | } |
761 | if (i != RX_RING_SIZE) { | ||
762 | for (j = 0; j < i; j++) | ||
763 | dev_kfree_skb(yp->rx_skbuff[j]); | ||
764 | return -ENOMEM; | ||
765 | } | ||
756 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); | 766 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); |
757 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); | 767 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); |
758 | 768 | ||
@@ -769,8 +779,6 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
769 | yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); | 779 | yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); |
770 | #else | 780 | #else |
771 | { | 781 | { |
772 | int j; | ||
773 | |||
774 | /* Tx ring needs a pair of descriptors, the second for the status. */ | 782 | /* Tx ring needs a pair of descriptors, the second for the status. */ |
775 | for (i = 0; i < TX_RING_SIZE; i++) { | 783 | for (i = 0; i < TX_RING_SIZE; i++) { |
776 | j = 2*i; | 784 | j = 2*i; |
@@ -805,7 +813,7 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
805 | } | 813 | } |
806 | #endif | 814 | #endif |
807 | yp->tx_tail_desc = &yp->tx_status[0]; | 815 | yp->tx_tail_desc = &yp->tx_status[0]; |
808 | return; | 816 | return 0; |
809 | } | 817 | } |
810 | 818 | ||
811 | static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) | 819 | static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d76c4c85367e..f99bc7f089f1 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -508,7 +508,7 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) | |||
508 | return error; | 508 | return error; |
509 | } | 509 | } |
510 | 510 | ||
511 | return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0; | 511 | return pci_restore_state(pci_dev); |
512 | } | 512 | } |
513 | 513 | ||
514 | static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) | 514 | static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index dbd0f947f497..7b70312181d7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -846,6 +846,8 @@ pci_restore_state(struct pci_dev *dev) | |||
846 | int i; | 846 | int i; |
847 | u32 val; | 847 | u32 val; |
848 | 848 | ||
849 | if (!dev->state_saved) | ||
850 | return 0; | ||
849 | /* PCI Express register must be restored first */ | 851 | /* PCI Express register must be restored first */ |
850 | pci_restore_pcie_state(dev); | 852 | pci_restore_pcie_state(dev); |
851 | 853 | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 749836668655..3f62dd50bbbe 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2135,9 +2135,9 @@ static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
2135 | struct dasd_device *base; | 2135 | struct dasd_device *base; |
2136 | 2136 | ||
2137 | block = bdev->bd_disk->private_data; | 2137 | block = bdev->bd_disk->private_data; |
2138 | base = block->base; | ||
2139 | if (!block) | 2138 | if (!block) |
2140 | return -ENODEV; | 2139 | return -ENODEV; |
2140 | base = block->base; | ||
2141 | 2141 | ||
2142 | if (!base->discipline || | 2142 | if (!base->discipline || |
2143 | !base->discipline->fill_geometry) | 2143 | !base->discipline->fill_geometry) |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 3c57c1a18bb8..d593bc76afe3 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -772,10 +772,8 @@ static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) | |||
772 | cdev = io_subchannel_allocate_dev(sch); | 772 | cdev = io_subchannel_allocate_dev(sch); |
773 | if (!IS_ERR(cdev)) { | 773 | if (!IS_ERR(cdev)) { |
774 | ret = io_subchannel_initialize_dev(sch, cdev); | 774 | ret = io_subchannel_initialize_dev(sch, cdev); |
775 | if (ret) { | 775 | if (ret) |
776 | kfree(cdev); | ||
777 | cdev = ERR_PTR(ret); | 776 | cdev = ERR_PTR(ret); |
778 | } | ||
779 | } | 777 | } |
780 | return cdev; | 778 | return cdev; |
781 | } | 779 | } |
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index 15dab96d05e3..7c815d3327f7 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c | |||
@@ -537,8 +537,12 @@ int bbc_envctrl_init(struct bbc_i2c_bus *bp) | |||
537 | } | 537 | } |
538 | if (temp_index != 0 && fan_index != 0) { | 538 | if (temp_index != 0 && fan_index != 0) { |
539 | kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); | 539 | kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); |
540 | if (IS_ERR(kenvctrld_task)) | 540 | if (IS_ERR(kenvctrld_task)) { |
541 | return PTR_ERR(kenvctrld_task); | 541 | int err = PTR_ERR(kenvctrld_task); |
542 | |||
543 | kenvctrld_task = NULL; | ||
544 | return err; | ||
545 | } | ||
542 | } | 546 | } |
543 | 547 | ||
544 | return 0; | 548 | return 0; |
@@ -561,7 +565,8 @@ void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp) | |||
561 | struct bbc_cpu_temperature *tp, *tpos; | 565 | struct bbc_cpu_temperature *tp, *tpos; |
562 | struct bbc_fan_control *fp, *fpos; | 566 | struct bbc_fan_control *fp, *fpos; |
563 | 567 | ||
564 | kthread_stop(kenvctrld_task); | 568 | if (kenvctrld_task) |
569 | kthread_stop(kenvctrld_task); | ||
565 | 570 | ||
566 | list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { | 571 | list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { |
567 | list_del(&tp->bp_list); | 572 | list_del(&tp->bp_list); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index f3da592f7bcc..35a13867495e 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -119,6 +119,64 @@ _base_fault_reset_work(struct work_struct *work) | |||
119 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 119 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); |
120 | } | 120 | } |
121 | 121 | ||
122 | /** | ||
123 | * mpt2sas_base_start_watchdog - start the fault_reset_work_q | ||
124 | * @ioc: pointer to scsi command object | ||
125 | * Context: sleep. | ||
126 | * | ||
127 | * Return nothing. | ||
128 | */ | ||
129 | void | ||
130 | mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc) | ||
131 | { | ||
132 | unsigned long flags; | ||
133 | |||
134 | if (ioc->fault_reset_work_q) | ||
135 | return; | ||
136 | |||
137 | /* initialize fault polling */ | ||
138 | INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); | ||
139 | snprintf(ioc->fault_reset_work_q_name, | ||
140 | sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id); | ||
141 | ioc->fault_reset_work_q = | ||
142 | create_singlethread_workqueue(ioc->fault_reset_work_q_name); | ||
143 | if (!ioc->fault_reset_work_q) { | ||
144 | printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n", | ||
145 | ioc->name, __func__, __LINE__); | ||
146 | return; | ||
147 | } | ||
148 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
149 | if (ioc->fault_reset_work_q) | ||
150 | queue_delayed_work(ioc->fault_reset_work_q, | ||
151 | &ioc->fault_reset_work, | ||
152 | msecs_to_jiffies(FAULT_POLLING_INTERVAL)); | ||
153 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q | ||
158 | * @ioc: pointer to scsi command object | ||
159 | * Context: sleep. | ||
160 | * | ||
161 | * Return nothing. | ||
162 | */ | ||
163 | void | ||
164 | mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc) | ||
165 | { | ||
166 | unsigned long flags; | ||
167 | struct workqueue_struct *wq; | ||
168 | |||
169 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
170 | wq = ioc->fault_reset_work_q; | ||
171 | ioc->fault_reset_work_q = NULL; | ||
172 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
173 | if (wq) { | ||
174 | if (!cancel_delayed_work(&ioc->fault_reset_work)) | ||
175 | flush_workqueue(wq); | ||
176 | destroy_workqueue(wq); | ||
177 | } | ||
178 | } | ||
179 | |||
122 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 180 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
123 | /** | 181 | /** |
124 | * _base_sas_ioc_info - verbose translation of the ioc status | 182 | * _base_sas_ioc_info - verbose translation of the ioc status |
@@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) | |||
440 | if (sas_loginfo.dw.bus_type != 3 /*SAS*/) | 498 | if (sas_loginfo.dw.bus_type != 3 /*SAS*/) |
441 | return; | 499 | return; |
442 | 500 | ||
501 | /* each nexus loss loginfo */ | ||
502 | if (log_info == 0x31170000) | ||
503 | return; | ||
504 | |||
443 | /* eat the loginfos associated with task aborts */ | 505 | /* eat the loginfos associated with task aborts */ |
444 | if (ioc->ignore_loginfos && (log_info == 30050000 || log_info == | 506 | if (ioc->ignore_loginfos && (log_info == 30050000 || log_info == |
445 | 0x31140000 || log_info == 0x31130000)) | 507 | 0x31140000 || log_info == 0x31130000)) |
@@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1109 | } | 1171 | } |
1110 | } | 1172 | } |
1111 | 1173 | ||
1112 | pci_set_drvdata(pdev, ioc->shost); | ||
1113 | _base_mask_interrupts(ioc); | 1174 | _base_mask_interrupts(ioc); |
1114 | r = _base_enable_msix(ioc); | 1175 | r = _base_enable_msix(ioc); |
1115 | if (r) | 1176 | if (r) |
@@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1132 | ioc->pci_irq = -1; | 1193 | ioc->pci_irq = -1; |
1133 | pci_release_selected_regions(ioc->pdev, ioc->bars); | 1194 | pci_release_selected_regions(ioc->pdev, ioc->bars); |
1134 | pci_disable_device(pdev); | 1195 | pci_disable_device(pdev); |
1135 | pci_set_drvdata(pdev, NULL); | ||
1136 | return r; | 1196 | return r; |
1137 | } | 1197 | } |
1138 | 1198 | ||
@@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc) | |||
3191 | ioc->chip_phys = 0; | 3251 | ioc->chip_phys = 0; |
3192 | pci_release_selected_regions(ioc->pdev, ioc->bars); | 3252 | pci_release_selected_regions(ioc->pdev, ioc->bars); |
3193 | pci_disable_device(pdev); | 3253 | pci_disable_device(pdev); |
3194 | pci_set_drvdata(pdev, NULL); | ||
3195 | return; | 3254 | return; |
3196 | } | 3255 | } |
3197 | 3256 | ||
@@ -3205,7 +3264,6 @@ int | |||
3205 | mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | 3264 | mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) |
3206 | { | 3265 | { |
3207 | int r, i; | 3266 | int r, i; |
3208 | unsigned long flags; | ||
3209 | 3267 | ||
3210 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3268 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
3211 | __func__)); | 3269 | __func__)); |
@@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3214 | if (r) | 3272 | if (r) |
3215 | return r; | 3273 | return r; |
3216 | 3274 | ||
3275 | pci_set_drvdata(ioc->pdev, ioc->shost); | ||
3217 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); | 3276 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); |
3218 | if (r) | 3277 | if (r) |
3219 | goto out_free_resources; | 3278 | goto out_free_resources; |
@@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3288 | if (r) | 3347 | if (r) |
3289 | goto out_free_resources; | 3348 | goto out_free_resources; |
3290 | 3349 | ||
3291 | /* initialize fault polling */ | 3350 | mpt2sas_base_start_watchdog(ioc); |
3292 | INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); | ||
3293 | snprintf(ioc->fault_reset_work_q_name, | ||
3294 | sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id); | ||
3295 | ioc->fault_reset_work_q = | ||
3296 | create_singlethread_workqueue(ioc->fault_reset_work_q_name); | ||
3297 | if (!ioc->fault_reset_work_q) { | ||
3298 | printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n", | ||
3299 | ioc->name, __func__, __LINE__); | ||
3300 | goto out_free_resources; | ||
3301 | } | ||
3302 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
3303 | if (ioc->fault_reset_work_q) | ||
3304 | queue_delayed_work(ioc->fault_reset_work_q, | ||
3305 | &ioc->fault_reset_work, | ||
3306 | msecs_to_jiffies(FAULT_POLLING_INTERVAL)); | ||
3307 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
3308 | return 0; | 3351 | return 0; |
3309 | 3352 | ||
3310 | out_free_resources: | 3353 | out_free_resources: |
@@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3312 | ioc->remove_host = 1; | 3355 | ioc->remove_host = 1; |
3313 | mpt2sas_base_free_resources(ioc); | 3356 | mpt2sas_base_free_resources(ioc); |
3314 | _base_release_memory_pools(ioc); | 3357 | _base_release_memory_pools(ioc); |
3358 | pci_set_drvdata(ioc->pdev, NULL); | ||
3315 | kfree(ioc->tm_cmds.reply); | 3359 | kfree(ioc->tm_cmds.reply); |
3316 | kfree(ioc->transport_cmds.reply); | 3360 | kfree(ioc->transport_cmds.reply); |
3317 | kfree(ioc->config_cmds.reply); | 3361 | kfree(ioc->config_cmds.reply); |
@@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3337 | void | 3381 | void |
3338 | mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | 3382 | mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) |
3339 | { | 3383 | { |
3340 | unsigned long flags; | ||
3341 | struct workqueue_struct *wq; | ||
3342 | 3384 | ||
3343 | dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3385 | dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
3344 | __func__)); | 3386 | __func__)); |
3345 | 3387 | ||
3346 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3388 | mpt2sas_base_stop_watchdog(ioc); |
3347 | wq = ioc->fault_reset_work_q; | ||
3348 | ioc->fault_reset_work_q = NULL; | ||
3349 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
3350 | if (!cancel_delayed_work(&ioc->fault_reset_work)) | ||
3351 | flush_workqueue(wq); | ||
3352 | destroy_workqueue(wq); | ||
3353 | |||
3354 | mpt2sas_base_free_resources(ioc); | 3389 | mpt2sas_base_free_resources(ioc); |
3355 | _base_release_memory_pools(ioc); | 3390 | _base_release_memory_pools(ioc); |
3391 | pci_set_drvdata(ioc->pdev, NULL); | ||
3356 | kfree(ioc->pfacts); | 3392 | kfree(ioc->pfacts); |
3357 | kfree(ioc->ctl_cmds.reply); | 3393 | kfree(ioc->ctl_cmds.reply); |
3358 | kfree(ioc->base_cmds.reply); | 3394 | kfree(ioc->base_cmds.reply); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 286c185fa9e4..acdcff150a35 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -69,10 +69,10 @@ | |||
69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" | 69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" |
70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" | 70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" |
71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" | 71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" |
72 | #define MPT2SAS_DRIVER_VERSION "01.100.03.00" | 72 | #define MPT2SAS_DRIVER_VERSION "01.100.04.00" |
73 | #define MPT2SAS_MAJOR_VERSION 01 | 73 | #define MPT2SAS_MAJOR_VERSION 01 |
74 | #define MPT2SAS_MINOR_VERSION 100 | 74 | #define MPT2SAS_MINOR_VERSION 100 |
75 | #define MPT2SAS_BUILD_VERSION 03 | 75 | #define MPT2SAS_BUILD_VERSION 04 |
76 | #define MPT2SAS_RELEASE_VERSION 00 | 76 | #define MPT2SAS_RELEASE_VERSION 00 |
77 | 77 | ||
78 | /* | 78 | /* |
@@ -673,6 +673,8 @@ typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, | |||
673 | 673 | ||
674 | /* base shared API */ | 674 | /* base shared API */ |
675 | extern struct list_head mpt2sas_ioc_list; | 675 | extern struct list_head mpt2sas_ioc_list; |
676 | void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc); | ||
677 | void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc); | ||
676 | 678 | ||
677 | int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc); | 679 | int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc); |
678 | void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc); | 680 | void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 58cfb97846f7..6ddee161beb3 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c | |||
@@ -236,17 +236,25 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
236 | Mpi2ConfigRequest_t *config_request; | 236 | Mpi2ConfigRequest_t *config_request; |
237 | int r; | 237 | int r; |
238 | u8 retry_count; | 238 | u8 retry_count; |
239 | u8 issue_reset; | 239 | u8 issue_host_reset = 0; |
240 | u16 wait_state_count; | 240 | u16 wait_state_count; |
241 | 241 | ||
242 | mutex_lock(&ioc->config_cmds.mutex); | ||
242 | if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) { | 243 | if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) { |
243 | printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n", | 244 | printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n", |
244 | ioc->name, __func__); | 245 | ioc->name, __func__); |
246 | mutex_unlock(&ioc->config_cmds.mutex); | ||
245 | return -EAGAIN; | 247 | return -EAGAIN; |
246 | } | 248 | } |
247 | retry_count = 0; | 249 | retry_count = 0; |
248 | 250 | ||
249 | retry_config: | 251 | retry_config: |
252 | if (retry_count) { | ||
253 | if (retry_count > 2) /* attempt only 2 retries */ | ||
254 | return -EFAULT; | ||
255 | printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n", | ||
256 | ioc->name, __func__, retry_count); | ||
257 | } | ||
250 | wait_state_count = 0; | 258 | wait_state_count = 0; |
251 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); | 259 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); |
252 | while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { | 260 | while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { |
@@ -254,8 +262,8 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
254 | printk(MPT2SAS_ERR_FMT | 262 | printk(MPT2SAS_ERR_FMT |
255 | "%s: failed due to ioc not operational\n", | 263 | "%s: failed due to ioc not operational\n", |
256 | ioc->name, __func__); | 264 | ioc->name, __func__); |
257 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 265 | r = -EFAULT; |
258 | return -EFAULT; | 266 | goto out; |
259 | } | 267 | } |
260 | ssleep(1); | 268 | ssleep(1); |
261 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); | 269 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); |
@@ -271,8 +279,8 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
271 | if (!smid) { | 279 | if (!smid) { |
272 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | 280 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", |
273 | ioc->name, __func__); | 281 | ioc->name, __func__); |
274 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 282 | r = -EAGAIN; |
275 | return -EAGAIN; | 283 | goto out; |
276 | } | 284 | } |
277 | 285 | ||
278 | r = 0; | 286 | r = 0; |
@@ -292,9 +300,15 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
292 | ioc->name, __func__); | 300 | ioc->name, __func__); |
293 | _debug_dump_mf(mpi_request, | 301 | _debug_dump_mf(mpi_request, |
294 | sizeof(Mpi2ConfigRequest_t)/4); | 302 | sizeof(Mpi2ConfigRequest_t)/4); |
295 | if (!(ioc->config_cmds.status & MPT2_CMD_RESET)) | 303 | retry_count++; |
296 | issue_reset = 1; | 304 | if (ioc->config_cmds.smid == smid) |
297 | goto issue_host_reset; | 305 | mpt2sas_base_free_smid(ioc, smid); |
306 | if ((ioc->shost_recovery) || | ||
307 | (ioc->config_cmds.status & MPT2_CMD_RESET)) | ||
308 | goto retry_config; | ||
309 | issue_host_reset = 1; | ||
310 | r = -EFAULT; | ||
311 | goto out; | ||
298 | } | 312 | } |
299 | if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID) | 313 | if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID) |
300 | memcpy(mpi_reply, ioc->config_cmds.reply, | 314 | memcpy(mpi_reply, ioc->config_cmds.reply, |
@@ -302,21 +316,13 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
302 | if (retry_count) | 316 | if (retry_count) |
303 | printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n", | 317 | printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n", |
304 | ioc->name, __func__); | 318 | ioc->name, __func__); |
319 | out: | ||
305 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 320 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; |
306 | return r; | 321 | mutex_unlock(&ioc->config_cmds.mutex); |
307 | 322 | if (issue_host_reset) | |
308 | issue_host_reset: | ||
309 | if (issue_reset) | ||
310 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, | 323 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, |
311 | FORCE_BIG_HAMMER); | 324 | FORCE_BIG_HAMMER); |
312 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 325 | return r; |
313 | if (!retry_count) { | ||
314 | printk(MPT2SAS_INFO_FMT "%s: attempting retry\n", | ||
315 | ioc->name, __func__); | ||
316 | retry_count++; | ||
317 | goto retry_config; | ||
318 | } | ||
319 | return -EFAULT; | ||
320 | } | 326 | } |
321 | 327 | ||
322 | /** | 328 | /** |
@@ -375,7 +381,6 @@ mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
375 | int r; | 381 | int r; |
376 | struct config_request mem; | 382 | struct config_request mem; |
377 | 383 | ||
378 | mutex_lock(&ioc->config_cmds.mutex); | ||
379 | memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t)); | 384 | memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t)); |
380 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 385 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
381 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 386 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -417,7 +422,6 @@ mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
417 | _config_free_config_dma_memory(ioc, &mem); | 422 | _config_free_config_dma_memory(ioc, &mem); |
418 | 423 | ||
419 | out: | 424 | out: |
420 | mutex_unlock(&ioc->config_cmds.mutex); | ||
421 | return r; | 425 | return r; |
422 | } | 426 | } |
423 | 427 | ||
@@ -438,7 +442,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, | |||
438 | int r; | 442 | int r; |
439 | struct config_request mem; | 443 | struct config_request mem; |
440 | 444 | ||
441 | mutex_lock(&ioc->config_cmds.mutex); | ||
442 | memset(config_page, 0, sizeof(Mpi2BiosPage2_t)); | 445 | memset(config_page, 0, sizeof(Mpi2BiosPage2_t)); |
443 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 446 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
444 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 447 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -480,7 +483,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, | |||
480 | _config_free_config_dma_memory(ioc, &mem); | 483 | _config_free_config_dma_memory(ioc, &mem); |
481 | 484 | ||
482 | out: | 485 | out: |
483 | mutex_unlock(&ioc->config_cmds.mutex); | ||
484 | return r; | 486 | return r; |
485 | } | 487 | } |
486 | 488 | ||
@@ -501,7 +503,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
501 | int r; | 503 | int r; |
502 | struct config_request mem; | 504 | struct config_request mem; |
503 | 505 | ||
504 | mutex_lock(&ioc->config_cmds.mutex); | ||
505 | memset(config_page, 0, sizeof(Mpi2BiosPage3_t)); | 506 | memset(config_page, 0, sizeof(Mpi2BiosPage3_t)); |
506 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 507 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
507 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 508 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -543,7 +544,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
543 | _config_free_config_dma_memory(ioc, &mem); | 544 | _config_free_config_dma_memory(ioc, &mem); |
544 | 545 | ||
545 | out: | 546 | out: |
546 | mutex_unlock(&ioc->config_cmds.mutex); | ||
547 | return r; | 547 | return r; |
548 | } | 548 | } |
549 | 549 | ||
@@ -564,7 +564,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
564 | int r; | 564 | int r; |
565 | struct config_request mem; | 565 | struct config_request mem; |
566 | 566 | ||
567 | mutex_lock(&ioc->config_cmds.mutex); | ||
568 | memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t)); | 567 | memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t)); |
569 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 568 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
570 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 569 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -606,7 +605,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
606 | _config_free_config_dma_memory(ioc, &mem); | 605 | _config_free_config_dma_memory(ioc, &mem); |
607 | 606 | ||
608 | out: | 607 | out: |
609 | mutex_unlock(&ioc->config_cmds.mutex); | ||
610 | return r; | 608 | return r; |
611 | } | 609 | } |
612 | 610 | ||
@@ -627,7 +625,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
627 | int r; | 625 | int r; |
628 | struct config_request mem; | 626 | struct config_request mem; |
629 | 627 | ||
630 | mutex_lock(&ioc->config_cmds.mutex); | ||
631 | memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t)); | 628 | memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t)); |
632 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 629 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
633 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 630 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -669,7 +666,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
669 | _config_free_config_dma_memory(ioc, &mem); | 666 | _config_free_config_dma_memory(ioc, &mem); |
670 | 667 | ||
671 | out: | 668 | out: |
672 | mutex_unlock(&ioc->config_cmds.mutex); | ||
673 | return r; | 669 | return r; |
674 | } | 670 | } |
675 | 671 | ||
@@ -690,7 +686,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
690 | int r; | 686 | int r; |
691 | struct config_request mem; | 687 | struct config_request mem; |
692 | 688 | ||
693 | mutex_lock(&ioc->config_cmds.mutex); | ||
694 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 689 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
695 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 690 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
696 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | 691 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; |
@@ -732,7 +727,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
732 | _config_free_config_dma_memory(ioc, &mem); | 727 | _config_free_config_dma_memory(ioc, &mem); |
733 | 728 | ||
734 | out: | 729 | out: |
735 | mutex_unlock(&ioc->config_cmds.mutex); | ||
736 | return r; | 730 | return r; |
737 | } | 731 | } |
738 | 732 | ||
@@ -753,7 +747,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, | |||
753 | int r; | 747 | int r; |
754 | struct config_request mem; | 748 | struct config_request mem; |
755 | 749 | ||
756 | mutex_lock(&ioc->config_cmds.mutex); | ||
757 | memset(config_page, 0, sizeof(Mpi2IOCPage8_t)); | 750 | memset(config_page, 0, sizeof(Mpi2IOCPage8_t)); |
758 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 751 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
759 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 752 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -795,7 +788,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, | |||
795 | _config_free_config_dma_memory(ioc, &mem); | 788 | _config_free_config_dma_memory(ioc, &mem); |
796 | 789 | ||
797 | out: | 790 | out: |
798 | mutex_unlock(&ioc->config_cmds.mutex); | ||
799 | return r; | 791 | return r; |
800 | } | 792 | } |
801 | 793 | ||
@@ -818,7 +810,6 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
818 | int r; | 810 | int r; |
819 | struct config_request mem; | 811 | struct config_request mem; |
820 | 812 | ||
821 | mutex_lock(&ioc->config_cmds.mutex); | ||
822 | memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t)); | 813 | memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t)); |
823 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 814 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
824 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 815 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -863,7 +854,6 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
863 | _config_free_config_dma_memory(ioc, &mem); | 854 | _config_free_config_dma_memory(ioc, &mem); |
864 | 855 | ||
865 | out: | 856 | out: |
866 | mutex_unlock(&ioc->config_cmds.mutex); | ||
867 | return r; | 857 | return r; |
868 | } | 858 | } |
869 | 859 | ||
@@ -886,7 +876,6 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
886 | int r; | 876 | int r; |
887 | struct config_request mem; | 877 | struct config_request mem; |
888 | 878 | ||
889 | mutex_lock(&ioc->config_cmds.mutex); | ||
890 | memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t)); | 879 | memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t)); |
891 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 880 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
892 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 881 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -931,7 +920,6 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
931 | _config_free_config_dma_memory(ioc, &mem); | 920 | _config_free_config_dma_memory(ioc, &mem); |
932 | 921 | ||
933 | out: | 922 | out: |
934 | mutex_unlock(&ioc->config_cmds.mutex); | ||
935 | return r; | 923 | return r; |
936 | } | 924 | } |
937 | 925 | ||
@@ -953,7 +941,6 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys) | |||
953 | Mpi2ConfigReply_t mpi_reply; | 941 | Mpi2ConfigReply_t mpi_reply; |
954 | Mpi2SasIOUnitPage0_t config_page; | 942 | Mpi2SasIOUnitPage0_t config_page; |
955 | 943 | ||
956 | mutex_lock(&ioc->config_cmds.mutex); | ||
957 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 944 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
958 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 945 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
959 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | 946 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; |
@@ -1002,7 +989,6 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys) | |||
1002 | _config_free_config_dma_memory(ioc, &mem); | 989 | _config_free_config_dma_memory(ioc, &mem); |
1003 | 990 | ||
1004 | out: | 991 | out: |
1005 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1006 | return r; | 992 | return r; |
1007 | } | 993 | } |
1008 | 994 | ||
@@ -1026,8 +1012,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1026 | Mpi2ConfigRequest_t mpi_request; | 1012 | Mpi2ConfigRequest_t mpi_request; |
1027 | int r; | 1013 | int r; |
1028 | struct config_request mem; | 1014 | struct config_request mem; |
1029 | |||
1030 | mutex_lock(&ioc->config_cmds.mutex); | ||
1031 | memset(config_page, 0, sz); | 1015 | memset(config_page, 0, sz); |
1032 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1016 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1033 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1017 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1070,7 +1054,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1070 | _config_free_config_dma_memory(ioc, &mem); | 1054 | _config_free_config_dma_memory(ioc, &mem); |
1071 | 1055 | ||
1072 | out: | 1056 | out: |
1073 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1074 | return r; | 1057 | return r; |
1075 | } | 1058 | } |
1076 | 1059 | ||
@@ -1095,7 +1078,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1095 | int r; | 1078 | int r; |
1096 | struct config_request mem; | 1079 | struct config_request mem; |
1097 | 1080 | ||
1098 | mutex_lock(&ioc->config_cmds.mutex); | ||
1099 | memset(config_page, 0, sz); | 1081 | memset(config_page, 0, sz); |
1100 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1082 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1101 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1083 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1138,7 +1120,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1138 | _config_free_config_dma_memory(ioc, &mem); | 1120 | _config_free_config_dma_memory(ioc, &mem); |
1139 | 1121 | ||
1140 | out: | 1122 | out: |
1141 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1142 | return r; | 1123 | return r; |
1143 | } | 1124 | } |
1144 | 1125 | ||
@@ -1161,7 +1142,6 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1161 | int r; | 1142 | int r; |
1162 | struct config_request mem; | 1143 | struct config_request mem; |
1163 | 1144 | ||
1164 | mutex_lock(&ioc->config_cmds.mutex); | ||
1165 | memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t)); | 1145 | memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t)); |
1166 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1146 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1167 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1147 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1206,7 +1186,6 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1206 | _config_free_config_dma_memory(ioc, &mem); | 1186 | _config_free_config_dma_memory(ioc, &mem); |
1207 | 1187 | ||
1208 | out: | 1188 | out: |
1209 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1210 | return r; | 1189 | return r; |
1211 | } | 1190 | } |
1212 | 1191 | ||
@@ -1230,7 +1209,6 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1230 | int r; | 1209 | int r; |
1231 | struct config_request mem; | 1210 | struct config_request mem; |
1232 | 1211 | ||
1233 | mutex_lock(&ioc->config_cmds.mutex); | ||
1234 | memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t)); | 1212 | memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t)); |
1235 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1213 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1236 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1214 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1277,7 +1255,6 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1277 | _config_free_config_dma_memory(ioc, &mem); | 1255 | _config_free_config_dma_memory(ioc, &mem); |
1278 | 1256 | ||
1279 | out: | 1257 | out: |
1280 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1281 | return r; | 1258 | return r; |
1282 | } | 1259 | } |
1283 | 1260 | ||
@@ -1300,7 +1277,6 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1300 | int r; | 1277 | int r; |
1301 | struct config_request mem; | 1278 | struct config_request mem; |
1302 | 1279 | ||
1303 | mutex_lock(&ioc->config_cmds.mutex); | ||
1304 | memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t)); | 1280 | memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t)); |
1305 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1281 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1306 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1282 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1345,7 +1321,6 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1345 | _config_free_config_dma_memory(ioc, &mem); | 1321 | _config_free_config_dma_memory(ioc, &mem); |
1346 | 1322 | ||
1347 | out: | 1323 | out: |
1348 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1349 | return r; | 1324 | return r; |
1350 | } | 1325 | } |
1351 | 1326 | ||
@@ -1367,7 +1342,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1367 | int r; | 1342 | int r; |
1368 | struct config_request mem; | 1343 | struct config_request mem; |
1369 | 1344 | ||
1370 | mutex_lock(&ioc->config_cmds.mutex); | ||
1371 | memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t)); | 1345 | memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t)); |
1372 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1346 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1373 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1347 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1413,7 +1387,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1413 | _config_free_config_dma_memory(ioc, &mem); | 1387 | _config_free_config_dma_memory(ioc, &mem); |
1414 | 1388 | ||
1415 | out: | 1389 | out: |
1416 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1417 | return r; | 1390 | return r; |
1418 | } | 1391 | } |
1419 | 1392 | ||
@@ -1435,7 +1408,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1435 | int r; | 1408 | int r; |
1436 | struct config_request mem; | 1409 | struct config_request mem; |
1437 | 1410 | ||
1438 | mutex_lock(&ioc->config_cmds.mutex); | ||
1439 | memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t)); | 1411 | memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t)); |
1440 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1412 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1441 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1413 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1481,7 +1453,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1481 | _config_free_config_dma_memory(ioc, &mem); | 1453 | _config_free_config_dma_memory(ioc, &mem); |
1482 | 1454 | ||
1483 | out: | 1455 | out: |
1484 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1485 | return r; | 1456 | return r; |
1486 | } | 1457 | } |
1487 | 1458 | ||
@@ -1505,7 +1476,6 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
1505 | int r; | 1476 | int r; |
1506 | struct config_request mem; | 1477 | struct config_request mem; |
1507 | 1478 | ||
1508 | mutex_lock(&ioc->config_cmds.mutex); | ||
1509 | memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t)); | 1479 | memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t)); |
1510 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1480 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1511 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1481 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1548,7 +1518,6 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
1548 | _config_free_config_dma_memory(ioc, &mem); | 1518 | _config_free_config_dma_memory(ioc, &mem); |
1549 | 1519 | ||
1550 | out: | 1520 | out: |
1551 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1552 | return r; | 1521 | return r; |
1553 | } | 1522 | } |
1554 | 1523 | ||
@@ -1572,7 +1541,6 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
1572 | struct config_request mem; | 1541 | struct config_request mem; |
1573 | u16 ioc_status; | 1542 | u16 ioc_status; |
1574 | 1543 | ||
1575 | mutex_lock(&ioc->config_cmds.mutex); | ||
1576 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1544 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1577 | *num_pds = 0; | 1545 | *num_pds = 0; |
1578 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1546 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1620,7 +1588,6 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
1620 | _config_free_config_dma_memory(ioc, &mem); | 1588 | _config_free_config_dma_memory(ioc, &mem); |
1621 | 1589 | ||
1622 | out: | 1590 | out: |
1623 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1624 | return r; | 1591 | return r; |
1625 | } | 1592 | } |
1626 | 1593 | ||
@@ -1645,7 +1612,6 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
1645 | int r; | 1612 | int r; |
1646 | struct config_request mem; | 1613 | struct config_request mem; |
1647 | 1614 | ||
1648 | mutex_lock(&ioc->config_cmds.mutex); | ||
1649 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1615 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1650 | memset(config_page, 0, sz); | 1616 | memset(config_page, 0, sz); |
1651 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1617 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1687,7 +1653,6 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
1687 | _config_free_config_dma_memory(ioc, &mem); | 1653 | _config_free_config_dma_memory(ioc, &mem); |
1688 | 1654 | ||
1689 | out: | 1655 | out: |
1690 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1691 | return r; | 1656 | return r; |
1692 | } | 1657 | } |
1693 | 1658 | ||
@@ -1711,7 +1676,6 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1711 | int r; | 1676 | int r; |
1712 | struct config_request mem; | 1677 | struct config_request mem; |
1713 | 1678 | ||
1714 | mutex_lock(&ioc->config_cmds.mutex); | ||
1715 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1679 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1716 | memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t)); | 1680 | memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t)); |
1717 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1681 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1754,7 +1718,6 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
1754 | _config_free_config_dma_memory(ioc, &mem); | 1718 | _config_free_config_dma_memory(ioc, &mem); |
1755 | 1719 | ||
1756 | out: | 1720 | out: |
1757 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1758 | return r; | 1721 | return r; |
1759 | } | 1722 | } |
1760 | 1723 | ||
@@ -1778,7 +1741,6 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle, | |||
1778 | struct config_request mem; | 1741 | struct config_request mem; |
1779 | u16 ioc_status; | 1742 | u16 ioc_status; |
1780 | 1743 | ||
1781 | mutex_lock(&ioc->config_cmds.mutex); | ||
1782 | *volume_handle = 0; | 1744 | *volume_handle = 0; |
1783 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1745 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
1784 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1746 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
@@ -1842,7 +1804,6 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle, | |||
1842 | _config_free_config_dma_memory(ioc, &mem); | 1804 | _config_free_config_dma_memory(ioc, &mem); |
1843 | 1805 | ||
1844 | out: | 1806 | out: |
1845 | mutex_unlock(&ioc->config_cmds.mutex); | ||
1846 | return r; | 1807 | return r; |
1847 | } | 1808 | } |
1848 | 1809 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 2a01a5f2a84d..2e9a4445596f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -2767,6 +2767,10 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
2767 | char *desc_ioc_state = NULL; | 2767 | char *desc_ioc_state = NULL; |
2768 | char *desc_scsi_status = NULL; | 2768 | char *desc_scsi_status = NULL; |
2769 | char *desc_scsi_state = ioc->tmp_string; | 2769 | char *desc_scsi_state = ioc->tmp_string; |
2770 | u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); | ||
2771 | |||
2772 | if (log_info == 0x31170000) | ||
2773 | return; | ||
2770 | 2774 | ||
2771 | switch (ioc_status) { | 2775 | switch (ioc_status) { |
2772 | case MPI2_IOCSTATUS_SUCCESS: | 2776 | case MPI2_IOCSTATUS_SUCCESS: |
@@ -3426,7 +3430,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3426 | __le64 sas_address; | 3430 | __le64 sas_address; |
3427 | int i; | 3431 | int i; |
3428 | unsigned long flags; | 3432 | unsigned long flags; |
3429 | struct _sas_port *mpt2sas_port; | 3433 | struct _sas_port *mpt2sas_port = NULL; |
3430 | int rc = 0; | 3434 | int rc = 0; |
3431 | 3435 | ||
3432 | if (!handle) | 3436 | if (!handle) |
@@ -3518,12 +3522,20 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3518 | &expander_pg1, i, handle))) { | 3522 | &expander_pg1, i, handle))) { |
3519 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 3523 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
3520 | ioc->name, __FILE__, __LINE__, __func__); | 3524 | ioc->name, __FILE__, __LINE__, __func__); |
3521 | continue; | 3525 | rc = -1; |
3526 | goto out_fail; | ||
3522 | } | 3527 | } |
3523 | sas_expander->phy[i].handle = handle; | 3528 | sas_expander->phy[i].handle = handle; |
3524 | sas_expander->phy[i].phy_id = i; | 3529 | sas_expander->phy[i].phy_id = i; |
3525 | mpt2sas_transport_add_expander_phy(ioc, &sas_expander->phy[i], | 3530 | |
3526 | expander_pg1, sas_expander->parent_dev); | 3531 | if ((mpt2sas_transport_add_expander_phy(ioc, |
3532 | &sas_expander->phy[i], expander_pg1, | ||
3533 | sas_expander->parent_dev))) { | ||
3534 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
3535 | ioc->name, __FILE__, __LINE__, __func__); | ||
3536 | rc = -1; | ||
3537 | goto out_fail; | ||
3538 | } | ||
3527 | } | 3539 | } |
3528 | 3540 | ||
3529 | if (sas_expander->enclosure_handle) { | 3541 | if (sas_expander->enclosure_handle) { |
@@ -3540,8 +3552,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3540 | 3552 | ||
3541 | out_fail: | 3553 | out_fail: |
3542 | 3554 | ||
3543 | if (sas_expander) | 3555 | if (mpt2sas_port) |
3544 | kfree(sas_expander->phy); | 3556 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, |
3557 | sas_expander->parent_handle); | ||
3545 | kfree(sas_expander); | 3558 | kfree(sas_expander); |
3546 | return rc; | 3559 | return rc; |
3547 | } | 3560 | } |
@@ -3663,12 +3676,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
3663 | sas_device->hidden_raid_component = is_pd; | 3676 | sas_device->hidden_raid_component = is_pd; |
3664 | 3677 | ||
3665 | /* get enclosure_logical_id */ | 3678 | /* get enclosure_logical_id */ |
3666 | if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, &enclosure_pg0, | 3679 | if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0( |
3667 | MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, | 3680 | ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, |
3668 | sas_device->enclosure_handle))) { | 3681 | sas_device->enclosure_handle))) |
3669 | sas_device->enclosure_logical_id = | 3682 | sas_device->enclosure_logical_id = |
3670 | le64_to_cpu(enclosure_pg0.EnclosureLogicalID); | 3683 | le64_to_cpu(enclosure_pg0.EnclosureLogicalID); |
3671 | } | ||
3672 | 3684 | ||
3673 | /* get device name */ | 3685 | /* get device name */ |
3674 | sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); | 3686 | sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); |
@@ -4250,12 +4262,6 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc, | |||
4250 | u16 handle = le16_to_cpu(element->VolDevHandle); | 4262 | u16 handle = le16_to_cpu(element->VolDevHandle); |
4251 | int rc; | 4263 | int rc; |
4252 | 4264 | ||
4253 | #if 0 /* RAID_HACKS */ | ||
4254 | if (le32_to_cpu(event_data->Flags) & | ||
4255 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) | ||
4256 | return; | ||
4257 | #endif | ||
4258 | |||
4259 | mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); | 4265 | mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); |
4260 | if (!wwid) { | 4266 | if (!wwid) { |
4261 | printk(MPT2SAS_ERR_FMT | 4267 | printk(MPT2SAS_ERR_FMT |
@@ -4310,12 +4316,6 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, | |||
4310 | unsigned long flags; | 4316 | unsigned long flags; |
4311 | struct MPT2SAS_TARGET *sas_target_priv_data; | 4317 | struct MPT2SAS_TARGET *sas_target_priv_data; |
4312 | 4318 | ||
4313 | #if 0 /* RAID_HACKS */ | ||
4314 | if (le32_to_cpu(event_data->Flags) & | ||
4315 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) | ||
4316 | return; | ||
4317 | #endif | ||
4318 | |||
4319 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 4319 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
4320 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | 4320 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); |
4321 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 4321 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
@@ -4428,14 +4428,38 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
4428 | struct _sas_device *sas_device; | 4428 | struct _sas_device *sas_device; |
4429 | unsigned long flags; | 4429 | unsigned long flags; |
4430 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); | 4430 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); |
4431 | Mpi2ConfigReply_t mpi_reply; | ||
4432 | Mpi2SasDevicePage0_t sas_device_pg0; | ||
4433 | u32 ioc_status; | ||
4431 | 4434 | ||
4432 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4435 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
4433 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4436 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
4434 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4437 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4435 | if (sas_device) | 4438 | if (sas_device) { |
4436 | sas_device->hidden_raid_component = 1; | 4439 | sas_device->hidden_raid_component = 1; |
4437 | else | 4440 | return; |
4438 | _scsih_add_device(ioc, handle, 0, 1); | 4441 | } |
4442 | |||
4443 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | ||
4444 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { | ||
4445 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
4446 | ioc->name, __FILE__, __LINE__, __func__); | ||
4447 | return; | ||
4448 | } | ||
4449 | |||
4450 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
4451 | MPI2_IOCSTATUS_MASK; | ||
4452 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
4453 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
4454 | ioc->name, __FILE__, __LINE__, __func__); | ||
4455 | return; | ||
4456 | } | ||
4457 | |||
4458 | _scsih_link_change(ioc, | ||
4459 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | ||
4460 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
4461 | |||
4462 | _scsih_add_device(ioc, handle, 0, 1); | ||
4439 | } | 4463 | } |
4440 | 4464 | ||
4441 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4465 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
@@ -4535,12 +4559,15 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
4535 | { | 4559 | { |
4536 | Mpi2EventIrConfigElement_t *element; | 4560 | Mpi2EventIrConfigElement_t *element; |
4537 | int i; | 4561 | int i; |
4562 | u8 foreign_config; | ||
4538 | 4563 | ||
4539 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4564 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
4540 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 4565 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
4541 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); | 4566 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); |
4542 | 4567 | ||
4543 | #endif | 4568 | #endif |
4569 | foreign_config = (le32_to_cpu(event_data->Flags) & | ||
4570 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; | ||
4544 | 4571 | ||
4545 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | 4572 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; |
4546 | for (i = 0; i < event_data->NumElements; i++, element++) { | 4573 | for (i = 0; i < event_data->NumElements; i++, element++) { |
@@ -4548,11 +4575,13 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
4548 | switch (element->ReasonCode) { | 4575 | switch (element->ReasonCode) { |
4549 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: | 4576 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: |
4550 | case MPI2_EVENT_IR_CHANGE_RC_ADDED: | 4577 | case MPI2_EVENT_IR_CHANGE_RC_ADDED: |
4551 | _scsih_sas_volume_add(ioc, element); | 4578 | if (!foreign_config) |
4579 | _scsih_sas_volume_add(ioc, element); | ||
4552 | break; | 4580 | break; |
4553 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: | 4581 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: |
4554 | case MPI2_EVENT_IR_CHANGE_RC_REMOVED: | 4582 | case MPI2_EVENT_IR_CHANGE_RC_REMOVED: |
4555 | _scsih_sas_volume_delete(ioc, element); | 4583 | if (!foreign_config) |
4584 | _scsih_sas_volume_delete(ioc, element); | ||
4556 | break; | 4585 | break; |
4557 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: | 4586 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: |
4558 | _scsih_sas_pd_hide(ioc, element); | 4587 | _scsih_sas_pd_hide(ioc, element); |
@@ -4671,6 +4700,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
4671 | u32 state; | 4700 | u32 state; |
4672 | struct _sas_device *sas_device; | 4701 | struct _sas_device *sas_device; |
4673 | unsigned long flags; | 4702 | unsigned long flags; |
4703 | Mpi2ConfigReply_t mpi_reply; | ||
4704 | Mpi2SasDevicePage0_t sas_device_pg0; | ||
4705 | u32 ioc_status; | ||
4674 | 4706 | ||
4675 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) | 4707 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) |
4676 | return; | 4708 | return; |
@@ -4687,22 +4719,40 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
4687 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4719 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4688 | 4720 | ||
4689 | switch (state) { | 4721 | switch (state) { |
4690 | #if 0 | ||
4691 | case MPI2_RAID_PD_STATE_OFFLINE: | ||
4692 | if (sas_device) | ||
4693 | _scsih_remove_device(ioc, handle); | ||
4694 | break; | ||
4695 | #endif | ||
4696 | case MPI2_RAID_PD_STATE_ONLINE: | 4722 | case MPI2_RAID_PD_STATE_ONLINE: |
4697 | case MPI2_RAID_PD_STATE_DEGRADED: | 4723 | case MPI2_RAID_PD_STATE_DEGRADED: |
4698 | case MPI2_RAID_PD_STATE_REBUILDING: | 4724 | case MPI2_RAID_PD_STATE_REBUILDING: |
4699 | case MPI2_RAID_PD_STATE_OPTIMAL: | 4725 | case MPI2_RAID_PD_STATE_OPTIMAL: |
4700 | if (sas_device) | 4726 | if (sas_device) { |
4701 | sas_device->hidden_raid_component = 1; | 4727 | sas_device->hidden_raid_component = 1; |
4702 | else | 4728 | return; |
4703 | _scsih_add_device(ioc, handle, 0, 1); | 4729 | } |
4730 | |||
4731 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, | ||
4732 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, | ||
4733 | handle))) { | ||
4734 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
4735 | ioc->name, __FILE__, __LINE__, __func__); | ||
4736 | return; | ||
4737 | } | ||
4738 | |||
4739 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
4740 | MPI2_IOCSTATUS_MASK; | ||
4741 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
4742 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
4743 | ioc->name, __FILE__, __LINE__, __func__); | ||
4744 | return; | ||
4745 | } | ||
4746 | |||
4747 | _scsih_link_change(ioc, | ||
4748 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | ||
4749 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
4750 | |||
4751 | _scsih_add_device(ioc, handle, 0, 1); | ||
4752 | |||
4704 | break; | 4753 | break; |
4705 | 4754 | ||
4755 | case MPI2_RAID_PD_STATE_OFFLINE: | ||
4706 | case MPI2_RAID_PD_STATE_NOT_CONFIGURED: | 4756 | case MPI2_RAID_PD_STATE_NOT_CONFIGURED: |
4707 | case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: | 4757 | case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: |
4708 | case MPI2_RAID_PD_STATE_HOT_SPARE: | 4758 | case MPI2_RAID_PD_STATE_HOT_SPARE: |
@@ -5774,6 +5824,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5774 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | 5824 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
5775 | u32 device_state; | 5825 | u32 device_state; |
5776 | 5826 | ||
5827 | mpt2sas_base_stop_watchdog(ioc); | ||
5777 | flush_scheduled_work(); | 5828 | flush_scheduled_work(); |
5778 | scsi_block_requests(shost); | 5829 | scsi_block_requests(shost); |
5779 | device_state = pci_choose_state(pdev, state); | 5830 | device_state = pci_choose_state(pdev, state); |
@@ -5816,6 +5867,7 @@ _scsih_resume(struct pci_dev *pdev) | |||
5816 | 5867 | ||
5817 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); | 5868 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); |
5818 | scsi_unblock_requests(shost); | 5869 | scsi_unblock_requests(shost); |
5870 | mpt2sas_base_start_watchdog(ioc); | ||
5819 | return 0; | 5871 | return 0; |
5820 | } | 5872 | } |
5821 | #endif /* CONFIG_PM */ | 5873 | #endif /* CONFIG_PM */ |
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 3fe9742c23ca..2f8643efe92c 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
38 | 38 | ||
39 | #include <asm/addrspace.h> | 39 | #include <asm/addrspace.h> |
40 | #include <asm/ar7/ar7.h> | 40 | #include <asm/mach-ar7/ar7.h> |
41 | 41 | ||
42 | #define DRVNAME "ar7_wdt" | 42 | #define DRVNAME "ar7_wdt" |
43 | #define LONGNAME "TI AR7 Watchdog Timer" | 43 | #define LONGNAME "TI AR7 Watchdog Timer" |