static int __devinit wcnss_wlan_probe(struct platform_device *pdev) { int ret = 0; /* verify we haven't been called more than once */ if (penv) { dev_err(&pdev->dev, "cannot handle multiple devices.\n"); return -ENODEV; } /* create an environment to track the device */ penv = kzalloc(sizeof(*penv), GFP_KERNEL); if (!penv) { dev_err(&pdev->dev, "cannot allocate device memory.\n"); return -ENOMEM; } penv->pdev = pdev; /* register sysfs entries */ ret = wcnss_create_sysfs(&pdev->dev); if (ret) return -ENOENT; #ifdef MODULE /* * Since we were built as a module, we are running because * the module was loaded, therefore we assume userspace * applications are available to service PIL, so we can * trigger the WCNSS configuration now */ pr_info(DEVICE " probed in MODULE mode\n"); return wcnss_trigger_config(pdev); #else /* * Since we were built into the kernel we'll be called as part * of kernel initialization. We don't know if userspace * applications are available to service PIL at this time * (they probably are not), so we simply create a device node * here. When userspace is available it should touch the * device so that we know that WCNSS configuration can take * place */ pr_info(DEVICE " probed in built-in mode\n"); return misc_register(&wcnss_misc); #endif }
static int __devinit wcnss_wlan_probe(struct platform_device *pdev) { int ret = 0; /* verify we haven't been called more than once */ if (penv) { dev_err(&pdev->dev, "cannot handle multiple devices.\n"); return -ENODEV; } /* create an environment to track the device */ penv = kzalloc(sizeof(*penv), GFP_KERNEL); if (!penv) { dev_err(&pdev->dev, "cannot allocate device memory.\n"); return -ENOMEM; } penv->pdev = pdev; /* register sysfs entries */ ret = wcnss_create_sysfs(&pdev->dev); if (ret) return -ENOENT; mutex_init(&penv->dev_lock); mutex_init(&penv->ctrl_lock); init_waitqueue_head(&penv->read_wait); /* * Since we were built into the kernel we'll be called as part * of kernel initialization. We don't know if userspace * applications are available to service PIL at this time * (they probably are not), so we simply create a device node * here. When userspace is available it should touch the * device so that we know that WCNSS configuration can take * place */ pr_info(DEVICE " probed in built-in mode\n"); misc_register(&wcnss_usr_ctrl); return misc_register(&wcnss_misc); }
static int wcnss_trigger_config(struct platform_device *pdev) { int ret; struct qcom_wcnss_opts *pdata; /* make sure we are only triggered once */ if (penv->triggered) return 0; penv->triggered = 1; /* initialize the WCNSS device configuration */ pdata = pdev->dev.platform_data; if (WCNSS_CONFIG_UNSPECIFIED == has_48mhz_xo) has_48mhz_xo = pdata->has_48mhz_xo; penv->wlan_config.use_48mhz_xo = has_48mhz_xo; penv->thermal_mitigation = 0; penv->gpios_5wire = platform_get_resource_byname(pdev, IORESOURCE_IO, "wcnss_gpios_5wire"); /* allocate 5-wire GPIO resources */ if (!penv->gpios_5wire) { dev_err(&pdev->dev, "insufficient IO resources\n"); ret = -ENOENT; goto fail_gpio_res; } /* Configure 5 wire GPIOs */ ret = wcnss_gpios_config(penv->gpios_5wire, true); if (ret) { dev_err(&pdev->dev, "WCNSS gpios config failed.\n"); goto fail_gpio_res; } /* power up the WCNSS */ ret = wcnss_wlan_power(&pdev->dev, &penv->wlan_config, WCNSS_WLAN_SWITCH_ON); if (ret) { dev_err(&pdev->dev, "WCNSS Power-up failed.\n"); goto fail_power; } /* trigger initialization of the WCNSS */ penv->pil = pil_get(WCNSS_PIL_DEVICE); if (IS_ERR(penv->pil)) { dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n"); ret = PTR_ERR(penv->pil); penv->pil = NULL; goto fail_pil; } /* allocate resources */ penv->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wcnss_mmio"); penv->tx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "wcnss_wlantx_irq"); penv->rx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "wcnss_wlanrx_irq"); if (!(penv->mmio_res && penv->tx_irq_res && penv->rx_irq_res)) { dev_err(&pdev->dev, "insufficient resources\n"); ret = -ENOENT; goto fail_res; } /* register sysfs entries */ ret = wcnss_create_sysfs(&pdev->dev); if (ret) goto fail_sysfs; return 0; fail_sysfs: fail_res: if (penv->pil) pil_put(penv->pil); fail_pil: wcnss_wlan_power(&pdev->dev, &penv->wlan_config, WCNSS_WLAN_SWITCH_OFF); fail_power: wcnss_gpios_config(penv->gpios_5wire, false); fail_gpio_res: kfree(penv); penv = NULL; return ret; }
static int wcnss_trigger_config(struct platform_device *pdev) { int ret; struct qcom_wcnss_opts *pdata; if (penv->triggered) return 0; penv->triggered = 1; pdata = pdev->dev.platform_data; if (WCNSS_CONFIG_UNSPECIFIED == has_48mhz_xo) has_48mhz_xo = pdata->has_48mhz_xo; penv->wlan_config.use_48mhz_xo = has_48mhz_xo; penv->thermal_mitigation = 0; penv->gpios_5wire = platform_get_resource_byname(pdev, IORESOURCE_IO, "wcnss_gpios_5wire"); if (!penv->gpios_5wire) { dev_err(&pdev->dev, "insufficient IO resources\n"); ret = -ENOENT; goto fail_gpio_res; } ret = wcnss_gpios_config(penv->gpios_5wire, true); if (ret) { dev_err(&pdev->dev, "WCNSS gpios config failed.\n"); goto fail_gpio_res; } ret = wcnss_wlan_power(&pdev->dev, &penv->wlan_config, WCNSS_WLAN_SWITCH_ON); if (ret) { dev_err(&pdev->dev, "WCNSS Power-up failed.\n"); goto fail_power; } penv->pil = pil_get(WCNSS_PIL_DEVICE); if (IS_ERR(penv->pil)) { dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n"); ret = PTR_ERR(penv->pil); penv->pil = NULL; goto fail_pil; } penv->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wcnss_mmio"); penv->tx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "wcnss_wlantx_irq"); penv->rx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "wcnss_wlanrx_irq"); if (!(penv->mmio_res && penv->tx_irq_res && penv->rx_irq_res)) { dev_err(&pdev->dev, "insufficient resources\n"); ret = -ENOENT; goto fail_res; } ret = wcnss_create_sysfs(&pdev->dev); if (ret) goto fail_sysfs; wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss"); penv->msm_wcnss_base = ioremap(MSM_RIVA_PHYS, SZ_256); if (!penv->msm_wcnss_base) { pr_err("%s: ioremap wcnss physical failed\n", __func__); goto fail_wake; } return 0; fail_wake: wake_lock_destroy(&penv->wcnss_wake_lock); fail_sysfs: fail_res: if (penv->pil) pil_put(penv->pil); fail_pil: wcnss_wlan_power(&pdev->dev, &penv->wlan_config, WCNSS_WLAN_SWITCH_OFF); fail_power: wcnss_gpios_config(penv->gpios_5wire, false); fail_gpio_res: kfree(penv); penv = NULL; return ret; }