static int mmci_remove(struct amba_device *dev) { struct mmc_host *mmc = amba_get_drvdata(dev); amba_set_drvdata(dev, NULL); if (mmc) { struct mmci_host *host = mmc_priv(mmc); del_timer_sync(&host->timer); mmc_remove_host(mmc); writel(0, host->base + MMCIMASK0); writel(0, host->base + MMCIMASK1); writel(0, host->base + MMCICOMMAND); writel(0, host->base + MMCIDATACTRL); free_irq(dev->irq[0], host); free_irq(dev->irq[1], host); iounmap(host->base); clk_disable(host->clk); clk_unuse(host->clk); clk_put(host->clk); mmc_free_host(mmc); amba_release_regions(dev); } return 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; }
static void __exit omap_ocpi_exit(void) { /* REVISIT: Disable OCPI */ if (!cpu_is_omap16xx()) return; clk_unuse(ocpi_ck); clk_put(ocpi_ck); }
static void __exit i2c_davinci_exit(void) { struct i2c_davinci_device dev; clk_disable (i2c_clock); clk_unuse (i2c_clock); i2c_del_adapter(&i2c_davinci_adap); dev.regs->icmdr = 0; free_irq(IRQ_I2C, &i2c_davinci_dev); release_region(I2C_BASE, I2C_IOSIZE); driver_unregister(&davinci_i2c_driver); platform_device_unregister(&davinci_i2c_device); }
static void dsp_reset(void) { disable_irq(INT_DSP_MMU); preempt_disable(); if (dsp_runstat > RUNSTAT_RESET) { __dsp_reset(); if (dsp_runstat == RUNSTAT_RUN) clk_unuse(api_ck_handle); dsp_runstat = RUNSTAT_RESET; } preempt_enable(); enable_irq(INT_DSP_MMU); }
/* * udc_disable - disable USB device controller */ static void udc_disable(struct elfin_udc *dev) { DPRINTK("%s, %p\n", __FUNCTION__, dev); udc_set_address(dev, 0); if (udc_clock) { clk_disable(udc_clock); clk_unuse(udc_clock); clk_put(udc_clock); udc_clock = NULL; } dev->ep0state = WAIT_FOR_SETUP; dev->gadget.speed = USB_SPEED_UNKNOWN; dev->usb_address = 0; }
static int pl011_remove(struct amba_device *dev) { struct uart_amba_port *uap = amba_get_drvdata(dev); int i; amba_set_drvdata(dev, NULL); uart_remove_one_port(&amba_reg, &uap->port); for (i = 0; i < ARRAY_SIZE(amba_ports); i++) if (amba_ports[i] == uap) amba_ports[i] = NULL; iounmap(uap->port.membase); clk_unuse(uap->clk); clk_put(uap->clk); kfree(uap); return 0; }
int musb_platform_exit(struct musb *musb) { phy_off(); #ifdef CONFIG_MACH_DAVINCI_EVM davinci_vbus_power(musb, 0 /*off */ , 1); #ifdef CONFIG_USB_MUSB_OTG /* Set EMACEN to enable OTG GPIO 16 for Emac control */ /* Set GPIO Direction */ DAVINCI_PINMUX0 |= (0x80000000); #endif #endif #if defined (CONFIG_MACH_DAVINCI_HD_EVM) && defined(CONFIG_USB_MUSB_HDRC_HCD) davinci_vbus_power(musb, 0 /*off */ , 1); //DAVINCI_PINMUX0 |= 0x10000000; //VDD3P3V_PWDN |= 0x10000000; #endif clk_disable (musb->clock); clk_unuse (musb->clock); return 0; }
int musb_platform_exit(struct musb *musb) { phy_off(); #ifdef CONFIG_MACH_DAVINCI_EVM #ifdef CONFIG_USB_MUSB_OTG /* Set EMACEN to enable OTG GPIO 16 for Emac control */ /* Set GPIO Direction */ davinci_cfg_reg(DM644X_EMACEN); #endif #endif #if defined(CONFIG_MACH_DAVINCI_HD_EVM) && defined(CONFIG_USB_MUSB_HDRC_HCD) davinci_vbus_power(musb, 0); #endif if (musb->clock) { clk_disable (musb->clock); clk_unuse (musb->clock); } return 0; }
static int s3c2410wdt_remove(struct device *dev) { if (wdt_mem != NULL) { release_resource(wdt_mem); kfree(wdt_mem); wdt_mem = NULL; } if (wdt_irq != NULL) { free_irq(wdt_irq->start, dev); wdt_irq = NULL; } if (wdt_clock != NULL) { clk_disable(wdt_clock); clk_unuse(wdt_clock); clk_put(wdt_clock); wdt_clock = NULL; } misc_deregister(&s3c2410wdt_miscdev); return 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; }
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); }
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; }