diff options
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index a4bbf3dadf58..bb6a92bc9e6a 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/moduleparam.h> | 36 | #include <linux/moduleparam.h> |
37 | #include <linux/mutex.h> | ||
37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
38 | #include <linux/pci_ids.h> | 39 | #include <linux/pci_ids.h> |
39 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
@@ -182,6 +183,8 @@ struct fw_ohci { | |||
182 | */ | 183 | */ |
183 | spinlock_t lock; | 184 | spinlock_t lock; |
184 | 185 | ||
186 | struct mutex phy_reg_mutex; | ||
187 | |||
185 | struct ar_context ar_request_ctx; | 188 | struct ar_context ar_request_ctx; |
186 | struct ar_context ar_response_ctx; | 189 | struct ar_context ar_response_ctx; |
187 | struct context at_request_ctx; | 190 | struct context at_request_ctx; |
@@ -517,13 +520,10 @@ static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) | |||
517 | return -EBUSY; | 520 | return -EBUSY; |
518 | } | 521 | } |
519 | 522 | ||
520 | static int ohci_update_phy_reg(struct fw_card *card, int addr, | 523 | static int update_phy_reg(struct fw_ohci *ohci, int addr, |
521 | int clear_bits, int set_bits) | 524 | int clear_bits, int set_bits) |
522 | { | 525 | { |
523 | struct fw_ohci *ohci = fw_ohci(card); | 526 | int ret = read_phy_reg(ohci, addr); |
524 | int ret; | ||
525 | |||
526 | ret = read_phy_reg(ohci, addr); | ||
527 | if (ret < 0) | 527 | if (ret < 0) |
528 | return ret; | 528 | return ret; |
529 | 529 | ||
@@ -541,13 +541,38 @@ static int read_paged_phy_reg(struct fw_ohci *ohci, int page, int addr) | |||
541 | { | 541 | { |
542 | int ret; | 542 | int ret; |
543 | 543 | ||
544 | ret = ohci_update_phy_reg(&ohci->card, 7, PHY_PAGE_SELECT, page << 5); | 544 | ret = update_phy_reg(ohci, 7, PHY_PAGE_SELECT, page << 5); |
545 | if (ret < 0) | 545 | if (ret < 0) |
546 | return ret; | 546 | return ret; |
547 | 547 | ||
548 | return read_phy_reg(ohci, addr); | 548 | return read_phy_reg(ohci, addr); |
549 | } | 549 | } |
550 | 550 | ||
551 | static int ohci_read_phy_reg(struct fw_card *card, int addr) | ||
552 | { | ||
553 | struct fw_ohci *ohci = fw_ohci(card); | ||
554 | int ret; | ||
555 | |||
556 | mutex_lock(&ohci->phy_reg_mutex); | ||
557 | ret = read_phy_reg(ohci, addr); | ||
558 | mutex_unlock(&ohci->phy_reg_mutex); | ||
559 | |||
560 | return ret; | ||
561 | } | ||
562 | |||
563 | static int ohci_update_phy_reg(struct fw_card *card, int addr, | ||
564 | int clear_bits, int set_bits) | ||
565 | { | ||
566 | struct fw_ohci *ohci = fw_ohci(card); | ||
567 | int ret; | ||
568 | |||
569 | mutex_lock(&ohci->phy_reg_mutex); | ||
570 | ret = update_phy_reg(ohci, addr, clear_bits, set_bits); | ||
571 | mutex_unlock(&ohci->phy_reg_mutex); | ||
572 | |||
573 | return ret; | ||
574 | } | ||
575 | |||
551 | static int ar_context_add_page(struct ar_context *ctx) | 576 | static int ar_context_add_page(struct ar_context *ctx) |
552 | { | 577 | { |
553 | struct device *dev = ctx->ohci->card.device; | 578 | struct device *dev = ctx->ohci->card.device; |
@@ -1676,7 +1701,7 @@ static int configure_1394a_enhancements(struct fw_ohci *ohci) | |||
1676 | clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; | 1701 | clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; |
1677 | set = 0; | 1702 | set = 0; |
1678 | } | 1703 | } |
1679 | ret = ohci_update_phy_reg(&ohci->card, 5, clear, set); | 1704 | ret = update_phy_reg(ohci, 5, clear, set); |
1680 | if (ret < 0) | 1705 | if (ret < 0) |
1681 | return ret; | 1706 | return ret; |
1682 | 1707 | ||
@@ -1856,12 +1881,8 @@ static int ohci_enable(struct fw_card *card, | |||
1856 | OHCI1394_HCControl_BIBimageValid); | 1881 | OHCI1394_HCControl_BIBimageValid); |
1857 | flush_writes(ohci); | 1882 | flush_writes(ohci); |
1858 | 1883 | ||
1859 | /* | 1884 | /* We are ready to go, reset bus to finish initialization. */ |
1860 | * We are ready to go, initiate bus reset to finish the | 1885 | fw_schedule_bus_reset(&ohci->card, false, true); |
1861 | * initialization. | ||
1862 | */ | ||
1863 | |||
1864 | fw_core_initiate_bus_reset(&ohci->card, 1); | ||
1865 | 1886 | ||
1866 | return 0; | 1887 | return 0; |
1867 | } | 1888 | } |
@@ -1936,7 +1957,7 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
1936 | * takes effect. | 1957 | * takes effect. |
1937 | */ | 1958 | */ |
1938 | if (ret == 0) | 1959 | if (ret == 0) |
1939 | fw_core_initiate_bus_reset(&ohci->card, 1); | 1960 | fw_schedule_bus_reset(&ohci->card, true, true); |
1940 | else | 1961 | else |
1941 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | 1962 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, |
1942 | next_config_rom, next_config_rom_bus); | 1963 | next_config_rom, next_config_rom_bus); |
@@ -2570,6 +2591,7 @@ static int ohci_queue_iso(struct fw_iso_context *base, | |||
2570 | 2591 | ||
2571 | static const struct fw_card_driver ohci_driver = { | 2592 | static const struct fw_card_driver ohci_driver = { |
2572 | .enable = ohci_enable, | 2593 | .enable = ohci_enable, |
2594 | .read_phy_reg = ohci_read_phy_reg, | ||
2573 | .update_phy_reg = ohci_update_phy_reg, | 2595 | .update_phy_reg = ohci_update_phy_reg, |
2574 | .set_config_rom = ohci_set_config_rom, | 2596 | .set_config_rom = ohci_set_config_rom, |
2575 | .send_request = ohci_send_request, | 2597 | .send_request = ohci_send_request, |
@@ -2645,6 +2667,7 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2645 | pci_set_drvdata(dev, ohci); | 2667 | pci_set_drvdata(dev, ohci); |
2646 | 2668 | ||
2647 | spin_lock_init(&ohci->lock); | 2669 | spin_lock_init(&ohci->lock); |
2670 | mutex_init(&ohci->phy_reg_mutex); | ||
2648 | 2671 | ||
2649 | tasklet_init(&ohci->bus_reset_tasklet, | 2672 | tasklet_init(&ohci->bus_reset_tasklet, |
2650 | bus_reset_tasklet, (unsigned long)ohci); | 2673 | bus_reset_tasklet, (unsigned long)ohci); |