static int __init tegra_gmi_char_probe(struct platform_device *pdev) { int err = -ENODEV; struct tegra_nor_chip_parms *plat = pdev->dev.platform_data; struct device *dev = &pdev->dev; if (!plat) { pr_err("%s: no platform device info\n", __func__); return -EINVAL; } info = devm_kzalloc(dev, sizeof(struct tegra_gmi_char_info), GFP_KERNEL); if (!info) return -ENOMEM; info->base = ((void __iomem *)IO_APB_VIRT + (TEGRA_SNOR_BASE - IO_APB_PHYS)); info->plat = plat; info->dev = dev; #ifdef CONFIG_TEGRA_GMI_ACCESS_CONTROL info->gmiLockHandle = register_gmi_device(DRV_NAME, 0); info->request_gmi_access = request_gmi_access; info->release_gmi_access = release_gmi_access; info->gmiLockHandle = register_gmi_device(DRV_NAME, 0); #else info->gmiLockHandle = NULL; info->request_gmi_access = NULL; info->release_gmi_access = NULL; #endif /* Clock setting */ info->clk = clk_get_sys("tegra-nor", NULL); if (IS_ERR(info->clk)) { pr_err("%s: can't get clock\n", __func__); return PTR_ERR(info->clk); } err = clk_prepare_enable(info->clk); if (err != 0) { pr_err("%s: can't enable clock\n", __func__); return err; } err = tegra_gmi_char_prepare_regs(info); if (err) { dev_err(dev, "Error initializing reg values\n"); return err; } // write init config snor_tegra_writel(info, info->init_config, TEGRA_SNOR_CONFIG_REG); snor_tegra_writel(info, info->timing1_read, TEGRA_SNOR_TIMING1_REG); snor_tegra_writel(info, info->timing0_read, TEGRA_SNOR_TIMING0_REG); platform_set_drvdata(pdev, info); info->gmi_class = class_create(THIS_MODULE, DRV_NAME); if (IS_ERR(info->gmi_class)) { err = PTR_ERR(info->gmi_class); return err; } err = alloc_chrdev_region(&info->gmi_dev_t, 0, 1, DRV_NAME); if (err < 0) { class_destroy(info->gmi_class); pr_err("%s: failed to allocate device region\n", DRV_NAME); return err; } cdev_init(&info->gmi_cdev, &gmichar_fops); err = cdev_add(&info->gmi_cdev, info->gmi_dev_t, 1); if (err) return err; info->gmi_device = device_create(info->gmi_class, NULL, info->gmi_dev_t, info, DRV_NAME); if (IS_ERR(info->gmi_device)) { pr_err("device create failed for %s\n", DRV_NAME); cdev_del(&info->gmi_cdev); goto fail; } return 0; fail: pr_err("Tegra GMI CHAR probe failed\n"); return err; }
static int __devinit tegra_gmi_pca_probe(struct platform_device *pdev) { int err = 0, err_gpio = 0; int err_int = 0; struct tegra_nor_chip_parms *plat = pdev->dev.platform_data; struct cs_info *csinfo = &plat->csinfo; struct gpio_state *state = &csinfo->gpio_cs; struct device *dev = &pdev->dev; struct resource *res; if (!plat) { pr_err("%s: no platform device info\n", __func__); err = -EINVAL; goto fail; } info = devm_kzalloc(dev, sizeof(struct tegra_gmi_pca_info), GFP_KERNEL); if (!info) { err = -ENOMEM; goto fail; } info->base = ((void __iomem *)IO_APB_VIRT + (TEGRA_SNOR_BASE - IO_APB_PHYS)); info->plat = plat; info->dev = dev; /* Intialise the SNOR controller before probe */ err = tegra_gmi_controller_init(info); if (err) { dev_err(dev, "Error initializing controller\n"); goto fail; } platform_set_drvdata(pdev, info); init_waitqueue_head(&pca_wait); err_gpio = gpio_request(state[0].gpio_num, state[0].label); gpio_direction_output(state[0].gpio_num, 0); res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!res) { dev_err(dev, "GPIO %d can't be used as interrupt\n", res->start); return -ENODEV; } err_int = gpio_request(res->start, NULL); gpio_direction_output(res->start, 0); irq = gpio_to_irq(res->start); info->gpio_num = res->start; if (irq <= 0) { printk(KERN_ALERT "GPIO %d can't be used as interrupt" , res->start); goto fail; } if (irq > -1) { if (request_irq(irq, pca_handler, IRQF_TRIGGER_FALLING, "i2c-pca-gmi", &pca_gmi_ops) < 0) { dev_err(dev, "Request irq%d failed\n", irq); goto fail; } } #ifdef CONFIG_TEGRA_GMI_ACCESS_CONTROL info->gmiFmLockHandle = register_gmi_device("gmi-i2c-pca", 0); #endif pca_gmi_data.i2c_clock = clock; pca_gmi_request_access(NULL); if (i2c_pca_add_bus(&pca_gmi_ops) < 0) { pca_gmi_release_access(NULL); dev_err(dev, "Failed to add i2c bus\n"); goto out_irq; } pca_gmi_release_access(NULL); return 0; out_irq: if (irq > -1) free_irq(irq, &pca_gmi_ops); fail: pr_err("Tegra GMI PCA probe failed\n"); return err; }