static int mcp_sa11x0_remove(struct platform_device *dev) { struct mcp *mcp = platform_get_drvdata(dev); struct mcp_sa11x0 *m = priv(mcp); struct resource *mem0, *mem1; if (m->mccr0 & MCCR0_MCE) dev_warn(&dev->dev, "device left active (missing disable call?)\n"); mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0); mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1); mcp_host_del(mcp); iounmap(m->base1); iounmap(m->base0); mcp_host_free(mcp); release_mem_region(mem1->start, resource_size(mem1)); release_mem_region(mem0->start, resource_size(mem0)); return 0; }
static int mcp_sa11x0_probe(struct platform_device *dev) { struct mcp_plat_data *data = dev->dev.platform_data; struct resource *mem0, *mem1; struct mcp_sa11x0 *m; struct mcp *mcp; int ret; if (!data) return -ENODEV; mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0); mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1); if (!mem0 || !mem1) return -ENXIO; if (!request_mem_region(mem0->start, resource_size(mem0), DRIVER_NAME)) { ret = -EBUSY; goto err_mem0; } if (!request_mem_region(mem1->start, resource_size(mem1), DRIVER_NAME)) { ret = -EBUSY; goto err_mem1; } mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0)); if (!mcp) { ret = -ENOMEM; goto err_alloc; } mcp->owner = THIS_MODULE; mcp->ops = &mcp_sa11x0; mcp->sclk_rate = data->sclk_rate; m = priv(mcp); m->mccr0 = data->mccr0 | 0x7f7f; m->mccr1 = data->mccr1; m->base0 = ioremap(mem0->start, resource_size(mem0)); m->base1 = ioremap(mem1->start, resource_size(mem1)); if (!m->base0 || !m->base1) { ret = -ENOMEM; goto err_ioremap; } platform_set_drvdata(dev, mcp); /* * Initialise device. Note that we initially * set the sampling rate to minimum. */ writel_relaxed(-1, MCSR(m)); writel_relaxed(m->mccr1, MCCR1(m)); writel_relaxed(m->mccr0, MCCR0(m)); /* * Calculate the read/write timeout (us) from the bit clock * rate. This is the period for 3 64-bit frames. Always * round this time up. */ mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / mcp->sclk_rate; ret = mcp_host_add(mcp, data->codec_pdata); if (ret == 0) return 0; platform_set_drvdata(dev, NULL); err_ioremap: iounmap(m->base1); iounmap(m->base0); mcp_host_free(mcp); err_alloc: release_mem_region(mem1->start, resource_size(mem1)); err_mem1: release_mem_region(mem0->start, resource_size(mem0)); err_mem0: return ret; }