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 */ |