From c8a94ded57e9cc2498d401b2f5c856213a3e19fb Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 12 Jun 2010 20:34:50 +0200 Subject: 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 --- drivers/firewire/core-topology.c | 5 ++--- drivers/firewire/core-transaction.c | 41 +++++++++++-------------------------- drivers/firewire/core.h | 2 +- drivers/firewire/ohci.c | 19 ++++++++++++----- 4 files changed, 29 insertions(+), 38 deletions(-) (limited to 'drivers') 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, } void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, - int self_id_count, u32 *self_ids) + int self_id_count, u32 *self_ids, bool bm_abdicate) { struct fw_node *local_node; unsigned long flags; @@ -552,8 +552,7 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, smp_wmb(); card->generation = generation; card->reset_jiffies = jiffies; - card->bm_abdicate = card->csr_abdicate; - card->csr_abdicate = false; + card->bm_abdicate = bm_abdicate; fw_schedule_bm_work(card, 0); 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 = { .start = CSR_REGISTER_BASE, .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, }; -static u32 read_state_register(struct fw_card *card) -{ - u32 value; - - /* Bit 8 (cmstr): */ - value = card->driver->read_csr_reg(card, CSR_STATE_CLEAR); - - /* Bit 10 (abdicate): */ - if (card->csr_abdicate) - value |= CSR_STATE_BIT_ABDICATE; - - return value; -} - static void update_split_timeout(struct fw_card *card) { unsigned int cycles; @@ -1021,29 +1007,25 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, switch (reg) { case CSR_STATE_CLEAR: - if (tcode == TCODE_READ_QUADLET_REQUEST) { - *data = cpu_to_be32(read_state_register(card)); - } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { + if (tcode == TCODE_READ_QUADLET_REQUEST) + *data = cpu_to_be32(card->driver-> + read_csr_reg(card, CSR_STATE_CLEAR)); + else if (tcode == TCODE_WRITE_QUADLET_REQUEST) card->driver->write_csr_reg(card, CSR_STATE_CLEAR, be32_to_cpu(*data)); - if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) - card->csr_abdicate = false; - } else { + else rcode = RCODE_TYPE_ERROR; - } break; case CSR_STATE_SET: - if (tcode == TCODE_READ_QUADLET_REQUEST) { - *data = cpu_to_be32(read_state_register(card)); - } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { + if (tcode == TCODE_READ_QUADLET_REQUEST) + *data = cpu_to_be32(card->driver-> + read_csr_reg(card, CSR_STATE_SET)); + else if (tcode == TCODE_WRITE_QUADLET_REQUEST) card->driver->write_csr_reg(card, CSR_STATE_SET, be32_to_cpu(*data)); - if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) - card->csr_abdicate = true; - } else { + else rcode = RCODE_TYPE_ERROR; - } break; case CSR_NODE_IDS: @@ -1063,7 +1045,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, case CSR_RESET_START: if (tcode == TCODE_WRITE_QUADLET_REQUEST) - card->csr_abdicate = false; + card->driver->write_csr_reg(card, CSR_STATE_CLEAR, + CSR_STATE_BIT_ABDICATE); else rcode = RCODE_TYPE_ERROR; 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) } void fw_core_handle_bus_reset(struct fw_card *card, int node_id, - int generation, int self_id_count, u32 *self_ids); + int generation, int self_id_count, u32 *self_ids, bool bm_abdicate); void fw_destroy_nodes(struct fw_card *card); /* 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 { unsigned int pri_req_max; u32 bus_time; bool is_root; + bool csr_state_setclear_abdicate; /* * Spinlock for accessing fw_ohci data. Never call out of @@ -1529,7 +1530,9 @@ static void bus_reset_tasklet(unsigned long data) self_id_count, ohci->self_id_buffer); fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation, - self_id_count, ohci->self_id_buffer); + self_id_count, ohci->self_id_buffer, + ohci->csr_state_setclear_abdicate); + ohci->csr_state_setclear_abdicate = false; } 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) switch (csr_offset) { case CSR_STATE_CLEAR: case CSR_STATE_SET: - /* the controller driver handles only the cmstr bit */ if (ohci->is_root && (reg_read(ohci, OHCI1394_LinkControlSet) & OHCI1394_LinkControl_cycleMaster)) - return CSR_STATE_BIT_CMSTR; + value = CSR_STATE_BIT_CMSTR; else - return 0; + value = 0; + if (ohci->csr_state_setclear_abdicate) + value |= CSR_STATE_BIT_ABDICATE; + + return value; case CSR_NODE_IDS: 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) switch (csr_offset) { case CSR_STATE_CLEAR: - /* the controller driver handles only the cmstr bit */ if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) { reg_write(ohci, OHCI1394_LinkControlClear, OHCI1394_LinkControl_cycleMaster); flush_writes(ohci); } + if (value & CSR_STATE_BIT_ABDICATE) + ohci->csr_state_setclear_abdicate = false; break; case CSR_STATE_SET: @@ -2092,6 +2099,8 @@ static void ohci_write_csr_reg(struct fw_card *card, int csr_offset, u32 value) OHCI1394_LinkControl_cycleMaster); flush_writes(ohci); } + if (value & CSR_STATE_BIT_ABDICATE) + ohci->csr_state_setclear_abdicate = true; break; case CSR_NODE_IDS: -- cgit v1.2.1