static int __init bridge_init(void)
{
	struct data_bridge	*dev;
	int			ret;
	int			i = 0;

	ret = ctrl_bridge_init();
	if (ret)
		return ret;

	bridge_wq  = create_singlethread_workqueue("mdm_bridge");
	if (!bridge_wq) {
		pr_err("%s: Unable to create workqueue:bridge\n", __func__);
		ret = -ENOMEM;
		goto free_ctrl;
	}

	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {

		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev) {
			err("%s: unable to allocate dev\n", __func__);
			ret = -ENOMEM;
			goto error;
		}

		dev->wq = bridge_wq;

		init_usb_anchor(&dev->tx_active);
		init_usb_anchor(&dev->rx_active);

		INIT_LIST_HEAD(&dev->rx_idle);

		skb_queue_head_init(&dev->rx_done);

		INIT_WORK(&dev->kevent, defer_kevent);
		INIT_WORK(&dev->process_rx_w, data_bridge_process_rx);

		__dev[i] = dev;
	}

	ret = usb_register(&bridge_driver);
	if (ret) {
		err("%s: unable to register mdm_bridge driver", __func__);
		goto error;
	}

	data_bridge_debugfs_init();

	return 0;

error:
	while (--i >= 0) {
		kfree(__dev[i]);
		__dev[i] = NULL;
	}
	destroy_workqueue(bridge_wq);
free_ctrl:
	ctrl_bridge_exit();
	return ret;
}
示例#2
0
int ieee80211_register_hw(struct ieee80211_hw *hw)
{
	struct ieee80211_local *local = hw_to_local(hw);
	int result;
	enum ieee80211_band band;
	int channels, i, j, max_bitrates;
	bool supp_ht;
	static const u32 cipher_suites[] = {
		WLAN_CIPHER_SUITE_WEP40,
		WLAN_CIPHER_SUITE_WEP104,
		WLAN_CIPHER_SUITE_TKIP,
		WLAN_CIPHER_SUITE_CCMP,

		/* keep last -- depends on hw flags! */
		WLAN_CIPHER_SUITE_AES_CMAC
	};

	/*
	 * generic code guarantees at least one band,
	 * set this very early because much code assumes
	 * that hw.conf.channel is assigned
	 */
	channels = 0;
	max_bitrates = 0;
	supp_ht = false;
	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
		struct ieee80211_supported_band *sband;

		sband = local->hw.wiphy->bands[band];
		if (!sband)
			continue;
		if (!local->oper_channel) {
			/* init channel we're on */
			local->hw.conf.channel =
			local->oper_channel = &sband->channels[0];
			local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
		}
		channels += sband->n_channels;

		if (max_bitrates < sband->n_bitrates)
			max_bitrates = sband->n_bitrates;
		supp_ht = supp_ht || sband->ht_cap.ht_supported;
	}

	local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
				      sizeof(void *) * channels, GFP_KERNEL);
	if (!local->int_scan_req)
		return -ENOMEM;

	/* if low-level driver supports AP, we also support VLAN */
	if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
		local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);

	/* mac80211 always supports monitor */
	local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);

	if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
		local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
	else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
		local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;

	/*
	 * Calculate scan IE length -- we need this to alloc
	 * memory and to subtract from the driver limit. It
	 * includes the (extended) supported rates and HT
	 * information -- SSID is the driver's responsibility.
	 */
	local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */
	if (supp_ht)
		local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);

	if (!local->ops->hw_scan) {
		/* For hw_scan, driver needs to set these up. */
		local->hw.wiphy->max_scan_ssids = 4;
		local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
	}

	/*
	 * If the driver supports any scan IEs, then assume the
	 * limit includes the IEs mac80211 will add, otherwise
	 * leave it at zero and let the driver sort it out; we
	 * still pass our IEs to the driver but userspace will
	 * not be allowed to in that case.
	 */
	if (local->hw.wiphy->max_scan_ie_len)
		local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;

	local->hw.wiphy->cipher_suites = cipher_suites;
	local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
	if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
		local->hw.wiphy->n_cipher_suites--;

	result = wiphy_register(local->hw.wiphy);
	if (result < 0)
		goto fail_wiphy_register;

	/*
	 * We use the number of queues for feature tests (QoS, HT) internally
	 * so restrict them appropriately.
	 */
	if (hw->queues > IEEE80211_MAX_QUEUES)
		hw->queues = IEEE80211_MAX_QUEUES;

	local->workqueue =
		create_singlethread_workqueue(wiphy_name(local->hw.wiphy));
	if (!local->workqueue) {
		result = -ENOMEM;
		goto fail_workqueue;
	}

	/*
	 * The hardware needs headroom for sending the frame,
	 * and we need some headroom for passing the frame to monitor
	 * interfaces, but never both at the same time.
	 */
	BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM !=
			sizeof(struct ieee80211_tx_status_rtap_hdr));
	local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
				   sizeof(struct ieee80211_tx_status_rtap_hdr));

	debugfs_hw_add(local);

	if (local->hw.max_listen_interval == 0)
		local->hw.max_listen_interval = 1;

	local->hw.conf.listen_interval = local->hw.max_listen_interval;

	result = sta_info_start(local);
	if (result < 0)
		goto fail_sta_info;

	result = ieee80211_wep_init(local);
	if (result < 0) {
		printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",
		       wiphy_name(local->hw.wiphy), result);
		goto fail_wep;
	}

	rtnl_lock();

	result = ieee80211_init_rate_ctrl_alg(local,
					      hw->rate_control_algorithm);
	if (result < 0) {
		printk(KERN_DEBUG "%s: Failed to initialize rate control "
		       "algorithm\n", wiphy_name(local->hw.wiphy));
		goto fail_rate;
	}

	/* add one default STA interface if supported */
	if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
		result = ieee80211_if_add(local, "wlan%d", NULL,
					  NL80211_IFTYPE_STATION, NULL);
		if (result)
			printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
			       wiphy_name(local->hw.wiphy));
	}

	rtnl_unlock();

	ieee80211_led_init(local);

	/* alloc internal scan request */
	i = 0;
	local->int_scan_req->ssids = &local->scan_ssid;
	local->int_scan_req->n_ssids = 1;
	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
		if (!hw->wiphy->bands[band])
			continue;
		for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) {
			local->int_scan_req->channels[i] =
				&hw->wiphy->bands[band]->channels[j];
			i++;
		}
	}
	local->int_scan_req->n_channels = i;

	local->network_latency_notifier.notifier_call =
		ieee80211_max_network_latency;
	result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
				     &local->network_latency_notifier);

	if (result) {
		rtnl_lock();
		goto fail_pm_qos;
	}

	return 0;

 fail_pm_qos:
	ieee80211_led_exit(local);
	ieee80211_remove_interfaces(local);
 fail_rate:
	rtnl_unlock();
	ieee80211_wep_free(local);
 fail_wep:
	sta_info_stop(local);
 fail_sta_info:
	destroy_workqueue(local->workqueue);
 fail_workqueue:
	wiphy_unregister(local->hw.wiphy);
 fail_wiphy_register:
	kfree(local->int_scan_req);
	return result;
}
示例#3
0
static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
						const bool have_5ghz)
{
	int i, band;
	struct ieee80211_hw *hw;
	struct cw1200_common *priv;

	hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
	if (!hw)
		return NULL;

	priv = hw->priv;
	priv->hw = hw;
	priv->hw_type = -1;
	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
	priv->rates = cw1200_rates; /* TODO: fetch from FW */
	priv->mcs_rates = cw1200_n_rates;
	if (cw1200_ba_rx_tids != -1)
		priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
	else
		priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
	if (cw1200_ba_tx_tids != -1)
		priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
	else
		priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */

	ieee80211_hw_set(hw, NEED_DTIM_BEFORE_ASSOC);
	ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
	ieee80211_hw_set(hw, AMPDU_AGGREGATION);
	ieee80211_hw_set(hw, CONNECTION_MONITOR);
	ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
	ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
	ieee80211_hw_set(hw, SIGNAL_DBM);
	ieee80211_hw_set(hw, SUPPORTS_PS);

	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
					  BIT(NL80211_IFTYPE_ADHOC) |
					  BIT(NL80211_IFTYPE_AP) |
					  BIT(NL80211_IFTYPE_MESH_POINT) |
					  BIT(NL80211_IFTYPE_P2P_CLIENT) |
					  BIT(NL80211_IFTYPE_P2P_GO);

#ifdef CONFIG_PM
	hw->wiphy->wowlan = &cw1200_wowlan_support;
#endif

	hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;

	hw->queues = 4;

	priv->rts_threshold = -1;

	hw->max_rates = 8;
	hw->max_rate_tries = 15;
	hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
		8;  /* TKIP IV */

	hw->sta_data_size = sizeof(struct cw1200_sta_priv);

	hw->wiphy->bands[NL80211_BAND_2GHZ] = &cw1200_band_2ghz;
	if (have_5ghz)
		hw->wiphy->bands[NL80211_BAND_5GHZ] = &cw1200_band_5ghz;

	/* Channel params have to be cleared before registering wiphy again */
	for (band = 0; band < NUM_NL80211_BANDS; band++) {
		struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
		if (!sband)
			continue;
		for (i = 0; i < sband->n_channels; i++) {
			sband->channels[i].flags = 0;
			sband->channels[i].max_antenna_gain = 0;
			sband->channels[i].max_power = 30;
		}
	}

	hw->wiphy->max_scan_ssids = 2;
	hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;

	if (macaddr)
		SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
	else
		SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);

	/* Fix up mac address if necessary */
	if (hw->wiphy->perm_addr[3] == 0 &&
	    hw->wiphy->perm_addr[4] == 0 &&
	    hw->wiphy->perm_addr[5] == 0) {
		get_random_bytes(&hw->wiphy->perm_addr[3], 3);
	}

	mutex_init(&priv->wsm_cmd_mux);
	mutex_init(&priv->conf_mutex);
	priv->workqueue = create_singlethread_workqueue("cw1200_wq");
	sema_init(&priv->scan.lock, 1);
	INIT_WORK(&priv->scan.work, cw1200_scan_work);
	INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
	INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
	INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
			  cw1200_clear_recent_scan_work);
	INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
	INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
	INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
	INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
	INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
	spin_lock_init(&priv->event_queue_lock);
	INIT_LIST_HEAD(&priv->event_queue);
	INIT_WORK(&priv->event_handler, cw1200_event_handler);
	INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
	INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
	spin_lock_init(&priv->bss_loss_lock);
	spin_lock_init(&priv->ps_state_lock);
	INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
	INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
	INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
	INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
	INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
	INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
	INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
	INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
	INIT_WORK(&priv->set_beacon_wakeup_period_work,
		  cw1200_set_beacon_wakeup_period_work);
	timer_setup(&priv->mcast_timeout, cw1200_mcast_timeout, 0);

	if (cw1200_queue_stats_init(&priv->tx_queue_stats,
				    CW1200_LINK_ID_MAX,
				    cw1200_skb_dtor,
				    priv)) {
		ieee80211_free_hw(hw);
		return NULL;
	}

	for (i = 0; i < 4; ++i) {
		if (cw1200_queue_init(&priv->tx_queue[i],
				      &priv->tx_queue_stats, i, 16,
				      cw1200_ttl[i])) {
			for (; i > 0; i--)
				cw1200_queue_deinit(&priv->tx_queue[i - 1]);
			cw1200_queue_stats_deinit(&priv->tx_queue_stats);
			ieee80211_free_hw(hw);
			return NULL;
		}
	}

	init_waitqueue_head(&priv->channel_switch_done);
	init_waitqueue_head(&priv->wsm_cmd_wq);
	init_waitqueue_head(&priv->wsm_startup_done);
	init_waitqueue_head(&priv->ps_mode_switch_done);
	wsm_buf_init(&priv->wsm_cmd_buf);
	spin_lock_init(&priv->wsm_cmd.lock);
	priv->wsm_cmd.done = 1;
	tx_policy_init(priv);

	return hw;
}
static int cw_bat_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
        struct cw_battery *cw_bat;
        int ret;
        int irq;
        int irq_flags;
        int loop = 0;

        cw_bat = devm_kzalloc(&client->dev, sizeof(*cw_bat), GFP_KERNEL);
        if (!cw_bat) {
                dev_err(&cw_bat->client->dev, "fail to allocate memory\n");
                return -ENOMEM;
        }

        i2c_set_clientdata(client, cw_bat);
        cw_bat->plat_data = client->dev.platform_data;
        ret = cw_bat_gpio_init(cw_bat);
        if (ret) {
                dev_err(&cw_bat->client->dev, "cw_bat_gpio_init error\n");
                return ret;
        }
        
        cw_bat->client = client;

        ret = cw_init(cw_bat);
        while ((loop++ < 200) && (ret != 0)) {
                ret = cw_init(cw_bat);
        }

        if (ret) 
                return ret;
        
        cw_bat->rk_bat.name = "rk-bat";
        cw_bat->rk_bat.type = POWER_SUPPLY_TYPE_BATTERY;
        cw_bat->rk_bat.properties = rk_battery_properties;
        cw_bat->rk_bat.num_properties = ARRAY_SIZE(rk_battery_properties);
        cw_bat->rk_bat.get_property = rk_battery_get_property;
        ret = power_supply_register(&client->dev, &cw_bat->rk_bat);
        if(ret < 0) {
                dev_err(&cw_bat->client->dev, "power supply register rk_bat error\n");
                goto rk_bat_register_fail;
        }

        cw_bat->rk_ac.name = "rk-ac";
        cw_bat->rk_ac.type = POWER_SUPPLY_TYPE_MAINS;
        cw_bat->rk_ac.properties = rk_ac_properties;
        cw_bat->rk_ac.num_properties = ARRAY_SIZE(rk_ac_properties);
        cw_bat->rk_ac.get_property = rk_ac_get_property;
        ret = power_supply_register(&client->dev, &cw_bat->rk_ac);
        if(ret < 0) {
                dev_err(&cw_bat->client->dev, "power supply register rk_ac error\n");
                goto rk_ac_register_fail;
        }

        cw_bat->rk_usb.name = "rk-usb";
        cw_bat->rk_usb.type = POWER_SUPPLY_TYPE_USB;
        cw_bat->rk_usb.properties = rk_usb_properties;
        cw_bat->rk_usb.num_properties = ARRAY_SIZE(rk_usb_properties);
        cw_bat->rk_usb.get_property = rk_usb_get_property;
        ret = power_supply_register(&client->dev, &cw_bat->rk_usb);
        if(ret < 0) {
                dev_err(&cw_bat->client->dev, "power supply register rk_ac error\n");
                goto rk_usb_register_fail;
        }

        cw_bat->charger_init_mode = dwc_otg_check_dpdm();

        cw_bat->dc_online = 0;
        cw_bat->usb_online = 0;
        cw_bat->charger_mode = 0;
        cw_bat->capacity = 2;
        cw_bat->voltage = 0;
        cw_bat->status = 0;
        cw_bat->time_to_empty = 0;
        cw_bat->bat_change = 0;

        cw_update_time_member_capacity_change(cw_bat);
        cw_update_time_member_charge_start(cw_bat);

        cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery");
        INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work);
        INIT_DELAYED_WORK(&cw_bat->dc_wakeup_work, dc_detect_do_wakeup);
        queue_delayed_work(cw_bat->battery_workqueue, &cw_bat->battery_delay_work, msecs_to_jiffies(10));
        
        if (cw_bat->plat_data->dc_det_pin != INVALID_GPIO) {
                irq = gpio_to_irq(cw_bat->plat_data->dc_det_pin);
                irq_flags = gpio_get_value(cw_bat->plat_data->dc_det_pin) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
                ret = request_irq(irq, dc_detect_irq_handler, irq_flags, "usb_detect", cw_bat);
                if (ret < 0) {
                        pr_err("%s: request_irq(%d) failed\n", __func__, irq);
                }
                enable_irq_wake(irq);
        }

#ifdef BAT_LOW_INTERRUPT
        INIT_DELAYED_WORK(&cw_bat->bat_low_wakeup_work, bat_low_detect_do_wakeup);
        wake_lock_init(&bat_low_wakelock, WAKE_LOCK_SUSPEND, "bat_low_detect");
        if (cw_bat->plat_data->bat_low_pin != INVALID_GPIO) {
                irq = gpio_to_irq(cw_bat->plat_data->bat_low_pin);
                ret = request_irq(irq, bat_low_detect_irq_handler, IRQF_TRIGGER_RISING, "bat_low_detect", cw_bat);
                if (ret < 0) {
                        gpio_free(cw_bat->plat_data->bat_low_pin);
                }
                enable_irq_wake(irq);
        }
#endif

        dev_info(&cw_bat->client->dev, "cw2015/cw2013 driver v1.2 probe sucess\n");
        return 0;

rk_usb_register_fail:
        power_supply_unregister(&cw_bat->rk_bat);
rk_ac_register_fail:
        power_supply_unregister(&cw_bat->rk_ac);
rk_bat_register_fail:
        dev_info(&cw_bat->client->dev, "cw2015/cw2013 driver v1.2 probe error!!!!\n");
        return ret;
}
示例#5
0
int bma020_acc_start(void)
{
	int result,err;
	struct input_dev *input_dev;

	struct device *dev_t;
	
	bma020acc_t accels; 
	
	result = register_chrdev( ACC_DEV_MAJOR, ACC_DEV_NAME, &acc_fops);

	if (result < 0) 
	{
		return result;
	}
	
	acc_class = class_create (THIS_MODULE, ACC_DEV_NAME);
	
	if (IS_ERR(acc_class)) 
	{
		unregister_chrdev( ACC_DEV_MAJOR, ACC_DEV_NAME);
		return PTR_ERR( acc_class );
	}

	dev_t = device_create( acc_class, NULL, MKDEV(ACC_DEV_MAJOR, 0), "%s", ACC_DEV_NAME);

	if (IS_ERR(dev_t)) 
	{
		return PTR_ERR(dev_t);
	}
	
	/*For testing*/
	if (device_create_file(dev_t, &dev_attr_acc_file) < 0)
		printk("Failed to create device file %s \n", dev_attr_acc_file.attr.name);
	
	mutex_init(&bma020.power_lock);

	/* hrtimer settings.  we poll for light values using a timer. */
	hrtimer_init(&bma020.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	bma020.acc_poll_delay = ns_to_ktime(240 * NSEC_PER_MSEC);
	bma020.timer.function = bma_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	bma020.wq = create_singlethread_workqueue("bma_wq");
	if (!bma020.wq) {
		err = -ENOMEM;
		printk("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}
	/* this is the thread function we run on the work queue */
	INIT_WORK(&bma020.work_acc, bma_work_func_acc);

	/* allocate lightsensor-level input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		printk("%s: could not allocate input device\n", __func__);
		err = -ENOMEM;
		goto err_input_allocate_device_light;
	}
	input_set_drvdata(input_dev, &bma020);
	input_dev->name = "accel";


	set_bit(EV_ABS, input_dev->evbit);	
	/* acceleration x-axis */
	input_set_capability(input_dev, EV_ABS, ABS_X);
	input_set_abs_params(input_dev, ABS_X, -1024, 1024, 0, 0);
	/* acceleration y-axis */
	input_set_capability(input_dev, EV_ABS, ABS_Y);
	input_set_abs_params(input_dev, ABS_Y, -1024, 1024, 0, 0);
	/* acceleration z-axis */
	input_set_capability(input_dev, EV_ABS, ABS_Z);
	input_set_abs_params(input_dev, ABS_Z, -1024, 1024, 0, 0);

	printk("registering lightsensor-level input device\n");
	err = input_register_device(input_dev);
	if (err < 0) {
		printk("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_light;
	}
	bma020.acc_input_dev = input_dev;


	err = sysfs_create_group(&input_dev->dev.kobj,&acc_attribute_group);
	if (err) {
		printk("Creating bma020 attribute group failed");
		goto error_device;
	}
//////////////////////////////////////////////////////////////////////////////
	
	result = i2c_acc_bma020_init();

	if(result)
	{
		return result;
	}

	bma020_chip_init();

	gprintk("[BMA020] read_xyz ==========================\n");
	bma020_read_accel_xyz( &accels );
	gprintk("[BMA020] x = %d  /  y =  %d  /  z = %d\n", accels.x, accels.y, accels.z );

	gprintk("[BMA020] ===================================\n");	

#ifdef BMA020_PROC_FS
	create_proc_read_entry(DRIVER_PROC_ENTRY, 0, 0, bma020_proc_read, NULL);
#endif	//BMA020_PROC_FS

	bma020_set_mode(BMA020_MODE_SLEEP);
	gprintk("[BMA020] set_mode BMA020_MODE_SLEEP\n");
	
	return 0;
error_device:
	sysfs_remove_group(&input_dev->dev.kobj, &acc_attribute_group);
err_input_register_device_light:
	input_unregister_device(bma020.acc_input_dev);
err_input_allocate_device_light:	
	destroy_workqueue(bma020.wq);
err_create_workqueue:
	mutex_destroy(&bma020.power_lock);
exit:
	return err;
}
示例#6
0
static int pixcir_probe(struct platform_device *pdev)
{
	int i;
    int err = 0;
	struct pixcir_data *pixcir = platform_get_drvdata(pdev);
    
	INIT_DELAYED_WORK(&pixcir->read_work, pixcir_read_work);
    pixcir->workqueue = create_singlethread_workqueue(pixcir->name);
	if (!pixcir->workqueue) {
		err = -ESRCH;
		goto exit_create_singlethread;
	}
    
    err = pixcir_sysfs_create_group(pixcir, &pixcir_group);
    if(err < 0){
        dbg("create sysfs group failed.\n");
        goto exit_create_group;
    }
    
	pixcir->input_dev = input_allocate_device();
	if (!pixcir->input_dev) {
		err = -ENOMEM;
		dbg("failed to allocate input device\n");
		goto exit_input_dev_alloc_failed;
	}
	
	pixcir->input_dev->name = pixcir->name;
	pixcir->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	set_bit(INPUT_PROP_DIRECT, pixcir->input_dev->propbit);

	input_set_abs_params(pixcir->input_dev,
			     ABS_MT_POSITION_X, 0, pixcir->xresl, 0, 0);
	input_set_abs_params(pixcir->input_dev,
			     ABS_MT_POSITION_Y, 0, pixcir->yresl, 0, 0);
    input_set_abs_params(pixcir->input_dev,
                 ABS_MT_TRACKING_ID, 0, 20, 0, 0);
#ifdef TOUCH_KEY 	
	for (i = 0; i <NUM_KEYS; i++)
		set_bit(keycodes[i], pixcir->input_dev->keybit);

	pixcir->input_dev->keycode = keycodes;
	pixcir->input_dev->keycodesize = sizeof(unsigned int);
	pixcir->input_dev->keycodemax = NUM_KEYS;
#endif
    pixcir->earlysus = 1;
	err = input_register_device(pixcir->input_dev);
	if (err) {
		dbg_err("pixcir_ts_probe: failed to register input device.\n");
		goto exit_input_register_device_failed;
	}
        
#ifdef CONFIG_HAS_EARLYSUSPEND
	pixcir->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	pixcir->early_suspend.suspend = pixcir_early_suspend;
	pixcir->early_suspend.resume = pixcir_late_resume;
	register_early_suspend(&pixcir->early_suspend);
#endif
    
	if(request_irq(pixcir->irq, pixcir_isr_handler, IRQF_SHARED, pixcir->name, pixcir) < 0){
		dbg_err("Could not allocate irq for ts_pixcir !\n");
		err = -1;
		goto exit_register_irq;
	}	
	
    gpio_enable(pixcir->igp_idx, pixcir->igp_bit, INPUT);
    gpio_pull_enable(pixcir->igp_idx, pixcir->igp_bit, PULL_UP);
    gpio_setup_irq(pixcir->igp_idx, pixcir->igp_bit, IRQ_FALLING);
    
    pixcir_reset(pixcir);
    msleep(200);
    pixcir_active(pixcir);
    pixcir->earlysus = 0;
    
    return 0;
    
exit_register_irq:
	unregister_early_suspend(&pixcir->early_suspend);
exit_input_register_device_failed:
	input_free_device(pixcir->input_dev);
exit_input_dev_alloc_failed:
    pixcir_sysfs_remove_group(pixcir, &pixcir_group);
exit_create_group:
	cancel_delayed_work_sync(&pixcir->read_work);
	destroy_workqueue(pixcir->workqueue);  
exit_create_singlethread:
    //kfree(pixcir);
	return err;
}
void diagfwd_sdio_init(const char *name)
{
	int ret;

	if (diag9k_debug_mask)
		DIAG_INFO("%s\n", __func__);

	driver->read_len_mdm = 0;
	if (driver->buf_in_sdio_1 == NULL)
		driver->buf_in_sdio_1 = kzalloc(MAX_IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_sdio_1 == NULL)
			goto err;
	if (driver->buf_in_sdio_2 == NULL)
		driver->buf_in_sdio_2 = kzalloc(MAX_IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_sdio_2 == NULL)
			goto err;
	if (driver->usb_buf_mdm_out  == NULL)
		driver->usb_buf_mdm_out = kzalloc(USB_MAX_OUT_BUF, GFP_KERNEL);
		if (driver->usb_buf_mdm_out == NULL)
			goto err;
	if (driver->write_ptr_mdm_1 == NULL)
		driver->write_ptr_mdm_1 = kzalloc(
			sizeof(struct diag_request), GFP_KERNEL);
		if (driver->write_ptr_mdm_1 == NULL)
			goto err;
	if (driver->write_ptr_mdm_2 == NULL)
		driver->write_ptr_mdm_2 = kzalloc(
			sizeof(struct diag_request), GFP_KERNEL);
		if (driver->write_ptr_mdm_2 == NULL)
			goto err;
	if (driver->usb_read_mdm_ptr == NULL)
		driver->usb_read_mdm_ptr = kzalloc(
			sizeof(struct diag_request), GFP_KERNEL);
		if (driver->usb_read_mdm_ptr == NULL)
			goto err;
	driver->diag_sdio_wq = create_singlethread_workqueue("diag_sdio_wq");
#ifdef CONFIG_DIAG_OVER_USB
	strncpy(usb_ch_name, name, 16);
	DIAG_INFO("%s using %s\n", __func__, usb_ch_name);
/*
	driver->mdm_ch = usb_diag_open(DIAG_MDM, driver,
			diag_usb_legacy_notifier);
	if (IS_ERR(driver->mdm_ch)) {
		printk(KERN_ERR "Unable to open USB diag MDM channel\n");
		goto err;
	}
*/

	INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
#endif
	INIT_WORK(&(driver->diag_read_sdio_work), diag_read_sdio_work_fn);
	INIT_WORK(&(driver->diag_remove_sdio_work), diag_remove_sdio_work_fn);
	ret = platform_driver_register(&msm_sdio_ch_driver);
	if (ret)
		DIAG_INFO("DIAG could not register SDIO device");
	else
		DIAG_INFO("DIAG registered SDIO device\n");

	ril_sdio_dbg_flag = (get_kernel_flag() & BIT19)?1 :0;
	return;
err:
		DIAG_INFO("\n Could not initialize diag buf for SDIO");
		kfree(driver->buf_in_sdio_1);
		kfree(driver->buf_in_sdio_2);
		kfree(driver->usb_buf_mdm_out);
		kfree(driver->write_ptr_mdm_1);
		kfree(driver->write_ptr_mdm_2);
		kfree(driver->usb_read_mdm_ptr);
		if (driver->diag_sdio_wq)
			destroy_workqueue(driver->diag_sdio_wq);
}
示例#8
0
文件: qxl_kms.c 项目: 020gzh/linux
static int qxl_device_init(struct qxl_device *qdev,
		    struct drm_device *ddev,
		    struct pci_dev *pdev,
		    unsigned long flags)
{
	int r, sb;

	qdev->dev = &pdev->dev;
	qdev->ddev = ddev;
	qdev->pdev = pdev;
	qdev->flags = flags;

	mutex_init(&qdev->gem.mutex);
	mutex_init(&qdev->update_area_mutex);
	mutex_init(&qdev->release_mutex);
	mutex_init(&qdev->surf_evict_mutex);
	INIT_LIST_HEAD(&qdev->gem.objects);

	qdev->rom_base = pci_resource_start(pdev, 2);
	qdev->rom_size = pci_resource_len(pdev, 2);
	qdev->vram_base = pci_resource_start(pdev, 0);
	qdev->io_base = pci_resource_start(pdev, 3);

	qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0));

	if (pci_resource_len(pdev, 4) > 0) {
		/* 64bit surface bar present */
		sb = 4;
		qdev->surfaceram_base = pci_resource_start(pdev, sb);
		qdev->surfaceram_size = pci_resource_len(pdev, sb);
		qdev->surface_mapping =
			io_mapping_create_wc(qdev->surfaceram_base,
					     qdev->surfaceram_size);
	}
	if (qdev->surface_mapping == NULL) {
		/* 64bit surface bar not present (or mapping failed) */
		sb = 1;
		qdev->surfaceram_base = pci_resource_start(pdev, sb);
		qdev->surfaceram_size = pci_resource_len(pdev, sb);
		qdev->surface_mapping =
			io_mapping_create_wc(qdev->surfaceram_base,
					     qdev->surfaceram_size);
	}

	DRM_DEBUG_KMS("qxl: vram %llx-%llx(%dM %dk), surface %llx-%llx(%dM %dk, %s)\n",
		 (unsigned long long)qdev->vram_base,
		 (unsigned long long)pci_resource_end(pdev, 0),
		 (int)pci_resource_len(pdev, 0) / 1024 / 1024,
		 (int)pci_resource_len(pdev, 0) / 1024,
		 (unsigned long long)qdev->surfaceram_base,
		 (unsigned long long)pci_resource_end(pdev, sb),
		 (int)qdev->surfaceram_size / 1024 / 1024,
		 (int)qdev->surfaceram_size / 1024,
		 (sb == 4) ? "64bit" : "32bit");

	qdev->rom = ioremap(qdev->rom_base, qdev->rom_size);
	if (!qdev->rom) {
		pr_err("Unable to ioremap ROM\n");
		return -ENOMEM;
	}

	qxl_check_device(qdev);

	r = qxl_bo_init(qdev);
	if (r) {
		DRM_ERROR("bo init failed %d\n", r);
		return r;
	}

	qdev->ram_header = ioremap(qdev->vram_base +
				   qdev->rom->ram_header_offset,
				   sizeof(*qdev->ram_header));

	qdev->command_ring = qxl_ring_create(&(qdev->ram_header->cmd_ring_hdr),
					     sizeof(struct qxl_command),
					     QXL_COMMAND_RING_SIZE,
					     qdev->io_base + QXL_IO_NOTIFY_CMD,
					     false,
					     &qdev->display_event);

	qdev->cursor_ring = qxl_ring_create(
				&(qdev->ram_header->cursor_ring_hdr),
				sizeof(struct qxl_command),
				QXL_CURSOR_RING_SIZE,
				qdev->io_base + QXL_IO_NOTIFY_CMD,
				false,
				&qdev->cursor_event);

	qdev->release_ring = qxl_ring_create(
				&(qdev->ram_header->release_ring_hdr),
				sizeof(uint64_t),
				QXL_RELEASE_RING_SIZE, 0, true,
				NULL);

	/* TODO - slot initialization should happen on reset. where is our
	 * reset handler? */
	qdev->n_mem_slots = qdev->rom->slots_end;
	qdev->slot_gen_bits = qdev->rom->slot_gen_bits;
	qdev->slot_id_bits = qdev->rom->slot_id_bits;
	qdev->va_slot_mask =
		(~(uint64_t)0) >> (qdev->slot_id_bits + qdev->slot_gen_bits);

	qdev->mem_slots =
		kmalloc(qdev->n_mem_slots * sizeof(struct qxl_memslot),
			GFP_KERNEL);

	idr_init(&qdev->release_idr);
	spin_lock_init(&qdev->release_idr_lock);
	spin_lock_init(&qdev->release_lock);

	idr_init(&qdev->surf_id_idr);
	spin_lock_init(&qdev->surf_id_idr_lock);

	mutex_init(&qdev->async_io_mutex);

	/* reset the device into a known state - no memslots, no primary
	 * created, no surfaces. */
	qxl_io_reset(qdev);

	/* must initialize irq before first async io - slot creation */
	r = qxl_irq_init(qdev);
	if (r)
		return r;

	/*
	 * Note that virtual is surface0. We rely on the single ioremap done
	 * before.
	 */
	qdev->main_mem_slot = setup_slot(qdev, 0,
		(unsigned long)qdev->vram_base,
		(unsigned long)qdev->vram_base + qdev->rom->ram_header_offset);
	qdev->surfaces_mem_slot = setup_slot(qdev, 1,
		(unsigned long)qdev->surfaceram_base,
		(unsigned long)qdev->surfaceram_base + qdev->surfaceram_size);
	DRM_INFO("main mem slot %d [%lx,%x]\n",
		 qdev->main_mem_slot,
		 (unsigned long)qdev->vram_base, qdev->rom->ram_header_offset);
	DRM_INFO("surface mem slot %d [%lx,%lx]\n",
		 qdev->surfaces_mem_slot,
		 (unsigned long)qdev->surfaceram_base,
		 (unsigned long)qdev->surfaceram_size);


	qdev->gc_queue = create_singlethread_workqueue("qxl_gc");
	INIT_WORK(&qdev->gc_work, qxl_gc_work);

	r = qxl_fb_init(qdev);
	if (r)
		return r;

	return 0;
}
static int mxhci_hsic_probe(struct platform_device *pdev)
{
	struct hc_driver *driver;
	struct device_node *node = pdev->dev.of_node;
	struct mxhci_hsic_hcd *mxhci;
	struct xhci_hcd		*xhci;
	struct resource *res;
	struct usb_hcd *hcd;
	unsigned int reg;
	int ret;
	int irq;
	u32 tmp[3];

	if (usb_disabled())
		return -ENODEV;

	driver = &mxhci_hsic_hc_driver;

	pdev->dev.dma_mask = &dma_mask;

	/* dbg log event settings */
	dbg_hsic.log_events =  enable_dbg_log;
	dbg_hsic.log_payload = enable_payload_log;
	dbg_hsic.inep_log_mask = ep_addr_rxdbg_mask;
	dbg_hsic.outep_log_mask = ep_addr_rxdbg_mask;

	/* usb2.0 root hub */
	driver->hcd_priv_size =	sizeof(struct mxhci_hsic_hcd);
	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd)
		return -ENOMEM;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = -ENODEV;
		goto put_hcd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		ret = -ENODEV;
		goto put_hcd;
	}

	hcd_to_bus(hcd)->skip_resume = true;
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "error mapping memory\n");
		ret = -EFAULT;
		goto put_hcd;
	}

	mxhci = hcd_to_hsic(hcd);
	mxhci->dev = &pdev->dev;

	mxhci->strobe = of_get_named_gpio(node, "hsic,strobe-gpio", 0);
	if (mxhci->strobe < 0) {
		ret = -EINVAL;
		goto put_hcd;
	}

	mxhci->data  = of_get_named_gpio(node, "hsic,data-gpio", 0);
	if (mxhci->data < 0) {
		ret = -EINVAL;
		goto put_hcd;
	}

	ret = of_property_read_u32_array(node, "qcom,vdd-voltage-level",
							tmp, ARRAY_SIZE(tmp));
	if (!ret) {
		mxhci->vdd_no_vol_level = tmp[0];
		mxhci->vdd_low_vol_level = tmp[1];
		mxhci->vdd_high_vol_level = tmp[2];
	} else {
		dev_err(&pdev->dev,
			"failed to read qcom,vdd-voltage-level property\n");
		ret = -EINVAL;
		goto put_hcd;
	}

	ret = mxhci_msm_config_gdsc(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to configure hsic gdsc\n");
		goto put_hcd;
	}

	ret = mxhci_hsic_init_clocks(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize clocks\n");
		goto put_hcd;
	}

	ret = mxhci_hsic_init_vddcx(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize vddcx\n");
		goto deinit_clocks;
	}

	mxhci_hsic_reset(mxhci);

	/* HSIC phy caliberation:set periodic caliberation interval ~2.048sec */
	mxhci_hsic_ulpi_write(mxhci, 0xFF, MSM_HSIC_IO_CAL_PER);

	/* Enable periodic IO calibration in HSIC_CFG register */
	mxhci_hsic_ulpi_write(mxhci, 0xA8, MSM_HSIC_CFG);

	/* Configure Strobe and Data GPIOs to enable HSIC */
	ret = mxhci_hsic_config_gpios(mxhci);
	if (ret) {
		dev_err(mxhci->dev, " gpio configuarion failed\n");
		goto deinit_vddcx;
	}

	/* enable STROBE_PAD_CTL */
	reg = readl_relaxed(TLMM_GPIO_HSIC_STROBE_PAD_CTL);
	writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_STROBE_PAD_CTL);

	/* enable DATA_PAD_CTL */
	reg = readl_relaxed(TLMM_GPIO_HSIC_DATA_PAD_CTL);
	writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_DATA_PAD_CTL);

	mb();

	/* Enable LPM in Sleep mode and suspend mode */
	reg = readl_relaxed(MSM_HSIC_CTRL_REG);
	reg |= CTRLREG_PLL_CTRL_SLEEP | CTRLREG_PLL_CTRL_SUSP;
	writel_relaxed(reg, MSM_HSIC_CTRL_REG);

	if (of_property_read_bool(node, "qti,disable-hw-clk-gating")) {
		reg = readl_relaxed(MSM_HSIC_GCTL);
		writel_relaxed((reg | GCTL_DSBLCLKGTNG), MSM_HSIC_GCTL);
	}

	/* enable pwr event irq for LPM_IN_L2_IRQ */
	writel_relaxed(LPM_IN_L2_IRQ_MASK, MSM_HSIC_PWR_EVNT_IRQ_MASK);

	mxhci->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq");
	if (mxhci->wakeup_irq < 0) {
		mxhci->wakeup_irq = 0;
		dev_err(&pdev->dev, "failed to init wakeup_irq\n");
	} else {
		/* enable wakeup irq only when entering lpm */
		irq_set_status_flags(mxhci->wakeup_irq, IRQ_NOAUTOEN);
		ret = devm_request_irq(&pdev->dev, mxhci->wakeup_irq,
			mxhci_hsic_wakeup_irq, 0, "mxhci_hsic_wakeup", mxhci);
		if (ret) {
			dev_err(&pdev->dev,
					"request irq failed (wakeup irq)\n");
			goto deinit_vddcx;
		}
	}

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto deinit_vddcx;

	hcd = dev_get_drvdata(&pdev->dev);
	xhci = hcd_to_xhci(hcd);

	/* USB 3.0 roothub */

	/* no need for another instance of mxhci */
	driver->hcd_priv_size = sizeof(struct xhci_hcd *);

	xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
			dev_name(&pdev->dev), hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto remove_usb2_hcd;
	}

	hcd_to_bus(xhci->shared_hcd)->skip_resume = true;
	/*
	 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
	 * is called by usb_add_hcd().
	 */
	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;

	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
	if (ret)
		goto put_usb3_hcd;

	spin_lock_init(&mxhci->wakeup_lock);

	mxhci->pwr_event_irq = platform_get_irq_byname(pdev, "pwr_event_irq");
	if (mxhci->pwr_event_irq < 0) {
		dev_err(&pdev->dev,
				"platform_get_irq for pwr_event_irq failed\n");
		goto remove_usb3_hcd;
	}

	ret = devm_request_irq(&pdev->dev, mxhci->pwr_event_irq,
				mxhci_hsic_pwr_event_irq,
				0, "mxhci_hsic_pwr_evt", mxhci);
	if (ret) {
		dev_err(&pdev->dev, "request irq failed (pwr event irq)\n");
		goto remove_usb3_hcd;
	}

	init_completion(&mxhci->phy_in_lpm);

	mxhci->wq = create_singlethread_workqueue("mxhci_wq");
	if (!mxhci->wq) {
		dev_err(&pdev->dev, "unable to create workqueue\n");
		ret = -ENOMEM;
		goto remove_usb3_hcd;
	}

	INIT_WORK(&mxhci->bus_vote_w, mxhci_hsic_bus_vote_w);

	mxhci->bus_scale_table = msm_bus_cl_get_pdata(pdev);
	if (!mxhci->bus_scale_table) {
		dev_dbg(&pdev->dev, "bus scaling is disabled\n");
	} else {
		mxhci->bus_perf_client =
			msm_bus_scale_register_client(mxhci->bus_scale_table);
		/* Configure BUS performance parameters for MAX bandwidth */
		if (mxhci->bus_perf_client) {
			mxhci->bus_vote = true;
			queue_work(mxhci->wq, &mxhci->bus_vote_w);
		} else {
			dev_err(&pdev->dev, "%s: bus scaling client reg err\n",
					__func__);
			ret = -ENODEV;
			goto delete_wq;
		}
	}

	ret = device_create_file(&pdev->dev, &dev_attr_config_imod);
	if (ret)
		dev_dbg(&pdev->dev, "%s: unable to create imod sysfs entry\n",
					__func__);

	/* Enable HSIC PHY */
	mxhci_hsic_ulpi_write(mxhci, 0x01, MSM_HSIC_CFG_SET);

	device_init_wakeup(&pdev->dev, 1);
	wakeup_source_init(&mxhci->ws, dev_name(&pdev->dev));
	pm_stay_awake(mxhci->dev);

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

delete_wq:
	destroy_workqueue(mxhci->wq);
remove_usb3_hcd:
	usb_remove_hcd(xhci->shared_hcd);
put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);
remove_usb2_hcd:
	usb_remove_hcd(hcd);
deinit_vddcx:
	mxhci_hsic_init_vddcx(mxhci, 0);
deinit_clocks:
	mxhci_hsic_init_clocks(mxhci, 0);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
示例#10
0
static int __devinit asuspec_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int err = 0;

	ASUSPEC_INFO("asuspec probe\n");
	err = sysfs_create_group(&client->dev.kobj, &asuspec_smbus_group);
	if (err) {
		ASUSPEC_ERR("Unable to create the sysfs\n");
		goto exit;
	}

	ec_chip = kzalloc(sizeof (struct asuspec_chip), GFP_KERNEL);
	if (!ec_chip) {
		ASUSPEC_ERR("Memory allocation fails\n");
		err = -ENOMEM;
		goto exit;
	}
		
	i2c_set_clientdata(client, ec_chip);
	ec_chip->client = client;
	ec_chip->client->driver = &asuspec_driver;				
	ec_chip->client->flags = 1;

	init_timer(&ec_chip->asuspec_timer);
	ec_chip->asuspec_timer.function = asuspec_enter_s3_timer;

	wake_lock_init(&ec_chip->wake_lock, WAKE_LOCK_SUSPEND, "asuspec_wake");
	mutex_init(&ec_chip->lock);
	mutex_init(&ec_chip->irq_lock);
	mutex_init(&ec_chip->state_change_lock);

	ec_chip->ec_ram_init = 0;
	ec_chip->status = 0;
	ec_chip->ec_in_s3 = 0;
	ec_chip->apwake_disabled = 0;
	asuspec_dockram_init(client);
	cdev_add(asuspec_cdev,asuspec_dev,1) ;

	ec_chip->pad_sdev.name = PAD_SDEV_NAME;
	ec_chip->pad_sdev.print_name = asuspec_switch_name;
	ec_chip->pad_sdev.print_state = asuspec_switch_state;
	if(switch_dev_register(&ec_chip->pad_sdev) < 0){
		ASUSPEC_ERR("switch_dev_register for pad failed!\n");
	}
	switch_set_state(&ec_chip->pad_sdev, 0);
	
	asuspec_wq = create_singlethread_workqueue("asuspec_wq");
	INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_work, asuspec_work_function);
	INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_init_work, asuspec_init_work_function);
	INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_fw_update_work, asuspec_fw_update_work_function);
	INIT_DELAYED_WORK_DEFERRABLE(&ec_chip->asuspec_enter_s3_work, asuspec_enter_s3_work_function);
	INIT_DELAYED_WORK_DEFERRABLE(&asuspec_stress_work, asuspec_stresstest_work_function);
	
	asuspec_irq_ec_request(client);
	asuspec_irq_ec_apwake(client);
	queue_delayed_work(asuspec_wq, &ec_chip->asuspec_init_work, 0);

	return 0;

exit:
	return err;
}
示例#11
0
void diagfwd_init(void)
{
	diag_debug_buf_idx = 0;
	spin_lock_init(&diagchar_smd_lock);
	spin_lock_init(&diagchar_smd_qdsp_lock);
	if (driver->usb_buf_out  == NULL &&
	     (driver->usb_buf_out = kzalloc(USB_MAX_OUT_BUF,
					 GFP_KERNEL)) == NULL)
		goto err;
	if (driver->hdlc_buf == NULL
	    && (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
		goto err;
	if (driver->msg_masks == NULL
	    && (driver->msg_masks = kzalloc(MSG_MASK_SIZE,
					     GFP_KERNEL)) == NULL)
		goto err;
	if (driver->log_masks == NULL &&
	    (driver->log_masks = kzalloc(LOG_MASK_SIZE, GFP_KERNEL)) == NULL)
		goto err;
	if (driver->event_masks == NULL &&
	    (driver->event_masks = kzalloc(EVENT_MASK_SIZE,
					    GFP_KERNEL)) == NULL)
		goto err;
	if (driver->client_map == NULL &&
	    (driver->client_map = kzalloc
	     ((driver->num_clients) * 4, GFP_KERNEL)) == NULL)
		goto err;
	if (driver->buf_tbl == NULL)
			driver->buf_tbl = kzalloc(buf_tbl_size *
			  sizeof(struct diag_write_device), GFP_KERNEL);
	if (driver->buf_tbl == NULL)
		goto err;
	if (driver->data_ready == NULL &&
	     (driver->data_ready = kzalloc(driver->num_clients * 4,
					    GFP_KERNEL)) == NULL)
		goto err;
	if (driver->table == NULL &&
	     (driver->table = kzalloc(diag_max_registration*
				      sizeof(struct diag_master_table),
				       GFP_KERNEL)) == NULL)
		goto err;
	if (driver->usb_write_ptr == NULL)
			driver->usb_write_ptr = kzalloc(
				sizeof(struct diag_request), GFP_KERNEL);
			if (driver->usb_write_ptr == NULL)
					goto err;
	if (driver->usb_write_ptr_qdsp == NULL)
			driver->usb_write_ptr_qdsp = kzalloc(
				sizeof(struct diag_request), GFP_KERNEL);
			if (driver->usb_write_ptr_qdsp == NULL)
					goto err;
	if (driver->usb_read_ptr == NULL)
			driver->usb_read_ptr = kzalloc(
				sizeof(struct diag_request), GFP_KERNEL);
			if (driver->usb_read_ptr == NULL)
				goto err;
	if (driver->pkt_buf == NULL &&
	     (driver->pkt_buf = kzalloc(PKT_SIZE,
					 GFP_KERNEL)) == NULL)
		goto err;

	driver->diag_wq = create_singlethread_workqueue("diag_wq");
	INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);

	diag_usb_register(&diagfwdops);

	platform_driver_register(&msm_smd_ch1_driver);

	return;
err:
		printk(KERN_INFO "\n Could not initialize diag buffers\n");
		kfree(driver->usb_buf_out);
		kfree(driver->hdlc_buf);
		kfree(driver->msg_masks);
		kfree(driver->log_masks);
		kfree(driver->event_masks);
		kfree(driver->client_map);
		kfree(driver->buf_tbl);
		kfree(driver->data_ready);
		kfree(driver->table);
		kfree(driver->pkt_buf);
		kfree(driver->usb_write_ptr);
		kfree(driver->usb_write_ptr_qdsp);
		kfree(driver->usb_read_ptr);
}
示例#12
0
static int ifx_spi_probe(struct spi_device *spi)
{
     int status;
     struct ifx_spi_data *spi_data;
     

    spi_data = (struct ifx_spi_data*)kmalloc(sizeof(struct ifx_spi_data), GFP_KERNEL);
    if (!spi_data)
    {    
	IFX_SPI_PRINTK("Failed to allocate memory for spi_data");    
	return -ENOMEM;
    }

     IFX_SPI_PRINTK("start !!");

    //initialize all member variables of ifx_spi_data
    memset((void*)spi_data, 0, sizeof(struct ifx_spi_data));

	spi_data->ifx_tty = NULL;
#ifdef WAKE_LOCK_RESUME
	spi_data->wake_lock_flag = 0;
#endif

    status = ifx_spi_allocate_frame_memory(spi_data, (IFX_SPI_MAX_BUF_SIZE + IFX_SPI_HEADER_SIZE));
    if(status != 0)
    {
	IFX_SPI_PRINTK("Failed to allocate memory for buffers");
 	
	return -ENOMEM;
    }

    dev_set_drvdata(&spi->dev,spi_data);
    spin_lock_init(&spi_data->spi_lock);
    INIT_WORK(&spi_data->ifx_work,ifx_spi_handle_work);   
	
    spi_data->ifx_wq = create_singlethread_workqueue("ifxn721");
    if(!spi_data->ifx_wq)
    {
	IFX_SPI_PRINTK("Failed to setup workqueue - ifx_wq");          
    }
	
	init_completion(&spi_data->ifx_read_write_completion);
	
      //config srdy,mrdy gpio value according to hw revision
       IFX_MRDY = TEGRA_GPIO_PO0;  //ULPI_DATA7
       IFX_SRDY =  TEGRA_GPIO_PO5;  //ULPI_DATA4

        /* Configure SPI */
	spi_data->spi = spi;

	spi->mode = SPI_MODE_1 ;
	spi->bits_per_word = 8; //32 is mdm only
	spi->chip_select = 0 ;
	spi->max_speed_hz = 24000000; //48000000; //to 24Mhz	

	status = spi_setup(spi);
        if(status < 0)
	{
		IFX_SPI_PRINTK("Failed to setup SPI \n");
        }             

#ifdef WAKE_LOCK_RESUME
	wake_lock_init(&spi_data->wake_lock, WAKE_LOCK_SUSPEND, "mspi_wake");
#endif

	gpio_request(IFX_MRDY, "ifx_mrdy");	
 	tegra_gpio_enable(IFX_MRDY);
		
	gpio_request(IFX_SRDY, "ifx_srdy");	
 	tegra_gpio_enable(IFX_SRDY);	
	
	gpio_direction_input(IFX_SRDY);

/* changed to level trigger */

	status = request_irq(gpio_to_irq(IFX_SRDY), 
					    ifx_spi_handle_srdy_irq,
					    IRQF_TRIGGER_RISING, 
					    spi->dev.driver->name, 
					    spi_data);

	if (status != 0)
	{
		IFX_SPI_PRINTK("Failed to request IRQ for SRDY");
		IFX_SPI_PRINTK("IFX SPI Probe Failed");
		ifx_spi_free_frame_memory(spi_data);
		if(spi_data)
		{
			kfree(spi_data);
		}          
	}
 	else
	{
		ifx_gspi_data = spi_data;
	}

	enable_irq_wake(gpio_to_irq(IFX_SRDY)); //wake irq...	
	
	IFX_SPI_PRINTK(" end !!!  ");
	return status;
}
示例#13
0
static int pn544_probe(struct i2c_client *client,
		       const struct i2c_device_id *id)
{
	int ret;
	struct pn544_i2c_platform_data *platform_data;
	struct pn544_dev *pn544_dev;

	if (client->dev.platform_data == NULL) {
		pr_err("%s : nfc probe fail\n", __func__);
		return -ENODEV;
	}
	platform_data = client->dev.platform_data;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s : need I2C_FUNC_I2C\n", __func__);
		return -ENODEV;
	}

	ret = gpio_request(platform_data->irq_gpio, "nfc_int");
	if (ret)
		return -ENODEV;
	ret = gpio_request(platform_data->ven_gpio, "nfc_ven");
	if (ret)
		goto err_ven;
	ret = gpio_request(platform_data->firm_gpio, "nfc_firm");
	if (ret)
		goto err_firm;
#ifdef CONFIG_NFC_PN547
	ret = gpio_request(platform_data->clk_req_gpio, "nfc_clk_req");
	if (ret)
		goto err_clk_req;
#endif
	pn544_dev = kzalloc(sizeof(*pn544_dev), GFP_KERNEL);
	if (pn544_dev == NULL) {
		dev_err(&client->dev,
			"failed to allocate memory for module data\n");
		ret = -ENOMEM;
		goto err_exit;
	}
#ifdef CONFIG_NFC_PN547
	pn544_dev->nfc_clock = msm_xo_get(MSM_XO_TCXO_A1, "nfc");
	if (IS_ERR(pn544_dev->nfc_clock)) {
		ret = PTR_ERR(pn544_dev->nfc_clock);
		printk(KERN_ERR "%s: Couldn't get TCXO_A1 vote for NFC (%d)\n",
					__func__, ret);
		ret = -ENODEV;
		goto err_get_clock;
	}
	pn544_dev->clock_state = false;
#endif
	pr_info("%s : IRQ num %d\n", __func__, client->irq);

	pn544_dev->irq_gpio = platform_data->irq_gpio;
	pn544_dev->ven_gpio = platform_data->ven_gpio;
	pn544_dev->firm_gpio = platform_data->firm_gpio;
	pn544_dev->conf_gpio = platform_data->conf_gpio;
#ifdef CONFIG_NFC_PN547
	pn544_dev->clk_req_gpio = platform_data->clk_req_gpio;
	pn544_dev->clk_req_irq = platform_data->clk_req_irq;
#endif
	pn544_dev->client = client;

	/* init mutex and queues */
	init_waitqueue_head(&pn544_dev->read_wq);
	mutex_init(&pn544_dev->read_mutex);

	pn544_dev->pn544_device.minor = MISC_DYNAMIC_MINOR;
#ifdef CONFIG_NFC_PN547
	pn544_dev->pn544_device.name = "pn547";
#else
	pn544_dev->pn544_device.name = "pn544";
#endif
	pn544_dev->pn544_device.fops = &pn544_dev_fops;

	ret = misc_register(&pn544_dev->pn544_device);
	if (ret) {
		pr_err("%s : misc_register failed\n", __FILE__);
		goto err_misc_register;
	}

	/* request irq.  the irq is set whenever the chip has data available
	 * for reading.  it is cleared when all data has been read.
	 */
	pr_info("%s : requesting IRQ %d\n", __func__, client->irq);
	gpio_direction_input(pn544_dev->irq_gpio);
	gpio_direction_output(pn544_dev->ven_gpio, 0);
	gpio_direction_output(pn544_dev->firm_gpio, 0);
#ifdef CONFIG_NFC_PN547
	gpio_direction_input(pn544_dev->clk_req_gpio);
#endif

	i2c_set_clientdata(client, pn544_dev);
	wake_lock_init(&pn544_dev->nfc_wake_lock,
			WAKE_LOCK_SUSPEND, "nfc_wake_lock");
#ifdef CONFIG_NFC_PN547
	pn544_dev->wq_clock = create_singlethread_workqueue("nfc_wq");
	if (!pn544_dev->wq_clock) {
		ret = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}
	INIT_WORK(&pn544_dev->work_nfc_clock, nfc_work_func_clock);
#endif
	ret = request_irq(client->irq, pn544_dev_irq_handler,
			  IRQF_TRIGGER_RISING, "pn544", pn544_dev);
	if (ret) {
		dev_err(&client->dev, "request_irq failed\n");
		goto err_request_irq_failed;
	}
	disable_irq_nosync(pn544_dev->client->irq);
	atomic_set(&pn544_dev->irq_enabled, 0);

#ifdef CONFIG_NFC_PN547
	ret = request_irq(pn544_dev->clk_req_irq, pn544_dev_clk_req_irq_handler,
		IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
			, "pn544_clk_req", pn544_dev);
	if (ret) {
		dev_err(&client->dev, "request_irq(clk_req) failed\n");
		goto err_request_irq_failed;
	}

	enable_irq_wake(pn544_dev->clk_req_irq);
#endif
	return 0;

err_request_irq_failed:
#ifdef CONFIG_NFC_PN547
err_create_workqueue:
#endif
	misc_deregister(&pn544_dev->pn544_device);
	wake_lock_destroy(&pn544_dev->nfc_wake_lock);
err_misc_register:
	mutex_destroy(&pn544_dev->read_mutex);
#ifdef CONFIG_NFC_PN547
	msm_xo_put(pn544_dev->nfc_clock);
err_get_clock:
#endif
	kfree(pn544_dev);
err_exit:
#ifdef CONFIG_NFC_PN547
	gpio_free(platform_data->clk_req_gpio);
err_clk_req:
#endif
	gpio_free(platform_data->firm_gpio);
err_firm:
	gpio_free(platform_data->ven_gpio);
err_ven:
	gpio_free(platform_data->irq_gpio);
	pr_err("[PN544] pn544_probe fail!\n");
	return ret;
}
示例#14
0
static int cypress_touchkey_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct input_dev *input_dev;
	struct cypress_touchkey_devdata *devdata;
	u8 data[3];
	int err;
	int cnt;
#if defined(TOUCH_UPDATE)
	int ret;
	int retry = 10;
#endif

	if (!dev->platform_data) {
		dev_err(dev, "%s: Platform data is NULL\n", __func__);
		return -EINVAL;
	}

	devdata = kzalloc(sizeof(*devdata), GFP_KERNEL);
	if (devdata == NULL) {
		dev_err(dev, "%s: failed to create our state\n", __func__);
		return -ENODEV;
	}

	devdata->client = client;
	i2c_set_clientdata(client, devdata);

	devdata->pdata = client->dev.platform_data;
#if defined(TOUCH_UPDATE)
	tempdata = devdata;
#endif
	if (!devdata->pdata->keycode) {
		dev_err(dev, "%s: Invalid platform data\n", __func__);
		err = -EINVAL;
		goto err_null_keycodes;
	}

	strlcpy(devdata->client->name, DEVICE_NAME, I2C_NAME_SIZE);

	input_dev = input_allocate_device();
	if (!input_dev) {
		err = -ENOMEM;
		goto err_input_alloc_dev;
	}

	devdata->input_dev = input_dev;
	dev_set_drvdata(&input_dev->dev, devdata);
	input_dev->name = DEVICE_NAME;
	input_dev->id.bustype = BUS_HOST;

	for (cnt = 0; cnt < devdata->pdata->keycode_cnt; cnt++)
		input_set_capability(input_dev, EV_KEY,
					devdata->pdata->keycode[cnt]);

	err = input_register_device(input_dev);
	if (err)
		goto err_input_reg_dev;

	devdata->is_powering_on = true;

	devdata->pdata->touchkey_onoff(TOUCHKEY_ON);

	err = i2c_master_recv(client, data, sizeof(data));
	if (err < sizeof(data)) {
		if (err >= 0)
			err = -EIO;
		dev_err(dev, "%s: error reading hardware version\n", __func__);
		goto err_read;
	}

	dev_info(dev, "%s: hardware rev1 = %#02x, rev2 = %#02x\n", __func__,
				data[1], data[2]);

	devdata->backlight_on = BACKLIGHT_ON;
	devdata->backlight_off = BACKLIGHT_OFF;

	devdata->has_legacy_keycode = 1;

	err = i2c_touchkey_write_byte(devdata, devdata->backlight_on);
	if (err) {
		dev_err(dev, "%s: touch keypad backlight on failed\n",
				__func__);
		goto err_backlight_on;
	}

	if (request_threaded_irq(client->irq, touchkey_interrupt_handler,
				touchkey_interrupt_thread, IRQF_TRIGGER_FALLING,
				DEVICE_NAME, devdata)) {
		dev_err(dev, "%s: Can't allocate irq.\n", __func__);
		goto err_req_irq;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	devdata->early_suspend.suspend = cypress_touchkey_early_suspend;
	devdata->early_suspend.resume = cypress_touchkey_early_resume;
#endif
	register_early_suspend(&devdata->early_suspend);

	devdata->is_powering_on = false;
#if defined(TOUCH_UPDATE)
	ret = misc_register(&touchkey_update_device);
	if (ret) {
		printk("%s misc_register fail\n", __FUNCTION__);
	}

	if (device_create_file
	    (touchkey_update_device.this_device, &dev_attr_touch_version) < 0) {
		printk("%s device_create_file fail dev_attr_touch_version\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_touch_version.attr.name);
	}

	if (device_create_file
	    (touchkey_update_device.this_device, &dev_attr_touch_update) < 0) {
		printk("%s device_create_file fail dev_attr_touch_update\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_touch_update.attr.name);
	}

	if (device_create_file
	    (touchkey_update_device.this_device, &dev_attr_brightness) < 0) {
		printk("%s device_create_file fail dev_attr_touch_update\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_brightness.attr.name);
	}

	if (device_create_file
	    (touchkey_update_device.this_device,
	     &dev_attr_enable_disable) < 0) {
		printk("%s device_create_file fail dev_attr_touch_update\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_enable_disable.attr.name);
	}

	touchkey_wq = create_singlethread_workqueue(DEVICE_NAME);
	if (!touchkey_wq)
		return -ENOMEM;

	while (retry--) {
		if (get_touchkey_firmware(data) == 0)	//melfas need delay for multiple read
			break;
	}
	printk("%s F/W version: 0x%x, Module version:0x%x\n", __FUNCTION__,
	       data[1], data[2]);
#endif

	return 0;

err_req_irq:
err_backlight_on:
err_read:
	devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
	input_unregister_device(input_dev);
	goto err_input_alloc_dev;
err_input_reg_dev:
	input_free_device(input_dev);
err_input_alloc_dev:
err_null_keycodes:
	kfree(devdata);
	return err;
}
示例#15
0
static int __devinit al3010_probe(struct i2c_client *client,
				    const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct al3010_data *data;
	int err = 0;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

	data = kzalloc(sizeof(struct al3010_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->client = client;
	i2c_set_clientdata(client, data);
	mutex_init(&data->lock);

	/* initialize the AL3010 chip */
	//err = al3010_init_client(client);
	//if (err){
		//printk("light sensor err : al3010 init fail in probe \n");
		//goto exit_kfree;
	//}

	/* register sysfs hooks */
	err = sysfs_create_group(&client->dev.kobj, &al3010_attr_group);
	if (err){
		printk("light sensor err : al3010 init sysfs fail\n");
		goto exit_kfree;
	}

	/* register device node */

	printk("light sensor info : al3010 probe successed\n");
	dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);

	/* init for i2c stress test */
	sensor_work_queue = create_singlethread_workqueue("i2c_lightsensor_wq");
	if(!sensor_work_queue){
		printk("al3010_probe: Unable to create workqueue");
		goto exit_kfree;
	}
	INIT_DELAYED_WORK(&al3010_poll_data_work, al3010_poll_data);
	al3010_client = client;
	data->misc_dev.minor  = MISC_DYNAMIC_MINOR;
	data->misc_dev.name = "lightsensor";
	data->misc_dev.fops = &al3010_fops;
	err = misc_register(&data->misc_dev);
	if (err){
		printk("light sensor err : Unable to register %s\misc device\n",
				data->misc_dev.name);
		goto exit_kfree;
	}

	return 0;

exit_kfree:
	kfree(data);
	return err;
}
void diagfwd_bridge_init(void)
{
	int ret;

	pr_debug("diag: in %s\n", __func__);
	driver->diag_bridge_wq = create_singlethread_workqueue(
							"diag_bridge_wq");
	driver->read_len_mdm = 0;
	driver->write_len_mdm = 0;
	driver->num_hsic_buf_tbl_entries = 0;
	if (driver->usb_buf_mdm_out  == NULL)
		driver->usb_buf_mdm_out = kzalloc(USB_MAX_OUT_BUF,
							 GFP_KERNEL);
	if (driver->usb_buf_mdm_out == NULL)
		goto err;
	/* Only used by smux move to smux probe function */
	if (driver->write_ptr_mdm == NULL)
		driver->write_ptr_mdm = kzalloc(
		sizeof(struct diag_request), GFP_KERNEL);
	if (driver->write_ptr_mdm == NULL)
		goto err;
	if (driver->usb_read_mdm_ptr == NULL)
		driver->usb_read_mdm_ptr = kzalloc(
		sizeof(struct diag_request), GFP_KERNEL);
	if (driver->usb_read_mdm_ptr == NULL)
		goto err;

	if (driver->hsic_buf_tbl == NULL)
		driver->hsic_buf_tbl = kzalloc(NUM_HSIC_BUF_TBL_ENTRIES *
				sizeof(struct diag_write_device), GFP_KERNEL);
	if (driver->hsic_buf_tbl == NULL)
		goto err;

	driver->count_hsic_pool = 0;
	driver->count_hsic_write_pool = 0;

	driver->itemsize_hsic = READ_HSIC_BUF_SIZE;
	driver->poolsize_hsic = N_MDM_WRITE;
	driver->itemsize_hsic_write = sizeof(struct diag_request);
	driver->poolsize_hsic_write = N_MDM_WRITE;

#ifdef CONFIG_DIAG_OVER_USB
	INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
#endif
	INIT_WORK(&(driver->diag_disconnect_work), diag_disconnect_work_fn);
	INIT_WORK(&(driver->diag_usb_read_complete_work),
			diag_usb_read_complete_fn);
#ifdef CONFIG_DIAG_OVER_USB
	driver->mdm_ch = usb_diag_open(DIAG_MDM, driver,
						 diagfwd_bridge_notifier);
	if (IS_ERR(driver->mdm_ch)) {
		pr_err("diag: Unable to open USB diag MDM channel\n");
		goto err;
	}
#endif
	/* register HSIC device */
	ret = platform_driver_register(&msm_hsic_ch_driver);
	if (ret)
		pr_err("diag: could not register HSIC device, ret: %d\n", ret);
	/* register SMUX device */
	ret = platform_driver_register(&msm_diagfwd_smux_driver);
	if (ret)
		pr_err("diag: could not register SMUX device, ret: %d\n", ret);

	return;
err:
	pr_err("diag: Could not initialize for bridge forwarding\n");
	kfree(driver->usb_buf_mdm_out);
	kfree(driver->hsic_buf_tbl);
	kfree(driver->write_ptr_mdm);
	kfree(driver->usb_read_mdm_ptr);
	if (driver->diag_bridge_wq)
		destroy_workqueue(driver->diag_bridge_wq);

	return;
}
示例#17
0
static void __diag_socket_init(struct diag_socket_info *info)
{
	uint16_t ins_base = 0;
	uint16_t ins_offset = 0;

	char wq_name[DIAG_SOCKET_NAME_SZ + 10];
	if (!info)
		return;

	init_waitqueue_head(&info->wait_q);
	info->inited = 0;
	atomic_set(&info->opened, 0);
	atomic_set(&info->diag_state, 0);
	info->pkt_len = 0;
	info->pkt_read = 0;
	info->hdl = NULL;
	info->fwd_ctxt = NULL;
	info->data_ready = 0;
	atomic_set(&info->flow_cnt, 0);
	spin_lock_init(&info->lock);
	strlcpy(wq_name, "DIAG_SOCKET_", 10);
	strlcat(wq_name, info->name, sizeof(info->name));
	init_waitqueue_head(&info->read_wait_q);
	info->wq = create_singlethread_workqueue(wq_name);
	if (!info->wq) {
		pr_err("diag: In %s, unable to create workqueue for socket channel %s\n",
		       __func__, info->name);
		return;
	}
	INIT_WORK(&(info->init_work), socket_init_work_fn);
	INIT_WORK(&(info->read_work), socket_read_work_fn);

	switch (info->peripheral) {
	case PERIPHERAL_MODEM:
		ins_base = MODEM_INST_BASE;
		break;
	case PERIPHERAL_LPASS:
		ins_base = LPASS_INST_BASE;
		break;
	case PERIPHERAL_WCNSS:
		ins_base = WCNSS_INST_BASE;
		break;
	case PERIPHERAL_SENSORS:
		ins_base = SENSORS_INST_BASE;
		break;
	}

	switch (info->type) {
	case TYPE_DATA:
		ins_offset = INST_ID_DATA;
		info->port_type = PORT_TYPE_SERVER;
		break;
	case TYPE_CNTL:
		ins_offset = INST_ID_CNTL;
		info->port_type = PORT_TYPE_SERVER;
		break;
	case TYPE_DCI:
		ins_offset = INST_ID_DCI;
		info->port_type = PORT_TYPE_SERVER;
		break;
	case TYPE_CMD:
		ins_offset = INST_ID_CMD;
		info->port_type = PORT_TYPE_CLIENT;
		break;
	case TYPE_DCI_CMD:
		ins_offset = INST_ID_DCI_CMD;
		info->port_type = PORT_TYPE_CLIENT;
		break;
	}

	info->svc_id = DIAG_SVC_ID;
	info->ins_id = ins_base + ins_offset;
	info->inited = 1;

	if (info->port_type == PORT_TYPE_SERVER)
		queue_work(info->wq, &(info->init_work));
}
示例#18
0
/*****************************************************************************
 函 数 名  : hi6559_irq_probe
 功能描述  : 
 输入参数  : 无
 输出参数  : 无
 返 回 值  : 无
*****************************************************************************/
static s32 __init hi6559_irq_probe(struct platform_device *pdev)
{
    s32 ret = BSP_PMU_OK;
    u16 i = 0;
    u8 regvalue = 0;

    hi6559_irq_data_st = kzalloc(sizeof(*hi6559_irq_data_st), GFP_KERNEL);
    if (hi6559_irq_data_st == NULL) 
    {
        pmic_print_error("hi6559 irq kzalloc is failed,please check!\n");
        return -ENOMEM;
    }
    hi6559_irq_data_st->irq = (unsigned)platform_get_irq(pdev, 0);

    spin_lock_init(&hi6559_irq_data_st->irq_lock);/*中断只在Acore实现,多core*/

    /* 初始化工作队列 */
    hi6559_irq_data_st->hi6559_irq_wq = create_singlethread_workqueue("bsp_hi6559_irq");
    INIT_WORK(&hi6559_irq_data_st->hi6559_irq_wk, (void *)hi6559_irq_wk_handler);

    /* 处理usb拔出误报,若usb不在位,多报usb拔出无影响 */
    bsp_hi6559_reg_read(HI6559_IRQ2_OFFSET, &regvalue);
    if((regvalue & (0x01 << 2)) && hi6559_usb_state_get())
    {
        bsp_hi6559_reg_write(HI6559_IRQ2_OFFSET, 0x04);
    }
    /* 清除所有下电中断寄存器 */
    for(i = 0;i < HI6559_IRQ_REG_NUM; i++)
    {
        bsp_hi6559_reg_read(HI6559_IRQ1_OFFSET + i,&regvalue);
        bsp_hi6559_reg_write(HI6559_IRQ1_OFFSET + i, regvalue);
    }
    /* 清除短路过流中断寄存器,这样过流中断位才能消除 */
    for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++)
    {
        bsp_hi6559_reg_read(HI6559_SCP_RECORD1_OFFSET + i, &regvalue);
        bsp_hi6559_reg_write(HI6559_SCP_RECORD1_OFFSET + i, regvalue);
    }

    /* 屏蔽所有中断 */
    for(i = 0;i < HI6559_IRQ_REG_NUM;i++)
    {
        bsp_hi6559_reg_write(HI6559_IRQ1_MASK_OFFSET + i, 0xff);
    }
    
    /* 中断注册 */
#ifdef CONFIG_MODULE_VIC
    ret = bsp_vic_connect(hi6559_irq_data_st->irq, hi6559_irq_handler,(s32)(hi6559_irq_data_st->irq));
    if (ret < 0) 
    {
        pmic_print_error("unable to connect PMIC HI6559 IRQ!\n");
        goto out;
    }
    ret = bsp_vic_enable(hi6559_irq_data_st->irq);
    if (ret < 0) {
        pmic_print_error("enable PMIC HI6559 IRQ error!\n");
        goto out;
    }
#else
    ret = request_irq((hi6559_irq_data_st->irq), hi6559_irq_handler, IRQF_DISABLED,
            "hi6559_irq", hi6559_irq_data_st);
    if (ret < 0) 
    {
        pmic_print_error("unable to request PMIC HI6559 IRQ!\n");
        goto out;
    }
#endif

    /* 打开所有中断 */
    for(i = 0; i < HI6559_IRQ_REG_NUM; i++)
    {
        bsp_hi6559_reg_write(HI6559_IRQ1_MASK_OFFSET + i, 0x0);
    }
    
    platform_set_drvdata(pdev, hi6559_irq_data_st);
    pmic_print_error("hi6559_irq_probe ok !\n");

    return ret;

out:
    kfree(hi6559_irq_data_st);
    return ret;

}
示例#19
0
文件: main.c 项目: UNwS/rtl8192su
struct r92su *r92su_alloc(struct device *main_dev)
{
	struct r92su *r92su = NULL;
	struct wiphy *wiphy;
	int err;

	wiphy = wiphy_new(&r92su_cfg80211_ops, sizeof(struct r92su));
	if (!wiphy) {
		err = -ENOMEM;
		goto err_out;
	}

	r92su = wiphy_priv(wiphy);
	r92su->wdev.wiphy = wiphy;
	mutex_init(&r92su->lock);
	spin_lock_init(&r92su->rx_path);

	if (modparam_noht)
		r92su->disable_ht = true;

	INIT_LIST_HEAD(&r92su->sta_list);
	/* Note: The sta_lock is only needed, if an entry in the
	 * station list is updated. The station data itself is
	 * protected by RCU.
	 */
	spin_lock_init(&r92su->sta_lock);

	set_wiphy_dev(r92su->wdev.wiphy, main_dev);
	r92su->wdev.iftype = NL80211_IFTYPE_STATION;

	wiphy->privid = r92su_priv_id;
	wiphy->mgmt_stypes = r92su_default_mgmt_stypes;
	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
				 BIT(NL80211_IFTYPE_ADHOC) |
				 BIT(NL80211_IFTYPE_MONITOR);
	wiphy->max_scan_ssids = 1;
	wiphy->max_scan_ie_len = 256;
	wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
	wiphy->cipher_suites = r92su_chiper_suites;
	wiphy->n_cipher_suites = ARRAY_SIZE(r92su_chiper_suites);
	wiphy->bss_priv_size = sizeof(struct r92su_bss_priv);

	init_completion(&r92su->scan_done);
	init_llist_head(&r92su->add_bss_list);
	INIT_WORK(&r92su->add_bss_work, r92su_bss_add_work);
	INIT_WORK(&r92su->connect_bss_work, r92su_bss_connect_work);
	INIT_WORK(&r92su->disconnect_work, r92su_disconnect_work);
	INIT_DELAYED_WORK(&r92su->survey_done_work, r92su_survey_done_work);
	r92su_hw_init(r92su);

	r92su->wq = create_singlethread_workqueue(R92SU_DRVNAME);
	if (!r92su->wq) {
		err = -ENOMEM;
		goto err_out;
	}

	return r92su;

err_out:
	r92su_unregister(r92su);
	r92su_free(r92su);
	return ERR_PTR(err);
}
示例#20
0
/**
 * gserial_setup - initialize TTY driver for one or more ports
 * @g: gadget to associate with these ports
 * @count: how many ports to support
 * Context: may sleep
 *
 * The TTY stack needs to know in advance how many devices it should
 * plan to manage.  Use this call to set up the ports you will be
 * exporting through USB.  Later, connect them to functions based
 * on what configuration is activated by the USB host; and disconnect
 * them as appropriate.
 *
 * An example would be a two-configuration device in which both
 * configurations expose port 0, but through different functions.
 * One configuration could even expose port 1 while the other
 * one doesn't.
 *
 * Returns negative errno or zero.
 */
int gserial_setup(struct usb_gadget *g, unsigned count)
{
	unsigned			i;
	struct usb_cdc_line_coding	coding;
	int				status;

	if (count == 0 || count > N_PORTS)
		return -EINVAL;

	gs_tty_driver = alloc_tty_driver(count);
	if (!gs_tty_driver)
		return -ENOMEM;

	gs_tty_driver->owner = THIS_MODULE;
	gs_tty_driver->driver_name = "g_serial";
	gs_tty_driver->name = PREFIX;
	/* uses dynamically assigned dev_t values */

	gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
	gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
	gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
				| TTY_DRIVER_RESET_TERMIOS;
	gs_tty_driver->init_termios = tty_std_termios;

	/* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
	 * MS-Windows.  Otherwise, most of these flags shouldn't affect
	 * anything unless we were to actually hook up to a serial line.
	 */
	gs_tty_driver->init_termios.c_cflag =
			B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	gs_tty_driver->init_termios.c_ispeed = 9600;
	gs_tty_driver->init_termios.c_ospeed = 9600;

	coding.dwDTERate = __constant_cpu_to_le32(480000000);
	coding.bCharFormat = USB_CDC_1_STOP_BITS;
	coding.bParityType = USB_CDC_NO_PARITY;
	coding.bDataBits = 8;

	tty_set_operations(gs_tty_driver, &gs_tty_ops);

	gserial_wq = create_singlethread_workqueue("k_gserial");
	if (!gserial_wq) {
		status = -ENOMEM;
		goto fail;
	}

	/* make devices be openable */
	for (i = 0; i < count; i++) {
		mutex_init(&ports[i].lock);
		status = gs_port_alloc(i, &coding);
		if (status) {
			count = i;
			goto fail;
		}
	}
	n_ports = count;

	/* export the driver ... */
	status = tty_register_driver(gs_tty_driver);
	if (status) {
		put_tty_driver(gs_tty_driver);
		pr_err("%s: cannot register, err %d\n",
				__func__, status);
		goto fail;
	}

	/* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
	for (i = 0; i < count; i++) {
		struct device	*tty_dev;

		tty_dev = tty_register_device(gs_tty_driver, i, &g->dev);
		if (IS_ERR(tty_dev))
			pr_warning("%s: no classdev for port %d, err %ld\n",
				__func__, i, PTR_ERR(tty_dev));
	}

	pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
			count, (count == 1) ? "" : "s");

	return status;
fail:
	while (count--)
		kfree(ports[count].port);
	destroy_workqueue(gserial_wq);
	put_tty_driver(gs_tty_driver);
	gs_tty_driver = NULL;
	return status;
}
示例#21
0
static int hdmi_probe(struct snd_soc_codec *codec)
{
	struct platform_device *pdev = to_platform_device(codec->dev);
	struct resource *hdmi_rsrc;
	int ret = 0;

	snd_soc_codec_set_drvdata(codec, &hdmi_data);

	hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!hdmi_rsrc) {
		dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n");
		ret = -EINVAL;
		goto res_err;
	}


	hdmi_data.oh = omap_hwmod_lookup("dss_hdmi");

	if (!hdmi_data.oh) {
		dev_err(&pdev->dev, "can't find omap_hwmod for hdmi\n");
		ret = -ENODEV;
		goto res_err;
	}

	/* Base address taken from platform */
	hdmi_data.ip_data.base_wp = ioremap(hdmi_rsrc->start,
					resource_size(hdmi_rsrc));

	if (!hdmi_data.ip_data.base_wp) {
		dev_err(&pdev->dev, "can't ioremap WP\n");
		ret = -ENOMEM;
		goto res_err;
	}

	hdmi_data.ip_data.hdmi_core_sys_offset = HDMI_CORE_SYS;
	hdmi_data.ip_data.hdmi_core_av_offset = HDMI_CORE_AV;
	hdmi_data.ip_data.hdmi_pll_offset = HDMI_PLLCTRL;
	hdmi_data.ip_data.hdmi_phy_offset = HDMI_PHY;

	hdmi_data.dssdev = omap_dss_find_device(NULL, hdmi_audio_match);

	if (!hdmi_data.dssdev) {
		dev_err(&pdev->dev, "can't find HDMI device\n");
		ret = -ENODEV;
		goto dssdev_err;
	}

	hdmi_data.notifier.notifier_call = hdmi_audio_notifier_callback;
	blocking_notifier_chain_register(&hdmi_data.dssdev->state_notifiers,
			&hdmi_data.notifier);

	hdmi_data.workqueue = create_singlethread_workqueue("hdmi-codec");

	INIT_DELAYED_WORK(&hdmi_data.delayed_work, hdmi_audio_work);

	return 0;

dssdev_err:
	iounmap(hdmi_data.ip_data.base_wp);
res_err:
	return ret;

}
/*====================================
 * character device file operations
 *===================================*/
static int lgx_open(struct inode* inode, struct file* filp)
{
	struct inno_lgx* lgx;
	unsigned int lg_num = iminor(inode);
	int i;                    
	inno_msg("+++++++++++++++++++++++++++++++++++++++++");
	inno_msg("CMMB IF208 open [%s]", lgx_ids_table[lg_num].name);
	inno_msg("+++++++++++++++++++++++++++++++++++++++++");

	if(lg_num >= LG_END){
		inno_err("minor error, should be [%d-%d]", LG0, UAM);
		return -1;
	}

	if(g_inno_dev.lgxs[lg_num]){ 	//already opened, just increase reference count
		down(&g_inno_dev.lgxs[lg_num]->sem);
		g_inno_dev.lgxs[lg_num]->use_count++;                           
		//g_inno_dev.lgxs[lg_num]->use_count = 1;
		inno_msg("reopen");
		up(&g_inno_dev.lgxs[lg_num]->sem);
		filp->private_data = g_inno_dev.lgxs[lg_num];
		return 0;
	}	

	/* OK, it's not open, Create it */
	lgx = (struct inno_lgx*)kmalloc(sizeof(struct inno_lgx), GFP_KERNEL);
	if(!lgx){
		inno_err("kmalloc lgx ==NULL");
		return -1;
	}
	else
		memset(lgx, 0, sizeof(struct inno_lgx));

	for(i=0; lgx_ids_table[i].name!=NULL; i++){
		if(lg_num == lgx_ids_table[i].id){
			lgx->ids = &lgx_ids_table[i];
			break;
		}
	}
	//allocat memory for get mfs file
	if (lgx_alloc_buffer(lgx)){
		kfree(lgx);
		lgx = NULL;
		return -1;
	}
	
//**********  global flag set ******************//
	cancle_wait = 0;                                   //xingyu 0328 add   solve poll wait
	flag_memset = 0;                                // memset the bitstream buffer
	once_closeirq=0;                                 // control close irq

	lgx->use_count = 1;
	sema_init(&lgx->sem,1);
	init_waitqueue_head(&lgx->read_wait);
#ifndef UAM_COMPLETE
	init_waitqueue_head(&lgx->uam_wait);
#else
//	if(lg_num==2){                // open uam
	if(strcmp(lgx->ids->name, "UAM") == 0){
	//if(lgx->ids->name =="UAM") {                          //xing 0922  use uamcomplete function
		inno_msg("uam_complete init");
		init_completion(&lgx->uam_complete);
	}
#endif
	g_inno_dev.lgxs[lg_num] = lgx;

	//inno_msg("open file for inno_num: %d\n", lg_num);
	if( innodev_startup(&g_inno_dev) ){
		inno_err("startup fail, free lgx");
		g_inno_dev.lgxs[lg_num] = NULL;
		lgx_free_buffer(lgx);
		kfree(lgx);
		return -1;
	}
	filp->private_data = lgx;
#ifdef _check_block_time            //printk rxbuf
	static int onetime =0;
	if (onetime ==0){                                     // when open file create better than module init for time
		onetime++;
		inno_msg("use thread to watch the block time");
		check_block_wq = create_singlethread_workqueue("siano work wq");
		INIT_WORK(&check_block_work,check_block_thread);
		queue_work(check_block_wq,&check_block_work);
	}
#endif
       inno_msg("use single thread for workqueue");
	return 0;
}
static int serial_omap_probe(struct platform_device *pdev)
{
	struct uart_omap_port	*up;
	struct resource		*mem, *irq;
	struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data;
	int ret;

	if (pdev->dev.of_node)
		omap_up_info = of_get_uart_port_info(&pdev->dev);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "no mem resource?\n");
		return -ENODEV;
	}

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!irq) {
		dev_err(&pdev->dev, "no irq resource?\n");
		return -ENODEV;
	}

	if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
				pdev->dev.driver->name)) {
		dev_err(&pdev->dev, "memory region already claimed\n");
		return -EBUSY;
	}

	if (gpio_is_valid(omap_up_info->DTR_gpio) &&
	    omap_up_info->DTR_present) {
		ret = gpio_request(omap_up_info->DTR_gpio, "omap-serial");
		if (ret < 0)
			return ret;
		ret = gpio_direction_output(omap_up_info->DTR_gpio,
					    omap_up_info->DTR_inverted);
		if (ret < 0)
			return ret;
	}

	up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL);
	if (!up)
		return -ENOMEM;

	if (gpio_is_valid(omap_up_info->DTR_gpio) &&
	    omap_up_info->DTR_present) {
		up->DTR_gpio = omap_up_info->DTR_gpio;
		up->DTR_inverted = omap_up_info->DTR_inverted;
	} else
		up->DTR_gpio = -EINVAL;
	up->DTR_active = 0;

	up->dev = &pdev->dev;
	up->port.dev = &pdev->dev;
	up->port.type = PORT_OMAP;
	up->port.iotype = UPIO_MEM;
	up->port.irq = irq->start;

	up->port.regshift = 2;
	up->port.fifosize = 64;
	up->port.ops = &serial_omap_pops;

	if (pdev->dev.of_node)
		up->port.line = of_alias_get_id(pdev->dev.of_node, "serial");
	else
		up->port.line = pdev->id;

	if (up->port.line < 0) {
		dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n",
								up->port.line);
		ret = -ENODEV;
		goto err_port_line;
	}

	up->pins = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR(up->pins)) {
		dev_warn(&pdev->dev, "did not get pins for uart%i error: %li\n",
			 up->port.line, PTR_ERR(up->pins));
		up->pins = NULL;
	}

	sprintf(up->name, "OMAP UART%d", up->port.line);
	up->port.mapbase = mem->start;
	up->port.membase = devm_ioremap(&pdev->dev, mem->start,
						resource_size(mem));
	if (!up->port.membase) {
		dev_err(&pdev->dev, "can't ioremap UART\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	up->port.flags = omap_up_info->flags;
	up->port.uartclk = omap_up_info->uartclk;
	if (!up->port.uartclk) {
		up->port.uartclk = DEFAULT_CLK_SPEED;
		dev_warn(&pdev->dev, "No clock speed specified: using default:"
						"%d\n", DEFAULT_CLK_SPEED);
	}

	up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
	up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
	pm_qos_add_request(&up->pm_qos_request,
		PM_QOS_CPU_DMA_LATENCY, up->latency);
	serial_omap_uart_wq = create_singlethread_workqueue(up->name);
	INIT_WORK(&up->qos_work, serial_omap_uart_qos_work);

	platform_set_drvdata(pdev, up);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_autosuspend_delay(&pdev->dev,
			omap_up_info->autosuspend_timeout);

	pm_runtime_irq_safe(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	omap_serial_fill_features_erratas(up);

	ui[up->port.line] = up;
	serial_omap_add_console_port(up);

	ret = uart_add_one_port(&serial_omap_reg, &up->port);
	if (ret != 0)
		goto err_add_port;

	pm_runtime_mark_last_busy(up->dev);
	pm_runtime_put_autosuspend(up->dev);
	return 0;

err_add_port:
	pm_runtime_put(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
err_ioremap:
err_port_line:
	dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
				pdev->id, __func__, ret);
	return ret;
}
示例#24
0
static int __devinit ezx_pcap_probe(struct spi_device *spi)
{
	struct pcap_platform_data *pdata = spi->dev.platform_data;
	struct pcap_chip *pcap;
	int i, adc_irq;
	int ret = -ENODEV;

	/* platform data is required */
	if (!pdata)
		goto ret;

	pcap = kzalloc(sizeof(*pcap), GFP_KERNEL);
	if (!pcap) {
		ret = -ENOMEM;
		goto ret;
	}

	mutex_init(&pcap->io_mutex);
	mutex_init(&pcap->adc_mutex);
	INIT_WORK(&pcap->isr_work, pcap_isr_work);
	INIT_WORK(&pcap->msr_work, pcap_msr_work);
	dev_set_drvdata(&spi->dev, pcap);

	/* setup spi */
	spi->bits_per_word = 32;
	spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0);
	ret = spi_setup(spi);
	if (ret)
		goto free_pcap;

	pcap->spi = spi;

	/* setup irq */
	pcap->irq_base = pdata->irq_base;
	pcap->workqueue = create_singlethread_workqueue("pcapd");
	if (!pcap->workqueue) {
		ret = -ENOMEM;
		dev_err(&spi->dev, "can't create pcap thread\n");
		goto free_pcap;
	}

	/* redirect interrupts to AP, except adcdone2 */
	if (!(pdata->config & PCAP_SECOND_PORT))
		ezx_pcap_write(pcap, PCAP_REG_INT_SEL,
					(1 << PCAP_IRQ_ADCDONE2));

	/* setup irq chip */
	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) {
		irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq);
		irq_set_chip_data(i, pcap);
#ifdef CONFIG_ARM
		set_irq_flags(i, IRQF_VALID);
#else
		irq_set_noprobe(i);
#endif
	}

	/* mask/ack all PCAP interrupts */
	ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT);
	ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER);
	pcap->msr = PCAP_MASK_ALL_INTERRUPT;

	irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING);
	irq_set_handler_data(spi->irq, pcap);
	irq_set_chained_handler(spi->irq, pcap_irq_handler);
	irq_set_irq_wake(spi->irq, 1);

	/* ADC */
	adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
					PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);

	ret = request_irq(adc_irq, pcap_adc_irq, 0, "ADC", pcap);
	if (ret)
		goto free_irqchip;

	/* setup subdevs */
	for (i = 0; i < pdata->num_subdevs; i++) {
		ret = pcap_add_subdev(pcap, &pdata->subdevs[i]);
		if (ret)
			goto remove_subdevs;
	}

	/* board specific quirks */
	if (pdata->init)
		pdata->init(pcap);

	return 0;

remove_subdevs:
	device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
/* free_adc: */
	free_irq(adc_irq, pcap);
free_irqchip:
	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
		irq_set_chip_and_handler(i, NULL, NULL);
/* destroy_workqueue: */
	destroy_workqueue(pcap->workqueue);
free_pcap:
	kfree(pcap);
ret:
	return ret;
}
示例#25
0
//------------------------------------------------------------------------------------
static int gp2a_opt_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int err = -1;
	int i;
	u8 value;	
#if USE_INTERRUPT
	int irq;
#endif
	int ret;

	struct gp2a_data *gp2a;

	printk("GP2A PROBE!\n");

	if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return err;	

	/* OK. For now, we presume we have a valid client. We now create the
	client structure, even though we cannot fill it completely yet. */
	if (!(gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL)))
	{
		err = -ENOMEM;
		goto exit;
	}
	
	i2c_set_clientdata(client, gp2a);
	opt_i2c_client = client;

   	if(opt_i2c_client == NULL)
	{
		pr_err("opt_probe failed : i2c_client is NULL\n"); 
		return -ENODEV;
	}
	else
		printk("opt_i2c_client : (%s)\n",opt_i2c_client->name);

	printk("[%s] slave addr = %x\n", __func__, client->addr);

#ifdef LIGHT_SENSOR_ENABLED
	/* hrtimer Settings */
	hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->timer.function = gp2a_timer_func;

    gp2a_wq = create_singlethread_workqueue("gp2a_wq");
    if (!gp2a_wq)
    {
		printk("create_singlethread_workqueue error \r\n");
		return -ENOMEM;
    }
    INIT_WORK(&gp2a->work_light, gp2a_work_func_light);
    
	err = misc_register(&light_device);
	if(err) {
		pr_err(KERN_ERR "misc_register failed - light\n");
	}

	/* set sysfs for light sensor */
	lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(lightsensor_class))
		pr_err("Failed to create class(lightsensor)!\n");

	switch_cmd_dev = device_create(lightsensor_class, NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(switch_cmd_dev))
		pr_err("Failed to create device(switch_cmd_dev)!\n");

	if (device_create_file(switch_cmd_dev, &dev_attr_lightsensor_file_cmd) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_lightsensor_file_cmd.attr.name);
  
	if (device_create_file(switch_cmd_dev, &dev_attr_lightsensor_file_state) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_lightsensor_file_state.attr.name);
	dev_set_drvdata(switch_cmd_dev,gp2a);

	gp2a_off(gp2a,LIGHT);
#endif

	/* Input device Settings */
	if(USE_INPUT_DEVICE)
	{
		gp2a->input_dev = input_allocate_device();
		if (gp2a->input_dev == NULL) 
		{
			pr_err("Failed to allocate input device\n");
			return -ENOMEM;
		}
		gp2a->input_dev->name = "proximity";
	
		set_bit(EV_SYN,gp2a->input_dev->evbit);
		set_bit(EV_ABS,gp2a->input_dev->evbit);
		
        input_set_abs_params(gp2a->input_dev, ABS_DISTANCE, 0, 1, 0, 0);
		
	
		err = input_register_device(gp2a->input_dev);
		if (err) 
		{
			pr_err("Unable to register %s input device\n", gp2a->input_dev->name);
			input_free_device(gp2a->input_dev);
			kfree(gp2a);
			return -1;
		}

	}

#if USE_INTERRUPT
	/* WORK QUEUE Settings */
	INIT_DELAYED_WORK(&gp2a->work_prox, gp2a_work_func_prox);
	gprintk("Workqueue Settings complete\n");
#endif

	/* misc device Settings */
	err = misc_register(&proximity_device);
	if(err) {
		pr_err(KERN_ERR "misc_register failed - prox \n");
	}

	/* wake lock init */
//	wake_lock_init(&prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock");
//#if !defined(CONFIG_MACH_RANT3)
	wake_lock_init(&prx_irq_wake_lock, WAKE_LOCK_SUSPEND, "prx_irq_wake_lock");
//#endif

	/* set sysfs for light sensor */
	proxsensor_class = class_create(THIS_MODULE, "proxsensor");
	if (IS_ERR(proxsensor_class))
		pr_err("Failed to create class(proxsensor)!\n");

	switch_cmd_dev = device_create(proxsensor_class, NULL, 0, NULL, "switch_cmd");	
	if (device_create_file(switch_cmd_dev, &dev_attr_proxsensor_file_state) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_proxsensor_file_state.attr.name);

#if defined(CONFIG_MACH_RANT3)
	if (device_create_file(switch_cmd_dev, &dev_attr_proxsensor_onoff_ctrl) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_proxsensor_onoff_ctrl.attr.name);
#endif

	dev_set_drvdata(switch_cmd_dev,gp2a);
	
	/* ktime init */
	timeA = ktime_set(0,0);
	timeB = ktime_set(0,0);

	/* GP2A Regs INIT SETTINGS */
	value = 0x00;
	err = opt_i2c_write((u8)(REGS_OPMOD),&value);
	if(err == -EIO) // NC gp2a
	    goto exit_kfree;
	    
/*	
	for(i=1;i<5;i++)
	{
		opt_i2c_write((u8)(i),&gp2a_original_image[i]);
	}
*/
	mdelay(2);
#if USE_INTERRUPT
	/* INT Settings */	
	irq = gpio_to_irq(GPIO_PS_VOUT);
	gp2a->irq = -1;
	set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);

	err = request_irq(irq, gp2a_irq_handler, IRQF_DISABLED, "gp2a_int", gp2a);
	if (err)
	{
		printk("[GP2A] request_irq failed for gp2a\n");
		goto exit_kfree;
	}

	printk("[GP2A] register irq = %d\n",irq);
	err = set_irq_wake(irq, 1);
	printk("[GP2A] register wakeup source = %d\n",err);
	if (err) 
		printk("[GP2A] register wakeup source failed\n");
	
	gp2a->irq = irq;
	gprintk("INT Settings complete\n");
#endif

	// maintain power-down mode before using sensor
	ret = gp2a_off(gp2a,ALL);
#if !defined(CONFIG_MACH_RANT3)
	if(ret==0) proximity_enable = 0;
#endif

	printk("gp2a_opt_probe is OK!!\n");
	return 0;
	
exit_kfree:
	printk("gp2a_opt_probe is exit_kfree!!\n");
	kfree(gp2a);
exit:
	return err;
}
示例#26
0
static int jpeg_probe(struct platform_device *pdev)
{
	struct jpeg_dev *dev;
	struct video_device *vfd;
	struct resource *res;
	int ret;

	/* global structure */
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&pdev->dev, "%s: not enough memory\n",
			__func__);
		ret = -ENOMEM;
		goto err_alloc;
	}

	dev->plat_dev = pdev;

	/* setup jpeg control */
	ret = jpeg_setup_controller(dev);
	if (ret) {
		jpeg_err("failed to setup controller\n");
		goto err_setup;
	}

	/* memory region */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		jpeg_err("failed to get jpeg memory region resource\n");
		ret = -ENOENT;
		goto err_res;
	}

	res = request_mem_region(res->start, resource_size(res),
				pdev->name);
	if (!res) {
		jpeg_err("failed to request jpeg io memory region\n");
		ret = -ENOMEM;
		goto err_region;
	}

	/* ioremap */
	dev->reg_base = ioremap(res->start, resource_size(res));
	if (!dev->reg_base) {
		jpeg_err("failed to remap jpeg io region\n");
		ret = -ENOENT;
		goto err_map;
	}

	/* irq */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		jpeg_err("failed to request jpeg irq resource\n");
		ret = -ENOENT;
		goto err_irq;
	}

	dev->irq_no = res->start;
	ret = request_irq(dev->irq_no, (void *)jpeg_irq,
			IRQF_DISABLED, pdev->name, dev);
	if (ret != 0) {
		jpeg_err("failed to jpeg request irq\n");
		ret = -ENOENT;
		goto err_irq;
	}

	/* clock */
	dev->clk = clk_get(&pdev->dev, "jpeg");
	if (IS_ERR(dev->clk)) {
		jpeg_err("failed to find jpeg clock source\n");
		ret = -ENOENT;
		goto err_clk;
	}

#ifdef CONFIG_PM_RUNTIME
#ifndef CONFIG_CPU_EXYNOS5250
	pm_runtime_enable(&pdev->dev);
#endif
#endif

	/* clock enable */
	clk_enable(dev->clk);

	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
	if (ret) {
		v4l2_err(&dev->v4l2_dev, "Failed to register v4l2 device\n");
		goto err_v4l2;
	}

	/* encoder */
	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
		ret = -ENOMEM;
		goto err_vd_alloc_enc;
	}

	*vfd = jpeg_enc_videodev;
	vfd->ioctl_ops = get_jpeg_enc_v4l2_ioctl_ops();
	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 12);
	if (ret) {
		v4l2_err(&dev->v4l2_dev,
			 "%s(): failed to register video device\n", __func__);
		video_device_release(vfd);
		goto err_vd_alloc_enc;
	}
	v4l2_info(&dev->v4l2_dev,
		"JPEG driver is registered to /dev/video%d\n", vfd->num);

	dev->vfd_enc = vfd;
	dev->m2m_dev_enc = v4l2_m2m_init(&jpeg_m2m_enc_ops);
	if (IS_ERR(dev->m2m_dev_enc)) {
		v4l2_err(&dev->v4l2_dev,
			"failed to initialize v4l2-m2m device\n");
		ret = PTR_ERR(dev->m2m_dev_enc);
		goto err_m2m_init_enc;
	}
	video_set_drvdata(vfd, dev);

	/* decoder */
	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
		ret = -ENOMEM;
		goto err_vd_alloc_dec;
	}

	*vfd = jpeg_dec_videodev;
	vfd->ioctl_ops = get_jpeg_dec_v4l2_ioctl_ops();
	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 11);
	if (ret) {
		v4l2_err(&dev->v4l2_dev,
			 "%s(): failed to register video device\n", __func__);
		video_device_release(vfd);
		goto err_vd_alloc_dec;
	}
	v4l2_info(&dev->v4l2_dev,
		"JPEG driver is registered to /dev/video%d\n", vfd->num);

	dev->vfd_dec = vfd;
	dev->m2m_dev_dec = v4l2_m2m_init(&jpeg_m2m_dec_ops);
	if (IS_ERR(dev->m2m_dev_dec)) {
		v4l2_err(&dev->v4l2_dev,
			"failed to initialize v4l2-m2m device\n");
		ret = PTR_ERR(dev->m2m_dev_dec);
		goto err_m2m_init_dec;
	}
	video_set_drvdata(vfd, dev);

	platform_set_drvdata(pdev, dev);

#ifdef CONFIG_VIDEOBUF2_CMA_PHYS
	dev->vb2 = &jpeg_vb2_cma;
#elif defined(CONFIG_VIDEOBUF2_ION)
	dev->vb2 = &jpeg_vb2_ion;
#endif
	dev->alloc_ctx = dev->vb2->init(dev);

	if (IS_ERR(dev->alloc_ctx)) {
		ret = PTR_ERR(dev->alloc_ctx);
		goto err_video_reg;
	}

#ifdef CONFIG_BUSFREQ_OPP
	/* To lock bus frequency in OPP mode */
	dev->bus_dev = dev_get("exynos-busfreq");
#endif

	dev->watchdog_workqueue = create_singlethread_workqueue(JPEG_NAME);
	INIT_WORK(&dev->watchdog_work, jpeg_watchdog_worker);
	atomic_set(&dev->watchdog_cnt, 0);
	init_timer(&dev->watchdog_timer);
	dev->watchdog_timer.data = (unsigned long)dev;
	dev->watchdog_timer.function = jpeg_watchdog;

	/* clock disable */
	clk_disable(dev->clk);

	return 0;

err_video_reg:
	v4l2_m2m_release(dev->m2m_dev_dec);
err_m2m_init_dec:
	video_unregister_device(dev->vfd_dec);
	video_device_release(dev->vfd_dec);
err_vd_alloc_dec:
	v4l2_m2m_release(dev->m2m_dev_enc);
err_m2m_init_enc:
	video_unregister_device(dev->vfd_enc);
	video_device_release(dev->vfd_enc);
err_vd_alloc_enc:
	v4l2_device_unregister(&dev->v4l2_dev);
err_v4l2:
	clk_disable(dev->clk);
	clk_put(dev->clk);
err_clk:
	free_irq(dev->irq_no, NULL);
err_irq:
	iounmap(dev->reg_base);
err_map:
err_region:
	kfree(res);
err_res:
	mutex_destroy(&dev->lock);
err_setup:
	kfree(dev);
err_alloc:
	return ret;

}
示例#27
0
static int cm3607_prox_probe( struct platform_device* pdev )
{	
	int ret=0;	
;
	
	/*misc device registration*/
    if( (ret = misc_register(&cm3607_misc_device)) < 0 )
    {
        error("cm3607_probe misc_register failed");
        goto ERR_MISC_REG; 	  	
    }
	
	/*Enabling LD016 of MAX8998(PMIC) and setting it to 2.8V*/
	Set_MAX8998_PM_REG(ELDO16, 1);  // enable LDO16
	Set_MAX8998_PM_REG(LDO16, 0x0C);  // Set LDO16 voltage to 2.8V
	
	/*Initialisation of GPIO_PS_OUT of proximity sensor*/
	s3c_gpio_cfgpin(GPIO_PS_OUT, S3C_GPIO_SFN(GPIO_PS_OUT_STATE));
	s3c_gpio_setpull(GPIO_PS_OUT, S3C_GPIO_PULL_NONE);

	/* Allocate driver_data */
	cm3607_data = kzalloc(sizeof(struct cm3607_prox_data),GFP_KERNEL);
	if(!cm3607_data)
	{
		error("kzalloc:allocating driver_data error");
		ret = -ENOMEM;
		goto ERR_MISC_REG;
	} 
	
	/*Input Device Settings*/
	cm3607_data->prox_input_dev = input_allocate_device();
	if (!cm3607_data->prox_input_dev) 
	{
        error("Not enough memory for cm3607_data->prox_input_dev");
        ret = -ENOMEM;
        goto ERR_INPUT_DEV;
    }
	cm3607_data->prox_input_dev->name = "proximity_cm3607";
	set_bit(EV_SYN,cm3607_data->prox_input_dev->evbit);
	set_bit(EV_ABS,cm3607_data->prox_input_dev->evbit);	
	input_set_abs_params(cm3607_data->prox_input_dev, ABS_DISTANCE, 0, 1, 0, 0);
	ret = input_register_device(cm3607_data->prox_input_dev);
    if (ret) 
	{
        error("Failed to register input device");
		input_free_device(cm3607_data->prox_input_dev);
        goto ERR_INPUT_REG;
    }
	debug("Input device settings complete");
	
	/* Workqueue Settings */
    cm3607_wq = create_singlethread_workqueue("cm3607_wq");
    if (!cm3607_wq)
	{
        error("Not enough memory for cm3607_wq");
        ret = -ENOMEM;
        goto ERR_INPUT_REG;
    }	     
    INIT_WORK(&cm3607_data->work_prox, cm3607_prox_work_func);
	debug("Workqueue settings complete");	
	
	/* Setting platform driver data */
	platform_set_drvdata(pdev, cm3607_data);

	cm3607_data->irq = -1;	
	set_irq_type(PROX_INT, IRQ_TYPE_EDGE_FALLING);	
	if( (ret = request_irq(PROX_INT, cm3607_irq_handler,IRQF_DISABLED , "proximity_int", NULL )) )
	{
        error("CM3607 request_irq failed IRQ_NO:%d", PROX_INT);
        goto ERR_INT_REQ;
	} 
	else
		debug("CM3607 request_irq success IRQ_NO:%d", PROX_INT);
	
	cm3607_data->irq = PROX_INT;
	
	/*GPIO_PS_EN Initialisation*/
	if (gpio_is_valid(GPIO_PS_EN)) 
	{
		if (gpio_request(GPIO_PS_EN, "GPJ3"))	
		{
			error("Failed to request GPIO_PS_EN");
			ret =-1;
			goto ERR_GPIO_REQ;
		}
		if(gpio_direction_output(GPIO_PS_EN, GPIO_LEVEL_LOW))
		{
			error("Failed to set output direction GPIO_PS_EN");
			ret=-1;
			goto ERR_GPIO_REQ;
		}		
	}
	else
	{
		error("GPIO_PS_EN is not valid");
		ret =-1;
		goto ERR_GPIO_REQ;
	}
	/*Setting CM3607 proximity sensor in normal operation mode*/
	proximity_mode(1);

	/*Pulling the Interrupt Pin High*/
	s3c_gpio_setpull(GPIO_PS_OUT, S3C_GPIO_PULL_UP);		
	debug("gpio_get_value of GPIO_PS_OUT is %d",gpio_get_value(GPIO_PS_OUT));   //test			
	
	input_report_abs(cm3607_data->prox_input_dev,ABS_DISTANCE,gpio_get_value(GPIO_PS_OUT));
	input_sync(cm3607_data->prox_input_dev);
	mdelay(1);
;
	
	//TEST
	if (device_create_file(cm3607_misc_device.this_device, &dev_attr_prox_value) < 0)
		error("Failed to create device file %s \n", dev_attr_prox_value.attr.name);
	
	return ret;
ERR_GPIO_REQ:	
ERR_INT_REQ:
    destroy_workqueue(cm3607_wq);
	input_unregister_device(cm3607_data->prox_input_dev);
ERR_INPUT_REG:
ERR_INPUT_DEV:
	kfree(cm3607_data);
ERR_MISC_REG:
	return ret;
} 
示例#28
0
static int
lightsensor_probe(struct platform_device *pdev)
{
	struct sensor_data *data = NULL;
	struct input_dev *input_data = NULL;
	int input_registered = 0, sysfs_created = 0;
	int rt;

	data = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
	if (!data) {
		rt = -ENOMEM;
		goto err;
	}
	data->enabled = 0;
	data->delay = SENSOR_DEFAULT_DELAY;
	data->testmode = 0;
#if !defined(CONFIG_KOR_MODEL_SHV_E160S) && !defined(CONFIG_KOR_MODEL_SHV_E160K) && !defined(CONFIG_KOR_MODEL_SHV_E160L)
	data->light_level_state =0;
#endif

	light_workqueue = create_singlethread_workqueue("klightd");
	if (!light_workqueue) {
		rt = -ENOMEM;
		printk(KERN_ERR "%s: Failed to allocate work queue\n", __func__);
		goto err;
	}

	INIT_DELAYED_WORK(&data->work, gp2a_work_func_light);

	input_data = input_allocate_device();
	if (!input_data) {
		rt = -ENOMEM;
		printk(KERN_ERR
			"sensor_probe: Failed to allocate input_data device\n");
		goto err;
	}

	set_bit(EV_ABS, input_data->evbit);
	input_set_capability(input_data, EV_ABS, ABS_X);
	input_set_capability(input_data, EV_ABS, ABS_MISC); 
	input_set_capability(input_data, EV_ABS, ABS_WAKE); /* wake */
	input_set_capability(input_data, EV_ABS, ABS_CONTROL_REPORT); /* enabled/delay */
	input_data->name = SENSOR_NAME;

	rt = input_register_device(input_data);
	if (rt) {
		printk(KERN_ERR
			"sensor_probe: Unable to register input_data device: %s\n",
			input_data->name);
		goto err;
	}
	input_set_drvdata(input_data, data);
	input_registered = 1;

	rt = sysfs_create_group(&input_data->dev.kobj,
				&lightsensor_attribute_group);
	if (rt) {
		printk(KERN_ERR
			"sensor_probe: sysfs_create_group failed[%s]\n",
			input_data->name);
		goto err;
	}
	sysfs_created = 1;
	mutex_init(&data->mutex);
	this_data = input_data;

#if 0 //def MSM_LIGHTSENSOR_ADC_READ  
	lightsensor_rpc_init();
#endif

	data->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(data->lightsensor_class)) {
		pr_err("%s: could not create lightsensor_class\n", __func__);
		goto err;
	}

	data->switch_cmd_dev = device_create(data->lightsensor_class,
						NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(data->switch_cmd_dev)) {
		pr_err("%s: could not create switch_cmd_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(data->switch_cmd_dev,
		&dev_attr_lightsensor_file_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_lightsensor_file_state.attr.name);
		goto err_light_device_create_file;
	}
	dev_set_drvdata(data->switch_cmd_dev, data);
	return 0;

err_light_device_create_file:
	device_destroy(data->lightsensor_class, 0);
err_light_device_create:
	class_destroy(data->lightsensor_class);
err:
	if (data != NULL) {
		if (input_data != NULL) {
			if (sysfs_created) {
				sysfs_remove_group(&input_data->dev.kobj,
						&lightsensor_attribute_group);
			}
			if (input_registered)
				input_unregister_device(input_data);
			else
				input_free_device(input_data);
			input_data = NULL;
		}
		kfree(data);
	}
	return rt;
}
示例#29
0
static int gp2a_i2c_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct input_dev *input_dev;
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = client->dev.platform_data;

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}
	if (!pdata->power || !pdata->light_adc_value) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("%s: failed to alloc memory for module data\n",
		       __func__);
		return -ENOMEM;
	}

	gp2a->pdata = pdata;
	gp2a->i2c_client = client;
	i2c_set_clientdata(client, gp2a);

	/* wake lock init */
	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
		       "prx_wake_lock");
	mutex_init(&gp2a->power_lock);

	ret = gp2a_setup_irq(gp2a);
	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* allocate proximity input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		goto err_input_allocate_device_proximity;
	}
	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	input_dev->name = "proximity_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	gp2a_dbgmsg("registering proximity input device\n");
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_proximity;
	}
	ret = sysfs_create_group(&input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}

	/* hrtimer settings.  we poll for light values using a timer. */
	hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	gp2a->timer.function = gp2a_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	gp2a->wq = create_singlethread_workqueue("gp2a_wq");
	if (!gp2a->wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}
	/* this is the thread function we run on the work queue */
	INIT_WORK(&gp2a->work_light, gp2a_work_func_light);

	/* allocate lightsensor-level input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		ret = -ENOMEM;
		goto err_input_allocate_device_light;
	}
	input_set_drvdata(input_dev, gp2a);
	input_dev->name = "light_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_MISC);
	input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);

	gp2a_dbgmsg("registering lightsensor-level input device\n");
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_light;
	}
	gp2a->light_input_dev = input_dev;
	ret = sysfs_create_group(&input_dev->dev.kobj,
				 &light_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}

	/* set sysfs for light sensor */

	ret = misc_register(&light_device);
	if (ret)
		pr_err(KERN_ERR "misc_register failed - light\n");

	gp2a->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(gp2a->lightsensor_class))
		pr_err("Failed to create class(lightsensor)!\n");

	gp2a->switch_cmd_dev = device_create(gp2a->lightsensor_class,
		NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(gp2a->switch_cmd_dev))
		pr_err("Failed to create device(switch_cmd_dev)!\n");

	if (device_create_file(gp2a->switch_cmd_dev,
		&dev_attr_lightsensor_file_state) < 0)
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_lightsensor_file_state.attr.name);

	dev_set_drvdata(gp2a->switch_cmd_dev, gp2a);

	/* set initial proximity value as 1 */
	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
	input_sync(gp2a->proximity_input_dev);
	goto done;

	/* error, unwind it all */
err_sysfs_create_group_light:
	input_unregister_device(gp2a->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(gp2a->wq);
err_create_workqueue:
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
	free_irq(gp2a->irq, 0);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	mutex_destroy(&gp2a->power_lock);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	return ret;
}
示例#30
0
static int lightsensor_probe(struct platform_device *pdev)
{
	struct sensor_data *data = NULL;
	int rt = -ENXIO;
	unsigned char get_data = 0;

	/* Check I2C communication */
	rt = opt_i2c_read(DATA0_LSB, &get_data, sizeof(get_data));

	if (rt < 0) {
		pr_err("%s failed : threre is no such device.\n", __func__);
		return rt;
	}

	gprintk("probe start!\n");

	data = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
	if (!data) {
		pr_err("%s: failed to alloc memory for module data\n",
		       __func__);
		return -ENOMEM;
	}

	data->enabled = 0;

	data->input_dev = input_allocate_device();
	if (!data->input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		rt = -ENOMEM;
		goto err_input_allocate_device_light;
	}

	input_set_capability(data->input_dev, EV_REL, REL_MISC);
	data->input_dev->name = SENSOR_NAME;

	rt = input_register_device(data->input_dev);
	if (rt) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(data->input_dev);
		goto err_input_register_device_light;
	}
	input_set_drvdata(data->input_dev, data);

	rt = sysfs_create_group(&data->input_dev->dev.kobj,
				&lightsensor_attribute_group);
	if (rt) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}
	mutex_init(&data->mutex);

	data->light_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(data->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(data->light_dev, &dev_attr_lux) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_lux.attr.name);
		goto err_light_device_create_file;
	}
	dev_set_drvdata(data->light_dev, data);

	data->wq = create_singlethread_workqueue("gp2a_wq");
	if (!data->wq) {
		rt = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_DELAYED_WORK(&data->work, gp2a_work_func_light);

	/* set platdata */
	platform_set_drvdata(pdev, data);

	gprintk("probe success!\n");

	goto done;

/* error, unwind it all */
err_create_workqueue:
	device_remove_file(data->light_dev, &dev_attr_lux);
err_light_device_create_file:
	sensors_classdev_unregister(data->light_dev);
err_light_device_create:
	mutex_destroy(&data->mutex);
	sysfs_remove_group(&data->input_dev->dev.kobj,
			   &lightsensor_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(data->input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	kfree(data);

done:
	return rt;
}