⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pxa.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
  conf.sock = sock;  conf.vcc = 0;  conf.vpp = 0;  conf.output = 0;  conf.speaker = 0;  conf.reset = 1;  ret = pcmcia_low_level->configure_socket(&conf);  if (ret == 0)    pxa_pcmcia_socket[sock].cs_state = dead_socket;  return ret;}/* pxa_pcmcia_events() * ^^^^^^^^^^^^^^^^^^^^^^ * Helper routine to generate a Card Services event mask based on * state information obtained from the kernel low-level PCMCIA layer * in a recent (and previous) sampling. Updates `prev_state'. * * Returns: an event mask for the given socket state. */static inline unsigned pxa_pcmcia_events(struct pcmcia_state *state,					    struct pcmcia_state *prev_state,					    unsigned int mask,					    unsigned int flags){  unsigned int events=0;  if(state->detect!=prev_state->detect){    DEBUG(2, "%s(): card detect value %u\n", __FUNCTION__, state->detect);    events|=mask&SS_DETECT;  }  if(state->ready!=prev_state->ready){    DEBUG(2, "%s(): card ready value %u\n", __FUNCTION__, state->ready);    events|=mask&((flags&SS_IOCARD)?0:SS_READY);  }  if(state->bvd1!=prev_state->bvd1){    DEBUG(2, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);    events|=mask&(flags&SS_IOCARD)?SS_STSCHG:SS_BATDEAD;  }  if(state->bvd2!=prev_state->bvd2){    DEBUG(2, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);    events|=mask&(flags&SS_IOCARD)?0:SS_BATWARN;  }  DEBUG(2, "events: %s%s%s%s%s%s\n",	(events==0)?"<NONE>":"",	(events&SS_DETECT)?"DETECT ":"",	(events&SS_READY)?"READY ":"",	(events&SS_BATDEAD)?"BATDEAD ":"",	(events&SS_BATWARN)?"BATWARN ":"",	(events&SS_STSCHG)?"STSCHG ":"");  *prev_state=*state;  return events;}  /* pxa_pcmcia_events() *//* pxa_pcmcia_task_handler() * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Processes serviceable socket events using the "eventd" thread context. * * Event processing (specifically, the invocation of the Card Services event * callback) occurs in this thread rather than in the actual interrupt * handler due to the use of scheduling operations in the PCMCIA core. */static void pxa_pcmcia_task_handler(void *data) {  struct pcmcia_state state[PXA_PCMCIA_MAX_SOCK];  struct pcmcia_state_array state_array;  int i, events, all_events, irq_status;  DEBUG(2, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);  state_array.size=pxa_pcmcia_socket_count;  state_array.state=state;  do {    DEBUG(3, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);    if((irq_status=pcmcia_low_level->socket_state(&state_array))<0)      printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");    all_events=0;    if(irq_status>0){      for(i=0; i<state_array.size; ++i, all_events|=events)	if((events=	    pxa_pcmcia_events(&state[i],				 &pxa_pcmcia_socket[i].k_state,				 pxa_pcmcia_socket[i].cs_state.csc_mask,				 pxa_pcmcia_socket[i].cs_state.flags)))	  if(pxa_pcmcia_socket[i].handler!=NULL)	    pxa_pcmcia_socket[i].handler(pxa_pcmcia_socket[i].handler_info,					    events);    }  } while(all_events);}  /* pxa_pcmcia_task_handler() */static struct tq_struct pxa_pcmcia_task = {	routine: pxa_pcmcia_task_handler};/* pxa_pcmcia_poll_event() * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * Let's poll for events in addition to IRQs since IRQ only is unreliable... */static void pxa_pcmcia_poll_event(unsigned long dummy){  DEBUG(3, "%s(): polling for events\n", __FUNCTION__);  poll_timer.function = pxa_pcmcia_poll_event;  poll_timer.expires = jiffies + PXA_PCMCIA_POLL_PERIOD;  add_timer(&poll_timer);  schedule_task(&pxa_pcmcia_task);}/* pxa_pcmcia_interrupt() * ^^^^^^^^^^^^^^^^^^^^^^^^^ * Service routine for socket driver interrupts (requested by the * low-level PCMCIA init() operation via pxa_pcmcia_thread()). * The actual interrupt-servicing work is performed by * pxa_pcmcia_thread(), largely because the Card Services event- * handling code performs scheduling operations which cannot be * executed from within an interrupt context. */static void pxa_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs){  DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);  schedule_task(&pxa_pcmcia_task);}/* pxa_pcmcia_register_callback() * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Implements the register_callback() operation for the in-kernel * PCMCIA service (formerly SS_RegisterCallback in Card Services). If  * the function pointer `handler' is not NULL, remember the callback  * location in the state for `sock', and increment the usage counter  * for the driver module. (The callback is invoked from the interrupt * service routine, pxa_pcmcia_interrupt(), to notify Card Services * of interesting events.) Otherwise, clear the callback pointer in the * socket state and decrement the module usage count. * * Returns: 0 */static int pxa_pcmcia_register_callback(unsigned int sock,					   void (*handler)(void *,							   unsigned int),					   void *info){  if(handler==NULL){    pxa_pcmcia_socket[sock].handler=NULL;    MOD_DEC_USE_COUNT;  } else {    MOD_INC_USE_COUNT;    pxa_pcmcia_socket[sock].handler=handler;    pxa_pcmcia_socket[sock].handler_info=info;  }  return 0;}/* pxa_pcmcia_inquire_socket() * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Implements the inquire_socket() operation for the in-kernel PCMCIA * service (formerly SS_InquireSocket in Card Services). Of note is * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of * `cap' to "trick" Card Services into tolerating large "I/O memory"  * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory * resource database check. (Mapped memory is set up within the socket * driver itself.) * * In conjunction with the STATIC_MAP capability is a new field, * `io_offset', recommended by David Hinds. Rather than go through * the SetIOMap interface (which is not quite suited for communicating * window locations up from the socket driver), we just pass up * an offset which is applied to client-requested base I/O addresses * in alloc_io_space(). * * Returns: 0 on success, -1 if no pin has been configured for `sock' */static int pxa_pcmcia_inquire_socket(unsigned int sock,					socket_cap_t *cap){  struct pcmcia_irq_info irq_info;  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);  if(sock>=pxa_pcmcia_socket_count){    printk(KERN_ERR "pxa_cs: socket %u not configured\n", sock);    return -1;  }  /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the   *   force_low argument to validate_mem() in rsrc_mgr.c -- since in   *   general, the mapped * addresses of the PCMCIA memory regions   *   will not be within 0xffff, setting force_low would be   *   undesirable.   *   * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory   *   resource database; we instead pass up physical address ranges   *   and allow other parts of Card Services to deal with remapping.   *   * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but   *   not 32-bit CardBus devices.   */  cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);  irq_info.sock=sock;  irq_info.irq=-1;  if(pcmcia_low_level->get_irq_info(&irq_info)<0){    printk(KERN_ERR "Error obtaining IRQ info from kernel for socket %u\n",	   sock);    return -1;  }  cap->irq_mask=0;  cap->map_size=PAGE_SIZE;  cap->pci_irq=irq_info.irq;  cap->io_offset=pxa_pcmcia_socket[sock].virt_io;  return 0;}  /* pxa_pcmcia_inquire_socket() *//* pxa_pcmcia_get_status() * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * Implements the get_status() operation for the in-kernel PCMCIA * service (formerly SS_GetStatus in Card Services). Essentially just * fills in bits in `status' according to internal driver state or * the value of the voltage detect chipselect register. * * As a debugging note, during card startup, the PCMCIA core issues * three set_socket() commands in a row the first with RESET deasserted, * the second with RESET asserted, and the last with RESET deasserted * again. Following the third set_socket(), a get_status() command will * be issued. The kernel is looking for the SS_READY flag (see * setup_socket(), reset_socket(), and unreset_socket() in cs.c). * * Returns: 0 */static int pxa_pcmcia_get_status(unsigned int sock,				    unsigned int *status){  struct pcmcia_state state[PXA_PCMCIA_MAX_SOCK];  struct pcmcia_state_array state_array;  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);  state_array.size=pxa_pcmcia_socket_count;  state_array.state=state;  if((pcmcia_low_level->socket_state(&state_array))<0){    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");    return -1;  }  pxa_pcmcia_socket[sock].k_state=state[sock];  *status=state[sock].detect?SS_DETECT:0;  *status|=state[sock].ready?SS_READY:0;  /* The power status of individual sockets is not available   * explicitly from the hardware, so we just remember the state   * and regurgitate it upon request:   */  *status|=pxa_pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;  if(pxa_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)    *status|=state[sock].bvd1?SS_STSCHG:0;  else {    if(state[sock].bvd1==0)      *status|=SS_BATDEAD;    else if(state[sock].bvd2==0)      *status|=SS_BATWARN;  }  *status|=state[sock].vs_3v?SS_3VCARD:0;  *status|=state[sock].vs_Xv?SS_XVCARD:0;  DEBUG(3, "\tstatus: %s%s%s%s%s%s%s%s\n",	(*status&SS_DETECT)?"DETECT ":"",	(*status&SS_READY)?"READY ":"", 	(*status&SS_BATDEAD)?"BATDEAD ":"",	(*status&SS_BATWARN)?"BATWARN ":"",	(*status&SS_POWERON)?"POWERON ":"",	(*status&SS_STSCHG)?"STSCHG ":"",	(*status&SS_3VCARD)?"3VCARD ":"",	(*status&SS_XVCARD)?"XVCARD ":"");  return 0;}  /* pxa_pcmcia_get_status() *//* pxa_pcmcia_get_socket() * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * Implements the get_socket() operation for the in-kernel PCMCIA * service (formerly SS_GetSocket in Card Services). Not a very  * exciting routine. * * Returns: 0 */static int pxa_pcmcia_get_socket(unsigned int sock,				    socket_state_t *state){  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);  /* This information was given to us in an earlier call to set_socket(),   * so we're just regurgitating it here:   */  *state=pxa_pcmcia_socket[sock].cs_state;  return 0;}/* pxa_pcmcia_set_socket() * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * Implements the set_socket() operation for the in-kernel PCMCIA * service (formerly SS_SetSocket in Card Services). We more or * less punt all of this work and let the kernel handle the details * of power configuration, reset, &c. We also record the value of * `state' in order to regurgitate it to the PCMCIA core later. * * Returns: 0 */static int pxa_pcmcia_set_socket(unsigned int sock,				    socket_state_t *state){  struct pcmcia_configure configure;  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);  DEBUG(3, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"	"\tVcc %d  Vpp %d  irq %d\n",	(state->csc_mask==0)?"<NONE>":"",	(state->csc_mask&SS_DETECT)?"DETECT ":"",	(state->csc_mask&SS_READY)?"READY ":"",	(state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",	(state->csc_mask&SS_BATWARN)?"BATWARN ":"",	(state->csc_mask&SS_STSCHG)?"STSCHG ":"",	(state->flags==0)?"<NONE>":"",	(state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",	(state->flags&SS_IOCARD)?"IOCARD ":"",	(state->flags&SS_RESET)?"RESET ":"",	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",	state->Vcc, state->Vpp, state->io_irq);  configure.sock=sock;  configure.vcc=state->Vcc;  configure.vpp=state->Vpp;  configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;  configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;  configure.reset=(state->flags&SS_RESET)?1:0;  if(pcmcia_low_level->configure_socket(&configure)<0){    printk(KERN_ERR "Unable to configure socket %u\n", sock);    return -1;  }  pxa_pcmcia_socket[sock].cs_state=*state;    return 0;}  /* pxa_pcmcia_set_socket() *//* pxa_pcmcia_get_io_map() * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * Implements the get_io_map() operation for the in-kernel PCMCIA * service (formerly SS_GetIOMap in Card Services). Just returns an * I/O map descriptor which was assigned earlier by a set_io_map(). * * Returns: 0 on success, -1 if the map index was out of range */static int pxa_pcmcia_get_io_map(unsigned int sock,				    struct pccard_io_map *map){  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);  if(map->map>=MAX_IO_WIN){    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,	   map->map);    return -1;  }  *map=pxa_pcmcia_socket[sock].io_map[map->map];  return 0;}/* pxa_pcmcia_set_io_map() * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * Implements the set_io_map() operation for the in-kernel PCMCIA * service (formerly SS_SetIOMap in Card Services). We configure * the map speed as requested, but override the address ranges * supplied by Card Services.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -