+/*
+ * Read/write a jtag register. Assumes a target with
+ * 8 bit IR and 32 bit DR.
+ */
+#define IRWIDTH 8 /* Default Instruction Register width */
+#define DRWIDTH 32 /* Default Data Register width */
+
+uint32 jtag_rwreg(osl_t * osh, void *h, uint32 ir, uint32 dr)
+{
+ chipcregs_t *cc = (chipcregs_t *) h;
+ uint32 tmp;
+
+ W_REG(osh, &cc->jtagir, ir);
+ W_REG(osh, &cc->jtagdr, dr);
+ tmp = JCMD_START | JCMD_ACC_IRDR |
+ ((IRWIDTH - 1) << JCMD_IRW_SHIFT) | (DRWIDTH - 1);
+ W_REG(osh, &cc->jtagcmd, tmp);
+ while (((tmp = R_REG(osh, &cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) {
+ /* OSL_DELAY(1); */
+ }
+
+ tmp = R_REG(osh, &cc->jtagdr);
+ return (tmp);
+}
+#endif
+
+/*
+ * Interface to register chipc secondary isr
+ */
+bool
+BCMINITFN(sb_cc_register_isr) (sb_t * sbh, cc_isr_fn isr, uint32 ccintmask,
+ void *cbdata) {
+ bool done = FALSE;
+ chipcregs_t *regs;
+ uint origidx;
+ uint i;
+
+ /* Save the current core index */
+ origidx = sb_coreidx(sbh);
+ regs = sb_setcore(sbh, SB_CC, 0);
+ ASSERT(regs);
+
+ for (i = 0; i < MAX_CC_INT_SOURCE; i++) {
+ if (cc_isr_desc[i].isr == NULL) {
+ cc_isr_desc[i].isr = isr;
+ cc_isr_desc[i].cbdata = cbdata;
+ cc_isr_desc[i].intmask = ccintmask;
+ done = TRUE;
+ break;
+ }
+ }
+
+ if (done) {
+ cc_intmask = R_REG(sb_osh(sbh), ®s->intmask);
+ cc_intmask |= ccintmask;
+ W_REG(sb_osh(sbh), ®s->intmask, cc_intmask);
+ }
+
+ /* restore original coreidx */
+ sb_setcoreidx(sbh, origidx);
+ return done;
+}
+
+/*
+ * chipc primary interrupt handler
+ */
+void sb_cc_isr(sb_t * sbh, chipcregs_t * regs)
+{
+ uint32 ccintstatus;
+ uint32 intstatus;
+ uint32 i;
+
+ /* prior to rev 21 chipc interrupt means uart and gpio */
+ if (sbh->ccrev >= 21)
+ ccintstatus = R_REG(sb_osh(sbh), ®s->intstatus) & cc_intmask;
+ else
+ ccintstatus = (CI_UART | CI_GPIO);
+
+ for (i = 0; i < MAX_CC_INT_SOURCE; i++) {
+ if ((cc_isr_desc[i].isr != NULL) &&
+ (intstatus = (cc_isr_desc[i].intmask & ccintstatus))) {
+ (cc_isr_desc[i].isr) (cc_isr_desc[i].cbdata, intstatus);
+ }
+ }
+}