Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f76ddd98 authored by Linus Torvalds's avatar Linus Torvalds
Browse files


Pull char/misc driver fixes from Greg Kroah-Hartman:
 "Here are some driver fixes for 3.7.  They include extcon driver fixes,
  a hyper-v bugfix, and two other minor driver fixes.

  All of these have been in the linux-next releases for a while.

  Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org&gt;">

* tag 'char-misc-3.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  sonypi: suspend/resume callbacks should be conditionally compiled on CONFIG_PM_SLEEP
  Drivers: hv: Cleanup error handling in vmbus_open()
  extcon : register for cable interest by cable name
  extcon: trivial: kfree missed from remove path
  extcon: driver model release call not needed
  extcon: MAX77693: Add platform data for MUIC device to initialize registers
  extcon: max77693: Use max77693_update_reg for rmw operations
  extcon: Fix kerneldoc for extcon_set_cable_state and extcon_set_cable_state_
  extcon: adc-jack: Add missing MODULE_LICENSE
  extcon: adc-jack: Fix checking return value of request_any_context_irq
  extcon: Fix return value in extcon_register_interest()
  extcon: unregister compat link on cleanup
  extcon: Unregister compat class at module unload to fix oops
  extcon: optimising the check_mutually_exclusive function
  extcon: standard cable names definition and declaration changed
  extcon-max8997: remove usage of ret in max8997_muic_handle_charger_type_detach
  extcon: Remove duplicate inclusion of extcon.h header file
parents 561ec64a 2cb55a2f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1456,7 +1456,7 @@ static int __devexit sonypi_remove(struct platform_device *dev)
	return 0;
}

#ifdef CONFIG_PM
#ifdef CONFIG_PM_SLEEP
static int old_camera_power;

static int sonypi_suspend(struct device *dev)
+7 −3
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 *
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
@@ -161,13 +162,12 @@ static int __devinit adc_jack_probe(struct platform_device *pdev)
	err = request_any_context_irq(data->irq, adc_jack_irq_thread,
			pdata->irq_flags, pdata->name, data);

	if (err) {
	if (err < 0) {
		dev_err(&pdev->dev, "error: irq %d\n", data->irq);
		err = -EINVAL;
		goto err_irq;
	}

	goto out;
	return 0;

err_irq:
	extcon_dev_unregister(&data->edev);
@@ -196,3 +196,7 @@ static struct platform_driver adc_jack_driver = {
};

module_platform_driver(adc_jack_driver);

MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
MODULE_DESCRIPTION("ADC Jack extcon driver");
MODULE_LICENSE("GPL v2");
+81 −61
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@
 * every single port-type of the following cable names. Please choose cable
 * names that are actually used in your extcon device.
 */
const char *extcon_cable_name[] = {
const char extcon_cable_name[][CABLE_NAME_MAX + 1] = {
	[EXTCON_USB]		= "USB",
	[EXTCON_USB_HOST]	= "USB-Host",
	[EXTCON_TA]		= "TA",
@@ -62,8 +62,6 @@ const char *extcon_cable_name[] = {
	[EXTCON_VIDEO_IN]	= "Video-in",
	[EXTCON_VIDEO_OUT]	= "Video-out",
	[EXTCON_MECHANICAL]	= "Mechanical",

	NULL,
};

static struct class *extcon_class;
@@ -91,17 +89,13 @@ static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state)
		return 0;

	for (i = 0; edev->mutually_exclusive[i]; i++) {
		int count = 0, j;
		int weight;
		u32 correspondants = new_state & edev->mutually_exclusive[i];
		u32 exp = 1;

		for (j = 0; j < 32; j++) {
			if (exp & correspondants)
				count++;
			if (count > 1)
		/* calculate the total number of bits set */
		weight = hweight32(correspondants);
		if (weight > 1)
			return i + 1;
			exp <<= 1;
		}
	}

	return 0;
@@ -362,7 +356,7 @@ int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name)
EXPORT_SYMBOL_GPL(extcon_get_cable_state);

/**
 * extcon_get_cable_state_() - Set the status of a specific cable.
 * extcon_set_cable_state_() - Set the status of a specific cable.
 * @edev:	the extcon device that has the cable.
 * @index:	cable index that can be retrieved by extcon_find_cable_index().
 * @cable_state:	the new cable status. The default semantics is
@@ -382,7 +376,7 @@ int extcon_set_cable_state_(struct extcon_dev *edev,
EXPORT_SYMBOL_GPL(extcon_set_cable_state_);

/**
 * extcon_get_cable_state() - Set the status of a specific cable.
 * extcon_set_cable_state() - Set the status of a specific cable.
 * @edev:	the extcon device that has the cable.
 * @cable_name:	cable name.
 * @cable_state:	the new cable status. The default semantics is
@@ -447,6 +441,8 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val,
 *			      extcon device.
 * @obj:	an empty extcon_specific_cable_nb object to be returned.
 * @extcon_name:	the name of extcon device.
 *			if NULL, extcon_register_interest will register
 *			every cable with the target cable_name given.
 * @cable_name:		the target cable name.
 * @nb:		the notifier block to get notified.
 *
@@ -466,9 +462,10 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
			     const char *extcon_name, const char *cable_name,
			     struct notifier_block *nb)
{
	if (!obj || !extcon_name || !cable_name || !nb)
	if (!obj || !cable_name || !nb)
		return -EINVAL;

	if (extcon_name) {
		obj->edev = extcon_get_extcon_dev(extcon_name);
		if (!obj->edev)
			return -ENODEV;
@@ -482,6 +479,27 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
		obj->internal_nb.notifier_call = _call_per_cable;

		return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb);
	} else {
		struct class_dev_iter iter;
		struct extcon_dev *extd;
		struct device *dev;

		if (!extcon_class)
			return -ENODEV;
		class_dev_iter_init(&iter, extcon_class, NULL, NULL);
		while ((dev = class_dev_iter_next(&iter))) {
			extd = (struct extcon_dev *)dev_get_drvdata(dev);

			if (extcon_find_cable_index(extd, cable_name) < 0)
				continue;

			class_dev_iter_exit(&iter);
			return extcon_register_interest(obj, extd->name,
						cable_name, nb);
		}

		return -ENODEV;
	}
}

/**
@@ -551,43 +569,9 @@ static int create_extcon_class(void)
	return 0;
}

static void extcon_cleanup(struct extcon_dev *edev, bool skip)
{
	mutex_lock(&extcon_dev_list_lock);
	list_del(&edev->entry);
	mutex_unlock(&extcon_dev_list_lock);

	if (!skip && get_device(edev->dev)) {
		int index;

		if (edev->mutually_exclusive && edev->max_supported) {
			for (index = 0; edev->mutually_exclusive[index];
			     index++)
				kfree(edev->d_attrs_muex[index].attr.name);
			kfree(edev->d_attrs_muex);
			kfree(edev->attrs_muex);
		}

		for (index = 0; index < edev->max_supported; index++)
			kfree(edev->cables[index].attr_g.name);

		if (edev->max_supported) {
			kfree(edev->extcon_dev_type.groups);
			kfree(edev->cables);
		}

		device_unregister(edev->dev);
		put_device(edev->dev);
	}

	kfree(edev->dev);
}

static void extcon_dev_release(struct device *dev)
{
	struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev);

	extcon_cleanup(edev, true);
	kfree(dev);
}

static const char *muex_name = "mutually_exclusive";
@@ -813,7 +797,40 @@ EXPORT_SYMBOL_GPL(extcon_dev_register);
 */
void extcon_dev_unregister(struct extcon_dev *edev)
{
	extcon_cleanup(edev, false);
	int index;

	mutex_lock(&extcon_dev_list_lock);
	list_del(&edev->entry);
	mutex_unlock(&extcon_dev_list_lock);

	if (IS_ERR_OR_NULL(get_device(edev->dev))) {
		dev_err(edev->dev, "Failed to unregister extcon_dev (%s)\n",
				dev_name(edev->dev));
		return;
	}

	if (edev->mutually_exclusive && edev->max_supported) {
		for (index = 0; edev->mutually_exclusive[index];
				index++)
			kfree(edev->d_attrs_muex[index].attr.name);
		kfree(edev->d_attrs_muex);
		kfree(edev->attrs_muex);
	}

	for (index = 0; index < edev->max_supported; index++)
		kfree(edev->cables[index].attr_g.name);

	if (edev->max_supported) {
		kfree(edev->extcon_dev_type.groups);
		kfree(edev->cables);
	}

#if defined(CONFIG_ANDROID)
	if (switch_class)
		class_compat_remove_link(switch_class, edev->dev, NULL);
#endif
	device_unregister(edev->dev);
	put_device(edev->dev);
}
EXPORT_SYMBOL_GPL(extcon_dev_unregister);

@@ -825,6 +842,9 @@ module_init(extcon_class_init);

static void __exit extcon_class_exit(void)
{
#if defined(CONFIG_ANDROID)
	class_compat_unregister(switch_class);
#endif
	class_destroy(extcon_class);
}
module_exit(extcon_class_exit);
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/extcon.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <linux/extcon.h>
+34 −12
Original line number Diff line number Diff line
@@ -239,25 +239,19 @@ const char *max77693_extcon_cable[] = {
static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
		enum max77693_muic_adc_debounce_time time)
{
	int ret = 0;
	u8 ctrl3;
	int ret;

	switch (time) {
	case ADC_DEBOUNCE_TIME_5MS:
	case ADC_DEBOUNCE_TIME_10MS:
	case ADC_DEBOUNCE_TIME_25MS:
	case ADC_DEBOUNCE_TIME_38_62MS:
		ret = max77693_read_reg(info->max77693->regmap_muic,
				MAX77693_MUIC_REG_CTRL3, &ctrl3);
		ctrl3 &= ~CONTROL3_ADCDBSET_MASK;
		ctrl3 |= (time << CONTROL3_ADCDBSET_SHIFT);

		ret = max77693_write_reg(info->max77693->regmap_muic,
				MAX77693_MUIC_REG_CTRL3, ctrl3);
		if (ret) {
		ret = max77693_update_reg(info->max77693->regmap_muic,
					  MAX77693_MUIC_REG_CTRL3,
					  time << CONTROL3_ADCDBSET_SHIFT,
					  CONTROL3_ADCDBSET_MASK);
		if (ret)
			dev_err(info->dev, "failed to set ADC debounce time\n");
			ret = -EINVAL;
		}
		break;
	default:
		dev_err(info->dev, "invalid ADC debounce time\n");
@@ -657,6 +651,8 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
static int __devinit max77693_muic_probe(struct platform_device *pdev)
{
	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
	struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
	struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;
	struct max77693_muic_info *info;
	int ret, i;
	u8 id;
@@ -727,6 +723,31 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)
		goto err_extcon;
	}

	/* Initialize MUIC register by using platform data */
	for (i = 0 ; i < muic_pdata->num_init_data ; i++) {
		enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR;

		max77693_write_reg(info->max77693->regmap_muic,
				muic_pdata->init_data[i].addr,
				muic_pdata->init_data[i].data);

		switch (muic_pdata->init_data[i].addr) {
		case MAX77693_MUIC_REG_INTMASK1:
			irq_src = MUIC_INT1;
			break;
		case MAX77693_MUIC_REG_INTMASK2:
			irq_src = MUIC_INT2;
			break;
		case MAX77693_MUIC_REG_INTMASK3:
			irq_src = MUIC_INT3;
			break;
		}

		if (irq_src < MAX77693_IRQ_GROUP_NR)
			info->max77693->irq_masks_cur[irq_src]
				= muic_pdata->init_data[i].data;
	}

	/* Check revision number of MUIC device*/
	ret = max77693_read_reg(info->max77693->regmap_muic,
			MAX77693_MUIC_REG_ID, &id);
@@ -762,6 +783,7 @@ static int __devexit max77693_muic_remove(struct platform_device *pdev)
		free_irq(muic_irqs[i].virq, info);
	cancel_work_sync(&info->irq_work);
	extcon_dev_unregister(info->edev);
	kfree(info->edev);
	kfree(info);

	return 0;
Loading