aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/vme/bridges/vme_tsi148.c
diff options
context:
space:
mode:
authorMartyn Welch <martyn.welch@gefanuc.com>2009-08-11 11:20:22 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-15 15:02:11 -0400
commit400822fec46ce69d2ba7692689a1689653f7b847 (patch)
tree2ceb1f136ca514a17d8a14e38dfcc7595d192add /drivers/staging/vme/bridges/vme_tsi148.c
parent238add523bf9c89db1a191599fff2770af55e0fd (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.c86
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! */
76void *crcsr_kernel; 76void *crcsr_kernel;
77dma_addr_t crcsr_bus; 77dma_addr_t crcsr_bus;
78struct vme_master_resource *flush_image; 78struct vme_master_resource *flush_image;
79struct semaphore vme_rmw; /* Only one RMW cycle at a time */ 79struct mutex vme_rmw; /* Only one RMW cycle at a time */
80struct semaphore vme_int; /* 80struct 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 */
84struct semaphore vme_irq; /* Locking for VME irq callback configuration */ 84struct mutex vme_irq; /* Locking for VME irq callback configuration */
85struct semaphore vme_lm; /* Locking for location monitor operations */ 85struct mutex vme_lm; /* Locking for location monitor operations */
86 86
87 87
88static char driver_name[] = "vme_tsi148"; 88static 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 */
518int tsi148_generate_irq(int level, int statid) 512int 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 */
1385ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, 1377ssize_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));