* reset, but then cleared when the units are ready again, which
* happens immediately for us.
*/
- return 0;
+ u32 value = 0x0000;
+
+ /* Bit 8 (cmstr): */
+ value |= card->driver->read_csr_reg(card, CSR_STATE_CLEAR);
+
+ return value;
}
static void update_split_timeout(struct fw_card *card)
if (tcode == TCODE_READ_QUADLET_REQUEST) {
*data = cpu_to_be32(read_state_register(card));
} else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
+ card->driver->write_csr_reg(card, CSR_STATE_CLEAR,
+ be32_to_cpu(*data));
} else {
rcode = RCODE_TYPE_ERROR;
}
if (tcode == TCODE_READ_QUADLET_REQUEST) {
*data = cpu_to_be32(read_state_register(card));
} else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
- /* FIXME: implement cmstr */
+ card->driver->write_csr_reg(card, CSR_STATE_SET,
+ be32_to_cpu(*data));
/* FIXME: implement abdicate */
} else {
rcode = RCODE_TYPE_ERROR;
unsigned quirks;
unsigned int pri_req_max;
u32 bus_time;
+ bool is_root;
/*
* Spinlock for accessing fw_ohci data. Never call out of
unsigned long flags;
void *free_rom = NULL;
dma_addr_t free_rom_bus = 0;
+ bool is_new_root;
reg = reg_read(ohci, OHCI1394_NodeID);
if (!(reg & OHCI1394_NodeID_idValid)) {
ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
OHCI1394_NodeID_nodeNumber);
+ is_new_root = (reg & OHCI1394_NodeID_root) != 0;
+ if (!(ohci->is_root && is_new_root))
+ reg_write(ohci, OHCI1394_LinkControlSet,
+ OHCI1394_LinkControl_cycleMaster);
+ ohci->is_root = is_new_root;
+
reg = reg_read(ohci, OHCI1394_SelfIDCount);
if (reg & OHCI1394_SelfIDCount_selfIDError) {
fw_notify("inconsistent self IDs\n");
u32 value;
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;
+ else
+ return 0;
+
case CSR_NODE_IDS:
return reg_read(ohci, OHCI1394_NodeID) << 16;
unsigned long flags;
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);
+ }
+ break;
+
+ case CSR_STATE_SET:
+ if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) {
+ reg_write(ohci, OHCI1394_LinkControlSet,
+ OHCI1394_LinkControl_cycleMaster);
+ flush_writes(ohci);
+ }
+ break;
+
case CSR_NODE_IDS:
reg_write(ohci, OHCI1394_NodeID, value >> 16);
flush_writes(ohci);
#define OHCI1394_LinkControl_cycleSource (1 << 22)
#define OHCI1394_NodeID 0x0E8
#define OHCI1394_NodeID_idValid 0x80000000
+#define OHCI1394_NodeID_root 0x40000000
#define OHCI1394_NodeID_nodeNumber 0x0000003f
#define OHCI1394_NodeID_busNumber 0x0000ffc0
#define OHCI1394_PhyControl 0x0EC