diff options
author | Martyn Welch <martyn.welch@gefanuc.com> | 2009-08-11 11:20:22 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 15:02:11 -0400 |
commit | 400822fec46ce69d2ba7692689a1689653f7b847 (patch) | |
tree | 2ceb1f136ca514a17d8a14e38dfcc7595d192add /drivers/staging/vme/bridges/vme_tsi148.c | |
parent | 238add523bf9c89db1a191599fff2770af55e0fd (diff) |
Staging: Use proper mutexes in the tsi-148 VME driver
The VME core and tsi-148 driver currently use semaphores as mutexes. Switch to proper
mutex implementation.
Signed-off-by: Martyn Welch <martyn.welch@gefanuc.com>
Reviewed-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/vme/bridges/vme_tsi148.c')
-rw-r--r-- | drivers/staging/vme/bridges/vme_tsi148.c | 86 |
1 files changed, 37 insertions, 49 deletions
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index a4929ad3f08..cc4955ac125 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c | |||
@@ -76,13 +76,13 @@ void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */ | |||
76 | void *crcsr_kernel; | 76 | void *crcsr_kernel; |
77 | dma_addr_t crcsr_bus; | 77 | dma_addr_t crcsr_bus; |
78 | struct vme_master_resource *flush_image; | 78 | struct vme_master_resource *flush_image; |
79 | struct semaphore vme_rmw; /* Only one RMW cycle at a time */ | 79 | struct mutex vme_rmw; /* Only one RMW cycle at a time */ |
80 | struct semaphore vme_int; /* | 80 | struct mutex vme_int; /* |
81 | * Only one VME interrupt can be | 81 | * Only one VME interrupt can be |
82 | * generated at a time, provide locking | 82 | * generated at a time, provide locking |
83 | */ | 83 | */ |
84 | struct semaphore vme_irq; /* Locking for VME irq callback configuration */ | 84 | struct mutex vme_irq; /* Locking for VME irq callback configuration */ |
85 | struct semaphore vme_lm; /* Locking for location monitor operations */ | 85 | struct mutex vme_lm; /* Locking for location monitor operations */ |
86 | 86 | ||
87 | 87 | ||
88 | static char driver_name[] = "vme_tsi148"; | 88 | static char driver_name[] = "vme_tsi148"; |
@@ -445,11 +445,10 @@ int tsi148_request_irq(int level, int statid, | |||
445 | { | 445 | { |
446 | u32 tmp; | 446 | u32 tmp; |
447 | 447 | ||
448 | /* Get semaphore */ | 448 | mutex_lock(&(vme_irq)); |
449 | down(&(vme_irq)); | ||
450 | 449 | ||
451 | if(tsi148_bridge->irq[level - 1].callback[statid].func) { | 450 | if(tsi148_bridge->irq[level - 1].callback[statid].func) { |
452 | up(&(vme_irq)); | 451 | mutex_unlock(&(vme_irq)); |
453 | printk("VME Interrupt already taken\n"); | 452 | printk("VME Interrupt already taken\n"); |
454 | return -EBUSY; | 453 | return -EBUSY; |
455 | } | 454 | } |
@@ -468,8 +467,7 @@ int tsi148_request_irq(int level, int statid, | |||
468 | tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; | 467 | tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; |
469 | iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); | 468 | iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); |
470 | 469 | ||
471 | /* Release semaphore */ | 470 | mutex_unlock(&(vme_irq)); |
472 | up(&(vme_irq)); | ||
473 | 471 | ||
474 | return 0; | 472 | return 0; |
475 | } | 473 | } |
@@ -482,8 +480,7 @@ void tsi148_free_irq(int level, int statid) | |||
482 | u32 tmp; | 480 | u32 tmp; |
483 | struct pci_dev *pdev; | 481 | struct pci_dev *pdev; |
484 | 482 | ||
485 | /* Get semaphore */ | 483 | mutex_lock(&(vme_irq)); |
486 | down(&(vme_irq)); | ||
487 | 484 | ||
488 | tsi148_bridge->irq[level - 1].count--; | 485 | tsi148_bridge->irq[level - 1].count--; |
489 | 486 | ||
@@ -505,22 +502,18 @@ void tsi148_free_irq(int level, int statid) | |||
505 | tsi148_bridge->irq[level - 1].callback[statid].func = NULL; | 502 | tsi148_bridge->irq[level - 1].callback[statid].func = NULL; |
506 | tsi148_bridge->irq[level - 1].callback[statid].priv_data = NULL; | 503 | tsi148_bridge->irq[level - 1].callback[statid].priv_data = NULL; |
507 | 504 | ||
508 | /* Release semaphore */ | 505 | mutex_unlock(&(vme_irq)); |
509 | up(&(vme_irq)); | ||
510 | } | 506 | } |
511 | 507 | ||
512 | /* | 508 | /* |
513 | * Generate a VME bus interrupt at the requested level & vector. Wait for | 509 | * Generate a VME bus interrupt at the requested level & vector. Wait for |
514 | * interrupt to be acked. | 510 | * interrupt to be acked. |
515 | * | ||
516 | * Only one interrupt can be generated at a time - so add a semaphore. | ||
517 | */ | 511 | */ |
518 | int tsi148_generate_irq(int level, int statid) | 512 | int tsi148_generate_irq(int level, int statid) |
519 | { | 513 | { |
520 | u32 tmp; | 514 | u32 tmp; |
521 | 515 | ||
522 | /* Get semaphore */ | 516 | mutex_lock(&(vme_int)); |
523 | down(&(vme_int)); | ||
524 | 517 | ||
525 | /* Read VICR register */ | 518 | /* Read VICR register */ |
526 | tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR); | 519 | tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR); |
@@ -537,8 +530,7 @@ int tsi148_generate_irq(int level, int statid) | |||
537 | /* XXX Consider implementing a timeout? */ | 530 | /* XXX Consider implementing a timeout? */ |
538 | wait_event_interruptible(iack_queue, tsi148_iack_received()); | 531 | wait_event_interruptible(iack_queue, tsi148_iack_received()); |
539 | 532 | ||
540 | /* Release semaphore */ | 533 | mutex_unlock(&(vme_int)); |
541 | up(&(vme_int)); | ||
542 | 534 | ||
543 | return 0; | 535 | return 0; |
544 | } | 536 | } |
@@ -1379,7 +1371,7 @@ skip_chk: | |||
1379 | } | 1371 | } |
1380 | 1372 | ||
1381 | 1373 | ||
1382 | /* XXX We need to change vme_master_resource->sem to a spinlock so that read | 1374 | /* XXX We need to change vme_master_resource->mtx to a spinlock so that read |
1383 | * and write functions can be used in an interrupt context | 1375 | * and write functions can be used in an interrupt context |
1384 | */ | 1376 | */ |
1385 | ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, | 1377 | ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, |
@@ -1455,7 +1447,7 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, | |||
1455 | i = image->number; | 1447 | i = image->number; |
1456 | 1448 | ||
1457 | /* Locking as we can only do one of these at a time */ | 1449 | /* Locking as we can only do one of these at a time */ |
1458 | down(&(vme_rmw)); | 1450 | mutex_lock(&(vme_rmw)); |
1459 | 1451 | ||
1460 | /* Lock image */ | 1452 | /* Lock image */ |
1461 | spin_lock(&(image->lock)); | 1453 | spin_lock(&(image->lock)); |
@@ -1490,7 +1482,7 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, | |||
1490 | 1482 | ||
1491 | spin_unlock(&(image->lock)); | 1483 | spin_unlock(&(image->lock)); |
1492 | 1484 | ||
1493 | up(&(vme_rmw)); | 1485 | mutex_unlock(&(vme_rmw)); |
1494 | 1486 | ||
1495 | return result; | 1487 | return result; |
1496 | } | 1488 | } |
@@ -1867,7 +1859,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) | |||
1867 | 1859 | ||
1868 | ctrlr = list->parent; | 1860 | ctrlr = list->parent; |
1869 | 1861 | ||
1870 | down(&(ctrlr->sem)); | 1862 | mutex_lock(&(ctrlr->mtx)); |
1871 | 1863 | ||
1872 | channel = ctrlr->number; | 1864 | channel = ctrlr->number; |
1873 | 1865 | ||
@@ -1878,7 +1870,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) | |||
1878 | * Return busy. | 1870 | * Return busy. |
1879 | */ | 1871 | */ |
1880 | /* Need to add to pending here */ | 1872 | /* Need to add to pending here */ |
1881 | up(&(ctrlr->sem)); | 1873 | mutex_unlock(&(ctrlr->mtx)); |
1882 | return -EBUSY; | 1874 | return -EBUSY; |
1883 | } else { | 1875 | } else { |
1884 | list_add(&(list->list), &(ctrlr->running)); | 1876 | list_add(&(list->list), &(ctrlr->running)); |
@@ -1932,7 +1924,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) | |||
1932 | 1924 | ||
1933 | bus_addr = virt_to_bus(&(entry->descriptor)); | 1925 | bus_addr = virt_to_bus(&(entry->descriptor)); |
1934 | 1926 | ||
1935 | up(&(ctrlr->sem)); | 1927 | mutex_unlock(&(ctrlr->mtx)); |
1936 | 1928 | ||
1937 | reg_split(bus_addr, &bus_addr_high, &bus_addr_low); | 1929 | reg_split(bus_addr, &bus_addr_high, &bus_addr_low); |
1938 | 1930 | ||
@@ -1959,9 +1951,9 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) | |||
1959 | } | 1951 | } |
1960 | 1952 | ||
1961 | /* Remove list from running list */ | 1953 | /* Remove list from running list */ |
1962 | down(&(ctrlr->sem)); | 1954 | mutex_lock(&(ctrlr->mtx)); |
1963 | list_del(&(list->list)); | 1955 | list_del(&(list->list)); |
1964 | up(&(ctrlr->sem)); | 1956 | mutex_unlock(&(ctrlr->mtx)); |
1965 | 1957 | ||
1966 | return retval; | 1958 | return retval; |
1967 | } | 1959 | } |
@@ -1999,13 +1991,12 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace, | |||
1999 | u32 lm_base_high, lm_base_low, lm_ctl = 0; | 1991 | u32 lm_base_high, lm_base_low, lm_ctl = 0; |
2000 | int i; | 1992 | int i; |
2001 | 1993 | ||
2002 | /* Get semaphore */ | 1994 | mutex_lock(&(vme_lm)); |
2003 | down(&(vme_lm)); | ||
2004 | 1995 | ||
2005 | /* If we already have a callback attached, we can't move it! */ | 1996 | /* If we already have a callback attached, we can't move it! */ |
2006 | for (i = 0; i < 4; i++) { | 1997 | for (i = 0; i < 4; i++) { |
2007 | if(lm_callback[i] != NULL) { | 1998 | if(lm_callback[i] != NULL) { |
2008 | up(&(vme_lm)); | 1999 | mutex_unlock(&(vme_lm)); |
2009 | printk("Location monitor callback attached, can't " | 2000 | printk("Location monitor callback attached, can't " |
2010 | "reset\n"); | 2001 | "reset\n"); |
2011 | return -EBUSY; | 2002 | return -EBUSY; |
@@ -2026,7 +2017,7 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace, | |||
2026 | lm_ctl |= TSI148_LCSR_LMAT_AS_A64; | 2017 | lm_ctl |= TSI148_LCSR_LMAT_AS_A64; |
2027 | break; | 2018 | break; |
2028 | default: | 2019 | default: |
2029 | up(&(vme_lm)); | 2020 | mutex_unlock(&(vme_lm)); |
2030 | printk("Invalid address space\n"); | 2021 | printk("Invalid address space\n"); |
2031 | return -EINVAL; | 2022 | return -EINVAL; |
2032 | break; | 2023 | break; |
@@ -2047,7 +2038,7 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace, | |||
2047 | iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL); | 2038 | iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL); |
2048 | iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); | 2039 | iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); |
2049 | 2040 | ||
2050 | up(&(vme_lm)); | 2041 | mutex_unlock(&(vme_lm)); |
2051 | 2042 | ||
2052 | return 0; | 2043 | return 0; |
2053 | } | 2044 | } |
@@ -2060,8 +2051,7 @@ int tsi148_lm_get(unsigned long long *lm_base, vme_address_t *aspace, | |||
2060 | { | 2051 | { |
2061 | u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; | 2052 | u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; |
2062 | 2053 | ||
2063 | /* Get semaphore */ | 2054 | mutex_lock(&(vme_lm)); |
2064 | down(&(vme_lm)); | ||
2065 | 2055 | ||
2066 | lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU); | 2056 | lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU); |
2067 | lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL); | 2057 | lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL); |
@@ -2094,7 +2084,7 @@ int tsi148_lm_get(unsigned long long *lm_base, vme_address_t *aspace, | |||
2094 | if (lm_ctl & TSI148_LCSR_LMAT_DATA) | 2084 | if (lm_ctl & TSI148_LCSR_LMAT_DATA) |
2095 | *cycle |= VME_DATA; | 2085 | *cycle |= VME_DATA; |
2096 | 2086 | ||
2097 | up(&(vme_lm)); | 2087 | mutex_unlock(&(vme_lm)); |
2098 | 2088 | ||
2099 | return enabled; | 2089 | return enabled; |
2100 | } | 2090 | } |
@@ -2108,20 +2098,19 @@ int tsi148_lm_attach(int monitor, void (*callback)(int)) | |||
2108 | { | 2098 | { |
2109 | u32 lm_ctl, tmp; | 2099 | u32 lm_ctl, tmp; |
2110 | 2100 | ||
2111 | /* Get semaphore */ | 2101 | mutex_lock(&(vme_lm)); |
2112 | down(&(vme_lm)); | ||
2113 | 2102 | ||
2114 | /* Ensure that the location monitor is configured - need PGM or DATA */ | 2103 | /* Ensure that the location monitor is configured - need PGM or DATA */ |
2115 | lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); | 2104 | lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); |
2116 | if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { | 2105 | if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { |
2117 | up(&(vme_lm)); | 2106 | mutex_unlock(&(vme_lm)); |
2118 | printk("Location monitor not properly configured\n"); | 2107 | printk("Location monitor not properly configured\n"); |
2119 | return -EINVAL; | 2108 | return -EINVAL; |
2120 | } | 2109 | } |
2121 | 2110 | ||
2122 | /* Check that a callback isn't already attached */ | 2111 | /* Check that a callback isn't already attached */ |
2123 | if (lm_callback[monitor] != NULL) { | 2112 | if (lm_callback[monitor] != NULL) { |
2124 | up(&(vme_lm)); | 2113 | mutex_unlock(&(vme_lm)); |
2125 | printk("Existing callback attached\n"); | 2114 | printk("Existing callback attached\n"); |
2126 | return -EBUSY; | 2115 | return -EBUSY; |
2127 | } | 2116 | } |
@@ -2144,7 +2133,7 @@ int tsi148_lm_attach(int monitor, void (*callback)(int)) | |||
2144 | iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); | 2133 | iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); |
2145 | } | 2134 | } |
2146 | 2135 | ||
2147 | up(&(vme_lm)); | 2136 | mutex_unlock(&(vme_lm)); |
2148 | 2137 | ||
2149 | return 0; | 2138 | return 0; |
2150 | } | 2139 | } |
@@ -2156,8 +2145,7 @@ int tsi148_lm_detach(int monitor) | |||
2156 | { | 2145 | { |
2157 | u32 lm_en, tmp; | 2146 | u32 lm_en, tmp; |
2158 | 2147 | ||
2159 | /* Get semaphore */ | 2148 | mutex_lock(&(vme_lm)); |
2160 | down(&(vme_lm)); | ||
2161 | 2149 | ||
2162 | /* Disable Location Monitor and ensure previous interrupts are clear */ | 2150 | /* Disable Location Monitor and ensure previous interrupts are clear */ |
2163 | lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); | 2151 | lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); |
@@ -2182,7 +2170,7 @@ int tsi148_lm_detach(int monitor) | |||
2182 | iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT); | 2170 | iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT); |
2183 | } | 2171 | } |
2184 | 2172 | ||
2185 | up(&(vme_lm)); | 2173 | mutex_unlock(&(vme_lm)); |
2186 | 2174 | ||
2187 | return 0; | 2175 | return 0; |
2188 | } | 2176 | } |
@@ -2347,10 +2335,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2347 | init_waitqueue_head(&dma_queue[0]); | 2335 | init_waitqueue_head(&dma_queue[0]); |
2348 | init_waitqueue_head(&dma_queue[1]); | 2336 | init_waitqueue_head(&dma_queue[1]); |
2349 | init_waitqueue_head(&iack_queue); | 2337 | init_waitqueue_head(&iack_queue); |
2350 | init_MUTEX(&(vme_int)); | 2338 | mutex_init(&(vme_int)); |
2351 | init_MUTEX(&(vme_irq)); | 2339 | mutex_init(&(vme_irq)); |
2352 | init_MUTEX(&(vme_rmw)); | 2340 | mutex_init(&(vme_rmw)); |
2353 | init_MUTEX(&(vme_lm)); | 2341 | mutex_init(&(vme_lm)); |
2354 | 2342 | ||
2355 | tsi148_bridge->parent = &(pdev->dev); | 2343 | tsi148_bridge->parent = &(pdev->dev); |
2356 | strcpy(tsi148_bridge->name, driver_name); | 2344 | strcpy(tsi148_bridge->name, driver_name); |
@@ -2436,7 +2424,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2436 | goto err_slave; | 2424 | goto err_slave; |
2437 | } | 2425 | } |
2438 | slave_image->parent = tsi148_bridge; | 2426 | slave_image->parent = tsi148_bridge; |
2439 | init_MUTEX(&(slave_image->sem)); | 2427 | mutex_init(&(slave_image->mtx)); |
2440 | slave_image->locked = 0; | 2428 | slave_image->locked = 0; |
2441 | slave_image->number = i; | 2429 | slave_image->number = i; |
2442 | slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | | 2430 | slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | |
@@ -2462,7 +2450,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2462 | goto err_dma; | 2450 | goto err_dma; |
2463 | } | 2451 | } |
2464 | dma_ctrlr->parent = tsi148_bridge; | 2452 | dma_ctrlr->parent = tsi148_bridge; |
2465 | init_MUTEX(&(dma_ctrlr->sem)); | 2453 | mutex_init(&(dma_ctrlr->mtx)); |
2466 | dma_ctrlr->locked = 0; | 2454 | dma_ctrlr->locked = 0; |
2467 | dma_ctrlr->number = i; | 2455 | dma_ctrlr->number = i; |
2468 | INIT_LIST_HEAD(&(dma_ctrlr->pending)); | 2456 | INIT_LIST_HEAD(&(dma_ctrlr->pending)); |