Пример #1
0
void __init s3c2440_register_uart(int idx, int port)
{
	switch (idx)
	{
		case 0:
			s3c2440_ports[idx].membase	= (void *)io_p2v(UART0_CTL_BASE);
			s3c2440_ports[idx].mapbase	= UART0_CTL_BASE;
			s3c2440_ports[idx].irq	= IRQ_RXD0;
			break;
		case 1:
			s3c2440_ports[idx].membase	= (void *)io_p2v(UART1_CTL_BASE);
			s3c2440_ports[idx].mapbase	= UART1_CTL_BASE;
			s3c2440_ports[idx].irq	= IRQ_RXD1;
			break;
		case 2:
			s3c2440_ports[idx].membase	= (void *)io_p2v(UART2_CTL_BASE);
			s3c2440_ports[idx].mapbase	= UART2_CTL_BASE;
			s3c2440_ports[idx].irq	= IRQ_RXD2;
			break;
		default:
			printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
			return;
	}

	s3c2440_ports[idx].flags	= ASYNC_BOOT_AUTOCONF;
}
/*------------------------------------------------------------------------------
    Function name   : hs_buttonisr
    Description     : interrupt handler

    Return type     : irqreturn_t
------------------------------------------------------------------------------*/
irqreturn_t hs_buttonisr(int irq, void *dev_id)
{
    ktime_t r, temp;
    unsigned int key_val, bias_val, button_threshold;

    /* Set the keypress threshold based on the bias voltage */
    bias_val = readl(io_p2v(REG_MICAUX_EN));
	if (bias_val == 1)
        button_threshold = mic.headset_pd->keypress_threshold_fp;
    else
        button_threshold = mic.headset_pd->keypress_threshold_lp;

    /* Read the ANACR12 register value to check if the interrupt being
     * serviced by the ISR is spurious */
    key_val = readl(io_p2v(REG_ANACR12));

    temp = ktime_get();
    r = ktime_sub(temp,mic.hsbtime);
    if((r.tv.sec > 0) || (r.tv.nsec > REF_TIME)){
	    mic.hsbtime = temp;
    } else {
        return IRQ_HANDLED;
    }

    /* If the value read from the ANACR12 register is greater than the
     * threshold, schedule the workqueue */
    if (key_val >= button_threshold){
#if defined(CONFIG_HAS_WAKELOCK)
    wake_lock_timeout(&headsetbutton_wake_lock,HZ);
#endif
	    schedule_delayed_work(&(mic.input_work) , 0);
    }else
	    pr_info("Headset Button press detected for a illegal interrupt\n");
    return IRQ_HANDLED;
}
void ipcs_intr_workqueue_process(struct work_struct *work)
{
    static int first = 1;
    if (first)
    {
        first = 0;
        set_user_nice(current, -16);
    }


	if(IpcCPCrashCheck())
	{
		cp_crashed  = 1;
		//patch-s from Broadcom for csp#529767 reason:FALSE file=ripisr_cp.c line=342 code=-1/0xffffffff tastk=RIP_H TS=48744870/FN=4873
		//reviewed by yuan
				/* Dumping Camera registers. MobC00180667 */
		{
			int i = 0;
			unsigned int camera_addr_base = 0x08440000; // Receiver Status reg set
			printk("\n Dumping Camera registers\n");
			for(i = 0; i < 8; i ++) {
				printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base)));
				camera_addr_base += 4;
			}
			camera_addr_base = 0x08440080; // Debug register set
			for(i = 0; i < 9; i ++) {
				printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base)));
				camera_addr_base += 4;
			}
			camera_addr_base = 0x08440100; // Channel information set
			for(i = 0; i < 12; i ++) {
				printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base)));
				camera_addr_base += 4;
			}
			camera_addr_base = 0x08440400; // Ping pong buffer management
			printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base)));
		}
		/* End of Camera register dump */
		//patch-e from Broadcom for csp#529767 reason:FALSE file=ripisr_cp.c line=342 code=-1/0xffffffff tastk=RIP_H TS=48744870/FN=4873

		if( BCMLOG_CPCRASH_MTD == BCMLOG_GetCpCrashDumpDevice() )
		{
			/* we kill AP when CP crashes */
			IPC_DEBUG(DBG_INFO, "Crashing AP now...\n\n");
			abort();  
		} else 
		{
			ProcessCPCrashedDump(work);
		}

		IPC_ProcessEvents();
	}else
	{
		IPC_ProcessEvents();  
#ifdef CONFIG_HAS_WAKELOCK 
	       wake_unlock(&ipc_wake_lock);
#endif // CONFIG_HAS_WAKELOCK
	}
}
Пример #4
0
void __init cpu8815_init_irq(void)
{
	
	vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START +  0, ~0, 0);
	vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0);

	clk_init();
}
Пример #5
0
/*
 * System reset via the watchdog timer
 */
void lpc32xx_watchdog_reset(void)
{
	/* Make sure WDT clocks are enabled */
	__raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
		LPC32XX_CLKPWR_TIMER_CLK_CTRL);

	/* Instant assert of RESETOUT_N with pulse length 1mS */
	__raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18));
	__raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC));
}
Пример #6
0
Файл: xc.c Проект: E-LLP/n900
struct xc *request_xc(int xcno, struct device *dev)
{
	struct xc *x = NULL;

	mutex_lock(&xc_lock);

	if (xcno > 3)
		goto exit;
	if (xc_in_use & (1 << xcno))
		goto exit;

	x = kmalloc(sizeof (struct xc), GFP_KERNEL);
	if (!x)
		goto exit;

	if (!request_mem_region
	    (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, kobject_name(&dev->kobj)))
		goto exit_free;

	if (!request_mem_region
	    (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, kobject_name(&dev->kobj)))
		goto exit_release_1;

	if (!request_mem_region
	    (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, kobject_name(&dev->kobj)))
		goto exit_release_2;

	x->xpec_base = (void * __iomem)io_p2v(NETX_PA_XPEC(xcno));
	x->xmac_base = (void * __iomem)io_p2v(NETX_PA_XMAC(xcno));
	x->sram_base = ioremap(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
	if (!x->sram_base)
		goto exit_release_3;

	x->irq = NETX_IRQ_XPEC(xcno);

	x->no = xcno;
	x->dev = dev;

	xc_in_use |= (1 << xcno);

	goto exit;

      exit_release_3:
	release_mem_region(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
      exit_release_2:
	release_mem_region(NETX_PA_XMAC(xcno), XMAC_MEM_SIZE);
      exit_release_1:
	release_mem_region(NETX_PA_XPEC(xcno), XPEC_MEM_SIZE);
      exit_free:
	kfree(x);
	x = NULL;
      exit:
	mutex_unlock(&xc_lock);
	return x;
}
Пример #7
0
void __init cpu8815_init_irq(void)
{
	/* This modified VIC cell has two register blocks, at 0 and 0x20 */
	vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START +  0, ~0, 0);
	vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0);

	/*
	 * Init clocks here so that they are available for system timer
	 * initialization.
	 */
	clk_init();
}
Пример #8
0
static void __init nomadik_timer_init(void)
{
	u32 src_cr;

	/* Configure timer sources in "system reset controller" ctrl reg */
	src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
	src_cr &= SRC_CR_INIT_MASK;
	src_cr |= SRC_CR_INIT_VAL;
	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));

	nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE), IRQ_MTU0);
}
// Switch class work to update state of headset
static void switch_work(struct work_struct *work)
{
    struct h2w_switch_data *data =
                container_of(to_delayed_work(work), struct h2w_switch_data, work);
	int headset_state;

        if (mic.headset_pd->check_hs_state) {
		enable_irq(mic.hsirq);
		mic.headset_pd->check_hs_state(&headset_state);

		/* Check headset state after the debounce time,
		 * if same exit, as there is no state change */
		if (headset_state == mic.headset_state)
			return;
		mic.headset_state = headset_state;
	}

        switch_set_state(&data->sdev, mic.headset_state);
	if(mic.headset_state){
		 if(mic.hsbst){
			mic.hsbst = 0;
			/* Turn on the Rx LDO on headset insertion, this 
			 * will only be applicable if headset detect is from GPIO
			 */
			if (mic.headset_pd->check_hs_state)
				writel(AUDIO_RX_LDO_ON(readl(io_p2v(REG_ANACR2))), 
						io_p2v(REG_ANACR2));
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_INIT);
		 	enable_irq(mic.hsbirq);
		 }
	} else {
		if(!mic.hsbst){
		 	disable_irq(mic.hsbirq);
			/* Turn off the Rx LDO on headset removal, this will only be
			 * applicable if headset detect is from GPIO
			 */
			if (mic.headset_pd->check_hs_state)
				// [email protected] 2012.05.02 begin
				// fix bug csp 522980. merge brcm patch
			{
				if (!((readl(io_p2v(REG_ANACR2))) & 0x4))
					writel(AUDIO_RX_LDO_OFF(readl(io_p2v(REG_ANACR2))), 
						io_p2v(REG_ANACR2));
      }
			  // [email protected] 2012.05.02 end
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);
			mic.hsbst = 1;
		}
	}
}
Пример #10
0
static void __init nomadik_timer_init(void)
{
	u32 src_cr;

	/* Configure timer sources in "system reset controller" ctrl reg */
	src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
	src_cr &= SRC_CR_INIT_MASK;
	src_cr |= SRC_CR_INIT_VAL;
	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));

	/* Save global pointer to mtu, used by platform timer code */
	mtu_base = io_p2v(NOMADIK_MTU0_BASE);

	nmdk_timer_init();
}
Пример #11
0
static int __init pxa95x_init(void)
{
	int ret = 0, i;

	if (cpu_is_pxa95x()) {
		mfp_init_base(io_p2v(MFPR_BASE));
		mfp_init_addr(pxa95x_mfp_addr_map);

		reset_status = ARSR;

		/*
                                         
    
                                                                
                                                             
   */
		ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);

		clkdev_add_table(pxa95x_clkregs, ARRAY_SIZE(pxa95x_clkregs));

		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
			return ret;

		register_syscore_ops(&pxa_irq_syscore_ops);
		register_syscore_ops(&pxa3xx_clock_syscore_ops);

		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
	}

	return ret;
}
Пример #12
0
static int __init pxa95x_init(void)
{
	int ret = 0, i;

	if (cpu_is_pxa95x()) {
		mfp_init_base(io_p2v(MFPR_BASE));
		mfp_init_addr(pxa95x_mfp_addr_map);

		reset_status = ARSR;

		/*
		 * clear RDH bit every time after reset
		 *
		 * Note: the last 3 bits DxS are write-1-to-clear so carefully
		 * preserve them here in case they will be referenced later
		 */
		ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);

		clkdev_add_table(pxa95x_clkregs, ARRAY_SIZE(pxa95x_clkregs));

		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
			return ret;

		register_syscore_ops(&pxa_irq_syscore_ops);
		register_syscore_ops(&pxa_gpio_syscore_ops);
		register_syscore_ops(&pxa3xx_clock_syscore_ops);

		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
	}

	return ret;
}
/*------------------------------------------------------------------------------
    Function name   : hs_isr
    Description     : interrupt handler

    Return type     : irqreturn_t
------------------------------------------------------------------------------*/
irqreturn_t hs_isr(int irq, void *dev_id)
{
    struct mic_t *p = (struct mic_t *)dev_id;
    unsigned long int val = readl(io_p2v(REG_ANACR12));

    p->hstime = ktime_get();
    if (p->headset_pd->check_hs_state)
    {
	/* Disable the irq here as not get any further interrupts
	 * from hsirq until we complete the debounce logic */
	disable_irq_nosync(irq);

	/* Schedule the work for s/w based debounce. Provide debounce_ms as
	 * 0 to schedule immediately */
	schedule_delayed_work(&(p->switch_data.work),
			msecs_to_jiffies(p->headset_pd->debounce_ms));
    }
    else
    {
	val = val & MIC_PLUGIN_MASK;
	/*If the value read from anacr12 is zero and still the ISR is invoked, then the interrupt is
	 * deemed illegal*/
	if(!val)
		return IRQ_NONE;

	p->headset_state = (p->headset_state)?0:1;
        set_irq_type(mic.hsirq, (p->headset_state) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING);
	schedule_delayed_work(&(p->switch_data.work), 0);
    }
    return IRQ_HANDLED; 

}
/*------------------------------------------------------------------------------
Function name   : hs_isr
Description     : interrupt handler

Return type     : irqreturn_t
------------------------------------------------------------------------------*/
irqreturn_t hs_isr(int irq, void *dev_id)
{
	struct mic_t *p = (struct mic_t *)dev_id;
	int attached_state = 0; 

	p->hstime = ktime_get();	
        wake_lock_timeout(&p->det_wake_lock, WAKE_LOCK_TIME);

	if (p->headset_pd->check_hs_state)
	{
		sync_use_mic = ENABLE;
		p->hsirq_triggerred = 1 ;
		p->headset_pd->check_hs_state(&attached_state);
		set_irq_type(mic.hsirq, (attached_state) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING);
		mod_timer(&p->timer,jiffies + msecs_to_jiffies(p->headset_pd->debounce_ms));
	}
	else
	{
		unsigned long int val = readl(io_p2v(REG_ANACR12));

		val = val & MIC_PLUGIN_MASK;
		/*If the value read from anacr12 is zero and still the ISR is invoked, then the interrupt is
		* deemed illegal*/
		if(!val)
		      return IRQ_NONE;

		p->headset_state = (p->headset_state) ? 0 : 1;
		set_irq_type(mic.hsirq, (p->headset_state) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING);
		sync_use_mic = ENABLE;
		schedule_work(&(p->switch_data.work));
	}

	return IRQ_HANDLED; 
}
Пример #15
0
static int __devinit daq1000_adc_probe(struct platform_device   *pdev)
{
	int tmp = 0;

	__raw_writel((1 << 6), GPIO_P3_MUX_CLR(GPIO_IOBASE));   	/* 设置GPO_06为GPO功能引脚      */

	/*
	 ** 在UART控制器中不使用modem控制管脚 , 这主要是配置GPI_28只作为GPI管脚使用
	 */
	tmp = __raw_readl(UARTCTL_CTRL(io_p2v(UART_CTRL_BASE)));
	tmp &= ~(1 << 11);
	__raw_writel(tmp, UARTCTL_CTRL(io_p2v(UART_CTRL_BASE)));


	return daq1000_adc_sysfs_register(&pdev->dev);
}
Пример #16
0
/*
 * This function is called from the board init ("init_machine").
 */
 void __init cpu8815_platform_init(void)
{
#ifdef CONFIG_CACHE_L2X0
	/* At full speed latency must be >=2, so 0x249 in low bits */
	l2x0_init(io_p2v(NOMADIK_L2CC_BASE), 0x00730249, 0xfe000fff);
#endif
	 return;
}
Пример #17
0
 void __init cpu8815_platform_init(void)
{
#ifdef CONFIG_CACHE_L2X0
	
	l2x0_init(io_p2v(NOMADIK_L2CC_BASE), 0x00730249, 0xfe000fff);
#endif
	 return;
}
Пример #18
0
/*
 * On Assabet, we must probe for the Neponset board _before_
 * paging_init() has occurred to actually determine the amount
 * of RAM available.  To do so, we map the appropriate IO section
 * in the page table here in order to access GPIO registers.
 */
static void __init map_sa1100_gpio_regs( void )
{
	unsigned long phys = __PREG(GPLR) & PMD_MASK;
	unsigned long virt = io_p2v(phys);
	int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO);
	pmd_t pmd;
	pmd_val(pmd) = phys | prot;
	set_pmd(pmd_offset(pgd_offset_k(virt), virt), pmd);
}
Пример #19
0
void cpu8815_restart(char mode, const char *cmd)
{
	void __iomem *src_rstsr = io_p2v(NOMADIK_SRC_BASE + 0x18);

	

	
	writel(1, src_rstsr);
}
Пример #20
0
void cpu8815_restart(char mode, const char *cmd)
{
	void __iomem *src_rstsr = io_p2v(NOMADIK_SRC_BASE + 0x18);

	/* FIXME: use egpio when implemented */

	/* Write anything to Reset status register */
	writel(1, src_rstsr);
}
Пример #21
0
static int __init pxa930_init(void)
{
	if (cpu_is_pxa930()) {
		mfp_init_base(io_p2v(MFPR_BASE));
		mfp_init_addr(pxa930_mfp_addr_map);
	}

	return 0;
}
static inline void __iomem *irq_base(int i)
{
	static unsigned long phys_base[] = {
		0x40d00000,
		0x40d0009c,
		0x40d00130,
	};

	return (void __iomem *)io_p2v(phys_base[i]);
}
Пример #23
0
static int __init pxa320_init(void)
{
	if (cpu_is_pxa320()) {
		mfp_init_base(io_p2v(MFPR_BASE));
		mfp_init_addr(pxa320_mfp_addr_map);
		clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs));
	}

	return 0;
}
/*
 * For non device-tree builds, keep legacy timer init
 */
void __init pxa_timer_init(void)
{
	if (cpu_is_pxa25x())
		pxa25x_clocks_init();
	if (cpu_is_pxa27x())
		pxa27x_clocks_init();
	if (cpu_is_pxa3xx())
		pxa3xx_clocks_init();
	pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a00000));
}
Пример #25
0
/**
 * Handles the write function
 * buffer: the incoming message to be handled
 * */
static void handle_write(const char* buffer)
{
	char *endPtr;
	int address_to_write = simple_strtol(buffer, &endPtr, 16);
	endPtr++; //Set endPtr ahead one position of the space in the message	
	int value_to_write = simple_strtol(endPtr, NULL, 16);
	
	printk( KERN_INFO "Writing value 0x%x to memory address 0x%08x\n", value_to_write, address_to_write);
	
	iowrite32(value_to_write, io_p2v(address_to_write));
}
Пример #26
0
/*
 * On Assabet, we must probe for the Neponset board _before_
 * paging_init() has occurred to actually determine the amount
 * of RAM available.  To do so, we map the appropriate IO section
 * in the page table here in order to access GPIO registers.
 */
static void __init map_sa1100_gpio_regs( void )
{
	unsigned long phys = __PREG(GPLR) & PMD_MASK;
	unsigned long virt = (unsigned long)io_p2v(phys);
	int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO);
	pmd_t *pmd;

	pmd = pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt);
	*pmd = __pmd(phys | prot);
	flush_pmd_entry(pmd);
}
static void type_work_func(struct work_struct *work)
{
#ifdef REG_DEBUG
	unsigned long val_anacr2, val_cmc, val_auxen;
#endif

	int adc = auxadc_access(2);

	if(adc>=KEY_3POLE_THRESHOLD)
	{
		if(FactoryMode == DISABLE)
			board_sysconfig(SYSCFG_AUXMIC, SYSCFG_ENABLE | SYSCFG_DISABLE);

		if (mic.headset_pd->check_hs_state)
			board_sysconfig(SYSCFG_HEADSET, SYSCFG_ENABLE);

		mic.headset_state = HEADSET_4_POLE;
		printk("%s: 4-pole inserted : ear_adc=%d\n", __func__, adc);
	}
	else
	{
		board_sysconfig(SYSCFG_AUXMIC, SYSCFG_DISABLE);

		mic.headset_state = HEADSET_3_POLE;
		printk("%s: 3-pole inserted : ear_adc=%d\n", __func__, adc);
	}

	switch_set_state(&(mic.switch_data.sdev), mic.headset_state);

	if(FactoryMode == DISABLE)
	sync_use_mic = DISABLE;

#ifdef REG_DEBUG
	val_anacr2 = readl(io_p2v(REG_ANACR2));
	val_cmc = readl(io_p2v(REG_AUXMIC_CMC));
	val_auxen = readl(io_p2v(REG_AUXMIC_AUXEN));
	printk("%s: REG_ANACR2=%x, REG_AUXMIC_CMC=%x, REG_AUXMIC_AUXEN=%x\n", __func__, val_anacr2, val_cmc, val_auxen);
#endif

}
static void input_work_func(struct work_struct *work)
{
	int delta;
	unsigned long key_val, bias_val, button_threshold;
	static int key_status = 0;

    /* Set the keypress threshold based on bias voltage*/
    bias_val = readl(io_p2v(REG_MICAUX_EN));
	if (bias_val == 1)
        button_threshold = mic.headset_pd->keypress_threshold_fp;
    else
        button_threshold = mic.headset_pd->keypress_threshold_lp;

    /* If the key_status is 0, send the event for a key press */
	 if(key_status == 0)
	 {
	     delta = check_delta(mic.hsbtime,mic.hstime);
	     if((mic.headset_state== 1) && (delta == 0)){
		 input_report_key(mic.headset_button_idev, KEY_BCM_HEADSET_BUTTON,1);
		 input_sync(mic.headset_button_idev);
	     }
	 }
	 /* Check if the value read from ANACR12 is greater than the
	  * threshold. If so, the key is still pressed and schedule the work
	  * queue till the value is less than the threshold */
	 key_val = readl(io_p2v(REG_ANACR12));
	 if (key_val >= button_threshold)
	 {
	     key_status = 1;
	     schedule_delayed_work(&(mic.input_work), KEY_PRESS_REF_TIME);
	 }
	 /*Once the value read from ANACR12 is lesser than the threshold, send
	  * the event for a button release */
	 else
	 {
	     key_status = 0;
	     input_report_key(mic.headset_button_idev, KEY_BCM_HEADSET_BUTTON, 0);
             input_sync(mic.headset_button_idev);
	 }
}
Пример #29
0
static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id)
{
	struct nmk_gpio_platform_data *pdata;
	struct nmk_gpio_chip *nmk_chip;
	struct gpio_chip *chip;
	int ret;

	pdata = dev->dev.platform_data;
	ret = amba_request_regions(dev, pdata->name);
	if (ret)
		return ret;

	nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
	if (!nmk_chip) {
		ret = -ENOMEM;
		goto out_amba;
	}
	/*
	 * The virt address in nmk_chip->addr is in the nomadik register space,
	 * so we can simply convert the resource address, without remapping
	 */
	nmk_chip->addr = io_p2v(dev->res.start);
	nmk_chip->chip = nmk_gpio_template;
	nmk_chip->parent_irq = pdata->parent_irq;

	chip = &nmk_chip->chip;
	chip->base = pdata->first_gpio;
	chip->label = pdata->name;
	chip->dev = &dev->dev;
	chip->owner = THIS_MODULE;

	ret = gpiochip_add(&nmk_chip->chip);
	if (ret)
		goto out_free;

	amba_set_drvdata(dev, nmk_chip);

	nmk_gpio_init_irq(nmk_chip);

	dev_info(&dev->dev, "Bits %i-%i at address %p\n",
		 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
	return 0;

 out_free:
	kfree(nmk_chip);
 out_amba:
	amba_release_regions(dev);
	dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
		  pdata->first_gpio, pdata->first_gpio+31);
	return ret;
}
Пример #30
0
static int __init omap_rng_probe(struct platform_device *pdev)
{
	struct resource *res, *mem;
	int ret;

	/*
	 * A bit ugly, and it will never actually happen but there can
	 * be only one RNG and this catches any bork
	 */
	BUG_ON(rng_dev);

	if (cpu_is_omap24xx()) {
		rng_ick = clk_get(NULL, "rng_ick");
		if (IS_ERR(rng_ick)) {
			dev_err(&pdev->dev, "Could not get rng_ick\n");
			ret = PTR_ERR(rng_ick);
			return ret;
		} else
			clk_enable(rng_ick);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!res)
		return -ENOENT;

	mem = request_mem_region(res->start, res->end - res->start + 1,
				 pdev->name);
	if (mem == NULL)
		return -EBUSY;

	dev_set_drvdata(&pdev->dev, mem);
	rng_base = (u32 __iomem *)io_p2v(res->start);

	ret = hwrng_register(&omap_rng_ops);
	if (ret) {
		release_resource(mem);
		rng_base = NULL;
		return ret;
	}

	dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
		omap_rng_read_reg(RNG_REV_REG));
	omap_rng_write_reg(RNG_MASK_REG, 0x1);

	rng_dev = pdev;

	return 0;
}