Commit e727efee authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'extcon-next-for-5.19' of...

Merge tag 'extcon-next-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon into char-misc-next

Chanwoo writes:

Update extcon next for v5.19

Detailed description for this pull request:
1. update extcon core driver
- extcon_get_extcon_dev() has been almost used to get the extcon device
on booting time. If extcon provider driver is probed at late time,
the extcon consumer driver get the -EPROBE_DEFER return value.
It requires the inefficient handling code of -EPROBE_DEFER.
Instead, extcon_get_extcon_dev() will return -EPROBE_DEFER
if the required extcon device is none. It makes the extcon consumer driver
to be simplified when getting extcon device.
- Register device after dev_set_drvdata because of accessing
the sysfs attributes at timing of between drv_set_data and device_register.
- Fix some kernel-doc comments of extcon functions.

2. update extcon provider driver
- Update extcon-intel-int3496.c
: Add support for controlling vbus power via regulator and support
to the extcon-intel-int3496.c driver to bind to devices without
an ACPi companion. And fix the minor clean-up.
- Use struct_size() helper on extcon-usbc-cros-ec.c
- Remove the disable irq operation in system sleep for using vbus/id
gpio as the wakeup source on extcon-usb-gpio.c
- Add support of SM5703 device by using existing extcon-sm5502.c
and rename i2c_devic_id from sm5703 to sm5703-muic to reduce confusion
between SM5703 MFD device and extcon device.
- Add usb role class support and add queue work sync before driver release
on extcon-ptn5150.c

* tag 'extcon-next-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon:
  extcon: Modify extcon device to be created after driver data is set
  extcon: sm5502: Clarify SM5703's i2c device ID
  extcon: ptn5150: Add usb role class support
  extcon: ptn5150: Add queue work sync before driver release
  extcon: sm5502: Add support for SM5703
  dt-bindings: extcon: bindings for SM5703
  extcon: usb-gpio: Remove disable irq operation in system sleep
  extcon: Fix some kernel-doc comments
  extcon: usbc-cros-ec: Use struct_size() helper in kzalloc()
  extcon: int3496: Add support for controlling Vbus through a regulator
  extcon: int3496: Add support for binding to plain platform devices
  extcon: int3496: Request non-exclusive access to the ID GPIO
  extcon: int3496: Make the driver a bit less verbose
  extcon: Fix extcon_get_extcon_dev() error handling
parents fa5602c6 5dcc2afe
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -20,11 +20,12 @@ properties:
    enum:
      - siliconmitus,sm5502-muic
      - siliconmitus,sm5504-muic
      - siliconmitus,sm5703-muic

  reg:
    maxItems: 1
    description: I2C slave address of the device. Usually 0x25 for SM5502,
      0x14 for SM5504.
    description: I2C slave address of the device. Usually 0x25 for SM5502
      and SM5703, 0x14 for SM5504.

  interrupts:
    maxItems: 1
+2 −1
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ config EXTCON_PALMAS
config EXTCON_PTN5150
	tristate "NXP PTN5150 CC LOGIC USB EXTCON support"
	depends on I2C && (GPIOLIB || COMPILE_TEST)
	depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH
	select REGMAP_I2C
	help
	  Say Y here to enable support for USB peripheral and USB host
@@ -156,7 +157,7 @@ config EXTCON_RT8973A
	  from abnormal high input voltage (up to 28V).

config EXTCON_SM5502
	tristate "Silicon Mitus SM5502/SM5504 EXTCON support"
	tristate "Silicon Mitus SM5502/SM5504/SM5703 EXTCON support"
	depends on I2C
	select IRQ_DOMAIN
	select REGMAP_I2C
+2 −2
Original line number Diff line number Diff line
@@ -394,8 +394,8 @@ static int axp288_extcon_probe(struct platform_device *pdev)
		if (adev) {
			info->id_extcon = extcon_get_extcon_dev(acpi_dev_name(adev));
			put_device(&adev->dev);
			if (!info->id_extcon)
				return -EPROBE_DEFER;
			if (IS_ERR(info->id_extcon))
				return PTR_ERR(info->id_extcon);

			dev_info(dev, "controlling USB role\n");
		} else {
+46 −8
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>

#define INT3496_GPIO_USB_ID	0
#define INT3496_GPIO_VBUS_EN	1
@@ -30,7 +31,9 @@ struct int3496_data {
	struct gpio_desc *gpio_usb_id;
	struct gpio_desc *gpio_vbus_en;
	struct gpio_desc *gpio_usb_mux;
	struct regulator *vbus_boost;
	int usb_id_irq;
	bool vbus_boost_enabled;
};

static const unsigned int int3496_cable[] = {
@@ -53,6 +56,27 @@ static const struct acpi_gpio_mapping acpi_int3496_default_gpios[] = {
	{ },
};

static void int3496_set_vbus_boost(struct int3496_data *data, bool enable)
{
	int ret;

	if (IS_ERR_OR_NULL(data->vbus_boost))
		return;

	if (data->vbus_boost_enabled == enable)
		return;

	if (enable)
		ret = regulator_enable(data->vbus_boost);
	else
		ret = regulator_disable(data->vbus_boost);

	if (ret == 0)
		data->vbus_boost_enabled = enable;
	else
		dev_err(data->dev, "Error updating Vbus boost regulator: %d\n", ret);
}

static void int3496_do_usb_id(struct work_struct *work)
{
	struct int3496_data *data =
@@ -71,6 +95,8 @@ static void int3496_do_usb_id(struct work_struct *work)

	if (!IS_ERR(data->gpio_vbus_en))
		gpiod_direction_output(data->gpio_vbus_en, !id);
	else
		int3496_set_vbus_boost(data, !id);

	extcon_set_state_sync(data->edev, EXTCON_USB_HOST, !id);
}
@@ -91,11 +117,13 @@ static int int3496_probe(struct platform_device *pdev)
	struct int3496_data *data;
	int ret;

	if (has_acpi_companion(dev)) {
		ret = devm_acpi_dev_add_driver_gpios(dev, acpi_int3496_default_gpios);
		if (ret) {
			dev_err(dev, "can't add GPIO ACPI mapping\n");
			return ret;
		}
	}

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
@@ -106,7 +134,8 @@ static int int3496_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	data->gpio_usb_id = devm_gpiod_get(dev, "id", GPIOD_IN);
	data->gpio_usb_id =
		devm_gpiod_get(dev, "id", GPIOD_IN | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
	if (IS_ERR(data->gpio_usb_id)) {
		ret = PTR_ERR(data->gpio_usb_id);
		dev_err(dev, "can't request USB ID GPIO: %d\n", ret);
@@ -120,12 +149,14 @@ static int int3496_probe(struct platform_device *pdev)
	}

	data->gpio_vbus_en = devm_gpiod_get(dev, "vbus", GPIOD_ASIS);
	if (IS_ERR(data->gpio_vbus_en))
		dev_info(dev, "can't request VBUS EN GPIO\n");
	if (IS_ERR(data->gpio_vbus_en)) {
		dev_dbg(dev, "can't request VBUS EN GPIO\n");
		data->vbus_boost = devm_regulator_get_optional(dev, "vbus");
	}

	data->gpio_usb_mux = devm_gpiod_get(dev, "mux", GPIOD_ASIS);
	if (IS_ERR(data->gpio_usb_mux))
		dev_info(dev, "can't request USB MUX GPIO\n");
		dev_dbg(dev, "can't request USB MUX GPIO\n");

	/* register extcon device */
	data->edev = devm_extcon_dev_allocate(dev, int3496_cable);
@@ -164,12 +195,19 @@ static const struct acpi_device_id int3496_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, int3496_acpi_match);

static const struct platform_device_id int3496_ids[] = {
	{ .name = "intel-int3496" },
	{},
};
MODULE_DEVICE_TABLE(platform, int3496_ids);

static struct platform_driver int3496_driver = {
	.driver = {
		.name = "intel-int3496",
		.acpi_match_table = int3496_acpi_match,
	},
	.probe = int3496_probe,
	.id_table = int3496_ids,
};

module_platform_driver(int3496_driver);
+36 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/extcon-provider.h>
#include <linux/gpio/consumer.h>
#include <linux/usb/role.h>

/* PTN5150 registers */
#define PTN5150_REG_DEVICE_ID			0x01
@@ -52,6 +53,7 @@ struct ptn5150_info {
	int irq;
	struct work_struct irq_work;
	struct mutex mutex;
	struct usb_role_switch *role_sw;
};

/* List of detectable cables */
@@ -70,6 +72,7 @@ static const struct regmap_config ptn5150_regmap_config = {
static void ptn5150_check_state(struct ptn5150_info *info)
{
	unsigned int port_status, reg_data, vbus;
	enum usb_role usb_role = USB_ROLE_NONE;
	int ret;

	ret = regmap_read(info->regmap, PTN5150_REG_CC_STATUS, &reg_data);
@@ -85,6 +88,7 @@ static void ptn5150_check_state(struct ptn5150_info *info)
		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false);
		gpiod_set_value_cansleep(info->vbus_gpiod, 0);
		extcon_set_state_sync(info->edev, EXTCON_USB, true);
		usb_role = USB_ROLE_DEVICE;
		break;
	case PTN5150_UFP_ATTACHED:
		extcon_set_state_sync(info->edev, EXTCON_USB, false);
@@ -95,10 +99,18 @@ static void ptn5150_check_state(struct ptn5150_info *info)
			gpiod_set_value_cansleep(info->vbus_gpiod, 1);

		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true);
		usb_role = USB_ROLE_HOST;
		break;
	default:
		break;
	}

	if (usb_role) {
		ret = usb_role_switch_set_role(info->role_sw, usb_role);
		if (ret)
			dev_err(info->dev, "failed to set %s role: %d\n",
				usb_role_string(usb_role), ret);
	}
}

static void ptn5150_irq_work(struct work_struct *work)
@@ -133,6 +145,13 @@ static void ptn5150_irq_work(struct work_struct *work)
			extcon_set_state_sync(info->edev,
					EXTCON_USB, false);
			gpiod_set_value_cansleep(info->vbus_gpiod, 0);

			ret = usb_role_switch_set_role(info->role_sw,
						       USB_ROLE_NONE);
			if (ret)
				dev_err(info->dev,
					"failed to set none role: %d\n",
					ret);
		}
	}

@@ -194,6 +213,14 @@ static int ptn5150_init_dev_type(struct ptn5150_info *info)
	return 0;
}

static void ptn5150_work_sync_and_put(void *data)
{
	struct ptn5150_info *info = data;

	cancel_work_sync(&info->irq_work);
	usb_role_switch_put(info->role_sw);
}

static int ptn5150_i2c_probe(struct i2c_client *i2c)
{
	struct device *dev = &i2c->dev;
@@ -284,6 +311,15 @@ static int ptn5150_i2c_probe(struct i2c_client *i2c)
	if (ret)
		return -EINVAL;

	info->role_sw = usb_role_switch_get(info->dev);
	if (IS_ERR(info->role_sw))
		return dev_err_probe(info->dev, PTR_ERR(info->role_sw),
				     "failed to get role switch\n");

	ret = devm_add_action_or_reset(dev, ptn5150_work_sync_and_put, info);
	if (ret)
		return ret;

	/*
	 * Update current extcon state if for example OTG connection was there
	 * before the probe
Loading