コード例 #1
0
/**
 * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 */
int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
			   struct platform_device *dev)
{
	struct usb_hcd *hcd = NULL;
	int retval;

	s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);
	s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);

	hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");
	if (hcd == NULL)
		return -ENOMEM;

	hcd->rsrc_start = dev->resource[0].start;
	hcd->rsrc_len   = dev->resource[0].end - dev->resource[0].start + 1;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_err(&dev->dev, "request_mem_region failed");
		retval = -EBUSY;
		goto err0;
	}

	clk = clk_get(NULL, "usb-host");
	if (IS_ERR(clk)) {
		dev_err(&dev->dev, "cannot get usb-host clock\n");
		retval = -ENOENT;
		goto err1;
	}

	clk_use(clk);
	s3c2410_start_hc(dev, hcd);

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&dev->dev, "ioremap failed\n");
		retval = -ENOMEM;
		goto err2;
	}

	ohci_hcd_init(hcd_to_ohci(hcd));

	retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
	if (retval != 0)
		goto err2;

	return 0;

 err2:
	s3c2410_stop_hc(dev);
	iounmap(hcd->regs);
	clk_unuse(clk);
	clk_put(clk);

 err1:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);

 err0:
	usb_put_hcd(hcd);
	return retval;
}
コード例 #2
0
ファイル: timer-gp.c プロジェクト: 1x23/unifi-gpl
static void __init omap2_gp_timer_init(void)
{
	struct clk * sys_ck;
	u32 tick_period = 120000;
	u32 l;

	/* Reset clock and prescale value */
	timer_write_reg(OS_TIMER_NR, GP_TIMER_TCLR, 0);

	sys_ck = clk_get(NULL, "sys_ck");
	if (IS_ERR(sys_ck))
		printk(KERN_ERR "Could not get sys_ck\n");
	else {
		clk_use(sys_ck);
		tick_period = clk_get_rate(sys_ck) / 100;
		clk_put(sys_ck);
	}

	tick_period /= 2;	/* Minimum prescale divider is 2 */
	tick_period -= 1;

	l = timer_read_reg(OS_TIMER_NR, GP_TIMER_TIDR);
	printk(KERN_INFO "OMAP2 GP timer (HW version %d.%d)\n",
	       (l >> 4) & 0x0f, l & 0x0f);

	setup_irq(38, &omap2_gp_timer_irq);

	omap2_gp_timer_start(OS_TIMER_NR, tick_period);
}
コード例 #3
0
ファイル: dsp_ctl.c プロジェクト: GodFox/magx_kernel_xpixl
/*
 * control functions
 */
static void dsp_run(void)
{
	disable_irq(INT_DSP_MMU);
	preempt_disable();
	if (dsp_runstat == RUNSTAT_RESET) {
		clk_use(api_ck_handle);
		__dsp_run();
		dsp_runstat = RUNSTAT_RUN;
	}
	preempt_enable();
	enable_irq(INT_DSP_MMU);
}
コード例 #4
0
ファイル: ocpi.c プロジェクト: 1x23/unifi-gpl
static int __init omap_ocpi_init(void)
{
	if (!cpu_is_omap16xx())
		return -ENODEV;

	ocpi_ck = clk_get(NULL, "l3_ocpi_ck");
	if (IS_ERR(ocpi_ck))
		return PTR_ERR(ocpi_ck);

	clk_use(ocpi_ck);
	ocpi_enable();
	printk("OMAP OCPI interconnect driver loaded\n");

	return 0;
}
コード例 #5
0
ファイル: s3c24xx_udc.c プロジェクト: kzlin129/tt-gpl
/* until it's enabled, this UDC should be completely invisible
 * to any USB host.
 */
static int udc_enable(struct elfin_udc *dev)
{
	u32 val;

	DPRINTK("%s, %p\n", __FUNCTION__, dev);

	dev->gadget.speed = USB_SPEED_UNKNOWN;

	val = usb_read(s3c24xx_misccr, 0);
	val &= ~((1<<3)|(1<<13));       // USB Device in Normal mode
	usb_write(val, s3c24xx_misccr, 0);

	val = __raw_readb(S3C2410_CLKSLOW);
	val &= ~S3C2410_CLKSLOW_USB_CLK_DISABLE; /* enable usb device clock */
	__raw_writeb(val, S3C2410_CLKSLOW);

	/* Enable Clock */
	udc_clock = clk_get(NULL, "usb-device");
	if (!udc_clock) {
		printk("failed to get udc clock source\n");
		return -ENOENT;
	}
	clk_use(udc_clock);
	clk_enable(udc_clock);

	val = (1<<0);
	usb_write(val, S3C2410_UDC_EP_INT_REG, 0);	//clear
	val = (1<<2);   //UD_USBINTE_RESET
	usb_write(val, S3C2410_UDC_USB_INT_REG, 0);	//clear

	/* Set MAXP values for each */
	usb_write(dev->ep[0].ep.maxpacket>>3, S3C2410_UDC_MAXP_REG, 0);

	usb_write(dev->ep[1].ep.maxpacket>>3, S3C2410_UDC_MAXP_REG, 1);

	usb_write(dev->ep[2].ep.maxpacket>>3, S3C2410_UDC_MAXP_REG, 2);

	usb_write(dev->ep[3].ep.maxpacket>>3, S3C2410_UDC_MAXP_REG, 3);

	usb_write(dev->ep[4].ep.maxpacket>>3, S3C2410_UDC_MAXP_REG, 4);

	return 0;
}
コード例 #6
0
ファイル: serial.c プロジェクト: 1x23/unifi-gpl
/*
 * Note that on Innovator-1510 UART2 pins conflict with USB2.
 * By default UART2 does not work on Innovator-1510 if you have
 * USB OHCI enabled. To use UART2, you must disable USB2 first.
 */
void __init omap_serial_init(void)
{
	int i;
	const struct omap_uart_config *info;

	if (cpu_is_omap730()) {
		serial_platform_data[0].regshift = 0;
		serial_platform_data[1].regshift = 0;
		serial_platform_data[0].irq = INT_730_UART_MODEM_1;
		serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
	}

	if (cpu_is_omap1510()) {
		serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
		serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
		serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
	}

	info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
	if (info == NULL)
		return;

	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
		unsigned char reg;

		if (!((1 << i) & info->enabled_uarts)) {
			serial_platform_data[i].membase = NULL;
			serial_platform_data[i].mapbase = 0;
			continue;
		}

		switch (i) {
		case 0:
			uart1_ck = clk_get(NULL, "uart1_ck");
			if (IS_ERR(uart1_ck))
				printk("Could not get uart1_ck\n");
			else {
				clk_use(uart1_ck);
				if (cpu_is_omap1510())
					clk_set_rate(uart1_ck, 12000000);
			}
			if (cpu_is_omap1510()) {
				omap_cfg_reg(UART1_TX);
				omap_cfg_reg(UART1_RTS);
				if (machine_is_omap_innovator()) {
					reg = fpga_read(OMAP1510_FPGA_POWER);
					reg |= OMAP1510_FPGA_PCR_COM1_EN;
					fpga_write(reg, OMAP1510_FPGA_POWER);
					udelay(10);
				}
			}
			break;
		case 1:
			uart2_ck = clk_get(NULL, "uart2_ck");
			if (IS_ERR(uart2_ck))
				printk("Could not get uart2_ck\n");
			else {
				clk_use(uart2_ck);
				if (cpu_is_omap1510())
					clk_set_rate(uart2_ck, 12000000);
				else
					clk_set_rate(uart2_ck, 48000000);
			}
			if (cpu_is_omap1510()) {
				omap_cfg_reg(UART2_TX);
				omap_cfg_reg(UART2_RTS);
				if (machine_is_omap_innovator()) {
					reg = fpga_read(OMAP1510_FPGA_POWER);
					reg |= OMAP1510_FPGA_PCR_COM2_EN;
					fpga_write(reg, OMAP1510_FPGA_POWER);
					udelay(10);
				}
			}
			break;
		case 2:
			uart3_ck = clk_get(NULL, "uart3_ck");
			if (IS_ERR(uart3_ck))
				printk("Could not get uart3_ck\n");
			else {
				clk_use(uart3_ck);
				if (cpu_is_omap1510())
					clk_set_rate(uart3_ck, 12000000);
			}
			if (cpu_is_omap1510()) {
				omap_cfg_reg(UART3_TX);
				omap_cfg_reg(UART3_RX);
			}
			break;
		}
		omap_serial_reset(&serial_platform_data[i]);
	}
}
コード例 #7
0
static int __init i2c_davinci_init(void)
{
	int status;
	struct device 	*dev = NULL;

	DEB0("%s %s", __TIME__, __DATE__);

	DEB1("i2c_davinci_init()\n");

        davinci_i2c_fix_ths7353_lockup( );

#if 0
	if (i2c_davinci_busFreq > 200)
		i2c_davinci_busFreq = 400;	/*Fast mode */
	else
		i2c_davinci_busFreq = 100;	/*Standard mode */
#endif

	i2c_clock = clk_get (dev, "I2CCLK");	

	if (i2c_clock == NULL)
        	return -1;
        
	clk_use (i2c_clock);
	clk_enable (i2c_clock);
	i2c_davinci_inputClock = clk_get_rate (i2c_clock);

	DEB1 ("IP CLOCK = %ld\n", i2c_davinci_inputClock);

	memset(&i2c_davinci_dev, 0, sizeof(i2c_davinci_dev));

	i2c_davinci_dev.regs = (davinci_i2cregsovly)I2C_BASE;

	status = (int)request_region(I2C_BASE, I2C_IOSIZE, MODULE_NAME);
	if (!status) {
		i2c_err("I2C is already in use\n");
		return -ENODEV;
	}

	status = request_irq(IRQ_I2C, i2c_davinci_isr, 0, MODULE_NAME,
			     &i2c_davinci_dev);
	if (status) {
		i2c_err("failed to request I2C IRQ");
		goto do_release_region;
	}

	i2c_set_adapdata(&i2c_davinci_adap, &i2c_davinci_dev);
	status = i2c_add_adapter(&i2c_davinci_adap);
	if (status) {
		i2c_err("failed to add adapter");
		goto do_free_irq;
		return status;
	}

	i2c_davinci_reset(&i2c_davinci_dev);

	if (driver_register(&davinci_i2c_driver) != 0)
		printk(KERN_ERR "Driver register failed for davinci_i2c\n");
	if (platform_device_register(&davinci_i2c_device) != 0) {
		printk(KERN_ERR "Device register failed for i2c\n");
		driver_unregister(&davinci_i2c_driver);
	}

	return 0;

      do_free_irq:
	free_irq(IRQ_I2C, &i2c_davinci_dev);
      do_release_region:
	release_region(I2C_BASE, I2C_IOSIZE);

	return status;
}
コード例 #8
0
static int s3c2410wdt_probe(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct resource *res;
	int started = 0;
	int ret;
	int size;

	DBG("%s: probe=%p, device=%p\n", __FUNCTION__, pdev, dev);

	/* get the memory region for the watchdog timer */

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		printk(KERN_INFO PFX "failed to get memory region resouce\n");
		return -ENOENT;
	}

	size = (res->end-res->start)+1;
	wdt_mem = request_mem_region(res->start, size, pdev->name);
	if (wdt_mem == NULL) {
		printk(KERN_INFO PFX "failed to get memory region\n");
		return -ENOENT;
	}

	wdt_base = ioremap(res->start, size);
	if (wdt_base == 0) {
		printk(KERN_INFO PFX "failed to ioremap() region\n");
		return -EINVAL;
	}

	DBG("probe: mapped wdt_base=%p\n", wdt_base);

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		printk(KERN_INFO PFX "failed to get irq resource\n");
		return -ENOENT;
	}

	ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, dev);
	if (ret != 0) {
		printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
		return ret;
	}

	wdt_clock = clk_get(dev, "watchdog");
	if (wdt_clock == NULL) {
		printk(KERN_INFO PFX "failed to find watchdog clock source\n");
		return -ENOENT;
	}

	clk_use(wdt_clock);
	clk_enable(wdt_clock);

	/* see if we can actually set the requested timer margin, and if
	 * not, try the default value */

	if (s3c2410wdt_set_heartbeat(tmr_margin)) {
		started = s3c2410wdt_set_heartbeat(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);

		if (started == 0) {
			printk(KERN_INFO PFX "tmr_margin value out of range, default %d used\n",
			       CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
		} else {
			printk(KERN_INFO PFX "default timer value is out of range, cannot start\n");
		}
	}

	ret = misc_register(&s3c2410wdt_miscdev);
	if (ret) {
		printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
			WATCHDOG_MINOR, ret);
		return ret;
	}

	if (tmr_atboot && started == 0) {
		printk(KERN_INFO PFX "Starting Watchdog Timer\n");
		s3c2410wdt_start();
	}

	return 0;
}
コード例 #9
0
static int pl011_probe(struct amba_device *dev, void *id)
{
    struct uart_amba_port *uap;
    void *base;
    int i, ret;

    for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
        if (amba_ports[i] == NULL)
            break;

    if (i == ARRAY_SIZE(amba_ports)) {
        ret = -EBUSY;
        goto out;
    }

    uap = kmalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
    if (uap == NULL) {
        ret = -ENOMEM;
        goto out;
    }

    base = ioremap(dev->res.start, PAGE_SIZE);
    if (!base) {
        ret = -ENOMEM;
        goto free;
    }

    memset(uap, 0, sizeof(struct uart_amba_port));
    uap->clk = clk_get(&dev->dev, "UARTCLK");
    if (IS_ERR(uap->clk)) {
        ret = PTR_ERR(uap->clk);
        goto unmap;
    }

    ret = clk_use(uap->clk);
    if (ret)
        goto putclk;

    uap->port.dev = &dev->dev;
    uap->port.mapbase = dev->res.start;
    uap->port.membase = base;
    uap->port.iotype = UPIO_MEM;
    uap->port.irq = dev->irq[0];
    uap->port.fifosize = 16;
    uap->port.ops = &amba_pl011_pops;
    uap->port.flags = UPF_BOOT_AUTOCONF;
    uap->port.line = i;

    amba_ports[i] = uap;

    amba_set_drvdata(dev, uap);
    ret = uart_add_one_port(&amba_reg, &uap->port);
    if (ret) {
        amba_set_drvdata(dev, NULL);
        amba_ports[i] = NULL;
        clk_unuse(uap->clk);
putclk:
        clk_put(uap->clk);
unmap:
        iounmap(base);
free:
        kfree(uap);
    }
out:
    return ret;
}
コード例 #10
0
static void s3c24xx_serial_set_termios(struct uart_port *port,
				       struct termios *termios,
				       struct termios *old)
{
	struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
	struct s3c24xx_uart_port *ourport = to_ourport(port);
	struct s3c24xx_uart_clksrc *clksrc = NULL;
	struct clk *clk = NULL;
	unsigned long flags;
	unsigned int baud, quot;
	unsigned int ulcon;
	unsigned int umcon;

	/*
	 * We don't support modem control lines.
	 */
	termios->c_cflag &= ~(HUPCL | CMSPAR);
	termios->c_cflag |= CLOCAL;

	/*
	 * Ask the core to calculate the divisor for us.
	 */

	baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);

	if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
		quot = port->custom_divisor;
	else
		quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);

	/* check to see if we need  to change clock source */

	if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
		s3c24xx_serial_setsource(port, clksrc);

		if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
			clk_disable(ourport->baudclk);
			clk_unuse(ourport->baudclk);
			ourport->baudclk  = NULL;
		}

		clk_use(clk);
		clk_enable(clk);

		ourport->clksrc = clksrc;
		ourport->baudclk = clk;
	}

	switch (termios->c_cflag & CSIZE) {
	case CS5:
		dbg("config: 5bits/char\n");
		ulcon = S3C2410_LCON_CS5;
		break;
	case CS6:
		dbg("config: 6bits/char\n");
		ulcon = S3C2410_LCON_CS6;
		break;
	case CS7:
		dbg("config: 7bits/char\n");
		ulcon = S3C2410_LCON_CS7;
		break;
	case CS8:
	default:
		dbg("config: 8bits/char\n");
		ulcon = S3C2410_LCON_CS8;
		break;
	}

	/* preserve original lcon IR settings */
	ulcon |= (cfg->ulcon & S3C2410_LCON_IRM);

	if (termios->c_cflag & CSTOPB)
		ulcon |= S3C2410_LCON_STOPB;

	umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0;

	if (termios->c_cflag & PARENB) {
		if (termios->c_cflag & PARODD)
			ulcon |= S3C2410_LCON_PODD;
		else
			ulcon |= S3C2410_LCON_PEVEN;
	} else {
		ulcon |= S3C2410_LCON_PNONE;
	}

	spin_lock_irqsave(&port->lock, flags);

	dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot);

	wr_regl(port, S3C2410_ULCON, ulcon);
	wr_regl(port, S3C2410_UBRDIV, quot);
	wr_regl(port, S3C2410_UMCON, umcon);

	dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
	    rd_regl(port, S3C2410_ULCON),
	    rd_regl(port, S3C2410_UCON),
	    rd_regl(port, S3C2410_UFCON));

	/*
	 * Update the per-port timeout.
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	/*
	 * Which character status flags are we interested in?
	 */
	port->read_status_mask = S3C2410_UERSTAT_OVERRUN;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY;

	/*
	 * Which character status flags should we ignore?
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN;
	if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= S3C2410_UERSTAT_FRAME;

	/*
	 * Ignore all characters if CREAD is not set.
	 */
	if ((termios->c_cflag & CREAD) == 0)
		port->ignore_status_mask |= RXSTAT_DUMMY_READ;

	spin_unlock_irqrestore(&port->lock, flags);
}
コード例 #11
0
static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
				    struct s3c24xx_uart_info *info,
				    struct platform_device *platdev)
{
	struct uart_port *port = &ourport->port;
	struct s3c2410_uartcfg *cfg;
	struct resource *res;

	dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev);

	if (platdev == NULL)
		return -ENODEV;

	cfg = s3c24xx_dev_to_cfg(&platdev->dev);

	if (port->mapbase != 0)
		return 0;

	if (cfg->hwport > 3)
		return -EINVAL;

	/* setup info for port */
	port->dev	= &platdev->dev;
	ourport->info	= info;

	/* copy the info in from provided structure */
	ourport->port.fifosize = info->fifosize;

	dbg("s3c24xx_serial_init_port: %p (hw %d)...\n", port, cfg->hwport);

	port->uartclk = 1;

	if (cfg->uart_flags & UPF_CONS_FLOW) {
		dbg("s3c24xx_serial_init_port: enabling flow control\n");
		port->flags |= UPF_CONS_FLOW;
	}

	/* sort our the physical and virtual addresses for each UART */

	res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		printk(KERN_ERR "failed to find memory resource for uart\n");
		return -EINVAL;
	}

	dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);

	port->mapbase	= res->start;
	port->membase	= S3C24XX_VA_UART + (res->start - S3C2410_PA_UART);
	port->irq	= platform_get_irq(platdev, 0);

	ourport->clk	= clk_get(&platdev->dev, "uart");

	if (ourport->clk != NULL && !IS_ERR(ourport->clk))
		clk_use(ourport->clk);

	dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n",
	    port->mapbase, port->membase, port->irq, port->uartclk);

	/* reset the fifos (and setup the uart) */
	s3c24xx_serial_resetport(port, cfg);
	return 0;
}
コード例 #12
0
static int __init i2c_davinci_init(void)
{
	int status;
	struct device 	*dev = NULL;

	DEB0("%s %s", __TIME__, __DATE__);

	DEB1("i2c_davinci_init()");

	if (cpu_is_davinci_dm6467())
		davinci_i2c_expander_op (0x3A, I2C_INT_DM646X, 0);

        /* 
	 * NOTE: On DaVinci EVM, the i2c bus frequency is set to 20kHz
	 *       so that the MSP430, which is doing software i2c, has
	 *       some extra processing time
	 */
	if (machine_is_davinci_evm())
		i2c_davinci_busFreq = 20;
	else if (machine_is_davinci_dm6467_evm())
		i2c_davinci_busFreq = 100;
	else if (i2c_davinci_busFreq > 200)
		i2c_davinci_busFreq = 400;	/*Fast mode */
	else
		i2c_davinci_busFreq = 100;	/*Standard mode */

	i2c_clock = clk_get (dev, "I2CCLK");

	if (IS_ERR(i2c_clock))
        	return -1;

	clk_use (i2c_clock);
	clk_enable (i2c_clock);
	i2c_davinci_inputClock = clk_get_rate (i2c_clock);

	DEB1 ("IP CLOCK = %ld", i2c_davinci_inputClock);

	memset(&i2c_davinci_dev, 0, sizeof(i2c_davinci_dev));
	init_waitqueue_head(&i2c_davinci_dev.cmd_wait);

	i2c_davinci_dev.regs = (davinci_i2cregsovly)I2C_BASE;

	status = (int)request_region(I2C_BASE, I2C_IOSIZE, MODULE_NAME);
	if (!status) {
		i2c_err("I2C is already in use\n");
		return -ENODEV;
	}

	status = request_irq(IRQ_I2C, i2c_davinci_isr, 0, "i2c",
			     &i2c_davinci_dev);
	if (status) {
		i2c_err("failed to request I2C IRQ");
		goto do_release_region;
	}

	i2c_set_adapdata(&i2c_davinci_adap, &i2c_davinci_dev);
	status = i2c_add_adapter(&i2c_davinci_adap);
	if (status) {
		i2c_err("failed to add adapter");
		goto do_free_irq;
	}

	i2c_davinci_reset(&i2c_davinci_dev);

	if (driver_register(&davinci_i2c_driver) != 0)
		printk(KERN_ERR "Driver register failed for davinci_i2c\n");
	if (platform_device_register(&davinci_i2c_device) != 0) {
		printk(KERN_ERR "Device register failed for i2c\n");
		driver_unregister(&davinci_i2c_driver);
	}

	return 0;

      do_free_irq:
	free_irq(IRQ_I2C, &i2c_davinci_dev);
      do_release_region:
	release_region(I2C_BASE, I2C_IOSIZE);

	return status;
}
コード例 #13
0
static int mmci_probe(struct amba_device *dev, void *id)
{
	struct mmc_platform_data *plat = dev->dev.platform_data;
	struct mmci_host *host;
	struct mmc_host *mmc;
	int ret;

	/* must have platform data */
	if (!plat) {
		ret = -EINVAL;
		goto out;
	}

	ret = amba_request_regions(dev, DRIVER_NAME);
	if (ret)
		goto out;

	mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto rel_regions;
	}

	host = mmc_priv(mmc);
	host->clk = clk_get(&dev->dev, "MCLK");
	if (IS_ERR(host->clk)) {
		ret = PTR_ERR(host->clk);
		host->clk = NULL;
		goto host_free;
	}

	ret = clk_use(host->clk);
	if (ret)
		goto clk_free;

	ret = clk_enable(host->clk);
	if (ret)
		goto clk_unuse;

	host->plat = plat;
	host->mclk = clk_get_rate(host->clk);
	host->mmc = mmc;
	host->base = ioremap(dev->res.start, SZ_4K);
	if (!host->base) {
		ret = -ENOMEM;
		goto clk_disable;
	}

	mmc->ops = &mmci_ops;
	mmc->f_min = (host->mclk + 511) / 512;
	mmc->f_max = min(host->mclk, fmax);
	mmc->ocr_avail = plat->ocr_mask;

	/*
	 * We can do SGIO
	 */
	mmc->max_hw_segs = 16;
	mmc->max_phys_segs = NR_SG;

	/*
	 * Since we only have a 16-bit data length register, we must
	 * ensure that we don't exceed 2^16-1 bytes in a single request.
	 * Choose 64 (512-byte) sectors as the limit.
	 */
	mmc->max_sectors = 64;

	/*
	 * Set the maximum segment size.  Since we aren't doing DMA
	 * (yet) we are only limited by the data length register.
	 */
	mmc->max_seg_size = mmc->max_sectors << 9;

	spin_lock_init(&host->lock);

	writel(0, host->base + MMCIMASK0);
	writel(0, host->base + MMCIMASK1);
	writel(0xfff, host->base + MMCICLEAR);

	ret = request_irq(dev->irq[0], mmci_irq, SA_SHIRQ, DRIVER_NAME " (cmd)", host);
	if (ret)
		goto unmap;

	ret = request_irq(dev->irq[1], mmci_pio_irq, SA_SHIRQ, DRIVER_NAME " (pio)", host);
	if (ret)
		goto irq0_free;

	writel(MCI_IRQENABLE, host->base + MMCIMASK0);

	amba_set_drvdata(dev, mmc);

	mmc_add_host(mmc);

	printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n",
		mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
		dev->res.start, dev->irq[0], dev->irq[1]);

	init_timer(&host->timer);
	host->timer.data = (unsigned long)host;
	host->timer.function = mmci_check_status;
	host->timer.expires = jiffies + HZ;
	add_timer(&host->timer);

	return 0;

 irq0_free:
	free_irq(dev->irq[0], host);
 unmap:
	iounmap(host->base);
 clk_disable:
	clk_disable(host->clk);
 clk_unuse:
	clk_unuse(host->clk);
 clk_free:
	clk_put(host->clk);
 host_free:
	mmc_free_host(mmc);
 rel_regions:
	amba_release_regions(dev);
 out:
	return ret;
}
コード例 #14
0
int __init musb_platform_init(struct musb *musb)
{
	void *__iomem tibase = musb->ctrl_base;
	u32 revision, phystatus;
	u8 id;
	struct platform_device *pdev = to_platform_device(musb->controller);
	struct musb_hdrc_platform_data *plat;
	struct clk *clkp;

	if (pdev->id == -1)
		id = 0;
	else
		id = pdev->id;
	
	switch (id) {
	case 0 :
		clkp = clk_get (NULL, "USBCLK");
		break;
	default :
		return -ENODEV;
	}
	if (IS_ERR(clkp))
		return -ENODEV;

	musb->clock = clkp;
	clk_use (clkp);
	if (clk_enable (clkp) != 0)
		return -ENODEV;

	plat = musb->controller->platform_data;

	/* overwrite the USB mode */
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	plat->mode = MUSB_HOST;

#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
	plat->mode = MUSB_PERIPHERAL;

#elif defined(CONFIG_USB_MUSB_OTG)
	plat->mode = MUSB_OTG;
#else
	dev_dbg(musb->controller, "incompatible Kconfig role setting");
	return -EINVAL;
#endif

	musb->board_mode = plat->mode;
	musb->pRegs += DAVINCI_BASE_OFFSET;

	/* returns zero if e.g. not clocked */
	revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
	if (revision == 0)
		return -ENODEV;

	/* note that transceiver issues make us want to charge
	 * VBUS only when the PHY PLL is not active.
	 */
#if defined(CONFIG_MACH_DAVINCI_EVM) || defined (CONFIG_MACH_DAVINCI_HD_EVM)
#ifdef CONFIG_USB_MUSB_OTG
	/* clear EMACEN to enble OTG GPIO 16 for VBus power control */
	/* Set GPIO Direction */
	REG_DVEVM_GPIO45_DIR &= ~(DVEVM_GPIO45_DIR_OUT);
	davinci_cfg_reg(DM644X_GPIO3V);
#endif
	evm_vbus_work.data = musb;
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM355
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	gpio_direction_output(2, 1);
#else
	gpio_direction_output(2, 0);
#endif
	 __raw_writel( __raw_readl (IO_ADDRESS(DM355_DEEPSLEEP_REG)) &
		0xfffffff0, IO_ADDRESS (DM355_DEEPSLEEP_REG));
#endif

	/* reset the controller */
	musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);

	/* start the on-chip PHY and its PLL */
	phy_on();

	msleep(5);
	phystatus = __raw_readl(IO_ADDRESS(USBPHY_CTL_PADDR));
#ifdef CONFIG_ARCH_DAVINCI_DM646x
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	__raw_writel(phystatus | DM646X_USBPHY_SESSION_VBUS |
		DM646X_USBPHY_NDATAPOL, IO_ADDRESS(USBPHY_CTL_PADDR));
#else
	__raw_writel (phystatus | DM646X_USBPHY_SESSION_VBUS |
		DM646X_USBPHY_NDATAPOL | DM646X_USBPHY_PERI_USBID,
		IO_ADDRESS(USBPHY_CTL_PADDR));
#endif
#endif

	/* NOTE:  irqs are in mixed mode, not bypass to pure-musb */
	pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
		 revision,
		 musb_readl((void *__iomem)IO_ADDRESS(USBPHY_CTL_PADDR), 0x00),
		 musb_readb(tibase, DAVINCI_USB_CTRL_REG));

	musb->isr = davinci_interrupt;
	return 0;
}
コード例 #15
0
int __init musb_platform_init(struct musb *musb)
{
	void *__iomem tibase = musb->ctrl_base;
	u32 revision, phystatus;
#ifdef CONFIG_ARCH_DAVINCI
	struct clk *clkp;
	
	clkp = clk_get (NULL, "USBCLK");
	if (IS_ERR(clkp))
		return -ENODEV;

	musb->clock = clkp;	
	clk_use (clkp);
	if(clk_enable (clkp) != 0)
		return -ENODEV;
#endif
	musb->pRegs += DAVINCI_BASE_OFFSET;

	/* returns zero if e.g. not clocked */
	revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
	if (revision == 0)
		return -ENODEV;

	/* note that transceiver issues make us want to charge
	 * VBUS only when the PHY PLL is not active.
	 */
#if defined(CONFIG_MACH_DAVINCI_EVM) || defined (CONFIG_MACH_DAVINCI_HD_EVM)
#ifdef CONFIG_USB_MUSB_OTG
	/* clear EMACEN to enble OTG GPIO 16 for VBus power control */
	/* Set GPIO Direction */
	REG_DVEVM_GPIO45_DIR &= ~(DVEVM_GPIO45_DIR_OUT);
	DAVINCI_PINMUX0 &= ~(0x80000000);
#endif
	evm_vbus_work.data = musb;
#endif
#ifdef CONFIG_ARCH_DAVINCI355
	gpio_set_direction(2, GIO_DIR_OUTPUT);
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	__gpio_set(2, 1);
#else
	__gpio_set(2, 0);
#endif
	 __raw_writel( __raw_readl(IO_ADDRESS(DEEPSLEEP_REG)) & 0xfffffff0,
			IO_ADDRESS(DEEPSLEEP_REG));
#endif
	/* reset the controller */
	musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
	phy_on();

	msleep(5);
	phystatus = __raw_readl(IO_ADDRESS(USBPHY_CTL_PADDR));
#ifdef CONFIG_ARCH_DAVINCI646x
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	__raw_writel(phystatus | USBPHY_SESSION_VBUS | USBPHY_NDATAPOL,
		IO_ADDRESS(USBPHY_CTL_PADDR));
#else
	__raw_writel (phystatus | USBPHY_SESSION_VBUS | USBPHY_NDATAPOL |
			 USBPHY_PERI_USBID, IO_ADDRESS(USBPHY_CTL_PADDR));
#endif
#endif

	/* NOTE:  irqs are in mixed mode, not bypass to pure-musb */
	pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
		 revision,
		 musb_readl((void *__iomem)IO_ADDRESS(USBPHY_CTL_PADDR), 0x00),
		 musb_readb(tibase, DAVINCI_USB_CTRL_REG));

	musb->isr = davinci_interrupt;
	return 0;
}