diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-06-12 14:34:50 -0400 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-06-19 07:01:41 -0400 |
| commit | c8a94ded57e9cc2498d401b2f5c856213a3e19fb (patch) | |
| tree | 8fd6a196ff953270c03700dd682108baf3ee369b | |
| parent | db3c9cc105ee844f6cd7a1beb9926fb8e9a093ae (diff) | |
firewire: normalize STATE_CLEAR/SET CSR access interface
Push the maintenance of STATE_CLEAR/SET.abdicate down into the card
driver. This way, the read/write_csr_reg driver method works uniformly
across all CSR offsets.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
| -rw-r--r-- | drivers/firewire/core-topology.c | 5 | ||||
| -rw-r--r-- | drivers/firewire/core-transaction.c | 41 | ||||
| -rw-r--r-- | drivers/firewire/core.h | 2 | ||||
| -rw-r--r-- | drivers/firewire/ohci.c | 19 | ||||
| -rw-r--r-- | include/linux/firewire.h | 3 |
5 files changed, 30 insertions, 40 deletions
diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index 3b9667c37b67..56e908ba43f1 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c | |||
| @@ -524,7 +524,7 @@ static void update_topology_map(struct fw_card *card, | |||
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, | 526 | void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, |
| 527 | int self_id_count, u32 *self_ids) | 527 | int self_id_count, u32 *self_ids, bool bm_abdicate) |
| 528 | { | 528 | { |
| 529 | struct fw_node *local_node; | 529 | struct fw_node *local_node; |
| 530 | unsigned long flags; | 530 | unsigned long flags; |
| @@ -552,8 +552,7 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, | |||
| 552 | smp_wmb(); | 552 | smp_wmb(); |
| 553 | card->generation = generation; | 553 | card->generation = generation; |
| 554 | card->reset_jiffies = jiffies; | 554 | card->reset_jiffies = jiffies; |
| 555 | card->bm_abdicate = card->csr_abdicate; | 555 | card->bm_abdicate = bm_abdicate; |
| 556 | card->csr_abdicate = false; | ||
| 557 | fw_schedule_bm_work(card, 0); | 556 | fw_schedule_bm_work(card, 0); |
| 558 | 557 | ||
| 559 | local_node = build_tree(card, self_ids, self_id_count); | 558 | local_node = build_tree(card, self_ids, self_id_count); |
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 62bf30560a3e..87d69cddb231 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
| @@ -982,20 +982,6 @@ static const struct fw_address_region registers_region = | |||
| 982 | { .start = CSR_REGISTER_BASE, | 982 | { .start = CSR_REGISTER_BASE, |
| 983 | .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, }; | 983 | .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, }; |
| 984 | 984 | ||
| 985 | static u32 read_state_register(struct fw_card *card) | ||
| 986 | { | ||
| 987 | u32 value; | ||
| 988 | |||
| 989 | /* Bit 8 (cmstr): */ | ||
| 990 | value = card->driver->read_csr_reg(card, CSR_STATE_CLEAR); | ||
| 991 | |||
| 992 | /* Bit 10 (abdicate): */ | ||
| 993 | if (card->csr_abdicate) | ||
| 994 | value |= CSR_STATE_BIT_ABDICATE; | ||
| 995 | |||
| 996 | return value; | ||
| 997 | } | ||
| 998 | |||
| 999 | static void update_split_timeout(struct fw_card *card) | 985 | static void update_split_timeout(struct fw_card *card) |
| 1000 | { | 986 | { |
| 1001 | unsigned int cycles; | 987 | unsigned int cycles; |
| @@ -1021,29 +1007,25 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
| 1021 | 1007 | ||
| 1022 | switch (reg) { | 1008 | switch (reg) { |
| 1023 | case CSR_STATE_CLEAR: | 1009 | case CSR_STATE_CLEAR: |
| 1024 | if (tcode == TCODE_READ_QUADLET_REQUEST) { | 1010 | if (tcode == TCODE_READ_QUADLET_REQUEST) |
| 1025 | *data = cpu_to_be32(read_state_register(card)); | 1011 | *data = cpu_to_be32(card->driver-> |
| 1026 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { | 1012 | read_csr_reg(card, CSR_STATE_CLEAR)); |
| 1013 | else if (tcode == TCODE_WRITE_QUADLET_REQUEST) | ||
| 1027 | card->driver->write_csr_reg(card, CSR_STATE_CLEAR, | 1014 | card->driver->write_csr_reg(card, CSR_STATE_CLEAR, |
| 1028 | be32_to_cpu(*data)); | 1015 | be32_to_cpu(*data)); |
| 1029 | if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) | 1016 | else |
| 1030 | card->csr_abdicate = false; | ||
| 1031 | } else { | ||
| 1032 | rcode = RCODE_TYPE_ERROR; | 1017 | rcode = RCODE_TYPE_ERROR; |
| 1033 | } | ||
| 1034 | break; | 1018 | break; |
| 1035 | 1019 | ||
| 1036 | case CSR_STATE_SET: | 1020 | case CSR_STATE_SET: |
| 1037 | if (tcode == TCODE_READ_QUADLET_REQUEST) { | 1021 | if (tcode == TCODE_READ_QUADLET_REQUEST) |
| 1038 | *data = cpu_to_be32(read_state_register(card)); | 1022 | *data = cpu_to_be32(card->driver-> |
| 1039 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { | 1023 | read_csr_reg(card, CSR_STATE_SET)); |
| 1024 | else if (tcode == TCODE_WRITE_QUADLET_REQUEST) | ||
| 1040 | card->driver->write_csr_reg(card, CSR_STATE_SET, | 1025 | card->driver->write_csr_reg(card, CSR_STATE_SET, |
| 1041 | be32_to_cpu(*data)); | 1026 | be32_to_cpu(*data)); |
| 1042 | if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) | 1027 | else |
| 1043 | card->csr_abdicate = true; | ||
| 1044 | } else { | ||
| 1045 | rcode = RCODE_TYPE_ERROR; | 1028 | rcode = RCODE_TYPE_ERROR; |
| 1046 | } | ||
| 1047 | break; | 1029 | break; |
| 1048 | 1030 | ||
| 1049 | case CSR_NODE_IDS: | 1031 | case CSR_NODE_IDS: |
| @@ -1063,7 +1045,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
| 1063 | 1045 | ||
| 1064 | case CSR_RESET_START: | 1046 | case CSR_RESET_START: |
| 1065 | if (tcode == TCODE_WRITE_QUADLET_REQUEST) | 1047 | if (tcode == TCODE_WRITE_QUADLET_REQUEST) |
| 1066 | card->csr_abdicate = false; | 1048 | card->driver->write_csr_reg(card, CSR_STATE_CLEAR, |
| 1049 | CSR_STATE_BIT_ABDICATE); | ||
| 1067 | else | 1050 | else |
| 1068 | rcode = RCODE_TYPE_ERROR; | 1051 | rcode = RCODE_TYPE_ERROR; |
| 1069 | break; | 1052 | break; |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index 8dc76d8711a5..8280c625170b 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
| @@ -196,7 +196,7 @@ static inline void fw_node_put(struct fw_node *node) | |||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | void fw_core_handle_bus_reset(struct fw_card *card, int node_id, | 198 | void fw_core_handle_bus_reset(struct fw_card *card, int node_id, |
| 199 | int generation, int self_id_count, u32 *self_ids); | 199 | int generation, int self_id_count, u32 *self_ids, bool bm_abdicate); |
| 200 | void fw_destroy_nodes(struct fw_card *card); | 200 | void fw_destroy_nodes(struct fw_card *card); |
| 201 | 201 | ||
| 202 | /* | 202 | /* |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 09bba9315de9..a55cf0911b72 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
| @@ -174,6 +174,7 @@ struct fw_ohci { | |||
| 174 | unsigned int pri_req_max; | 174 | unsigned int pri_req_max; |
| 175 | u32 bus_time; | 175 | u32 bus_time; |
| 176 | bool is_root; | 176 | bool is_root; |
| 177 | bool csr_state_setclear_abdicate; | ||
| 177 | 178 | ||
| 178 | /* | 179 | /* |
| 179 | * Spinlock for accessing fw_ohci data. Never call out of | 180 | * Spinlock for accessing fw_ohci data. Never call out of |
| @@ -1529,7 +1530,9 @@ static void bus_reset_tasklet(unsigned long data) | |||
| 1529 | self_id_count, ohci->self_id_buffer); | 1530 | self_id_count, ohci->self_id_buffer); |
| 1530 | 1531 | ||
| 1531 | fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation, | 1532 | fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation, |
| 1532 | self_id_count, ohci->self_id_buffer); | 1533 | self_id_count, ohci->self_id_buffer, |
| 1534 | ohci->csr_state_setclear_abdicate); | ||
| 1535 | ohci->csr_state_setclear_abdicate = false; | ||
| 1533 | } | 1536 | } |
| 1534 | 1537 | ||
| 1535 | static irqreturn_t irq_handler(int irq, void *data) | 1538 | static irqreturn_t irq_handler(int irq, void *data) |
| @@ -2032,13 +2035,16 @@ static u32 ohci_read_csr_reg(struct fw_card *card, int csr_offset) | |||
| 2032 | switch (csr_offset) { | 2035 | switch (csr_offset) { |
| 2033 | case CSR_STATE_CLEAR: | 2036 | case CSR_STATE_CLEAR: |
| 2034 | case CSR_STATE_SET: | 2037 | case CSR_STATE_SET: |
| 2035 | /* the controller driver handles only the cmstr bit */ | ||
| 2036 | if (ohci->is_root && | 2038 | if (ohci->is_root && |
| 2037 | (reg_read(ohci, OHCI1394_LinkControlSet) & | 2039 | (reg_read(ohci, OHCI1394_LinkControlSet) & |
| 2038 | OHCI1394_LinkControl_cycleMaster)) | 2040 | OHCI1394_LinkControl_cycleMaster)) |
| 2039 | return CSR_STATE_BIT_CMSTR; | 2041 | value = CSR_STATE_BIT_CMSTR; |
| 2040 | else | 2042 | else |
| 2041 | return 0; | 2043 | value = 0; |
| 2044 | if (ohci->csr_state_setclear_abdicate) | ||
| 2045 | value |= CSR_STATE_BIT_ABDICATE; | ||
| 2046 | |||
| 2047 | return value; | ||
| 2042 | 2048 | ||
| 2043 | case CSR_NODE_IDS: | 2049 | case CSR_NODE_IDS: |
| 2044 | return reg_read(ohci, OHCI1394_NodeID) << 16; | 2050 | return reg_read(ohci, OHCI1394_NodeID) << 16; |
| @@ -2078,12 +2084,13 @@ static void ohci_write_csr_reg(struct fw_card *card, int csr_offset, u32 value) | |||
| 2078 | 2084 | ||
| 2079 | switch (csr_offset) { | 2085 | switch (csr_offset) { |
| 2080 | case CSR_STATE_CLEAR: | 2086 | case CSR_STATE_CLEAR: |
| 2081 | /* the controller driver handles only the cmstr bit */ | ||
| 2082 | if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) { | 2087 | if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) { |
| 2083 | reg_write(ohci, OHCI1394_LinkControlClear, | 2088 | reg_write(ohci, OHCI1394_LinkControlClear, |
| 2084 | OHCI1394_LinkControl_cycleMaster); | 2089 | OHCI1394_LinkControl_cycleMaster); |
| 2085 | flush_writes(ohci); | 2090 | flush_writes(ohci); |
| 2086 | } | 2091 | } |
| 2092 | if (value & CSR_STATE_BIT_ABDICATE) | ||
| 2093 | ohci->csr_state_setclear_abdicate = false; | ||
| 2087 | break; | 2094 | break; |
| 2088 | 2095 | ||
| 2089 | case CSR_STATE_SET: | 2096 | case CSR_STATE_SET: |
| @@ -2092,6 +2099,8 @@ static void ohci_write_csr_reg(struct fw_card *card, int csr_offset, u32 value) | |||
| 2092 | OHCI1394_LinkControl_cycleMaster); | 2099 | OHCI1394_LinkControl_cycleMaster); |
| 2093 | flush_writes(ohci); | 2100 | flush_writes(ohci); |
| 2094 | } | 2101 | } |
| 2102 | if (value & CSR_STATE_BIT_ABDICATE) | ||
| 2103 | ohci->csr_state_setclear_abdicate = true; | ||
| 2095 | break; | 2104 | break; |
| 2096 | 2105 | ||
| 2097 | case CSR_NODE_IDS: | 2106 | case CSR_NODE_IDS: |
diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 5acb5fc19180..5553018d45d6 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h | |||
| @@ -119,8 +119,7 @@ struct fw_card { | |||
| 119 | int bm_retries; | 119 | int bm_retries; |
| 120 | int bm_generation; | 120 | int bm_generation; |
| 121 | __be32 bm_transaction_data[2]; | 121 | __be32 bm_transaction_data[2]; |
| 122 | bool bm_abdicate; /* value of csr_abdicate before last bus reset */ | 122 | bool bm_abdicate; |
| 123 | bool csr_abdicate; /* visible in CSR STATE_CLEAR/SET registers */ | ||
| 124 | 123 | ||
| 125 | bool priority_budget_implemented; /* controller feature */ | 124 | bool priority_budget_implemented; /* controller feature */ |
| 126 | bool broadcast_channel_auto_allocated; /* controller feature */ | 125 | bool broadcast_channel_auto_allocated; /* controller feature */ |
