static int gps_hostwake_probe(struct platform_device *pdev) { int ret; int irq; struct gps_geofence_wake *ac_data = &g_geofence_wake; struct bcm_gps_hostwake_platform_data *pdata; /* HOST_WAKE : to indicate that ASIC has an geofence event. unsigned int gpio_hostwake; */ pr_debug(PFX "%s\n", __func__); /* Read device tree information */ pdata = pdev->dev.platform_data; if (!pdata) { pr_debug(PFX "%s : fail to get platform_data.\n", __func__); return -1; } /* 1. Init GPIO and IRQ for HOST_WAKE */ irq = gps_gpio_irq_init(pdata->gpio_hostwake); if (irq < 0) return -EIO; /* 2. Register Driver */ memset(ac_data, 0, sizeof(struct gps_geofence_wake)); /* 2.1 Misc device setup */ ac_data->misc.minor = MISC_DYNAMIC_MINOR; ac_data->misc.name = HOST_WAKE_MODULE_NAME; ac_data->misc.fops = &gps_geofence_wake_fops; /* 2.2 Information that be used later */ ac_data->irq = irq; ac_data->host_req_pin = pdata->gpio_hostwake; pr_notice(PFX "misc register, name %s, irq %d, host req pin num %d\n", ac_data->misc.name, irq, ac_data->host_req_pin); /* 2.3 Register misc driver */ ret = misc_register(&ac_data->misc); if (ret) { pr_err(PFX "cannot register gps geofence wake miscdev on minor=%d (%d)\n", MISC_DYNAMIC_MINOR, ret); return ret; } /* 3. Init wake_lock */ wake_lock_init(&ac_data->wake_lock, WAKE_LOCK_SUSPEND, "gps_geofence_wakelock"); return 0; }
static int k3_gps_bcm_probe(struct platform_device* pdev) { GPS_BCM_INFO* gps_bcm = NULL; struct device* gps_power_dev = &pdev->dev; struct device_node* np = gps_power_dev->of_node; int ret = 0; int irq = 0; struct gps_geofence_wake* ac_data = &g_geofence_wake; printk(KERN_INFO "[GPS] start find gps_power and ic type is 4774\n"); gps_bcm = kzalloc(sizeof(GPS_BCM_INFO), GFP_KERNEL); if (!gps_bcm) { printk(KERN_ERR "[GPS] Alloc memory failed\n"); return -ENOMEM; } gps_dir = proc_mkdir("gps", NULL); if (!gps_dir) { printk(KERN_ERR "[GPS] proc dir create failed\n"); ret = -ENOMEM; goto err_free_gps; } ret = gps_bcm4774_node_init(np, &gps_bcm->gpioid_en, GPS_PROC_EN, &gps_proc_fops_nstandby); if (0 != ret) { printk(KERN_ERR "[GPS] gps_bcm4774_node_init gps_bcm failed.\n"); ret = -1; goto err_free_nstandby; } gps_bcm->gpioid_hostwake.gpio = of_get_named_gpio(np, "huawei,gps_hostwake", 0); if (!gpio_is_valid(gps_bcm->gpioid_hostwake.gpio)) { ret = -1; printk(KERN_ERR "[GPS] get huawei,gps_hostwake failed.\n"); goto err_free_gps_en; } // 1. Init GPIO and IRQ for HOST_WAKE printk("[gps]%s,gps_bcm->gpioid_hostwake.gpio=%d\n", __func__, gps_bcm->gpioid_hostwake.gpio); // 2. Register Driver memset(ac_data, 0, sizeof(struct gps_geofence_wake)); // 2.1 Misc device setup ac_data->misc.minor = MISC_DYNAMIC_MINOR; ac_data->misc.name = HOST_WAKE_MODULE_NAME; ac_data->misc.fops = &gps_geofence_wake_fops; // 2.2 Information that be used later ac_data->irq = irq; ac_data->host_req_pin = gps_bcm->gpioid_hostwake.gpio; printk("[gps]misc register, name %s, irq %d, host req pin num %d\n", ac_data->misc.name, irq, ac_data->host_req_pin); // 2.3 Register misc driver if (0 != (ret = misc_register(&ac_data->misc))) { printk("[gps]cannot register gps geofence wake miscdev on minor=%d (%d)\n", MISC_DYNAMIC_MINOR, ret); goto err_free_host_wake; } // 3. Init wake_lock wake_lock_init(&ac_data->wake_lock, WAKE_LOCK_SUSPEND, "gps_geofence_wakelock"); printk("[gps]wake_lock_init done\n"); irq = gps_gpio_irq_init(gps_bcm->gpioid_hostwake.gpio); if (irq < 0) { printk("[gps]hostwake irq error\n"); goto err_free_misc_register; } /* Set 32KC clock */ gps_bcm->clk = of_clk_get_by_name(np, "gps_32k"); if (IS_ERR(gps_bcm->clk)) { printk(KERN_ERR "[GPS] clk_32k get failed!\n"); ret = -1; goto err_free_misc_register; } ret = clk_prepare_enable(gps_bcm->clk); if (ret) { printk(KERN_ERR "[GPS] clk_32k enable is failed\n"); goto err_free_clk; } printk(KERN_INFO "[GPS] clk_32k is finished\n"); ret = gps_bcm4774_node_init(np, &gps_bcm->mcu_req, GPS_PROC_MCUREQ, &gps_proc_fops_mcureq); if (0 != ret) { printk(KERN_ERR "[GPS]gps_bcm4774_node_init mcu_req failed \n"); goto err_free_mcureq; } ret = gps_bcm4774_node_init(np, &gps_bcm->mcu_req_rsp, GPS_PROC_MCUREQ_RSP, &gps_proc_fops_mcureq_rsp); if (0 != ret) { printk(KERN_ERR "[GPS]gps_bcm4774_node_init mcu_req_rsp failed \n"); goto err_free_mcureq_rsp; } gps_bcm->pctrl = devm_pinctrl_get(gps_power_dev); if (IS_ERR(gps_bcm->pctrl)) { printk(KERN_ERR "[GPS] pinctrl get error!\n"); ret = -1; goto err_free_clk; } gps_bcm->pins_normal = pinctrl_lookup_state(gps_bcm->pctrl, "default"); if (IS_ERR(gps_bcm->pins_normal)) { printk(KERN_ERR "[GPS] gps_bcm->pins_normal lookup error!\n"); ret = -1; goto err_free_pinctrl; } gps_bcm->pins_idle = pinctrl_lookup_state(gps_bcm->pctrl, "idle"); if (IS_ERR(gps_bcm->pins_idle)) { printk(KERN_ERR "[GPS] gps_bcm->pins_idle lookup error!\n"); ret = -1; goto err_free_pinctrl; } ret = pinctrl_select_state(gps_bcm->pctrl, gps_bcm->pins_normal); if (ret) { printk(KERN_ERR "[GPS] pinctrl_select_state error!\n"); goto err_free_pinctrl; } printk(KERN_INFO "[GPS] pinctrl is finish\n"); gps_bcm->refclk = of_clk_get_by_name(np, "clk_gps"); if (IS_ERR(gps_bcm->refclk)) { printk(KERN_ERR "[GPS] @@@ref_clk get failed!\n"); ret = -1; goto err_free_pinctrl; } ret = clk_set_rate(gps_bcm->refclk , GPS_REF_CLK_FREQ_19M); if (ret < 0) { printk(KERN_ERR "[GPS] clk_set_rate HI3635_CLK_RATE failed\n"); goto err_free_refclk; } gps_ref_clk = gps_bcm->refclk; printk(KERN_INFO "[GPS] ref clk is finished!\n"); platform_set_drvdata(pdev, gps_bcm); g_gps_bcm = gps_bcm; return 0; err_free_refclk: clk_put(gps_bcm->refclk); err_free_pinctrl: pinctrl_put(gps_bcm->pctrl); err_free_mcureq: err_free_mcureq_rsp: err_free_clk: clk_put(gps_bcm->clk); err_free_misc_register: misc_deregister(&ac_data->misc); wake_lock_destroy(&ac_data->wake_lock); pr_err("%s: misc_deregister!\n", __func__); err_free_host_wake: gpio_free(gps_bcm->gpioid_hostwake.gpio); pr_err("%s: err_free_host_wake!\n", __func__); err_free_gps_en: gpio_free(gps_bcm->gpioid_en.gpio); err_free_nstandby: err_free_gps: kfree(gps_bcm); gps_bcm = NULL; g_gps_bcm = NULL; return ret; }