/* Allocate private resource */ adm_info_t * adm_attach(si_t *sih, char *vars) { adm_info_t *adm; int gpio; /* Allocate private data */ if (!(adm = MALLOC(si_osh(sih), sizeof(adm_info_t)))) { ET_ERROR(("adm_attach: out of memory, malloc %d bytes", MALLOCED(si_osh(sih)))); return NULL; } bzero((char *) adm, sizeof(adm_info_t)); adm->sih = sih; adm->vars = vars; /* Init GPIO mapping. Default GPIO: 2, 3, 4 */ gpio = getgpiopin(vars, "adm_eecs", 2); ET_ERROR(("adm_attach: got %d as adm_eecs", gpio)); if (gpio == GPIO_PIN_NOTDEFINED) { ET_ERROR(("adm_attach: adm_eecs gpio fail: GPIO 2 in use")); goto error; } adm->eecs = 1 << gpio; gpio = getgpiopin(vars, "adm_eesk", 3); ET_ERROR(("adm_attach: got %d as adm_eesk", gpio)); if (gpio == GPIO_PIN_NOTDEFINED) { ET_ERROR(("adm_attach: adm_eesk gpio fail: GPIO 3 in use")); goto error; } adm->eesk = 1 << gpio; gpio = getgpiopin(vars, "adm_eedi", 4); ET_ERROR(("adm_attach: got %d as adm_eedi", gpio)); if (gpio == GPIO_PIN_NOTDEFINED) { ET_ERROR(("adm_attach: adm_eedi gpio fail: GPIO 4 in use")); goto error; } adm->eedi = 1 << gpio; return adm; error: adm_detach(adm); return NULL; }
static void chipdetach(struct bcm4xxx *ch) { ET_TRACE(("et%d: chipdetach\n", ch->etc->unit)); if (ch == NULL) return; #ifdef ETROBO /* free robo state */ if (ch->etc->robo) bcm_robo_detach(ch->etc->robo); #endif /* ETROBO */ #ifdef ETADM /* free ADMtek state */ if (ch->adm) adm_detach(ch->adm); #endif /* ETADM */ /* free dma state */ if (ch->di) dma_detach(ch->di); ch->di = NULL; /* put the core back into reset */ if (ch->sih) si_core_disable(ch->sih, 0); /* free si handle */ si_detach(ch->sih); ch->sih = NULL; /* free vars */ if (ch->vars) MFREE(ch->osh, ch->vars, ch->vars_size); /* free chip private state */ MFREE(ch->osh, ch, sizeof(struct bcm4xxx)); }