void htc_mdm2ap_wakeup_irq_enable_disable(bool enable)
{
	//return if no wakeup gpio
	if (!mdm_drv || mdm_drv->mdm2ap_wakeup_gpio == 0 || mdm_drv->mdm_wakeup_irq == 0)
		return;

	if (mdm2ap_wakeup_irq_enabled != enable)
	{
		if ( get_radio_flag() & 0x0001 )
			pr_info("%s(%d)\n", __func__, enable);

		if (enable)
		{
			enable_irq_wake(mdm_drv->mdm_wakeup_irq);
			enable_irq(mdm_drv->mdm_wakeup_irq);
		}
		else
		{
			disable_irq_wake(mdm_drv->mdm_wakeup_irq);
			disable_irq_nosync(mdm_drv->mdm_wakeup_irq);
		}
		mdm2ap_wakeup_irq_enabled = enable;
	}

	if ( get_radio_flag() & 0x0001 )
		pr_info("dump_gpio: %s\t= %d\n", "MDM2AP_WAKEUP", gpio_get_value(mdm_drv->mdm2ap_wakeup_gpio));
}
Example #2
0
static int __init bridge_init(void)
{
	int	ret;

	/* ++SSD_RIL */
	if (get_radio_flag() & 0x20000)
		usb_diag_enable = true;
	/* --SSD_RIL */
	/* ++SSD_RIL:USB PM DEBUG */
	if (get_radio_flag() & 0x0008)
		usb_pm_debug_enabled = true;
	/* --SSD_RIL */
	ret = usb_register(&bridge_driver);
	if (ret) {
		err("%s: unable to register mdm_bridge driver", __func__);
		return ret;
	}

	bridge_wq  = create_singlethread_workqueue("mdm_bridge");
	if (!bridge_wq) {
		usb_deregister(&bridge_driver);
		pr_err("%s: Unable to create workqueue:bridge\n", __func__);
		return -ENOMEM;
	}

	data_bridge_debugfs_init();

	return 0;
}
static bool is_smlog_enabled(void)
{
	if(boot_mode == APP_IN_HLOS){
		if(is_ut_rom()){
			if(get_radio_flag() & RADIO_SMLOG_FLAG)
				return false;
			else
				return true;
		}else if(get_radio_flag() & RADIO_SMLOG_FLAG)
			return true;
		else
			return false;
	}else
		return false;
}
Example #4
0
int rmnet_usb_ctrl_start_rx(struct rmnet_ctrl_udev *dev)
{
	int	retval = 0;

	mutex_lock(&dev->udev_lock);
	if (!dev->inturb->anchor) {
		usb_anchor_urb(dev->inturb, &dev->rx_submitted);
		retval = usb_submit_urb(dev->inturb, GFP_KERNEL);
		if (retval < 0) {
			usb_unanchor_urb(dev->inturb);
			if (retval != -ENODEV)
				pr_err("%s Intr submit %d\n", __func__, retval);
		}

#ifdef CONFIG_QCT_9K_MODEM
		if (get_radio_flag() & RADIO_FLAG_MORE_LOG) {
			if (dev && dev->intf) {
				dev_info(&(dev->intf->dev), "%s submit dev->inturb:0x%p, retval:%x\n", __func__, dev->inturb, retval);
			}
		}
#endif
	}
	mutex_unlock(&dev->udev_lock);

	return retval;
}
static void msm8916_add_usb_devices(void)
{
	int mode = board_mfg_mode();
	android_usb_pdata.serial_number = board_serialno();

	if (mode != 0) {
		android_usb_pdata.nluns = 1;
		android_usb_pdata.cdrom_lun = 0x0;
	}

	if ((!(get_radio_flag() & BIT(17))) && (mode == MFG_MODE_MFGKERNEL || mode == MFG_MODE_MFGKERNEL_DIAG58)) {
		android_usb_pdata.fserial_init_string = "tty,tty:autobot,tty:serial,tty:autobot,tty:acm";
	}
#ifdef CONFIG_MACH_A11_UL
	android_usb_pdata.product_id = 0x05fd;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x0652;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x0653;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x0654;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x0655;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x05F5;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x05F6;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x05F7;
#elif defined(CONFIG_MACH_DUMMY)
	android_usb_pdata.product_id = 0x05F8;
#endif
	platform_device_register(&android_usb_device);
}
int get_ap2mdm_sw_bc5_status(void)
{
	mdm_drv->ap2mdm_sw_bc5_status = gpio_get_value(mdm_drv->ap2mdm_sw_bc5_gpio);
	if ( get_radio_flag() & 0x0008 )
		pr_info("%s dump_gpio: %s\t= %d\n", __func__, "AP2MDM_SW_BC5", mdm_drv->ap2mdm_sw_bc5_status);
	return mdm_drv->ap2mdm_sw_bc5_status;
}
static irqreturn_t mdm_errfatal(int irq, void *dev_id)
{
	extern unsigned int HTC_HSIC_PHY_FOOTPRINT;	//HTC

	pr_debug("%s: mdm got errfatal interrupt\n", __func__);

	#ifdef HTC_DEBUG_USB_PHY_POWER_ON_STUCK
	pr_info("HTC_HSIC_PHY_FOOTPRINT(%d)\n", HTC_HSIC_PHY_FOOTPRINT);	//HTC
	#endif //HTC_DEBUG_USB_PHY_POWER_ON_STUCK

	if ( get_radio_flag() & 0x0001 ) {
		trace_printk("%s: mdm got errfatal interrupt\n", __func__);
		tracing_off();
	}

	if (mdm_drv->mdm_ready &&
		(gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1) && !device_ehci_shutdown) {

		//++SSD_RIL: set mdm_drv->mdm_ready before restart modem
		mdm_drv->mdm_ready = 0;
		//--SSD_RIL

		//HTC_Kris+++
		mdm_in_fatal_handler = true;
		mdm_is_alive = false;
		//HTC_Kris---

		pr_debug("%s: scheduling work now\n", __func__);
		queue_work(mdm_queue, &mdm_fatal_work);
	}
	return IRQ_HANDLED;
}
static int rmnet_usb_resume(struct usb_interface *iface)
{
	int			retval = 0;
	int			oldstate;
	struct usbnet		*unet;
	struct rmnet_ctrl_dev	*dev;

	//htc_dbg
	if (get_radio_flag() & 0x0001)
	pr_info("%s intf %p\n", __func__, iface);
	unet = usb_get_intfdata(iface);
	if (!unet) {
		pr_err("%s:data device not found\n", __func__);
		retval = -ENODEV;
		goto fail;
	}

	dev = (struct rmnet_ctrl_dev *)unet->data[1];
	if (!dev) {
		dev_err(&iface->dev, "%s: ctrl device not found\n", __func__);
		retval = -ENODEV;
		goto fail;
	}
	oldstate = iface->dev.power.power_state.event;
	iface->dev.power.power_state.event = PM_EVENT_ON;

	retval = usbnet_resume(iface);
	if (!retval) {
		if (oldstate & PM_EVENT_SUSPEND)
			retval = rmnet_usb_ctrl_start(dev);
	}
fail:
	return retval;
}
Example #9
0
static void mdm_status_fn(struct work_struct *work)
{
	int i;
	int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);

	if (!mdm_drv->mdm_ready)
		return;

	
	if (value == 0) {
		for (i = HTC_MDM_ERROR_CONFIRM_TIME_MS; i > 0; i--) {
			msleep(1);
			if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1) {
				pr_info("%s: mdm status low %d(ms) confirm failed... Abort!\n", __func__, HTC_MDM_ERROR_CONFIRM_TIME_MS);
				return;
			}
		}
	}
	

	if ( ( get_radio_flag() & RADIO_FLAG_USB_UPLOAD ) ) {
		if ( value == 0 ) {
			int val_gpio = 0;
			msleep(40);
			val_gpio = gpio_get_value(mdm_drv->mdm2ap_hsic_ready_gpio);
			pr_info("%s:mdm2ap_hsic_ready_gpio=[%d]\n", __func__, val_gpio);
		}
	}

	
	mdm_status_change_notified = true;
	
	mdm_drv->ops->status_cb(mdm_drv, value);

	pr_debug("%s: status:%d\n", __func__, value);

	if (value == 0) {
		pr_info("%s: unexpected reset external modem\n", __func__);

		
		dump_mdm_related_gpio();

		
		pr_info("### Show Blocked State in ###\n");
		show_state_filter(TASK_UNINTERRUPTIBLE);
		if (get_restart_level() == RESET_SOC)
			msm_rtb_disable();

		if (get_restart_level() == RESET_SOC)
			set_mdm2ap_errfatal_restart_flag(1);
		

		subsystem_restart(EXTERNAL_MODEM);
	} else if (value == 1) {
		pr_info("%s: status = 1: mdm is now ready\n", __func__);
	}
}
static irqreturn_t ap2mdm_sw_bc5_isr(int irq, void *dev_id)
{
	int gpio_status = gpio_get_value(mdm_drv->ap2mdm_sw_bc5_gpio);

	if (!is_mdm_support_ap2mdm_sw_bc5) {
		if (mdm_drv->ap2mdm_sw_bc5_status == 1 && gpio_status == 0)	{
			//falling happens
			is_mdm_support_ap2mdm_sw_bc5 = true;
			pr_info("is_mdm_support_ap2mdm_sw_bc5 = true\n");
		}
	}

	mdm_drv->ap2mdm_sw_bc5_status = gpio_status;

	if ( get_radio_flag() & 0x0008 )
		pr_info("%s dump_gpio: %s\t= %d\n", __func__, "AP2MDM_SW_BC5", mdm_drv->ap2mdm_sw_bc5_status);

	if ( get_radio_flag() & 0x0001 )
		trace_printk("AP2MDM_SW_BC5=%d\n", mdm_drv->ap2mdm_sw_bc5_status);
	return IRQ_HANDLED;
}
Example #11
0
static void smd_tty_read(unsigned long param)
{
	unsigned char *ptr;
	int avail;
	struct smd_tty_info *info = (struct smd_tty_info *)param;
	struct tty_struct *tty = info->tty;

	if (!tty)
		return;

	for (;;) {
		if (is_in_reset(info)) {
			
			tty_insert_flip_char(tty, 0x00, TTY_BREAK);
			tty_flip_buffer_push(tty);
			break;
		}

		if (test_bit(TTY_THROTTLED, &tty->flags)) break;
		avail = smd_read_avail(info->ch);
		if (avail == 0)
			break;

		if (avail > MAX_TTY_BUF_SIZE)
			avail = MAX_TTY_BUF_SIZE;

		avail = tty_prepare_flip_string(tty, &ptr, avail);
		if (avail <= 0) {
			mod_timer(&info->buf_req_timer,
					jiffies + msecs_to_jiffies(30));
			return;
		}

		if (smd_read(info->ch, ptr, avail) != avail) {
			printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!");
		
		} else {
			if (get_radio_flag() & 0x0008) {
				int i = 0;
				printk("[RIL]");
				for (i = 0; i< avail; i++)
					printk("%c", *(ptr+i));
			}
		
		}

		wake_lock_timeout(&info->wake_lock, HZ / 2);
		tty_flip_buffer_push(tty);
	}

	
	tty_wakeup(tty);
}
static int rmnet_usb_suspend(struct usb_interface *iface, pm_message_t message)
{
	struct usbnet		*unet;
	struct rmnet_ctrl_dev	*dev;
	int			time = 0;
	int			retval = 0;

	//htc_dbg
	if (get_radio_flag() & 0x0001)
		pr_info("%s intf %p\n", __func__, iface);

	unet = usb_get_intfdata(iface);
	if (!unet) {
		pr_err("%s:data device not found\n", __func__);
		retval = -ENODEV;
		goto fail;
	}

	dev = (struct rmnet_ctrl_dev *)unet->data[1];
	if (!dev) {
		dev_err(&iface->dev, "%s: ctrl device not found\n",
				__func__);
		retval = -ENODEV;
		goto fail;
	}

	retval = usbnet_suspend(iface, message);
	if (!retval) {
		if (message.event & PM_EVENT_SUSPEND) {
			time = usb_wait_anchor_empty_timeout(&dev->tx_submitted,
								1000);
			if (!time)
			{
				pr_info("%s :+usb_kill_anchored_urbs\n", __func__);
				usb_kill_anchored_urbs(&dev->tx_submitted);
				pr_info("%s :-usb_kill_anchored_urbs\n", __func__);
			}

			retval = rmnet_usb_ctrl_stop_rx(dev);
			iface->dev.power.power_state.event = message.event;
		}
		/*  TBD : do we need to set/clear usbnet->udev->reset_resume*/
	} else
		dev_err(&iface->dev,
			"%s: device is busy can not suspend\n", __func__);

fail:
	return retval;
}
Example #13
0
File: mdm2.c Project: Arvoreen/ATnT
static void power_down_mdm(struct mdm_modem_drv *mdm_drv)
{
	//++HTC
	extern bool is_in_subsystem_restart;
	//--HTC
	int i;
	int mfg_mode;

	pr_info("+power_down_mdm\n");

	mfg_mode = board_mfg_mode();

	if (mfg_mode == BOARD_MFG_MODE_OFFMODE_CHARGING) {
		pr_info("-power_down_mdm: offmode charging\n");
		return;
	}

	//++SSD_RIL: Mars_Lin@20120608: disable irq before power off mdm
	mdm_common_enable_irq(mdm_drv, MDM_MODEM_IRQ_DISABLE);
	//--SSD_RIL

	/* APQ8064 only uses one pin to control pon and reset.
	 * If this pin is down over 300ms, memory data will loss.
	 * Currently sbl1 will help pull this pin up, and need 120~140ms.
	 * To decrease down time, we do not shut down MDM here and last until 8k PS_HOLD is pulled.
	 */
#if 1	//HTC
if (is_in_subsystem_restart && (get_radio_flag() & 0x8))
{
	pr_info("%s: Need to capture MDM RAM Dump, don't Pulling RESET gpio LOW here to prevent MDM memory data loss\n", __func__);
}
else
{
	pr_info("%s: Pulling RESET gpio LOW\n", __func__);
	gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 0);

	for (i = MDM_HOLD_TIME; i > 0; i -= MDM_MODEM_DELTA) {
		//pet_watchdog();
		msleep(MDM_MODEM_DELTA);
	}
}
#endif

	if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0)
		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
	//mdm_peripheral_disconnect(mdm_drv);
	
	pr_info("-power_down_mdm\n");
}
static irqreturn_t mdm2ap_wakeup_isr(int irq, void *dev_id)
{
	if ( get_radio_flag() & 0x0008 )
		pr_info("%s\n", __func__);

	//disable irq
	spin_lock(&enable_wake_irq_lock);
	htc_mdm2ap_wakeup_irq_enable_disable(false);
	spin_unlock(&enable_wake_irq_lock);

	if (mdm_drv->mdm_ready && (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1)) {
		spin_lock(&mdm_hsic_wakeup_lock);
		mdm_hsic_wakeup();
		spin_unlock(&mdm_hsic_wakeup_lock);
	}
	else {
		pr_debug("%s: mdm_ready:%d mdm2ap_status_gpio:%d\n", __func__, mdm_drv->mdm_ready, gpio_get_value(mdm_drv->mdm2ap_status_gpio) );
	}

	if ( get_radio_flag() & 0x0001 )
		pr_info("%s end\n", __func__);

	return IRQ_HANDLED;
}
Example #15
0
static void mdm_status_fn(struct work_struct *work)
{
	int i;
	int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);

	if (!mdm_drv->mdm_ready)
		return;

	
	if (value == 0) {
		for (i = HTC_MDM_ERROR_CONFIRM_TIME_MS; i > 0; i--) {
			msleep(1);
			if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1) {
				pr_info("%s: mdm status low %d(ms) confirm failed... Abort!\n", __func__, HTC_MDM_ERROR_CONFIRM_TIME_MS);
				return;
			}
		}
	}
	

	if ( ( get_radio_flag() & RADIO_FLAG_USB_UPLOAD ) ) {
		if ( value == 0 ) {
			int val_gpio = 0;
			msleep(40);
			val_gpio = gpio_get_value(mdm_drv->mdm2ap_hsic_ready_gpio);
			pr_info("%s:mdm2ap_hsic_ready_gpio=[%d]\n", __func__, val_gpio);
		}
	}

	
	mdm_status_change_notified = true;
	
	mdm_drv->ops->status_cb(mdm_drv, value);

	pr_debug("%s: status:%d\n", __func__, value);

	if (value == 0) {
		pr_info("%s: unexpected reset external modem\n", __func__);

		
		mdm_crash_dump_dbg_info();
		

		subsystem_restart(EXTERNAL_MODEM);
	} else if (value == 1) {
		pr_info("%s: status = 1: mdm is now ready\n", __func__);
	}
}
static void mdm_fatal_fn(struct work_struct *work)
{
	//HTC_Kris+++
	unsigned long flags;
	extern bool is_mdm_hsic_phy_suspended;
	extern bool is_mdm_hsic_wakeup_in_progress;
	extern void mdm_hsic_disable_auto_suspend(void);
	int i;
	//HTC_Kris---

	pr_info("%s: Reseting the mdm due to an errfatal\n", __func__);

	//HTC_Kris+++
	pr_info("%s: mdm_hsic_disable_auto_suspend+\n", __func__);
	mdm_hsic_disable_auto_suspend();
	pr_info("%s: mdm_hsic_disable_auto_suspend-\n", __func__);
	//HTC_Kris---

	/* HTC added start */
	dump_mdm_related_gpio();
	//++SSD_RIL:20120724:delay 3 secs before call subsystem restart
	if ( get_radio_flag() & 0x0008 ) {
		mdelay(3000);
	}
	//--SSD_RIL
	/* HTC added end */

	//HTC_Kris+++
	//Before do radio restart, make sure mdm_hsic_phy is not suspended, otherwise, PORTSC will be kept at 1800
	if (is_mdm_hsic_phy_suspended) {
		pr_info("%s(%d): is_mdm_hsic_phy_suspended:%d\n", __func__, __LINE__, is_mdm_hsic_phy_suspended);
		pr_info("%s(%d): wakeup hsic\n", __func__, __LINE__);
		spin_lock_irqsave(&mdm_hsic_wakeup_lock, flags);
		mdm_hsic_wakeup();
		spin_unlock_irqrestore(&mdm_hsic_wakeup_lock, flags);

		//wait until mdm_hsic_phy is not suspended, at most 10 seconds
		for (i = 0; i < 100; i++) {
			msleep_interruptible(1000);
			if (!is_mdm_hsic_phy_suspended && !is_mdm_hsic_wakeup_in_progress)
				break;
		}
		pr_info("%s(%d): is_mdm_hsic_phy_suspended:%d\n", __func__, __LINE__, is_mdm_hsic_phy_suspended);
	}
	//HTC_Kris---

	subsystem_restart(EXTERNAL_MODEM);
}
static void execute_ftrace_cmd(char* cmd)
{
	int ret;

	if ( get_radio_flag() == 0 )
		return;

	//wait until ftrace cmd can be executed
	ret = wait_for_completion_interruptible(&ftrace_cmd_can_be_executed);
	INIT_COMPLETION(ftrace_cmd_can_be_executed);
	if (!ret) {
		//copy cmd to ftrace_cmd buffer
		mutex_lock(&ftrace_cmd_lock);
		memset(ftrace_cmd, 0, sizeof(ftrace_cmd));
		strcpy(ftrace_cmd, cmd);
		pr_info("%s(%s)\n", __func__, ftrace_cmd);
		mutex_unlock(&ftrace_cmd_lock);

		//signal the waiting thread there is pending cmd
		complete(&ftrace_cmd_pending);
	}
}
Example #18
0
static void ctrl_write_callback(struct urb *urb)
{
	struct ctrl_pkt *cpkt = urb->context;
	struct rmnet_ctrl_dev *dev = cpkt->ctxt;

#ifdef CONFIG_QCT_9K_MODEM
	if (get_radio_flag() & RADIO_FLAG_MORE_LOG)
		pr_info("[RMNET] wcb: %d/%d\n", urb->status, urb->actual_length);
#endif

	if (urb->status) {
		dev->cudev->tx_ctrl_err_cnt++;
		//error case
		pr_info("[RMNET] %s :Write status/size %d/%d\n", __func__, urb->status, urb->actual_length);
		pr_debug_ratelimited("Write status/size %d/%d\n", urb->status, urb->actual_length);
	}

	kfree(urb->setup_packet);
	kfree(urb->transfer_buffer);
	usb_free_urb(urb);
	kfree(cpkt);
	usb_autopm_put_interface_async(dev->cudev->intf);
}
Example #19
0
int rmnet_usb_ctrl_init(void)
{
	struct rmnet_ctrl_dev	*dev;
	int			n;
	int			status;

	
	if (get_radio_flag() & 0x0001)
		usb_pm_debug_enabled  = true;

	if (get_radio_flag() & 0x0002)
		enable_ctl_msg_debug = true;
	

#ifdef HTC_LOG_RMNET_USB_CTRL
	if (get_radio_flag() & 0x0008)
		enable_dbg_rmnet_usb_ctrl = true;
#endif	

	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {

		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev) {
			status = -ENOMEM;
			goto error0;
		}
		
		snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n);

		dev->wq = create_singlethread_workqueue(dev->name);
		if (!dev->wq) {
			pr_err("unable to allocate workqueue");
			kfree(dev);
			goto error0;
		}

		mutex_init(&dev->dev_lock);
		spin_lock_init(&dev->rx_lock);
		init_waitqueue_head(&dev->read_wait_queue);
		init_waitqueue_head(&dev->open_wait_queue);
		INIT_LIST_HEAD(&dev->rx_list);
		init_usb_anchor(&dev->tx_submitted);
		init_usb_anchor(&dev->rx_submitted);
		INIT_WORK(&dev->get_encap_work, get_encap_work);

		status = rmnet_usb_ctrl_alloc_rx(dev);
		if (status < 0) {
			kfree(dev);
			goto error0;
		}

		ctrl_dev[n] = dev;
	}

	status = alloc_chrdev_region(&ctrldev_num, 0, NUM_CTRL_CHANNELS,
			DEVICE_NAME);
	if (IS_ERR_VALUE(status)) {
		pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
		       __func__, status);
		goto error0;
	}

	ctrldev_classp = class_create(THIS_MODULE, DEVICE_NAME);
	if (IS_ERR(ctrldev_classp)) {
		pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
		status = -ENOMEM;
		goto error1;
	}
	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {
		cdev_init(&ctrl_dev[n]->cdev, &ctrldev_fops);
		ctrl_dev[n]->cdev.owner = THIS_MODULE;

		status = cdev_add(&ctrl_dev[n]->cdev, (ctrldev_num + n), 1);

		if (IS_ERR_VALUE(status)) {
			pr_err("%s: cdev_add() ret %i\n", __func__, status);
			kfree(ctrl_dev[n]);
			goto error2;
		}

		ctrl_dev[n]->devicep =
				device_create(ctrldev_classp, NULL,
				(ctrldev_num + n), NULL,
				DEVICE_NAME "%d", n);

		if (IS_ERR(ctrl_dev[n]->devicep)) {
			pr_err("%s: device_create() ENOMEM\n", __func__);
			status = -ENOMEM;
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}
		
		status = device_create_file(ctrl_dev[n]->devicep,
					&dev_attr_modem_wait);
		if (status) {
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}

		dev_set_drvdata(ctrl_dev[n]->devicep, ctrl_dev[n]);
	}

	rmnet_usb_ctrl_debugfs_init();
	pr_info("rmnet usb ctrl Initialized.\n");
	return 0;

error2:
		while (--n >= 0) {
			cdev_del(&ctrl_dev[n]->cdev);
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
		}

		class_destroy(ctrldev_classp);
		n = NUM_CTRL_CHANNELS;
error1:
	unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS);
error0:
	while (--n >= 0)
		kfree(ctrl_dev[n]);

	return status;
}
long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
	int status, ret = 0;

	if (_IOC_TYPE(cmd) != CHARM_CODE) {
		pr_err("%s: invalid ioctl code\n", __func__);
		return -EINVAL;
	}

	pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
	switch (cmd) {
	case WAKE_CHARM:
		pr_info("%s: Powering on mdm\n", __func__);
		//++SSD_RIL: Mars_Lin@20120606: reset HSIC READY STATUS
		get_hsic_ready_1st_hi = 0;
		//--SSD_RIL
		mdm_drv->mdm_ready = 0;	/* HTC added for the MDM reloading for the /dev/ttyUSB0 node checking failed situation */
		mdm_drv->ops->power_on_mdm_cb(mdm_drv);
		break;
	case CHECK_FOR_BOOT:
		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
			put_user(1, (unsigned long __user *) arg);
		else
			put_user(0, (unsigned long __user *) arg);
		break;
	case NORMAL_BOOT_DONE:
	{
		//++SSD_RIL: 20120624: check mdm2ap_status_gpio and trigger status_cb if value is 1
		int value = 0;
		//--SSD_RIL: 20120624

		pr_debug("%s: check if mdm is booted up\n", __func__);

		get_user(status, (unsigned long __user *) arg);
		if (status) {
			pr_debug("%s: normal boot failed\n", __func__);
			mdm_drv->mdm_boot_status = -EIO;
		} else {
			pr_info("%s: normal boot done\n", __func__);
			mdm_drv->mdm_boot_status = 0;
		}

		mdm_drv->mdm_ready = 1;

		//HTC_Kris+++
		mdm_is_alive = true;
		//HTC_Kris---

		//++SSD_RIL: 20120624: check mdm2ap_status_gpio and trigger status_cb if value is 1
		mutex_lock(&MDM_BOOT_STATUS_CHECK_LOCK);
		value = mdm2ap_gpio_status;
		pr_info("%s: mdm2ap_status_gpio=[%d]\n", __func__, value);
		if (value) {
		    pr_info("%s: Set mdm9k_status to 1\n", __func__);
		    mdm_drv->ops->status_cb(mdm_drv, value);
		}
		mutex_unlock(&MDM_BOOT_STATUS_CHECK_LOCK);
		//--SSD_RIL: 20120624

		if (mdm_drv->ops->normal_boot_done_cb != NULL)
		{
			pr_info("normal_boot_done_cb\n");
			mdm_drv->ops->normal_boot_done_cb(mdm_drv);
		}

		if (!first_boot)
			complete(&mdm_boot);
		else
			first_boot = 0;

		//enable ftrace log if radio flag 1 is set
		if  (get_radio_flag() & 0x1) {
			static bool is_enable = false;
			if (!is_enable) {
				is_enable = true;
				if (ftrace_queue) {
					queue_work(ftrace_queue, &ftrace_enable_basic_log_work);
				}
			}
		}
	}
		break;
	case RAM_DUMP_DONE:
		pr_debug("%s: mdm done collecting RAM dumps\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status)
			mdm_drv->mdm_ram_dump_status = -EIO;
		else {
			pr_info("%s: ramdump collection completed\n", __func__);
			mdm_drv->mdm_ram_dump_status = 0;
		}
		complete(&mdm_ram_dumps);
		break;
	case WAIT_FOR_RESTART:
		pr_debug("%s: wait for mdm to need images reloaded\n",
				__func__);
		ret = wait_for_completion_interruptible(&mdm_needs_reload);
		if (!ret)
			put_user(mdm_drv->boot_type,
					 (unsigned long __user *) arg);
		INIT_COMPLETION(mdm_needs_reload);
		break;
/* HTC added start */
	case GET_FTRACE_CMD:
		{
			// execute ftrace cmd only when radio flag is non-zero
			if ( get_radio_flag() != 0 ) {
				complete(&ftrace_cmd_can_be_executed);

				ret = wait_for_completion_interruptible(&ftrace_cmd_pending);
				if (!ret) {
					mutex_lock(&ftrace_cmd_lock);
					pr_info("ioctl GET_FTRACE_CMD: %s\n", ftrace_cmd);
					copy_to_user((void __user *)arg, ftrace_cmd, sizeof(ftrace_cmd));
					mutex_unlock(&ftrace_cmd_lock);
				}
				INIT_COMPLETION(ftrace_cmd_pending);
			}
			break;
		}
	case GET_MFG_MODE:
		pr_info("%s: board_mfg_mode()=%d\n", __func__, board_mfg_mode());
		put_user(board_mfg_mode(),
				 (unsigned long __user *) arg);
		break;
	case GET_RADIO_FLAG:
		pr_info("%s:get_radio_flag()=%x\n", __func__, get_radio_flag());
		put_user(get_radio_flag(),
				 (unsigned long __user *) arg);
		break;
	case EFS_SYNC_DONE:
		pr_info("%s:%s efs sync is done\n", __func__, (atomic_read(&final_efs_wait)? " FINAL": ""));
		atomic_set(&final_efs_wait, 0);
		break;
	case EFS_SYNC_TIMEOUT:
		break;
	/* HTC added start: Workaournd for real-time MDM ramdump druing subsystem restart */
	case WAIT_FOR_PORT_RELEASE:
		pr_info("%s: %s to wait for tty port released\n", __func__, need_release_port? "Need": "Don't need");
		if (need_release_port) {
			wait_for_completion(&port_released);
			INIT_COMPLETION(port_released);
		}
		break;
	case CHECK_PORT_UTIL:
		pr_info("%s: %s to release tty port\n", __func__, need_release_port? "Need": "Don't need");
		put_user(need_release_port, (unsigned long __user *) arg);
		if (need_release_port) {
			complete(&port_released);
			need_release_port = 0;
		}
		break;
	/* HTC workaound end */
/* HTC added end */
	default:
		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
		break;
	}

	return ret;
}
Example #21
0
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
	int rc;

	memcpy(&msm_rpm_data, data, sizeof(struct msm_rpm_platform_data));
	msm_rpm_stat_data = (stats_blob *)msm_rpm_data.reg_base_addrs[MSM_RPM_PAGE_STAT];
	msm_rpm_sel_mask_size = msm_rpm_data.sel_last / 32 + 1;
	BUG_ON(SEL_MASK_SIZE < msm_rpm_sel_mask_size);

#ifndef CONFIG_ARCH_MSM8X60
	if ((get_radio_flag() & KERNEL_FLAG_APPSBARK) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_RAM_DUMP;

	if ((get_kernel_flag() & KERNEL_FLAG_PM_MONITOR) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_POWER_MEASUREMENT;

	
	if ((get_kernel_flag() & KERNEL_FLAG_RPM_DISABLE_WATCHDOG) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_DISABLE_WATCHDOG;
#endif
	fw_major = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_MAJOR));
	fw_minor = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_MINOR));
	fw_build = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_BUILD));
	/*pr_info("%s: RPM firmware %u.%u.%u\n", __func__,
			fw_major, fw_minor, fw_build);*/

	if (fw_major != msm_rpm_data.ver[0]) {
		/*pr_err("%s: RPM version %u.%u.%u incompatible with "
				"this driver version %u.%u.%u\n", __func__,
				fw_major, fw_minor, fw_build,
				msm_rpm_data.ver[0],
				msm_rpm_data.ver[1],
				msm_rpm_data.ver[2]);*/
		return -EFAULT;
	}

	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_MAJOR), msm_rpm_data.ver[0]);
	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_MINOR), msm_rpm_data.ver[1]);
	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_BUILD), msm_rpm_data.ver[2]);

	rc = request_irq(data->irq_ack, msm_rpm_ack_interrupt,
			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
			"rpm_drv", msm_rpm_ack_interrupt);
	if (rc) {
		/*pr_err("%s: failed to request irq %d: %d\n",
			__func__, data->irq_ack, rc);*/
		return rc;
	}

	rc = irq_set_irq_wake(data->irq_ack, 1);
	if (rc) {
		/*pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, data->irq_ack, rc);*/
		return rc;
	}

	rc = request_irq(data->irq_err, msm_rpm_err_interrupt,
			IRQF_TRIGGER_RISING, "rpm_err", NULL);
	if (rc) {
		/*pr_err("%s: failed to request error interrupt: %d\n",
			__func__, rc);*/
		return rc;
	}

	rc = request_irq(data->irq_wakeup,
			msm_pm_rpm_wakeup_interrupt, IRQF_TRIGGER_RISING,
			"pm_drv", msm_pm_rpm_wakeup_interrupt);
	if (rc) {
		/*pr_err("%s: failed to request irq %u: %d\n",
			__func__, data->irq_wakeup, rc);*/
		return rc;
	}

	rc = irq_set_irq_wake(data->irq_wakeup, 1);
	if (rc) {
		/*pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, data->irq_wakeup, rc);*/
		return rc;
	}

	msm_rpm_populate_map(data);
	msm_rpm_print_sleep_tick();

	return platform_driver_register(&msm_rpm_platform_driver);
}
Example #22
0
static ssize_t rmnet_ctl_read(struct file *file, char __user *buf, size_t count,
		loff_t *ppos)
{
	int				retval = 0;
	int				bytes_to_read;
	unsigned int			hdr_len = 0;
	struct rmnet_ctrl_dev		*dev;
	struct ctrl_pkt_list_elem	*list_elem = NULL;
	unsigned long			flags;

	dev = file->private_data;
	if (!dev)
		return -ENODEV;

	DBG("%s: Read from %s\n", __func__, dev->name);

ctrl_read:
	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status)) {
		dev_dbg(dev->devicep, "%s: Device not connected\n",
			__func__);
		return -ENETRESET;
	}
	spin_lock_irqsave(&dev->rx_lock, flags);
	if (list_empty(&dev->rx_list)) {
		spin_unlock_irqrestore(&dev->rx_lock, flags);

		retval = wait_event_interruptible(dev->read_wait_queue,
				!list_empty(&dev->rx_list) ||
				!test_bit(RMNET_CTRL_DEV_READY,
					&dev->cudev->status));
		if (retval < 0)
			return retval;

		goto ctrl_read;
	}

	list_elem = list_first_entry(&dev->rx_list,
				     struct ctrl_pkt_list_elem, list);
	bytes_to_read = (uint32_t)(list_elem->cpkt.data_size);
	if (bytes_to_read > count) {
		spin_unlock_irqrestore(&dev->rx_lock, flags);
		dev_err(dev->devicep, "%s: Packet size %d > buf size %d\n",
			__func__, bytes_to_read, count);
		return -ENOMEM;
	}
	spin_unlock_irqrestore(&dev->rx_lock, flags);

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status))
		hdr_len = sizeof(struct mux_hdr);

	if (copy_to_user(buf, list_elem->cpkt.data + hdr_len, bytes_to_read)) {
			dev_err(dev->devicep,
				"%s: copy_to_user failed for %s\n",
				__func__, dev->name);
		return -EFAULT;
	}
	spin_lock_irqsave(&dev->rx_lock, flags);
	list_del(&list_elem->list);
	spin_unlock_irqrestore(&dev->rx_lock, flags);

	kfree(list_elem->cpkt.data);
	kfree(list_elem);
	DBG("%s: Returning %d bytes to %s\n", __func__, bytes_to_read,
			dev->name);
	DUMP_BUFFER("Read: ", bytes_to_read, buf);

#ifdef CONFIG_QCT_9K_MODEM
	if (get_radio_flag() & RADIO_FLAG_MORE_LOG)
		pr_info("[RMNET] R: %i\n", bytes_to_read);
#endif

	return bytes_to_read;
}
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
	unsigned int irq;
	int rc;
#ifdef CONFIG_ARCH_MSM8960
	int i;
#endif
	msm_rpm_platform = data;

	msm_rpm_stat_data = (stats_blob *)msm_rpm_platform->reg_base_addrs[MSM_RPM_PAGE_STAT];

#ifdef CONFIG_ARCH_MSM8960
	if (rpm_debug_enable != 0) {
		unsigned int *rpm_memtest;
		void *imem_loc = ioremap_nocache(IMEM_DEBUG_LOC, 4);
		rpm_memtest = kmalloc(1024*4, GFP_KERNEL);
		pa_memtest_rpm = __pa(rpm_memtest);
		pr_info("RPMTest address: %x\n", pa_memtest_rpm);

		for(i = 0; i < 1024; i++) {
			rpm_memtest[i] = 0xEFBEADDE;
		}

		writel(pa_memtest_rpm, imem_loc);
		iounmap(imem_loc);

		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_RAM_DEBUG;
	}
	if ((get_radio_flag() & 0x8) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_RAM_DUMP;

	pr_info("%s : rpm_debug_mode : 0x%x\n", __func__, msm_rpm_stat_data->rpm_debug_mode);
#endif

	fw_major = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MAJOR);
	fw_minor = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MINOR);
	fw_build = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_BUILD);
	pr_info("%s: RPM firmware %u.%u.%u\n", __func__,
			fw_major, fw_minor, fw_build);

	if (fw_major != RPM_MAJOR_VER) {
		pr_err("%s: RPM version %u.%u.%u incompatible with "
				"this driver version %u.%u.%u\n", __func__,
				fw_major, fw_minor, fw_build,
				RPM_MAJOR_VER, RPM_MINOR_VER, RPM_BUILD_VER);
		return -EFAULT;
	}

	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MAJOR,
			RPM_MAJOR_VER);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MINOR,
			RPM_MINOR_VER);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_BUILD,
			RPM_BUILD_VER);

	irq = msm_rpm_platform->irq_ack;

	rc = request_irq(irq, msm_rpm_ack_interrupt,
			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
			"rpm_drv", msm_rpm_ack_interrupt);
	if (rc) {
		pr_err("%s: failed to request irq %d: %d\n",
			__func__, irq, rc);
		return rc;
	}

	rc = irq_set_irq_wake(irq, 1);
	if (rc) {
		pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, irq, rc);
		return rc;
	}

	msm_rpm_populate_map();
	msm_rpm_print_sleep_tick();
	return platform_driver_register(&msm_rpm_platform_driver);
}
Example #24
0
static int __init bridge_init(void)
{
	struct data_bridge	*dev;
	int			ret;
	int			i = 0;

	
	if (get_radio_flag() & 0x20000)
		usb_diag_enable = true;
	
	
	if (get_radio_flag() & 0x0001)
		usb_pm_debug_enabled = true;
	
	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;

		
		dev->name = "none";

		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;
}
Example #25
0
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf,
		size_t size, loff_t *pos)
{
	int			status;
	size_t			total_len;
	void			*wbuf;
	void			*actual_data;
	struct ctrl_pkt		*cpkt;
	struct rmnet_ctrl_dev	*dev = file->private_data;

	if (!dev)
		return -ENODEV;

	if (size <= 0)
		return -EINVAL;

	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status))
		return -ENETRESET;

	DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name);

#ifdef CONFIG_QCT_9K_MODEM
	if (get_radio_flag() & RADIO_FLAG_MORE_LOG)
		pr_info("[RMNET] W: %i\n", size);
#endif

	total_len = size;

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status))
		total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4);

	wbuf = kmalloc(total_len , GFP_KERNEL);
	if (!wbuf)
		return -ENOMEM;

	cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL);
	if (!cpkt) {
		kfree(wbuf);
		return -ENOMEM;
	}
	actual_data = cpkt->data = wbuf;
	cpkt->data_size = total_len;
	cpkt->ctxt = dev;

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) {
		actual_data = wbuf + sizeof(struct mux_hdr);
		rmnet_usb_ctrl_mux(dev->ch_id, cpkt);
	}

	status = copy_from_user(actual_data, buf, size);
	if (status) {
		dev_err(dev->devicep,
		"%s: Unable to copy data from userspace %d\n",
		__func__, status);
		kfree(wbuf);
		kfree(cpkt);
		return status;
	}
	DUMP_BUFFER("Write: ", size, buf);

#ifdef CONFIG_QCT_9K_MODEM
	status = rmnet_usb_ctrl_write(dev, cpkt, size);
	if (status == size)
		return size;
	else
		pr_err("[%s] status %d\n", __func__, status);
#else
	status = rmnet_usb_ctrl_write_cmd(dev->cudev,
			USB_CDC_SEND_ENCAPSULATED_COMMAND, 0, cpkt->data,
			cpkt->data_size);
	if (status > 0)
		dev->cudev->snd_encap_cmd_cnt++;

	kfree(cpkt->data);
	kfree(cpkt);
#endif

	return status;
}
Example #26
0
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
{
	struct usb_wwan_intf_private *data;
	struct usb_host_interface *intf = serial->interface->cur_altsetting;
	int retval = -ENODEV;
	__u8 nintf;
	__u8 ifnum;
	bool is_gobi1k = id->driver_info ? true : false;

	dbg("%s", __func__);
	dbg("Is Gobi 1000 = %d", is_gobi1k);

	nintf = serial->dev->actconfig->desc.bNumInterfaces;
	dbg("Num Interfaces = %d", nintf);
	ifnum = intf->desc.bInterfaceNumber;
	dbg("This Interface = %d", ifnum);

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

	spin_lock_init(&data->susp_lock);

	/* ++SSD_RIL */
	if (!(board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2))
	/* --SSD_RIL */
		usb_enable_autosuspend(serial->dev);

	switch (nintf) {
	case 1:
		/* QDL mode */
		/* Gobi 2000 has a single altsetting, older ones have two */
		if (serial->interface->num_altsetting == 2)
			intf = &serial->interface->altsetting[1];
		else if (serial->interface->num_altsetting > 2)
			break;

		if (intf->desc.bNumEndpoints == 2 &&
		    usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
		    usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
			dbg("QDL port found");

			if (serial->interface->num_altsetting == 1) {
				retval = 0; /* Success */
				break;
			}

			retval = usb_set_interface(serial->dev, ifnum, 1);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		}
		break;

	case 3:
	case 4:
		/* Composite mode; don't bind to the QMI/net interface as that
		 * gets handled by other drivers.
		 */

		/* Gobi 1K USB layout:
		 * 0: serial port (doesn't respond)
		 * 1: serial port (doesn't respond)
		 * 2: AT-capable modem port
		 * 3: QMI/net
		 *
		 * Gobi 2K+ USB layout:
		 * 0: QMI/net
		 * 1: DM/DIAG (use libqcdm from ModemManager for communication)
		 * 2: AT-capable modem port
		 * 3: NMEA
		 */

		if (ifnum == 1 && !is_gobi1k) {
			dbg("Gobi 2K+ DM/DIAG interface found");
			retval = usb_set_interface(serial->dev, ifnum, 0);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		} else if (ifnum == 2) {
			dbg("Modem port found");
			retval = usb_set_interface(serial->dev, ifnum, 0);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		} else if (ifnum==3 && !is_gobi1k) {
			/*
			 * NMEA (serial line 9600 8N1)
			 * # echo "\$GPS_START" > /dev/ttyUSBx
			 * # echo "\$GPS_STOP"  > /dev/ttyUSBx
			 */
			dbg("Gobi 2K+ NMEA GPS interface found");
			retval = usb_set_interface(serial->dev, ifnum, 0);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		}
		break;
	case 8:
	case 9:
		/* ++SSD_RIL */
		if (get_radio_flag() & 0x20000)
		usb_diag_enable = true;
		/* --SSD_RIL */
		if (ifnum != EFS_SYNC_IFC_NUM && !(!usb_diag_enable && ifnum == DUN_IFC_NUM && (board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2))) { /* SSD_RIL: Add DUN interface for serial USB*/
#ifdef CONFIG_BUILD_EDIAG
			if (ifnum != SYSMON_IFC_NUM) {
#endif
				kfree(data);
				break;
#ifdef CONFIG_BUILD_EDIAG
			}
#endif
		}
#ifdef CONFIG_BUILD_EDIAG
		if (ifnum == SYSMON_IFC_NUM)
			dev_info(&serial->dev->dev, "SYSMON device is created as TTY device\n");
#endif
		retval = 0;
		break;
	default:
		dev_err(&serial->dev->dev,
			"unknown number of interfaces: %d\n", nintf);
		kfree(data);
		retval = -ENODEV;
	}

	/* Set serial->private if not returning -ENODEV */
	if (retval != -ENODEV)
		usb_set_serial_data(serial, data);
	return retval;
}
Example #27
0
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
{
	struct usb_wwan_intf_private *data;
	struct usb_host_interface *intf = serial->interface->cur_altsetting;
	int retval = -ENODEV;
	__u8 nintf;
	__u8 ifnum;
	bool is_gobi1k = id->driver_info ? true : false;

	dbg("%s", __func__);
	dbg("Is Gobi 1000 = %d", is_gobi1k);

	nintf = serial->dev->actconfig->desc.bNumInterfaces;
	dbg("Num Interfaces = %d", nintf);
	ifnum = intf->desc.bInterfaceNumber;
	dbg("This Interface = %d", ifnum);

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

	spin_lock_init(&data->susp_lock);

	
	if (!(board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2))
	
		usb_enable_autosuspend(serial->dev);

	switch (nintf) {
	case 1:
		
		
		if (serial->interface->num_altsetting == 2)
			intf = &serial->interface->altsetting[1];
		else if (serial->interface->num_altsetting > 2)
			break;

		if (intf->desc.bNumEndpoints == 2 &&
		    usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
		    usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
			dbg("QDL port found");

			if (serial->interface->num_altsetting == 1) {
				retval = 0; 
				break;
			}

			retval = usb_set_interface(serial->dev, ifnum, 1);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		}
		break;

	case 3:
	case 4:


		if (ifnum == 1 && !is_gobi1k) {
			dbg("Gobi 2K+ DM/DIAG interface found");
			retval = usb_set_interface(serial->dev, ifnum, 0);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		} else if (ifnum == 2) {
			dbg("Modem port found");
			retval = usb_set_interface(serial->dev, ifnum, 0);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		} else if (ifnum==3 && !is_gobi1k) {
			dbg("Gobi 2K+ NMEA GPS interface found");
			retval = usb_set_interface(serial->dev, ifnum, 0);
			if (retval < 0) {
				dev_err(&serial->dev->dev,
					"Could not set interface, error %d\n",
					retval);
				retval = -ENODEV;
				kfree(data);
			}
		}
		break;

	case 9:
		
		if (get_radio_flag() & 0x20000)
		usb_diag_enable = true;
		
		if (ifnum != EFS_SYNC_IFC_NUM && !(!usb_diag_enable && ifnum == DUN_IFC_NUM && (board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2))) { 
			kfree(data);
			break;
		}

		retval = 0;
		break;
	default:
		dev_err(&serial->dev->dev,
			"unknown number of interfaces: %d\n", nintf);
		kfree(data);
		retval = -ENODEV;
	}

	
	if (retval != -ENODEV)
		usb_set_serial_data(serial, data);
	return retval;
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info;
	struct usb_device	*udev;
	unsigned int		iface_num;
	static int		first_rmnet_iface_num = -EINVAL;
	int			status = 0;

//++SSD_RIL:20120731: For tx/rx enable_hlt/disable_hlt
	if( machine_is_evitareul() ) {
		rnmet_usb_hlt_enabled = 1;
		pr_info("%s:rnmet_usb_hlt_enabled = 1\n", __func__);
	}
//--SSD_RIL
//++SSD_RIL:20120814: For CPU/Freq min default value
	if ( rnmet_usb_hlt_enabled == 1 && get_radio_flag() & 0x0002 ) {
		rnmet_usb_cpu_freq_enabled = 1;
	}
//--SSD_RIL

	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	info = (struct driver_info *)prod->driver_info;
	if (!test_bit(iface_num, &info->data))
		return -ENODEV;

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&iface->dev, "usbnet_probe failed %d\n", status);
		goto out;
	}
	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
	if (status)
		goto out;

	if (first_rmnet_iface_num == -EINVAL)
		first_rmnet_iface_num = iface_num;

	/*save control device intstance */
	unet->data[1] = (unsigned long)ctrl_dev	\
			[iface_num - first_rmnet_iface_num];

	status = rmnet_usb_ctrl_probe(iface, unet->status,
		(struct rmnet_ctrl_dev *)unet->data[1]);
	if (status)
		goto out;

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&iface->dev, "mode debugfs file is not available\n");

	udev = unet->udev;

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);

		/* set default autosuspend timeout for modem and roothub */
		pm_runtime_set_autosuspend_delay(&udev->dev, 1000);
		dev_err(&udev->dev, "pm_runtime_set_autosuspend_delay 1000\n");
		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);
		dev_err(&udev->parent->dev, "pm_runtime_set_autosuspend_delay 200\n");
	}

out:
//++SSD_RIL:20120814: For CPU/Freq min default value
	if ( rnmet_usb_cpu_freq_enabled == 1 ) {
		rmnet_usb_freq_request();
	}
//--SSD_RIL


//++SSD_RIL:20121017: get -71 but already register rmnet netdev
if (status == -EPROTO && already_register_rmNET  ) {
	pr_info("%s fail ,status = %d,unregister_netdev \n", __func__,status);
	//unregister_netdev(unet->net);
	//usb_put_dev(unet->udev);
	usbnet_disconnect(iface);
}
//--SSD_RIL:20121017: get -71 but already register rmnet netdev

	return status;
}
Example #29
0
long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
	int status, ret = 0;

	if (_IOC_TYPE(cmd) != CHARM_CODE) {
		pr_err("%s: invalid ioctl code\n", __func__);
		return -EINVAL;
	}

	pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
	switch (cmd) {
	case WAKE_CHARM:
		pr_info("%s: Powering on mdm\n", __func__);
		mdm_drv->mdm_ready = 0;	
		mdm_drv->mdm_hsic_reconnectd = 0;
		mdm_drv->ops->power_on_mdm_cb(mdm_drv);
		break;
	case CHECK_FOR_BOOT:
		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
			put_user(1, (unsigned long __user *) arg);
		else
			put_user(0, (unsigned long __user *) arg);
		break;
	case NORMAL_BOOT_DONE:
		{
			int ret_mdm_hsic_reconnectd = 0;
			pr_debug("%s: check if mdm is booted up\n", __func__);
			get_user(status, (unsigned long __user *) arg);
			if (status) {
				pr_debug("%s: normal boot failed\n", __func__);
				mdm_drv->mdm_boot_status = -EIO;
			} else {
				pr_info("%s: normal boot done\n", __func__);
				mdm_drv->mdm_boot_status = 0;
			}
			
	                mdm_status_change_notified = false;
	                queue_work_on(0, mdm_gpio_monitor_queue, &mdm_status_check_work);
	                
			mdm_drv->mdm_ready = 1;

			if (mdm_drv->ops->normal_boot_done_cb != NULL)
				mdm_drv->ops->normal_boot_done_cb(mdm_drv);

			ret_mdm_hsic_reconnectd = mdm_hsic_reconnectd_check_fn();

			if ( ret_mdm_hsic_reconnectd == 1 ) {
				pr_info("%s: ret_mdm_hsic_reconnectd == 1\n", __func__);
			} else {
				pr_info("%s: ret_mdm_hsic_reconnectd == 0\n", __func__);
			}

			if (!first_boot)
				complete(&mdm_boot);
			else
				first_boot = 0;
		}
		break;
	case RAM_DUMP_DONE:
		pr_debug("%s: mdm done collecting RAM dumps\n", __func__);
		get_user(status, (unsigned long __user *) arg);
		if (status)
			mdm_drv->mdm_ram_dump_status = -EIO;
		else {
			pr_info("%s: ramdump collection completed\n", __func__);
			mdm_drv->mdm_ram_dump_status = 0;
		}
		complete(&mdm_ram_dumps);
		break;
	case WAIT_FOR_RESTART:
		pr_debug("%s: wait for mdm to need images reloaded\n",
				__func__);

		if (mdm_drv) {
	        dump_gpio("MDM2AP_STATUS", mdm_drv->mdm2ap_status_gpio);
	        dump_gpio("MDM2AP_ERRFATAL", mdm_drv->mdm2ap_errfatal_gpio);
		}

		ret = wait_for_completion_interruptible(&mdm_needs_reload);
		if (!ret) {
			put_user(mdm_drv->boot_type,
					 (unsigned long __user *) arg);

			pr_err("%s: mdm_drv->boot_type:%d\n", __func__, mdm_drv->boot_type);
		}
		INIT_COMPLETION(mdm_needs_reload);
		break;
	case GET_MFG_MODE:
		pr_info("%s: board_mfg_mode()=%d\n", __func__, board_mfg_mode());
		put_user(board_mfg_mode(),
				 (unsigned long __user *) arg);
		break;
	case SET_MODEM_ERRMSG:
		pr_info("%s: Set modem fatal errmsg\n", __func__);
		ret = set_mdm_errmsg((void __user *) arg);
		break;
	case GET_RADIO_FLAG:
		pr_info("%s:get_radio_flag()=%x\n", __func__, get_radio_flag());
		put_user(get_radio_flag(),
				 (unsigned long __user *) arg);
		break;
	case EFS_SYNC_DONE:
		pr_info("%s: efs sync is done\n", __func__);
		break;
	case NV_WRITE_DONE:
		pr_info("%s: NV write done!\n", __func__);
		notify_mdm_nv_write_done();
		break;
	default:
		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
		ret = -EINVAL;
		break;
	}

	return ret;
}
Example #30
0
static void resp_avail_cb(struct urb *urb)
{
	struct usb_device		*udev;
	struct ctrl_pkt_list_elem	*list_elem = NULL;
	struct rmnet_ctrl_udev		*dev = urb->context;
	struct rmnet_ctrl_dev		*rx_dev;
	void				*cpkt;
	int					status = 0;
	int					ch_id = -EINVAL;
	size_t				cpkt_size = 0;

	/*usb device disconnect*/
	if (urb->dev->state == USB_STATE_NOTATTACHED)
		return;

	udev = interface_to_usbdev(dev->intf);

#ifdef CONFIG_QCT_9K_MODEM
	if (get_radio_flag() & RADIO_FLAG_MORE_LOG)
		pr_info("[RMNET] rcb\n");
#endif

	usb_autopm_put_interface_async(dev->intf);

	switch (urb->status) {
	case 0:
		/*success*/
		break;

	/*do not resubmit*/
	case -ESHUTDOWN:
	case -ENOENT:
	case -ECONNRESET:
	case -EPROTO:
		return;

	/*resubmit*/
	case -EOVERFLOW:
		pr_err_ratelimited("%s: Babble error happened\n", __func__);
	default:
		pr_debug_ratelimited("%s: Non zero urb status = %d\n",
				__func__, urb->status);
		goto resubmit_int_urb;
	}

#ifdef CONFIG_QCT_9K_MODEM
	if (get_radio_flag() & RADIO_FLAG_MORE_LOG)
		pr_info("[RMNET] rcb: %i\n", urb->actual_length);
#endif
	cpkt = urb->transfer_buffer;
	cpkt_size = urb->actual_length;
	if (!cpkt_size) {
		dev->zlp_cnt++;
		dev_dbg(&dev->intf->dev, "%s: zero length pkt received\n",
				__func__);
		goto resubmit_int_urb;
	}

	list_elem = kmalloc(sizeof(struct ctrl_pkt_list_elem), GFP_ATOMIC);
	if (!list_elem) {
		dev_err(&dev->intf->dev, "%s: list_elem alloc failed\n",
				__func__);
		return;
	}
	list_elem->cpkt.data = kmalloc(cpkt_size, GFP_ATOMIC);
	if (!list_elem->cpkt.data) {
		dev_err(&dev->intf->dev, "%s: list_elem->data alloc failed\n",
			__func__);
		kfree(list_elem);
		return;
	}
	memcpy(list_elem->cpkt.data, cpkt, cpkt_size);
	list_elem->cpkt.data_size = cpkt_size;

#ifdef CONFIG_QCT_9K_MODEM
	if (get_radio_flag() & RADIO_FLAG_MORE_LOG)
		pr_info("[RMNET] wake_up\n");
#endif
	ch_id = dev->ctrldev_id;

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) {
		ch_id = rmnet_usb_ctrl_dmux(list_elem);
		if (ch_id < 0) {
			dev->invalid_mux_id_cnt++;
			kfree(list_elem->cpkt.data);
			kfree(list_elem);
			goto resubmit_int_urb;
		}
	}

	rx_dev = &ctrl_devs[dev->rdev_num][ch_id];

	dev->get_encap_resp_cnt++;
	dev_dbg(&dev->intf->dev, "Read %d bytes for %s\n",
		urb->actual_length, rx_dev->name);

	spin_lock(&rx_dev->rx_lock);
	list_add_tail(&list_elem->list, &rx_dev->rx_list);
	spin_unlock(&rx_dev->rx_lock);

	wake_up(&rx_dev->read_wait_queue);

resubmit_int_urb:
	/*check if it is already submitted in resume*/
	if (!dev->inturb->anchor) {
		usb_mark_last_busy(udev);
		usb_anchor_urb(dev->inturb, &dev->rx_submitted);
		status = usb_submit_urb(dev->inturb, GFP_ATOMIC);
		if (status) {
			usb_unanchor_urb(dev->inturb);
			if (status != -ENODEV)
				pr_err("%s: Error re-submitting Int URB %d\n",
				__func__, status);
		}
	}
}