/* ssa_pcmcia_driver_init()
 * ^^^^^^^^^^^^^^^^^^^^^^^^
 *
 * This routine performs a basic sanity check to ensure that this
 * kernel has been built with the appropriate board-specific low-level
 * PCMCIA support, performs low-level PCMCIA initialization, registers
 * this socket driver with Card Services, and then spawns the daemon
 * thread which is the real workhorse of the socket driver.
 *
 * Returns: 0 on success, -1 on error
 */
static int __init ssa_pcmcia_driver_init (void)
{
   ssa_pcmcia_socket_t *skt = &ssa_pcmcia_socket;
   servinfo_t info;
   int ret;

   printk (KERN_INFO "SSA PCMCIA (CS release %s)\n", CS_RELEASE);

   CardServices (GetCardServicesInfo, &info);
   if (info.Revision != CS_RELEASE_CODE) {
      printk ("Card Services release codes do not match\n");
      return -EINVAL;
   }

   /* setup GPIO directions etc ?? */
   /* setup irq to catch card detect and battery status changes... */

   writel (SMC_WAITSTATES_PCMCIA_IO, IO_ADDRESS_SMC_BASE + 8);
   
   lowlevel_socket_state (&skt->k_state);

   ret = register_ss_entry (SSA_PCMCIA_SOCKET_COUNT, &ssa_pcmcia_operations);
   if (ret < 0) {
      printk ("Unable to register sockets\n");
      return ret;
   }

   ssa_pcmcia_poll_event (0);       /* startup the event poll timer. param is not used */
   return 0;
}
static int __init ivpnss_init(void)
{
	servinfo_t serv;
	int rc;

	printk("iVPNSS: IXP4xx/iVPN socket service driver\n" \
		"(C) Copyright 2004, Greg Ungerer <*****@*****.**>\n");

	ivpnss_hwsetup();
	if ((rc = ivpnss_memmap()))
		return rc;

	pcmcia_get_card_services_info(&serv);
	if (serv.Revision != CS_RELEASE_CODE) {
		printk("iVPNSS: Card Services version mis-match!\n");
		return -ENODEV;
	}

	if (register_ss_entry(1, &ivpnss_operations)) {
		printk("iVPNSS: failed to register socket service?\n");
		return -ENODEV;
	}

	if (register_chrdev(IVPNSS_MAJOR, IVPNSS_NAME, &ivpnss_fops))
		printk("iVPNSS: failed to register debug char device?\n");

	return 0;
}
Exemple #3
0
static int __init clps6700_init(void)
{
	unsigned int v;
	int err, nr;

	PLD_CF = 0;
	v = clps_readl(SYSCON2) | SYSCON2_PCCARD1 | SYSCON2_PCCARD2;
	clps_writel(v, SYSCON2);
	v = clps_readl(SYSCON1) | SYSCON1_EXCKEN;
	clps_writel(v, SYSCON1);

	for (nr = 0; nr < NR_CLPS6700; nr++) {
		err = clps6700_init_skt(nr);
		if (err)
			goto free;
	}

	err = register_ss_entry(nr, &clps6700_operations);
	if (err)
		goto free;

	return 0;

free:
	clps6700_free_resources();
	/*
	 * An error occurred.  Unmap and free all CLPS6700
	 */
	return err;
}
Exemple #4
0
/* pxa_pcmcia_driver_init()
 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *
 * This routine performs a basic sanity check to ensure that this
 * kernel has been built with the appropriate board-specific low-level
 * PCMCIA support, performs low-level PCMCIA initialization, registers
 * this socket driver with Card Services, and then spawns the daemon
 * thread which is the real workhorse of the socket driver.
 *
 * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
 * on the low-level kernel interface.
 *
 * Returns: 0 on success, -1 on error
 */
static int __init pxa_pcmcia_driver_init(void){
  servinfo_t info;
  struct pcmcia_init pcmcia_init;
  struct pcmcia_state state[PXA_PCMCIA_MAX_SOCK];
  struct pcmcia_state_array state_array;
  unsigned int i, clock;
  unsigned long mecr;

  printk(KERN_INFO "Intel PXA250/210 PCMCIA (CS release %s)\n", CS_RELEASE);

  CardServices(GetCardServicesInfo, &info);

  if(info.Revision!=CS_RELEASE_CODE){
    printk(KERN_ERR "Card Services release codes do not match\n");
    return -1;
  }

  /* Setup GPIOs for PCMCIA/CF alternate function mode.
   *
   * It would be nice if set_GPIO_mode included support
   * for driving GPIO outputs to default high/low state
   * before programming GPIOs as outputs. Setting GPIO
   * outputs to default high/low state via GPSR/GPCR
   * before defining them as outputs should reduce
   * the possibility of glitching outputs during GPIO
   * setup. This of course assumes external terminators
   * are present to hold GPIOs in a defined state.
   *
   * In the meantime, setup default state of GPIO
   * outputs before we enable them as outputs.
   */

  GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
                      GPIO_bit(GPIO49_nPWE) |
                      GPIO_bit(GPIO50_nPIOR) |
                      GPIO_bit(GPIO51_nPIOW) |
                      GPIO_bit(GPIO52_nPCE_1) |
                      GPIO_bit(GPIO53_nPCE_2);

  set_GPIO_mode(GPIO48_nPOE_MD);
  set_GPIO_mode(GPIO49_nPWE_MD);
  set_GPIO_mode(GPIO50_nPIOR_MD);
  set_GPIO_mode(GPIO51_nPIOW_MD);
  set_GPIO_mode(GPIO52_nPCE_1_MD);
  set_GPIO_mode(GPIO53_nPCE_2_MD);
  set_GPIO_mode(GPIO54_pSKTSEL_MD); /* REVISIT: s/b dependent on num sockets */
  set_GPIO_mode(GPIO55_nPREG_MD);
  set_GPIO_mode(GPIO56_nPWAIT_MD);
  set_GPIO_mode(GPIO57_nIOIS16_MD);


  if(machine_is_lubbock()){
#ifdef CONFIG_ARCH_LUBBOCK
    pcmcia_low_level=&lubbock_pcmcia_ops;
#endif
  } else if (machine_is_pxa_idp()) {
    pcmcia_low_level=&pxa_idp_pcmcia_ops;
  } else if( machine_is_pxa_cerf()){
    pcmcia_low_level=&cerf_pcmcia_ops;
  }

  if (!pcmcia_low_level) {
    printk(KERN_ERR "This hardware is not supported by the PXA250/210 Card Service driver\n");
    return -ENODEV;
  }

  pcmcia_init.handler=pxa_pcmcia_interrupt;

  if((pxa_pcmcia_socket_count=pcmcia_low_level->init(&pcmcia_init))<0){
    printk(KERN_ERR "Unable to initialize kernel PCMCIA service.\n");
    return -EIO;
  }

  state_array.size=pxa_pcmcia_socket_count;
  state_array.state=state;

  /* Configure MECR based on the number of sockets present. */
  if (pxa_pcmcia_socket_count == 2) {
    MECR |= GPIO_bit(0);
  } else {
    MECR &= ~GPIO_bit(0);
  }

  if(pcmcia_low_level->socket_state(&state_array)<0){
    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
    return -EIO;
  }

  /* Well, it looks good to go. So we can now enable the PCMCIA
   * controller.
   */
  MECR |= GPIO_bit(1);

  /* We need to initialize the MCXX registers to default values
   * here because we're not guaranteed to see a SetIOMap operation
   * at runtime.
   */

  clock = get_lclk_frequency_10khz();

  for(i=0; i<pxa_pcmcia_socket_count; ++i){
    pxa_pcmcia_socket[i].k_state=state[i];

    /* This is an interim fix. Apparently, SetSocket is no longer
     * called to initialize each socket (prior to the first detect
     * event). For now, we'll just manually set up the mask.
     */
    pxa_pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;

    pxa_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE;
    pxa_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i);
    pxa_pcmcia_socket[i].phys_mem=_PCMCIAMem(i);

    /* REVISIT: cleanup these macros */
    //MCIO_SET(i, PXA_PCMCIA_IO_ACCESS, clock);
    //MCATTR_SET(i, PXA_PCMCIA_5V_MEM_ACCESS, clock);
    //MCMEM_SET(i, PXA_PCMCIA_5V_MEM_ACCESS, clock);

    pxa_pcmcia_socket[i].speed_io=PXA_PCMCIA_IO_ACCESS;
    pxa_pcmcia_socket[i].speed_attr=PXA_PCMCIA_5V_MEM_ACCESS;
    pxa_pcmcia_socket[i].speed_mem=PXA_PCMCIA_5V_MEM_ACCESS;
  }

/* REVISIT: cleanup these macros */
MCMEM0 = ((pxa_mcxx_setup(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
       | ((pxa_mcxx_asst(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
       | ((pxa_mcxx_hold(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
MCMEM1 = ((pxa_mcxx_setup(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
       | ((pxa_mcxx_asst(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
       | ((pxa_mcxx_hold(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
MCATT0 = ((pxa_mcxx_setup(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
       | ((pxa_mcxx_asst(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
       | ((pxa_mcxx_hold(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
MCATT1 = ((pxa_mcxx_setup(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
       | ((pxa_mcxx_asst(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
       | ((pxa_mcxx_hold(PXA_PCMCIA_5V_MEM_ACCESS, clock)
		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
MCIO0 = ((pxa_mcxx_setup(PXA_PCMCIA_IO_ACCESS, clock)
		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
       | ((pxa_mcxx_asst(PXA_PCMCIA_IO_ACCESS, clock)
		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
       | ((pxa_mcxx_hold(PXA_PCMCIA_IO_ACCESS, clock)
		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
MCIO1 = ((pxa_mcxx_setup(PXA_PCMCIA_IO_ACCESS, clock)
		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
       | ((pxa_mcxx_asst(PXA_PCMCIA_IO_ACCESS, clock)
		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
       | ((pxa_mcxx_hold(PXA_PCMCIA_IO_ACCESS, clock)
		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);

#ifdef CONFIG_CPU_FREQ
  if(cpufreq_register_notifier(&pxa_pcmcia_notifier_block) < 0){
    printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
    return -ENXIO;
  }
#endif

  /* Only advertise as many sockets as we can detect: */
  if(register_ss_entry(pxa_pcmcia_socket_count, 
		       &pxa_pcmcia_operations)<0){
    printk(KERN_ERR "Unable to register socket service routine\n");
    return -ENXIO;
  }

  /* Start the event poll timer.  It will reschedule by itself afterwards. */
  pxa_pcmcia_poll_event(0);

  DEBUG(1, "pxa_cs: initialization complete\n");

  return 0;

}  /* pxa_pcmcia_driver_init() */
static int __init au1000_pcmcia_driver_init(void)
{
	servinfo_t info;
	struct pcmcia_init pcmcia_init;
	struct pcmcia_state state;
	unsigned int i;
	unsigned long timing3;

	printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE);

	CardServices(GetCardServicesInfo, &info);

	if(info.Revision!=CS_RELEASE_CODE){
		printk(KERN_ERR "Card Services release codes do not match\n");
		return -1;
	}

#ifdef CONFIG_MIPS_PB1000
	pcmcia_low_level=&pb1000_pcmcia_ops;
#elif defined(CONFIG_MIPS_PB1500)
	pcmcia_low_level=&pb1500_pcmcia_ops;
#else
#error Unsupported AU1000 board.
#endif

	pcmcia_init.handler=au1000_pcmcia_interrupt;
	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
		return -EIO;
	}

	/* setup the static bus controller */
	timing3 = 0x100e3a07;
	writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
	writel(timing3, MEM_STTIME3); 
	writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
	au_sync_delay(1);

	pcmcia_socket = 
		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
				GFP_KERNEL);
	if (!pcmcia_socket) {
		printk(KERN_ERR "Card Services can't get memory \n");
		return -1;
	}
	memset(pcmcia_socket, 0,
			sizeof(struct au1000_pcmcia_socket) * socket_count);
			
	for(i=0; i < socket_count; i++) {

		if(pcmcia_low_level->socket_state(i, &state)<0){
			printk(KERN_ERR "Unable to get PCMCIA status\n");
			return -EIO;
		}
		pcmcia_socket[i].k_state=state;
		pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
		
		if (i == 0) {
			pcmcia_socket[i].virt_io = 
				(u32)ioremap(0xC0000000, 0x1000);
			pcmcia_socket[i].phys_attr = 0xC4000000;
			pcmcia_socket[i].phys_mem = 0xC8000000;
		}
		else  {
			printk(KERN_ERR "au1000: socket 1 not supported\n");
			return 1;
		}
	}

	/* Only advertise as many sockets as we can detect: */
	if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
		printk(KERN_ERR "Unable to register socket service routine\n");
		return -ENXIO;
	}

	/* Start the event poll timer.  
	 * It will reschedule by itself afterwards. 
	 */
	au1000_pcmcia_poll_event(0);

	DEBUG(1, "au1000: initialization complete\n");
	return 0;

}  /* au1000_pcmcia_driver_init() */
static int __init au1000_pcmcia_driver_init(void)
{
	servinfo_t info;
	struct pcmcia_init pcmcia_init;
	struct pcmcia_state state;
	unsigned int i;

	printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE);

#ifndef CONFIG_64BIT_PHYS_ADDR
	printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabled\n");
	return -1;
#endif

	CardServices(GetCardServicesInfo, &info);

	if(info.Revision!=CS_RELEASE_CODE){
		printk(KERN_ERR "Card Services release codes do not match\n");
		return -1;
	}

#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
	pcmcia_low_level=&pb1x00_pcmcia_ops;
#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500)
	pcmcia_low_level=&db1x00_pcmcia_ops;
#elif defined(CONFIG_MIPS_XXS1500)
	pcmcia_low_level=&xxs1500_pcmcia_ops;
#else
#error Unsupported AU1000 board.
#endif

	pcmcia_init.handler=au1000_pcmcia_interrupt;
	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
		return -EIO;
	}

	/* NOTE: the chip select must already be setup */

	pcmcia_socket = 
		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
				GFP_KERNEL);
	if (!pcmcia_socket) {
		printk(KERN_ERR "Card Services can't get memory \n");
		return -1;
	}
	memset(pcmcia_socket, 0,
			sizeof(struct au1000_pcmcia_socket) * socket_count);
			
	/* 
	 * Assuming max of 2 sockets, which the Au1000 supports.
	 * WARNING: the Pb1000 has two sockets, and both work, but you
	 * can't use them both at the same time due to glue logic conflicts.
	 */
	for(i=0; i < socket_count; i++) {

		if(pcmcia_low_level->socket_state(i, &state)<0){
			printk(KERN_ERR "Unable to get PCMCIA status\n");
			return -EIO;
		}
		pcmcia_socket[i].k_state=state;
		pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
		
		/*
		 * PCMCIA drivers use the inb/outb macros to access the
		 * IO registers. Since mips_io_port_base is added to the
		 * access address, we need to subtract it here.
		 */
		if (i == 0) {
			pcmcia_socket[i].virt_io = 
				(u32)ioremap((ioaddr_t)AU1X_SOCK0_IO, 0x1000) -
				mips_io_port_base;
			pcmcia_socket[i].phys_attr = 
				(ioaddr_t)AU1X_SOCK0_PHYS_ATTR;
			pcmcia_socket[i].phys_mem = 
				(ioaddr_t)AU1X_SOCK0_PHYS_MEM;
		}
#ifndef CONFIG_MIPS_XXS1500
		else  {
			pcmcia_socket[i].virt_io = 
				(u32)ioremap((ioaddr_t)AU1X_SOCK1_IO, 0x1000) -
				mips_io_port_base;
			pcmcia_socket[i].phys_attr = 
				(ioaddr_t)AU1X_SOCK1_PHYS_ATTR;
			pcmcia_socket[i].phys_mem = 
				(ioaddr_t)AU1X_SOCK1_PHYS_MEM;
		}
#endif
	}

	/* Only advertise as many sockets as we can detect: */
	if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
		printk(KERN_ERR "Unable to register socket service routine\n");
		return -ENXIO;
	}

	/* Start the event poll timer.  
	 * It will reschedule by itself afterwards. 
	 */
	au1000_pcmcia_poll_event(0);

	DEBUG(1, "au1000: initialization complete\n");
	return 0;

}  /* au1000_pcmcia_driver_init() */
/*
 * bcm47xx_pcmcia_driver_init()
 *
 * This routine performs a basic sanity check to ensure that this
 * kernel has been built with the appropriate board-specific low-level
 * PCMCIA support, performs low-level PCMCIA initialization, registers
 * this socket driver with Card Services, and then spawns the daemon
 * thread which is the real workhorse of the socket driver.
 *
 * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
 * on the low-level kernel interface.
 *
 * Returns: 0 on success, -1 on error
 */
static int __init bcm47xx_pcmcia_driver_init(void)
{
	servinfo_t info;
	struct pcmcia_init pcmcia_init;
	struct pcmcia_state state;
	unsigned int i;
	unsigned long tmp;


	printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE);

	CardServices(GetCardServicesInfo, &info);

	if (info.Revision != CS_RELEASE_CODE) {
		printk(KERN_ERR "Card Services release codes do not match\n");
		return -1;
	}

#ifdef CONFIG_BCM4710
	pcmcia_low_level=&bcm4710_pcmcia_ops;
#else
#error Unsupported Broadcom BCM47XX board.
#endif

	pcmcia_init.handler=bcm47xx_pcmcia_interrupt;

	if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) {
		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
		return -EIO;
	} else {
		printk("\t%d PCMCIA sockets initialized.\n", socket_count);
	}

	pcmcia_socket = 
		kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count, 
				GFP_KERNEL);
	memset(pcmcia_socket, 0, 
			sizeof(struct bcm47xx_pcmcia_socket) * socket_count);
	if (!pcmcia_socket) {
		printk(KERN_ERR "Card Services can't get memory \n");
		return -1;
	}
			
	for (i = 0; i < socket_count; i++) {
		if (pcmcia_low_level->socket_state(i, &state) < 0) {
			printk(KERN_ERR "Unable to get PCMCIA status\n");
			return -EIO;
		}
		pcmcia_socket[i].k_state = state;
		pcmcia_socket[i].cs_state.csc_mask = SS_DETECT;
		
		if (i == 0) {
			pcmcia_socket[i].virt_io =
				(unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000);
			/* Substract ioport base which gets added by in/out */
			pcmcia_socket[i].virt_io -= mips_io_port_base;
			pcmcia_socket[i].phys_attr =
				(unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF);
			pcmcia_socket[i].phys_mem =
				(unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF);
		} else  {
			printk(KERN_ERR "bcm4710: socket 1 not supported\n");
			return 1;
		}
	}

	/* Only advertise as many sockets as we can detect: */
	if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) {
		printk(KERN_ERR "Unable to register socket service routine\n");
		return -ENXIO;
	}

	/* Start the event poll timer.  
	 * It will reschedule by itself afterwards. 
	 */
	bcm47xx_pcmcia_poll_event(0);

	DEBUG(1, "bcm4710: initialization complete\n");
	return 0;

}
Exemple #8
0
static int __init init_hs(void)
{
	servinfo_t serv;
	int i;
	unsigned short v;

    	/*
	 * Check API version
	 */
	pcmcia_get_card_services_info(&serv);
	if (serv.Revision != CS_RELEASE_CODE) {
	    printk(KERN_NOTICE MODNAME ": Card Services release does not match!\n");
	    return -ENODEV;
	}

/*	hd64465_io_debug = 1; */
	
	/* Wake both sockets out of STANDBY mode */
	/* TODO: wait 15ms */
	v = inw(HD64465_REG_SMSCR);
	v &= ~(HD64465_SMSCR_PC0ST|HD64465_SMSCR_PC1ST);
	outw(v, HD64465_REG_SMSCR);

	/* keep power controller out of shutdown mode */
	v = inb(HD64465_REG_PCC0SCR);
	v |= HD64465_PCCSCR_SHDN;
	outb(v, HD64465_REG_PCC0SCR);

    	/* use serial (TPS2206) power controller */
	v = inb(HD64465_REG_PCC0CSCR);
	v |= HD64465_PCCCSCR_PSWSEL;
	outb(v, HD64465_REG_PCC0CSCR);

    	hs_set_voltages(&hs_sockets[0], 0, 0);
    	hs_set_voltages(&hs_sockets[1], 0, 0);
	
	/*
	 * Setup hs_sockets[] structures and request system resources.
	 * TODO: on memory allocation failure, power down the socket
	 *       before quitting.
	 */
	i = hs_init_socket(&hs_sockets[0],
	    HD64465_IRQ_PCMCIA0,
	    HD64465_PCC0_BASE,
	    HD64465_REG_PCC0ISR);
	if (i < 0)
	    return i;
	i = hs_init_socket(&hs_sockets[1],
	    HD64465_IRQ_PCMCIA1,
	    HD64465_PCC1_BASE,
	    HD64465_REG_PCC1ISR);
	if (i < 0)
	    return i;

/*	hd64465_io_debug = 0; */
	    

	if (register_ss_entry(HS_MAX_SOCKETS, &hs_operations) != 0) {
	    for (i=0 ; i<HS_MAX_SOCKETS ; i++)
		hs_exit_socket(&hs_sockets[i]);
    	    return -ENODEV;
	}

	printk(KERN_INFO "HD64465 PCMCIA bridge:\n");
	for (i=0 ; i<HS_MAX_SOCKETS ; i++) {
	    hs_socket_t *sp = &hs_sockets[i];
	    
	    printk(KERN_INFO "  socket %d at 0x%08lx irq %d io window %ldK@0x%08lx\n",
	    	i, sp->mem_base, sp->irq,
		sp->io_vma->size>>10, (unsigned long)sp->io_vma->addr);
	}

    	return 0;
}
/* sa1100_pcmcia_driver_init()
 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *
 * This routine performs a basic sanity check to ensure that this
 * kernel has been built with the appropriate board-specific low-level
 * PCMCIA support, performs low-level PCMCIA initialization, registers
 * this socket driver with Card Services, and then spawns the daemon
 * thread which is the real workhorse of the socket driver.
 *
 * Returns: 0 on success, -1 on error
 */
static int __init sa1100_pcmcia_driver_init(void)
{
  servinfo_t info;
  struct pcmcia_init pcmcia_init;
  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
  struct pcmcia_state_array state_array;
  unsigned int i, clock;
  unsigned long mecr;
  int ret;

  printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);

  CardServices(GetCardServicesInfo, &info);

  if (info.Revision != CS_RELEASE_CODE) {
    printk(KERN_ERR "Card Services release codes do not match\n");
    return -EINVAL;
  }

  ret = sa1100_pcmcia_machine_init();
  if (ret)
    return ret;

  pcmcia_init.handler = sa1100_pcmcia_interrupt;

  ret = pcmcia_low_level->init(&pcmcia_init);
  if (ret < 0) {
    printk(KERN_ERR "Unable to initialize kernel PCMCIA service (%d).\n", ret);
    return ret == -1 ? -EIO : ret;
  }

  sa1100_pcmcia_socket_count = ret;
  state_array.size  = sa1100_pcmcia_socket_count;
  state_array.state = state;

  memset(state, 0, sizeof(state));

  if (pcmcia_low_level->socket_state(&state_array) < 0) {
    pcmcia_low_level->shutdown();
    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
    return -EIO;
  }

  /*
   * We initialize the MECR to default values here, because we are
   * not guaranteed to see a SetIOMap operation at runtime.
   */
  mecr = MECR;

  clock = cpufreq_get(0);

  for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
    struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
    struct pcmcia_irq_info irq_info;

    if (!request_mem_region(_PCMCIA(i), PCMCIASp, "PCMCIA")) {
      ret = -EBUSY;
      goto out_err;
    }

    irq_info.sock = i;
    irq_info.irq  = -1;
    ret = pcmcia_low_level->get_irq_info(&irq_info);
    if (ret < 0)
      printk(KERN_ERR "Unable to get IRQ for socket %u (%d)\n", i, ret);

    skt->irq        = irq_info.irq;
    skt->k_state    = state[i];
    skt->speed_io   = SA1100_PCMCIA_IO_ACCESS;
    skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS;
    skt->speed_mem  = SA1100_PCMCIA_5V_MEM_ACCESS;
    skt->phys_attr  = _PCMCIAAttr(i);
    skt->phys_mem   = _PCMCIAMem(i);
    skt->virt_io    = ioremap(_PCMCIAIO(i), 0x10000);

    if (skt->virt_io == NULL) {
      ret = -ENOMEM;
      goto out_err;
    }

    MECR_FAST_SET(mecr, i, 0);
    MECR_BSIO_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_io, clock));
    MECR_BSA_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_attr, clock));
    MECR_BSM_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_mem, clock));
  }

  MECR = mecr;

#ifdef CONFIG_CPU_FREQ
  ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block);
  if (ret < 0) {
    printk(KERN_ERR "Unable to register CPU frequency change notifier (%d)\n", ret);
    goto out_err;
  }
#endif

  /* Only advertise as many sockets as we can detect */
  ret = register_ss_entry(sa1100_pcmcia_socket_count,
			  &sa1100_pcmcia_operations);
  if (ret < 0) {
    printk(KERN_ERR "Unable to register sockets\n");
    goto out_err;
  }

  /*
   * Start the event poll timer.  It will reschedule by itself afterwards.
   */
  sa1100_pcmcia_poll_event(0);

  return 0;

 out_err:
  for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
    iounmap(sa1100_pcmcia_socket[i].virt_io);
    release_mem_region(_PCMCIA(i), PCMCIASp);
  }

  pcmcia_low_level->shutdown();

  return ret;
}  /* sa1100_pcmcia_driver_init() */
Exemple #10
0
/* sa1100_pcmcia_driver_init()
 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *
 * This routine performs a basic sanity check to ensure that this
 * kernel has been built with the appropriate board-specific low-level
 * PCMCIA support, performs low-level PCMCIA initialization, registers
 * this socket driver with Card Services, and then spawns the daemon
 * thread which is the real workhorse of the socket driver.
 *
 * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
 * on the low-level kernel interface.
 *
 * Returns: 0 on success, -1 on error
 */
static int __init sa1100_pcmcia_driver_init(void){
  servinfo_t info;
  struct pcmcia_init pcmcia_init;
  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
  struct pcmcia_state_array state_array;
  unsigned int i, clock;
  unsigned long mecr;

  printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);

  CardServices(GetCardServicesInfo, &info);

  if(info.Revision!=CS_RELEASE_CODE){
    printk(KERN_ERR "Card Services release codes do not match\n");
    return -1;
  }

  if(machine_is_assabet()){
#ifdef CONFIG_SA1100_ASSABET
    if(machine_has_neponset()){
#ifdef CONFIG_ASSABET_NEPONSET
      pcmcia_low_level=&neponset_pcmcia_ops;
#else
      printk(KERN_ERR "Card Services disabled: missing Neponset support\n");
      return -1;
#endif
    }else{
      pcmcia_low_level=&assabet_pcmcia_ops;
    }
#endif
  } else if (machine_is_freebird()) {
#ifdef CONFIG_SA1100_FREEBIRD
    pcmcia_low_level = &freebird_pcmcia_ops;
#endif
  } else if (machine_is_h3xxx()) {
#ifdef CONFIG_SA1100_H3XXX
    pcmcia_low_level = &h3600_pcmcia_ops;
#endif    
  } else if (machine_is_cerf()) {
#ifdef CONFIG_SA1100_CERF
    pcmcia_low_level = &cerf_pcmcia_ops;
#endif
  } else if (machine_is_graphicsclient()) {
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
    pcmcia_low_level = &gcplus_pcmcia_ops;
#endif
  } else if (machine_is_xp860()) {
#ifdef CONFIG_SA1100_XP860
    pcmcia_low_level = &xp860_pcmcia_ops;
#endif
  } else if (machine_is_yopy()) {
#ifdef CONFIG_SA1100_YOPY
    pcmcia_low_level = &yopy_pcmcia_ops;
#endif
  } else if (machine_is_shannon()) {
#ifdef CONFIG_SA1100_SHANNON
    pcmcia_low_level = &shannon_pcmcia_ops;
#endif
  } else if (machine_is_pangolin()) {
#ifdef CONFIG_SA1100_PANGOLIN
    pcmcia_low_level = &pangolin_pcmcia_ops;
#endif
  } else if (machine_is_jornada720()) {
#ifdef CONFIG_SA1100_JORNADA720
    pcmcia_low_level = &jornada720_pcmcia_ops;
#endif
  } else if(machine_is_pfs168()){
#ifdef CONFIG_SA1100_PFS168
    pcmcia_low_level=&pfs168_pcmcia_ops;
#endif
  } else if(machine_is_flexanet()){
#ifdef CONFIG_SA1100_FLEXANET
    pcmcia_low_level=&flexanet_pcmcia_ops;
#endif
 } else if(machine_is_simpad()){
#ifdef CONFIG_SA1100_SIMPAD
    pcmcia_low_level=&simpad_pcmcia_ops;
#endif
  } else if(machine_is_graphicsmaster()) {
#ifdef CONFIG_SA1100_GRAPHICSMASTER
    pcmcia_low_level=&graphicsmaster_pcmcia_ops;
#endif
  } else if(machine_is_adsbitsy()) {
#ifdef CONFIG_SA1100_ADSBITSY
    pcmcia_low_level=&adsbitsy_pcmcia_ops;
#endif
  } else if(machine_is_stork()) {
#ifdef CONFIG_SA1100_STORK
    pcmcia_low_level=&stork_pcmcia_ops;
#endif
  }

  if (!pcmcia_low_level) {
    printk(KERN_ERR "This hardware is not supported by the SA1100 Card Service driver\n");
    return -ENODEV;
  }

  pcmcia_init.handler=sa1100_pcmcia_interrupt;

  if((sa1100_pcmcia_socket_count=pcmcia_low_level->init(&pcmcia_init))<0){
    printk(KERN_ERR "Unable to initialize kernel PCMCIA service.\n");
    return -EIO;
  }

  state_array.size=sa1100_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 -EIO;
  }

  /* We initialize the MECR to default values here, because we are
   * not guaranteed to see a SetIOMap operation at runtime.
   */
  mecr=0;

  clock = cpufreq_get(0);

  for(i=0; i<sa1100_pcmcia_socket_count; ++i){
    sa1100_pcmcia_socket[i].k_state=state[i];

    /* This is an interim fix. Apparently, SetSocket is no longer
     * called to initialize each socket (prior to the first detect
     * event). For now, we'll just manually set up the mask.
     */
    sa1100_pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;

    sa1100_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE;
    sa1100_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i);
    sa1100_pcmcia_socket[i].phys_mem=_PCMCIAMem(i);

    MECR_FAST_SET(mecr, i, 0);
    MECR_BSIO_SET(mecr, i,
		  sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_IO_ACCESS, clock));
    MECR_BSA_SET(mecr, i,
		 sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
    MECR_BSM_SET(mecr, i,
		 sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));

    sa1100_pcmcia_socket[i].speed_io=SA1100_PCMCIA_IO_ACCESS;
    sa1100_pcmcia_socket[i].speed_attr=SA1100_PCMCIA_5V_MEM_ACCESS;
    sa1100_pcmcia_socket[i].speed_mem=SA1100_PCMCIA_5V_MEM_ACCESS;
  }

  MECR=mecr;

#ifdef CONFIG_CPU_FREQ
  if(cpufreq_register_notifier(&sa1100_pcmcia_notifier_block) < 0){
    printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
    return -ENXIO;
  }
#endif

  /* Only advertise as many sockets as we can detect: */
  if(register_ss_entry(sa1100_pcmcia_socket_count, 
		       &sa1100_pcmcia_operations)<0){
    printk(KERN_ERR "Unable to register socket service routine\n");
    return -ENXIO;
  }

  /* Start the event poll timer.  It will reschedule by itself afterwards. */
  sa1100_pcmcia_poll_event(0);

  DEBUG(1, "sa1100: initialization complete\n");

  return 0;

}  /* sa1100_pcmcia_driver_init() */