diff options
| -rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 52 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 28 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 36 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 |
8 files changed, 98 insertions, 96 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index d4762799351d..a9041d1a8ff0 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | struct tda998x_priv { | 32 | struct tda998x_priv { |
| 33 | struct i2c_client *cec; | 33 | struct i2c_client *cec; |
| 34 | struct i2c_client *hdmi; | 34 | struct i2c_client *hdmi; |
| 35 | struct mutex mutex; | ||
| 36 | struct delayed_work dwork; | ||
| 35 | uint16_t rev; | 37 | uint16_t rev; |
| 36 | uint8_t current_page; | 38 | uint8_t current_page; |
| 37 | int dpms; | 39 | int dpms; |
| @@ -402,9 +404,10 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) | |||
| 402 | uint8_t addr = REG2ADDR(reg); | 404 | uint8_t addr = REG2ADDR(reg); |
| 403 | int ret; | 405 | int ret; |
| 404 | 406 | ||
| 407 | mutex_lock(&priv->mutex); | ||
| 405 | ret = set_page(priv, reg); | 408 | ret = set_page(priv, reg); |
| 406 | if (ret < 0) | 409 | if (ret < 0) |
| 407 | return ret; | 410 | goto out; |
| 408 | 411 | ||
| 409 | ret = i2c_master_send(client, &addr, sizeof(addr)); | 412 | ret = i2c_master_send(client, &addr, sizeof(addr)); |
| 410 | if (ret < 0) | 413 | if (ret < 0) |
| @@ -414,10 +417,12 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) | |||
| 414 | if (ret < 0) | 417 | if (ret < 0) |
| 415 | goto fail; | 418 | goto fail; |
| 416 | 419 | ||
| 417 | return ret; | 420 | goto out; |
| 418 | 421 | ||
| 419 | fail: | 422 | fail: |
| 420 | dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); | 423 | dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); |
| 424 | out: | ||
| 425 | mutex_unlock(&priv->mutex); | ||
| 421 | return ret; | 426 | return ret; |
| 422 | } | 427 | } |
| 423 | 428 | ||
| @@ -431,13 +436,16 @@ reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) | |||
| 431 | buf[0] = REG2ADDR(reg); | 436 | buf[0] = REG2ADDR(reg); |
| 432 | memcpy(&buf[1], p, cnt); | 437 | memcpy(&buf[1], p, cnt); |
| 433 | 438 | ||
| 439 | mutex_lock(&priv->mutex); | ||
| 434 | ret = set_page(priv, reg); | 440 | ret = set_page(priv, reg); |
| 435 | if (ret < 0) | 441 | if (ret < 0) |
| 436 | return; | 442 | goto out; |
| 437 | 443 | ||
| 438 | ret = i2c_master_send(client, buf, cnt + 1); | 444 | ret = i2c_master_send(client, buf, cnt + 1); |
| 439 | if (ret < 0) | 445 | if (ret < 0) |
| 440 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 446 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 447 | out: | ||
| 448 | mutex_unlock(&priv->mutex); | ||
| 441 | } | 449 | } |
| 442 | 450 | ||
| 443 | static int | 451 | static int |
| @@ -459,13 +467,16 @@ reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val) | |||
| 459 | uint8_t buf[] = {REG2ADDR(reg), val}; | 467 | uint8_t buf[] = {REG2ADDR(reg), val}; |
| 460 | int ret; | 468 | int ret; |
| 461 | 469 | ||
| 470 | mutex_lock(&priv->mutex); | ||
| 462 | ret = set_page(priv, reg); | 471 | ret = set_page(priv, reg); |
| 463 | if (ret < 0) | 472 | if (ret < 0) |
| 464 | return; | 473 | goto out; |
| 465 | 474 | ||
| 466 | ret = i2c_master_send(client, buf, sizeof(buf)); | 475 | ret = i2c_master_send(client, buf, sizeof(buf)); |
| 467 | if (ret < 0) | 476 | if (ret < 0) |
| 468 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 477 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 478 | out: | ||
| 479 | mutex_unlock(&priv->mutex); | ||
| 469 | } | 480 | } |
| 470 | 481 | ||
| 471 | static void | 482 | static void |
| @@ -475,13 +486,16 @@ reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val) | |||
| 475 | uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; | 486 | uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; |
| 476 | int ret; | 487 | int ret; |
| 477 | 488 | ||
| 489 | mutex_lock(&priv->mutex); | ||
| 478 | ret = set_page(priv, reg); | 490 | ret = set_page(priv, reg); |
| 479 | if (ret < 0) | 491 | if (ret < 0) |
| 480 | return; | 492 | goto out; |
| 481 | 493 | ||
| 482 | ret = i2c_master_send(client, buf, sizeof(buf)); | 494 | ret = i2c_master_send(client, buf, sizeof(buf)); |
| 483 | if (ret < 0) | 495 | if (ret < 0) |
| 484 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 496 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 497 | out: | ||
| 498 | mutex_unlock(&priv->mutex); | ||
| 485 | } | 499 | } |
| 486 | 500 | ||
| 487 | static void | 501 | static void |
| @@ -536,6 +550,17 @@ tda998x_reset(struct tda998x_priv *priv) | |||
| 536 | reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); | 550 | reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); |
| 537 | } | 551 | } |
| 538 | 552 | ||
| 553 | /* handle HDMI connect/disconnect */ | ||
| 554 | static void tda998x_hpd(struct work_struct *work) | ||
| 555 | { | ||
| 556 | struct delayed_work *dwork = to_delayed_work(work); | ||
| 557 | struct tda998x_priv *priv = | ||
| 558 | container_of(dwork, struct tda998x_priv, dwork); | ||
| 559 | |||
| 560 | if (priv->encoder && priv->encoder->dev) | ||
| 561 | drm_kms_helper_hotplug_event(priv->encoder->dev); | ||
| 562 | } | ||
| 563 | |||
| 539 | /* | 564 | /* |
| 540 | * only 2 interrupts may occur: screen plug/unplug and EDID read | 565 | * only 2 interrupts may occur: screen plug/unplug and EDID read |
| 541 | */ | 566 | */ |
| @@ -559,8 +584,7 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data) | |||
| 559 | priv->wq_edid_wait = 0; | 584 | priv->wq_edid_wait = 0; |
| 560 | wake_up(&priv->wq_edid); | 585 | wake_up(&priv->wq_edid); |
| 561 | } else if (cec != 0) { /* HPD change */ | 586 | } else if (cec != 0) { /* HPD change */ |
| 562 | if (priv->encoder && priv->encoder->dev) | 587 | schedule_delayed_work(&priv->dwork, HZ/10); |
| 563 | drm_helper_hpd_irq_event(priv->encoder->dev); | ||
| 564 | } | 588 | } |
| 565 | return IRQ_HANDLED; | 589 | return IRQ_HANDLED; |
| 566 | } | 590 | } |
| @@ -1170,8 +1194,10 @@ static void tda998x_destroy(struct tda998x_priv *priv) | |||
| 1170 | /* disable all IRQs and free the IRQ handler */ | 1194 | /* disable all IRQs and free the IRQ handler */ |
| 1171 | cec_write(priv, REG_CEC_RXSHPDINTENA, 0); | 1195 | cec_write(priv, REG_CEC_RXSHPDINTENA, 0); |
| 1172 | reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); | 1196 | reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); |
| 1173 | if (priv->hdmi->irq) | 1197 | if (priv->hdmi->irq) { |
| 1174 | free_irq(priv->hdmi->irq, priv); | 1198 | free_irq(priv->hdmi->irq, priv); |
| 1199 | cancel_delayed_work_sync(&priv->dwork); | ||
| 1200 | } | ||
| 1175 | 1201 | ||
| 1176 | i2c_unregister_device(priv->cec); | 1202 | i2c_unregister_device(priv->cec); |
| 1177 | } | 1203 | } |
| @@ -1255,6 +1281,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | |||
| 1255 | struct device_node *np = client->dev.of_node; | 1281 | struct device_node *np = client->dev.of_node; |
| 1256 | u32 video; | 1282 | u32 video; |
| 1257 | int rev_lo, rev_hi, ret; | 1283 | int rev_lo, rev_hi, ret; |
| 1284 | unsigned short cec_addr; | ||
| 1258 | 1285 | ||
| 1259 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); | 1286 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); |
| 1260 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); | 1287 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); |
| @@ -1262,12 +1289,16 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | |||
| 1262 | 1289 | ||
| 1263 | priv->current_page = 0xff; | 1290 | priv->current_page = 0xff; |
| 1264 | priv->hdmi = client; | 1291 | priv->hdmi = client; |
| 1265 | priv->cec = i2c_new_dummy(client->adapter, 0x34); | 1292 | /* CEC I2C address bound to TDA998x I2C addr by configuration pins */ |
| 1293 | cec_addr = 0x34 + (client->addr & 0x03); | ||
| 1294 | priv->cec = i2c_new_dummy(client->adapter, cec_addr); | ||
| 1266 | if (!priv->cec) | 1295 | if (!priv->cec) |
| 1267 | return -ENODEV; | 1296 | return -ENODEV; |
| 1268 | 1297 | ||
| 1269 | priv->dpms = DRM_MODE_DPMS_OFF; | 1298 | priv->dpms = DRM_MODE_DPMS_OFF; |
| 1270 | 1299 | ||
| 1300 | mutex_init(&priv->mutex); /* protect the page access */ | ||
| 1301 | |||
| 1271 | /* wake up the device: */ | 1302 | /* wake up the device: */ |
| 1272 | cec_write(priv, REG_CEC_ENAMODS, | 1303 | cec_write(priv, REG_CEC_ENAMODS, |
| 1273 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); | 1304 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); |
| @@ -1323,8 +1354,9 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | |||
| 1323 | if (client->irq) { | 1354 | if (client->irq) { |
| 1324 | int irqf_trigger; | 1355 | int irqf_trigger; |
| 1325 | 1356 | ||
| 1326 | /* init read EDID waitqueue */ | 1357 | /* init read EDID waitqueue and HDP work */ |
| 1327 | init_waitqueue_head(&priv->wq_edid); | 1358 | init_waitqueue_head(&priv->wq_edid); |
| 1359 | INIT_DELAYED_WORK(&priv->dwork, tda998x_hpd); | ||
| 1328 | 1360 | ||
| 1329 | /* clear pending interrupts */ | 1361 | /* clear pending interrupts */ |
| 1330 | reg_read(priv, REG_INT_FLAGS_0); | 1362 | reg_read(priv, REG_INT_FLAGS_0); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 7b5d22110f25..6c6b655defcf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -406,11 +406,9 @@ int vmw_3d_resource_inc(struct vmw_private *dev_priv, | |||
| 406 | if (unlikely(ret != 0)) | 406 | if (unlikely(ret != 0)) |
| 407 | --dev_priv->num_3d_resources; | 407 | --dev_priv->num_3d_resources; |
| 408 | } else if (unhide_svga) { | 408 | } else if (unhide_svga) { |
| 409 | mutex_lock(&dev_priv->hw_mutex); | ||
| 410 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 409 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
| 411 | vmw_read(dev_priv, SVGA_REG_ENABLE) & | 410 | vmw_read(dev_priv, SVGA_REG_ENABLE) & |
| 412 | ~SVGA_REG_ENABLE_HIDE); | 411 | ~SVGA_REG_ENABLE_HIDE); |
| 413 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 414 | } | 412 | } |
| 415 | 413 | ||
| 416 | mutex_unlock(&dev_priv->release_mutex); | 414 | mutex_unlock(&dev_priv->release_mutex); |
| @@ -433,13 +431,10 @@ void vmw_3d_resource_dec(struct vmw_private *dev_priv, | |||
| 433 | mutex_lock(&dev_priv->release_mutex); | 431 | mutex_lock(&dev_priv->release_mutex); |
| 434 | if (unlikely(--dev_priv->num_3d_resources == 0)) | 432 | if (unlikely(--dev_priv->num_3d_resources == 0)) |
| 435 | vmw_release_device(dev_priv); | 433 | vmw_release_device(dev_priv); |
| 436 | else if (hide_svga) { | 434 | else if (hide_svga) |
| 437 | mutex_lock(&dev_priv->hw_mutex); | ||
| 438 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 435 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
| 439 | vmw_read(dev_priv, SVGA_REG_ENABLE) | | 436 | vmw_read(dev_priv, SVGA_REG_ENABLE) | |
| 440 | SVGA_REG_ENABLE_HIDE); | 437 | SVGA_REG_ENABLE_HIDE); |
| 441 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 442 | } | ||
| 443 | 438 | ||
| 444 | n3d = (int32_t) dev_priv->num_3d_resources; | 439 | n3d = (int32_t) dev_priv->num_3d_resources; |
| 445 | mutex_unlock(&dev_priv->release_mutex); | 440 | mutex_unlock(&dev_priv->release_mutex); |
| @@ -600,12 +595,14 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 600 | dev_priv->dev = dev; | 595 | dev_priv->dev = dev; |
| 601 | dev_priv->vmw_chipset = chipset; | 596 | dev_priv->vmw_chipset = chipset; |
| 602 | dev_priv->last_read_seqno = (uint32_t) -100; | 597 | dev_priv->last_read_seqno = (uint32_t) -100; |
| 603 | mutex_init(&dev_priv->hw_mutex); | ||
| 604 | mutex_init(&dev_priv->cmdbuf_mutex); | 598 | mutex_init(&dev_priv->cmdbuf_mutex); |
| 605 | mutex_init(&dev_priv->release_mutex); | 599 | mutex_init(&dev_priv->release_mutex); |
| 606 | mutex_init(&dev_priv->binding_mutex); | 600 | mutex_init(&dev_priv->binding_mutex); |
| 607 | rwlock_init(&dev_priv->resource_lock); | 601 | rwlock_init(&dev_priv->resource_lock); |
| 608 | ttm_lock_init(&dev_priv->reservation_sem); | 602 | ttm_lock_init(&dev_priv->reservation_sem); |
| 603 | spin_lock_init(&dev_priv->hw_lock); | ||
| 604 | spin_lock_init(&dev_priv->waiter_lock); | ||
| 605 | spin_lock_init(&dev_priv->cap_lock); | ||
| 609 | 606 | ||
| 610 | for (i = vmw_res_context; i < vmw_res_max; ++i) { | 607 | for (i = vmw_res_context; i < vmw_res_max; ++i) { |
| 611 | idr_init(&dev_priv->res_idr[i]); | 608 | idr_init(&dev_priv->res_idr[i]); |
| @@ -626,14 +623,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 626 | 623 | ||
| 627 | dev_priv->enable_fb = enable_fbdev; | 624 | dev_priv->enable_fb = enable_fbdev; |
| 628 | 625 | ||
| 629 | mutex_lock(&dev_priv->hw_mutex); | ||
| 630 | |||
| 631 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 626 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
| 632 | svga_id = vmw_read(dev_priv, SVGA_REG_ID); | 627 | svga_id = vmw_read(dev_priv, SVGA_REG_ID); |
| 633 | if (svga_id != SVGA_ID_2) { | 628 | if (svga_id != SVGA_ID_2) { |
| 634 | ret = -ENOSYS; | 629 | ret = -ENOSYS; |
| 635 | DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); | 630 | DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); |
| 636 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 637 | goto out_err0; | 631 | goto out_err0; |
| 638 | } | 632 | } |
| 639 | 633 | ||
| @@ -683,10 +677,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 683 | dev_priv->prim_bb_mem = dev_priv->vram_size; | 677 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
| 684 | 678 | ||
| 685 | ret = vmw_dma_masks(dev_priv); | 679 | ret = vmw_dma_masks(dev_priv); |
| 686 | if (unlikely(ret != 0)) { | 680 | if (unlikely(ret != 0)) |
| 687 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 688 | goto out_err0; | 681 | goto out_err0; |
| 689 | } | ||
| 690 | 682 | ||
| 691 | /* | 683 | /* |
| 692 | * Limit back buffer size to VRAM size. Remove this once | 684 | * Limit back buffer size to VRAM size. Remove this once |
| @@ -695,8 +687,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 695 | if (dev_priv->prim_bb_mem > dev_priv->vram_size) | 687 | if (dev_priv->prim_bb_mem > dev_priv->vram_size) |
| 696 | dev_priv->prim_bb_mem = dev_priv->vram_size; | 688 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
| 697 | 689 | ||
| 698 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 699 | |||
| 700 | vmw_print_capabilities(dev_priv->capabilities); | 690 | vmw_print_capabilities(dev_priv->capabilities); |
| 701 | 691 | ||
| 702 | if (dev_priv->capabilities & SVGA_CAP_GMR2) { | 692 | if (dev_priv->capabilities & SVGA_CAP_GMR2) { |
| @@ -1160,9 +1150,7 @@ static int vmw_master_set(struct drm_device *dev, | |||
| 1160 | if (unlikely(ret != 0)) | 1150 | if (unlikely(ret != 0)) |
| 1161 | return ret; | 1151 | return ret; |
| 1162 | vmw_kms_save_vga(dev_priv); | 1152 | vmw_kms_save_vga(dev_priv); |
| 1163 | mutex_lock(&dev_priv->hw_mutex); | ||
| 1164 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); | 1153 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); |
| 1165 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 1166 | } | 1154 | } |
| 1167 | 1155 | ||
| 1168 | if (active) { | 1156 | if (active) { |
| @@ -1196,9 +1184,7 @@ out_no_active_lock: | |||
| 1196 | if (!dev_priv->enable_fb) { | 1184 | if (!dev_priv->enable_fb) { |
| 1197 | vmw_kms_restore_vga(dev_priv); | 1185 | vmw_kms_restore_vga(dev_priv); |
| 1198 | vmw_3d_resource_dec(dev_priv, true); | 1186 | vmw_3d_resource_dec(dev_priv, true); |
| 1199 | mutex_lock(&dev_priv->hw_mutex); | ||
| 1200 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | 1187 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
| 1201 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 1202 | } | 1188 | } |
| 1203 | return ret; | 1189 | return ret; |
| 1204 | } | 1190 | } |
| @@ -1233,9 +1219,7 @@ static void vmw_master_drop(struct drm_device *dev, | |||
| 1233 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); | 1219 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); |
| 1234 | vmw_kms_restore_vga(dev_priv); | 1220 | vmw_kms_restore_vga(dev_priv); |
| 1235 | vmw_3d_resource_dec(dev_priv, true); | 1221 | vmw_3d_resource_dec(dev_priv, true); |
| 1236 | mutex_lock(&dev_priv->hw_mutex); | ||
| 1237 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | 1222 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
| 1238 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 1239 | } | 1223 | } |
| 1240 | 1224 | ||
| 1241 | dev_priv->active_master = &dev_priv->fbdev_master; | 1225 | dev_priv->active_master = &dev_priv->fbdev_master; |
| @@ -1367,10 +1351,8 @@ static void vmw_pm_complete(struct device *kdev) | |||
| 1367 | struct drm_device *dev = pci_get_drvdata(pdev); | 1351 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1368 | struct vmw_private *dev_priv = vmw_priv(dev); | 1352 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1369 | 1353 | ||
| 1370 | mutex_lock(&dev_priv->hw_mutex); | ||
| 1371 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 1354 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
| 1372 | (void) vmw_read(dev_priv, SVGA_REG_ID); | 1355 | (void) vmw_read(dev_priv, SVGA_REG_ID); |
| 1373 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 1374 | 1356 | ||
| 1375 | /** | 1357 | /** |
| 1376 | * Reclaim 3d reference held by fbdev and potentially | 1358 | * Reclaim 3d reference held by fbdev and potentially |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 4ee799b43d5d..d26a6daa9719 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -399,7 +399,8 @@ struct vmw_private { | |||
| 399 | uint32_t memory_size; | 399 | uint32_t memory_size; |
| 400 | bool has_gmr; | 400 | bool has_gmr; |
| 401 | bool has_mob; | 401 | bool has_mob; |
| 402 | struct mutex hw_mutex; | 402 | spinlock_t hw_lock; |
| 403 | spinlock_t cap_lock; | ||
| 403 | 404 | ||
| 404 | /* | 405 | /* |
| 405 | * VGA registers. | 406 | * VGA registers. |
| @@ -449,8 +450,9 @@ struct vmw_private { | |||
| 449 | atomic_t marker_seq; | 450 | atomic_t marker_seq; |
| 450 | wait_queue_head_t fence_queue; | 451 | wait_queue_head_t fence_queue; |
| 451 | wait_queue_head_t fifo_queue; | 452 | wait_queue_head_t fifo_queue; |
| 452 | int fence_queue_waiters; /* Protected by hw_mutex */ | 453 | spinlock_t waiter_lock; |
| 453 | int goal_queue_waiters; /* Protected by hw_mutex */ | 454 | int fence_queue_waiters; /* Protected by waiter_lock */ |
| 455 | int goal_queue_waiters; /* Protected by waiter_lock */ | ||
| 454 | atomic_t fifo_queue_waiters; | 456 | atomic_t fifo_queue_waiters; |
| 455 | uint32_t last_read_seqno; | 457 | uint32_t last_read_seqno; |
| 456 | spinlock_t irq_lock; | 458 | spinlock_t irq_lock; |
| @@ -553,20 +555,35 @@ static inline struct vmw_master *vmw_master(struct drm_master *master) | |||
| 553 | return (struct vmw_master *) master->driver_priv; | 555 | return (struct vmw_master *) master->driver_priv; |
| 554 | } | 556 | } |
| 555 | 557 | ||
| 558 | /* | ||
| 559 | * The locking here is fine-grained, so that it is performed once | ||
| 560 | * for every read- and write operation. This is of course costly, but we | ||
| 561 | * don't perform much register access in the timing critical paths anyway. | ||
| 562 | * Instead we have the extra benefit of being sure that we don't forget | ||
| 563 | * the hw lock around register accesses. | ||
| 564 | */ | ||
| 556 | static inline void vmw_write(struct vmw_private *dev_priv, | 565 | static inline void vmw_write(struct vmw_private *dev_priv, |
| 557 | unsigned int offset, uint32_t value) | 566 | unsigned int offset, uint32_t value) |
| 558 | { | 567 | { |
| 568 | unsigned long irq_flags; | ||
| 569 | |||
| 570 | spin_lock_irqsave(&dev_priv->hw_lock, irq_flags); | ||
| 559 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); | 571 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); |
| 560 | outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT); | 572 | outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT); |
| 573 | spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags); | ||
| 561 | } | 574 | } |
| 562 | 575 | ||
| 563 | static inline uint32_t vmw_read(struct vmw_private *dev_priv, | 576 | static inline uint32_t vmw_read(struct vmw_private *dev_priv, |
| 564 | unsigned int offset) | 577 | unsigned int offset) |
| 565 | { | 578 | { |
| 566 | uint32_t val; | 579 | unsigned long irq_flags; |
| 580 | u32 val; | ||
| 567 | 581 | ||
| 582 | spin_lock_irqsave(&dev_priv->hw_lock, irq_flags); | ||
| 568 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); | 583 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); |
| 569 | val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT); | 584 | val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT); |
| 585 | spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags); | ||
| 586 | |||
| 570 | return val; | 587 | return val; |
| 571 | } | 588 | } |
| 572 | 589 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index b7594cb758af..945f1e0dad92 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | |||
| @@ -35,7 +35,7 @@ struct vmw_fence_manager { | |||
| 35 | struct vmw_private *dev_priv; | 35 | struct vmw_private *dev_priv; |
| 36 | spinlock_t lock; | 36 | spinlock_t lock; |
| 37 | struct list_head fence_list; | 37 | struct list_head fence_list; |
| 38 | struct work_struct work, ping_work; | 38 | struct work_struct work; |
| 39 | u32 user_fence_size; | 39 | u32 user_fence_size; |
| 40 | u32 fence_size; | 40 | u32 fence_size; |
| 41 | u32 event_fence_action_size; | 41 | u32 event_fence_action_size; |
| @@ -134,14 +134,6 @@ static const char *vmw_fence_get_timeline_name(struct fence *f) | |||
| 134 | return "svga"; | 134 | return "svga"; |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static void vmw_fence_ping_func(struct work_struct *work) | ||
| 138 | { | ||
| 139 | struct vmw_fence_manager *fman = | ||
| 140 | container_of(work, struct vmw_fence_manager, ping_work); | ||
| 141 | |||
| 142 | vmw_fifo_ping_host(fman->dev_priv, SVGA_SYNC_GENERIC); | ||
| 143 | } | ||
| 144 | |||
| 145 | static bool vmw_fence_enable_signaling(struct fence *f) | 137 | static bool vmw_fence_enable_signaling(struct fence *f) |
| 146 | { | 138 | { |
| 147 | struct vmw_fence_obj *fence = | 139 | struct vmw_fence_obj *fence = |
| @@ -155,11 +147,7 @@ static bool vmw_fence_enable_signaling(struct fence *f) | |||
| 155 | if (seqno - fence->base.seqno < VMW_FENCE_WRAP) | 147 | if (seqno - fence->base.seqno < VMW_FENCE_WRAP) |
| 156 | return false; | 148 | return false; |
| 157 | 149 | ||
| 158 | if (mutex_trylock(&dev_priv->hw_mutex)) { | 150 | vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); |
| 159 | vmw_fifo_ping_host_locked(dev_priv, SVGA_SYNC_GENERIC); | ||
| 160 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 161 | } else | ||
| 162 | schedule_work(&fman->ping_work); | ||
| 163 | 151 | ||
| 164 | return true; | 152 | return true; |
| 165 | } | 153 | } |
| @@ -305,7 +293,6 @@ struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv) | |||
| 305 | INIT_LIST_HEAD(&fman->fence_list); | 293 | INIT_LIST_HEAD(&fman->fence_list); |
| 306 | INIT_LIST_HEAD(&fman->cleanup_list); | 294 | INIT_LIST_HEAD(&fman->cleanup_list); |
| 307 | INIT_WORK(&fman->work, &vmw_fence_work_func); | 295 | INIT_WORK(&fman->work, &vmw_fence_work_func); |
| 308 | INIT_WORK(&fman->ping_work, &vmw_fence_ping_func); | ||
| 309 | fman->fifo_down = true; | 296 | fman->fifo_down = true; |
| 310 | fman->user_fence_size = ttm_round_pot(sizeof(struct vmw_user_fence)); | 297 | fman->user_fence_size = ttm_round_pot(sizeof(struct vmw_user_fence)); |
| 311 | fman->fence_size = ttm_round_pot(sizeof(struct vmw_fence_obj)); | 298 | fman->fence_size = ttm_round_pot(sizeof(struct vmw_fence_obj)); |
| @@ -323,7 +310,6 @@ void vmw_fence_manager_takedown(struct vmw_fence_manager *fman) | |||
| 323 | bool lists_empty; | 310 | bool lists_empty; |
| 324 | 311 | ||
| 325 | (void) cancel_work_sync(&fman->work); | 312 | (void) cancel_work_sync(&fman->work); |
| 326 | (void) cancel_work_sync(&fman->ping_work); | ||
| 327 | 313 | ||
| 328 | spin_lock_irqsave(&fman->lock, irq_flags); | 314 | spin_lock_irqsave(&fman->lock, irq_flags); |
| 329 | lists_empty = list_empty(&fman->fence_list) && | 315 | lists_empty = list_empty(&fman->fence_list) && |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 09e10aefcd8e..39f2b03888e7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
| @@ -44,10 +44,10 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) | |||
| 44 | if (!dev_priv->has_mob) | 44 | if (!dev_priv->has_mob) |
| 45 | return false; | 45 | return false; |
| 46 | 46 | ||
| 47 | mutex_lock(&dev_priv->hw_mutex); | 47 | spin_lock(&dev_priv->cap_lock); |
| 48 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_3D); | 48 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_3D); |
| 49 | result = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 49 | result = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
| 50 | mutex_unlock(&dev_priv->hw_mutex); | 50 | spin_unlock(&dev_priv->cap_lock); |
| 51 | 51 | ||
| 52 | return (result != 0); | 52 | return (result != 0); |
| 53 | } | 53 | } |
| @@ -120,7 +120,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
| 120 | DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); | 120 | DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); |
| 121 | DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); | 121 | DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); |
| 122 | 122 | ||
| 123 | mutex_lock(&dev_priv->hw_mutex); | ||
| 124 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); | 123 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); |
| 125 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); | 124 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); |
| 126 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); | 125 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); |
| @@ -143,7 +142,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
| 143 | mb(); | 142 | mb(); |
| 144 | 143 | ||
| 145 | vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); | 144 | vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); |
| 146 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 147 | 145 | ||
| 148 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); | 146 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); |
| 149 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); | 147 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); |
| @@ -160,31 +158,28 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
| 160 | return vmw_fifo_send_fence(dev_priv, &dummy); | 158 | return vmw_fifo_send_fence(dev_priv, &dummy); |
| 161 | } | 159 | } |
| 162 | 160 | ||
| 163 | void vmw_fifo_ping_host_locked(struct vmw_private *dev_priv, uint32_t reason) | 161 | void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) |
| 164 | { | 162 | { |
| 165 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 163 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
| 164 | static DEFINE_SPINLOCK(ping_lock); | ||
| 165 | unsigned long irq_flags; | ||
| 166 | 166 | ||
| 167 | /* | ||
| 168 | * The ping_lock is needed because we don't have an atomic | ||
| 169 | * test-and-set of the SVGA_FIFO_BUSY register. | ||
| 170 | */ | ||
| 171 | spin_lock_irqsave(&ping_lock, irq_flags); | ||
| 167 | if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) { | 172 | if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) { |
| 168 | iowrite32(1, fifo_mem + SVGA_FIFO_BUSY); | 173 | iowrite32(1, fifo_mem + SVGA_FIFO_BUSY); |
| 169 | vmw_write(dev_priv, SVGA_REG_SYNC, reason); | 174 | vmw_write(dev_priv, SVGA_REG_SYNC, reason); |
| 170 | } | 175 | } |
| 171 | } | 176 | spin_unlock_irqrestore(&ping_lock, irq_flags); |
| 172 | |||
| 173 | void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) | ||
| 174 | { | ||
| 175 | mutex_lock(&dev_priv->hw_mutex); | ||
| 176 | |||
| 177 | vmw_fifo_ping_host_locked(dev_priv, reason); | ||
| 178 | |||
| 179 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 180 | } | 177 | } |
| 181 | 178 | ||
| 182 | void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | 179 | void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) |
| 183 | { | 180 | { |
| 184 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 181 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
| 185 | 182 | ||
| 186 | mutex_lock(&dev_priv->hw_mutex); | ||
| 187 | |||
| 188 | vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); | 183 | vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); |
| 189 | while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) | 184 | while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) |
| 190 | ; | 185 | ; |
| @@ -198,7 +193,6 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
| 198 | vmw_write(dev_priv, SVGA_REG_TRACES, | 193 | vmw_write(dev_priv, SVGA_REG_TRACES, |
| 199 | dev_priv->traces_state); | 194 | dev_priv->traces_state); |
| 200 | 195 | ||
| 201 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 202 | vmw_marker_queue_takedown(&fifo->marker_queue); | 196 | vmw_marker_queue_takedown(&fifo->marker_queue); |
| 203 | 197 | ||
| 204 | if (likely(fifo->static_buffer != NULL)) { | 198 | if (likely(fifo->static_buffer != NULL)) { |
| @@ -271,7 +265,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, | |||
| 271 | return vmw_fifo_wait_noirq(dev_priv, bytes, | 265 | return vmw_fifo_wait_noirq(dev_priv, bytes, |
| 272 | interruptible, timeout); | 266 | interruptible, timeout); |
| 273 | 267 | ||
| 274 | mutex_lock(&dev_priv->hw_mutex); | 268 | spin_lock(&dev_priv->waiter_lock); |
| 275 | if (atomic_add_return(1, &dev_priv->fifo_queue_waiters) > 0) { | 269 | if (atomic_add_return(1, &dev_priv->fifo_queue_waiters) > 0) { |
| 276 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); | 270 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
| 277 | outl(SVGA_IRQFLAG_FIFO_PROGRESS, | 271 | outl(SVGA_IRQFLAG_FIFO_PROGRESS, |
| @@ -280,7 +274,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, | |||
| 280 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 274 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 281 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 275 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 282 | } | 276 | } |
| 283 | mutex_unlock(&dev_priv->hw_mutex); | 277 | spin_unlock(&dev_priv->waiter_lock); |
| 284 | 278 | ||
| 285 | if (interruptible) | 279 | if (interruptible) |
| 286 | ret = wait_event_interruptible_timeout | 280 | ret = wait_event_interruptible_timeout |
| @@ -296,14 +290,14 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, | |||
| 296 | else if (likely(ret > 0)) | 290 | else if (likely(ret > 0)) |
| 297 | ret = 0; | 291 | ret = 0; |
| 298 | 292 | ||
| 299 | mutex_lock(&dev_priv->hw_mutex); | 293 | spin_lock(&dev_priv->waiter_lock); |
| 300 | if (atomic_dec_and_test(&dev_priv->fifo_queue_waiters)) { | 294 | if (atomic_dec_and_test(&dev_priv->fifo_queue_waiters)) { |
| 301 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); | 295 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
| 302 | dev_priv->irq_mask &= ~SVGA_IRQFLAG_FIFO_PROGRESS; | 296 | dev_priv->irq_mask &= ~SVGA_IRQFLAG_FIFO_PROGRESS; |
| 303 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 297 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 304 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 298 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 305 | } | 299 | } |
| 306 | mutex_unlock(&dev_priv->hw_mutex); | 300 | spin_unlock(&dev_priv->waiter_lock); |
| 307 | 301 | ||
| 308 | return ret; | 302 | return ret; |
| 309 | } | 303 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 37881ecf5d7a..69c8ce23123c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
| @@ -135,13 +135,13 @@ static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, | |||
| 135 | (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); | 135 | (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); |
| 136 | compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; | 136 | compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; |
| 137 | 137 | ||
| 138 | mutex_lock(&dev_priv->hw_mutex); | 138 | spin_lock(&dev_priv->cap_lock); |
| 139 | for (i = 0; i < max_size; ++i) { | 139 | for (i = 0; i < max_size; ++i) { |
| 140 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | 140 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
| 141 | compat_cap->pairs[i][0] = i; | 141 | compat_cap->pairs[i][0] = i; |
| 142 | compat_cap->pairs[i][1] = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 142 | compat_cap->pairs[i][1] = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
| 143 | } | 143 | } |
| 144 | mutex_unlock(&dev_priv->hw_mutex); | 144 | spin_unlock(&dev_priv->cap_lock); |
| 145 | 145 | ||
| 146 | return 0; | 146 | return 0; |
| 147 | } | 147 | } |
| @@ -191,12 +191,12 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
| 191 | if (num > SVGA3D_DEVCAP_MAX) | 191 | if (num > SVGA3D_DEVCAP_MAX) |
| 192 | num = SVGA3D_DEVCAP_MAX; | 192 | num = SVGA3D_DEVCAP_MAX; |
| 193 | 193 | ||
| 194 | mutex_lock(&dev_priv->hw_mutex); | 194 | spin_lock(&dev_priv->cap_lock); |
| 195 | for (i = 0; i < num; ++i) { | 195 | for (i = 0; i < num; ++i) { |
| 196 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | 196 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
| 197 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 197 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
| 198 | } | 198 | } |
| 199 | mutex_unlock(&dev_priv->hw_mutex); | 199 | spin_unlock(&dev_priv->cap_lock); |
| 200 | } else if (gb_objects) { | 200 | } else if (gb_objects) { |
| 201 | ret = vmw_fill_compat_cap(dev_priv, bounce, size); | 201 | ret = vmw_fill_compat_cap(dev_priv, bounce, size); |
| 202 | if (unlikely(ret != 0)) | 202 | if (unlikely(ret != 0)) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index 0c423766c441..9fe9827ee499 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | |||
| @@ -62,13 +62,8 @@ irqreturn_t vmw_irq_handler(int irq, void *arg) | |||
| 62 | 62 | ||
| 63 | static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno) | 63 | static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno) |
| 64 | { | 64 | { |
| 65 | uint32_t busy; | ||
| 66 | 65 | ||
| 67 | mutex_lock(&dev_priv->hw_mutex); | 66 | return (vmw_read(dev_priv, SVGA_REG_BUSY) == 0); |
| 68 | busy = vmw_read(dev_priv, SVGA_REG_BUSY); | ||
| 69 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 70 | |||
| 71 | return (busy == 0); | ||
| 72 | } | 67 | } |
| 73 | 68 | ||
| 74 | void vmw_update_seqno(struct vmw_private *dev_priv, | 69 | void vmw_update_seqno(struct vmw_private *dev_priv, |
| @@ -184,7 +179,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, | |||
| 184 | 179 | ||
| 185 | void vmw_seqno_waiter_add(struct vmw_private *dev_priv) | 180 | void vmw_seqno_waiter_add(struct vmw_private *dev_priv) |
| 186 | { | 181 | { |
| 187 | mutex_lock(&dev_priv->hw_mutex); | 182 | spin_lock(&dev_priv->waiter_lock); |
| 188 | if (dev_priv->fence_queue_waiters++ == 0) { | 183 | if (dev_priv->fence_queue_waiters++ == 0) { |
| 189 | unsigned long irq_flags; | 184 | unsigned long irq_flags; |
| 190 | 185 | ||
| @@ -195,12 +190,12 @@ void vmw_seqno_waiter_add(struct vmw_private *dev_priv) | |||
| 195 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 190 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 196 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 191 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 197 | } | 192 | } |
| 198 | mutex_unlock(&dev_priv->hw_mutex); | 193 | spin_unlock(&dev_priv->waiter_lock); |
| 199 | } | 194 | } |
| 200 | 195 | ||
| 201 | void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) | 196 | void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) |
| 202 | { | 197 | { |
| 203 | mutex_lock(&dev_priv->hw_mutex); | 198 | spin_lock(&dev_priv->waiter_lock); |
| 204 | if (--dev_priv->fence_queue_waiters == 0) { | 199 | if (--dev_priv->fence_queue_waiters == 0) { |
| 205 | unsigned long irq_flags; | 200 | unsigned long irq_flags; |
| 206 | 201 | ||
| @@ -209,13 +204,13 @@ void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) | |||
| 209 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 204 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 210 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 205 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 211 | } | 206 | } |
| 212 | mutex_unlock(&dev_priv->hw_mutex); | 207 | spin_unlock(&dev_priv->waiter_lock); |
| 213 | } | 208 | } |
| 214 | 209 | ||
| 215 | 210 | ||
| 216 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) | 211 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) |
| 217 | { | 212 | { |
| 218 | mutex_lock(&dev_priv->hw_mutex); | 213 | spin_lock(&dev_priv->waiter_lock); |
| 219 | if (dev_priv->goal_queue_waiters++ == 0) { | 214 | if (dev_priv->goal_queue_waiters++ == 0) { |
| 220 | unsigned long irq_flags; | 215 | unsigned long irq_flags; |
| 221 | 216 | ||
| @@ -226,12 +221,12 @@ void vmw_goal_waiter_add(struct vmw_private *dev_priv) | |||
| 226 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 221 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 227 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 222 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 228 | } | 223 | } |
| 229 | mutex_unlock(&dev_priv->hw_mutex); | 224 | spin_unlock(&dev_priv->waiter_lock); |
| 230 | } | 225 | } |
| 231 | 226 | ||
| 232 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) | 227 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) |
| 233 | { | 228 | { |
| 234 | mutex_lock(&dev_priv->hw_mutex); | 229 | spin_lock(&dev_priv->waiter_lock); |
| 235 | if (--dev_priv->goal_queue_waiters == 0) { | 230 | if (--dev_priv->goal_queue_waiters == 0) { |
| 236 | unsigned long irq_flags; | 231 | unsigned long irq_flags; |
| 237 | 232 | ||
| @@ -240,7 +235,7 @@ void vmw_goal_waiter_remove(struct vmw_private *dev_priv) | |||
| 240 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 235 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
| 241 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 236 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
| 242 | } | 237 | } |
| 243 | mutex_unlock(&dev_priv->hw_mutex); | 238 | spin_unlock(&dev_priv->waiter_lock); |
| 244 | } | 239 | } |
| 245 | 240 | ||
| 246 | int vmw_wait_seqno(struct vmw_private *dev_priv, | 241 | int vmw_wait_seqno(struct vmw_private *dev_priv, |
| @@ -315,9 +310,7 @@ void vmw_irq_uninstall(struct drm_device *dev) | |||
| 315 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) | 310 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) |
| 316 | return; | 311 | return; |
| 317 | 312 | ||
| 318 | mutex_lock(&dev_priv->hw_mutex); | ||
| 319 | vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); | 313 | vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); |
| 320 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 321 | 314 | ||
| 322 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); | 315 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
| 323 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); | 316 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 3725b521d931..8725b79e7847 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -1828,9 +1828,7 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force) | |||
| 1828 | struct vmw_private *dev_priv = vmw_priv(dev); | 1828 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1829 | struct vmw_display_unit *du = vmw_connector_to_du(connector); | 1829 | struct vmw_display_unit *du = vmw_connector_to_du(connector); |
| 1830 | 1830 | ||
| 1831 | mutex_lock(&dev_priv->hw_mutex); | ||
| 1832 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); | 1831 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); |
| 1833 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 1834 | 1832 | ||
| 1835 | return ((vmw_connector_to_du(connector)->unit < num_displays && | 1833 | return ((vmw_connector_to_du(connector)->unit < num_displays && |
| 1836 | du->pref_active) ? | 1834 | du->pref_active) ? |
