All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] extcon: sm5502: Add support for SM5504
@ 2021-06-01 20:00 Stephan Gerhold
  2021-06-01 20:00 ` [PATCH v3 1/3] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Stephan Gerhold @ 2021-06-01 20:00 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
	~postmarketos/upstreaming, Stephan Gerhold

This patch series adds support for SM5504 to the existing extcon-sm5502
driver. SM5502 and SM5504 are fairly similar so support for SM5504 can
be added with a few simple if statements in the code.

I also put a few cleanup patches in front and convert the device tree
bindings to DT schema.

I tested this patch series on both SM5502 (Samsung Galaxy A5 2015)
and SM5504 (Samsung Galaxy S4 Mini Value Edition) and it seems to work
just fine for both.

---
Changes in v3:
  - Drop patch 1-4 (already applied)
  - Avoid if (type == TYPE_SM5504) everywhere in the code, instead
    introduce a struct sm5502_type that encodes chip-specific information.

v2: https://lore.kernel.org/lkml/20210531133438.3511-1-stephan@gerhold.net/
Changes in v2: Fix compile warning in last patch
v1: https://lore.kernel.org/lkml/20210520112334.129556-1-stephan@gerhold.net/

Stephan Gerhold (3):
  dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic
  extcon: sm5502: Refactor driver to use chip-specific struct
  extcon: sm5502: Add support for SM5504

 .../extcon/siliconmitus,sm5502-muic.yaml      |   6 +-
 drivers/extcon/Kconfig                        |   2 +-
 drivers/extcon/extcon-sm5502.c                | 196 +++++++++++++++---
 drivers/extcon/extcon-sm5502.h                |  82 +++++++-
 4 files changed, 248 insertions(+), 38 deletions(-)

-- 
2.31.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 1/3] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic
  2021-06-01 20:00 [PATCH v3 0/3] extcon: sm5502: Add support for SM5504 Stephan Gerhold
@ 2021-06-01 20:00 ` Stephan Gerhold
  2021-06-02 19:37   ` Rob Herring
  2021-06-01 20:00 ` [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct Stephan Gerhold
  2021-06-01 20:00 ` [PATCH v3 3/3] extcon: sm5502: Add support for SM5504 Stephan Gerhold
  2 siblings, 1 reply; 11+ messages in thread
From: Stephan Gerhold @ 2021-06-01 20:00 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
	~postmarketos/upstreaming, Stephan Gerhold

Document support for SM5504 with the new siliconmitus,sm5504-muic
compatible.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
 .../bindings/extcon/siliconmitus,sm5502-muic.yaml           | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml b/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
index 0432b0502e0b..fd2e55088888 100644
--- a/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
+++ b/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/extcon/siliconmitus,sm5502-muic.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: SM5502 MUIC (Micro-USB Interface Controller) device
+title: SM5502/SM5504 MUIC (Micro-USB Interface Controller) device
 
 maintainers:
   - Chanwoo Choi <cw00.choi@samsung.com>
@@ -19,10 +19,12 @@ properties:
   compatible:
     enum:
       - siliconmitus,sm5502-muic
+      - siliconmitus,sm5504-muic
 
   reg:
     maxItems: 1
-    description: I2C slave address of the device. Usually 0x25 for SM5502.
+    description: I2C slave address of the device. Usually 0x25 for SM5502,
+      0x14 for SM5504.
 
   interrupts:
     maxItems: 1
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct
  2021-06-01 20:00 [PATCH v3 0/3] extcon: sm5502: Add support for SM5504 Stephan Gerhold
  2021-06-01 20:00 ` [PATCH v3 1/3] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
@ 2021-06-01 20:00 ` Stephan Gerhold
  2021-06-02 15:13   ` Chanwoo Choi
  2021-06-01 20:00 ` [PATCH v3 3/3] extcon: sm5502: Add support for SM5504 Stephan Gerhold
  2 siblings, 1 reply; 11+ messages in thread
From: Stephan Gerhold @ 2021-06-01 20:00 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
	~postmarketos/upstreaming, Stephan Gerhold

Prepare for supporting SM5504 in the extcon-sm5502 driver by replacing
enum sm5504_types with a struct sm5504_type that stores the chip-specific
definitions. This struct can then be defined separately for SM5504
without having to add if (type == TYPE_SM5504) everywhere in the code.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
Changes in v3: New patch to simplify diff on next patch
---
 drivers/extcon/extcon-sm5502.c | 64 +++++++++++++++++++++-------------
 drivers/extcon/extcon-sm5502.h |  4 ---
 2 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index 9f40bb9f1f81..951f6ca4c479 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -40,17 +40,13 @@ struct sm5502_muic_info {
 	struct i2c_client *i2c;
 	struct regmap *regmap;
 
+	const struct sm5502_type *type;
 	struct regmap_irq_chip_data *irq_data;
-	struct muic_irq *muic_irqs;
-	unsigned int num_muic_irqs;
 	int irq;
 	bool irq_attach;
 	bool irq_detach;
 	struct work_struct irq_work;
 
-	struct reg_data *reg_data;
-	unsigned int num_reg_data;
-
 	struct mutex mutex;
 
 	/*
@@ -62,6 +58,17 @@ struct sm5502_muic_info {
 	struct delayed_work wq_detcable;
 };
 
+struct sm5502_type {
+	struct muic_irq *muic_irqs;
+	unsigned int num_muic_irqs;
+	const struct regmap_irq_chip *irq_chip;
+
+	struct reg_data *reg_data;
+	unsigned int num_reg_data;
+
+	int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
+};
+
 /* Default value of SM5502 register to bring up MUIC device. */
 static struct reg_data sm5502_reg_data[] = {
 	{
@@ -502,11 +509,11 @@ static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
 	struct sm5502_muic_info *info = data;
 	int i, irq_type = -1, ret;
 
-	for (i = 0; i < info->num_muic_irqs; i++)
-		if (irq == info->muic_irqs[i].virq)
-			irq_type = info->muic_irqs[i].irq;
+	for (i = 0; i < info->type->num_muic_irqs; i++)
+		if (irq == info->type->muic_irqs[i].virq)
+			irq_type = info->type->muic_irqs[i].irq;
 
-	ret = sm5502_parse_irq(info, irq_type);
+	ret = info->type->parse_irq(info, irq_type);
 	if (ret < 0) {
 		dev_warn(info->dev, "cannot handle is interrupt:%d\n",
 				    irq_type);
@@ -551,14 +558,14 @@ static void sm5502_init_dev_type(struct sm5502_muic_info *info)
 			    version_id, vendor_id);
 
 	/* Initiazle the register of SM5502 device to bring-up */
-	for (i = 0; i < info->num_reg_data; i++) {
+	for (i = 0; i < info->type->num_reg_data; i++) {
 		unsigned int val = 0;
 
-		if (!info->reg_data[i].invert)
-			val |= ~info->reg_data[i].val;
+		if (!info->type->reg_data[i].invert)
+			val |= ~info->type->reg_data[i].val;
 		else
-			val = info->reg_data[i].val;
-		regmap_write(info->regmap, info->reg_data[i].reg, val);
+			val = info->type->reg_data[i].val;
+		regmap_write(info->regmap, info->type->reg_data[i].reg, val);
 	}
 }
 
@@ -579,10 +586,9 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
 	info->dev = &i2c->dev;
 	info->i2c = i2c;
 	info->irq = i2c->irq;
-	info->muic_irqs = sm5502_muic_irqs;
-	info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
-	info->reg_data = sm5502_reg_data;
-	info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
+	info->type = device_get_match_data(info->dev);
+	if (!info->type)
+		return -EINVAL;
 
 	mutex_init(&info->mutex);
 
@@ -598,16 +604,17 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
 
 	/* Support irq domain for SM5502 MUIC device */
 	irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
-	ret = devm_regmap_add_irq_chip(info->dev, info->regmap, info->irq, irq_flags,
-				       0, &sm5502_muic_irq_chip, &info->irq_data);
+	ret = devm_regmap_add_irq_chip(info->dev, info->regmap, info->irq,
+				       irq_flags, 0, info->type->irq_chip,
+				       &info->irq_data);
 	if (ret != 0) {
 		dev_err(info->dev, "failed to request IRQ %d: %d\n",
 				    info->irq, ret);
 		return ret;
 	}
 
-	for (i = 0; i < info->num_muic_irqs; i++) {
-		struct muic_irq *muic_irq = &info->muic_irqs[i];
+	for (i = 0; i < info->type->num_muic_irqs; i++) {
+		struct muic_irq *muic_irq = &info->type->muic_irqs[i];
 		int virq = 0;
 
 		virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq);
@@ -659,8 +666,17 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
 	return 0;
 }
 
+static const struct sm5502_type sm5502_data = {
+	.muic_irqs = sm5502_muic_irqs,
+	.num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs),
+	.irq_chip = &sm5502_muic_irq_chip,
+	.reg_data = sm5502_reg_data,
+	.num_reg_data = ARRAY_SIZE(sm5502_reg_data),
+	.parse_irq = sm5502_parse_irq,
+};
+
 static const struct of_device_id sm5502_dt_match[] = {
-	{ .compatible = "siliconmitus,sm5502-muic" },
+	{ .compatible = "siliconmitus,sm5502-muic", .data = &sm5502_data },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, sm5502_dt_match);
@@ -691,7 +707,7 @@ static SIMPLE_DEV_PM_OPS(sm5502_muic_pm_ops,
 			 sm5502_muic_suspend, sm5502_muic_resume);
 
 static const struct i2c_device_id sm5502_i2c_id[] = {
-	{ "sm5502", TYPE_SM5502 },
+	{ "sm5502", (kernel_ulong_t)&sm5502_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, sm5502_i2c_id);
diff --git a/drivers/extcon/extcon-sm5502.h b/drivers/extcon/extcon-sm5502.h
index ce1f1ec310c4..d187205df7b3 100644
--- a/drivers/extcon/extcon-sm5502.h
+++ b/drivers/extcon/extcon-sm5502.h
@@ -8,10 +8,6 @@
 #ifndef __LINUX_EXTCON_SM5502_H
 #define __LINUX_EXTCON_SM5502_H
 
-enum sm5502_types {
-	TYPE_SM5502,
-};
-
 /* SM5502 registers */
 enum sm5502_reg {
 	SM5502_REG_DEVICE_ID = 0x01,
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v3 3/3] extcon: sm5502: Add support for SM5504
  2021-06-01 20:00 [PATCH v3 0/3] extcon: sm5502: Add support for SM5504 Stephan Gerhold
  2021-06-01 20:00 ` [PATCH v3 1/3] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
  2021-06-01 20:00 ` [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct Stephan Gerhold
@ 2021-06-01 20:00 ` Stephan Gerhold
  2 siblings, 0 replies; 11+ messages in thread
From: Stephan Gerhold @ 2021-06-01 20:00 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
	~postmarketos/upstreaming, Stephan Gerhold

SM5504 is another MUIC from Silicon Mitus that is fairly similar
to SM5502. They seem to use the same register set, but:

  - SM5504 has some additional bits in SM5502_REG_CONTROL
  - SM5504 has a quite different set of interrupts
  - SM5504 reports USB OTG as dev_type1 = BIT(0) instead of BIT(7)

Overall it's minor and we can support this by defining a separate
struct sm5502_type for SM5504.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
Changes in v3: Avoid if statements, use struct sm5502_type indirection

Changes in v2: Fix warning: cast to smaller integer type 'enum sm5502_types'
               from 'const void *' [-Wvoid-pointer-to-enum-cast]
               reported by kernel test robot
v2: https://lore.kernel.org/lkml/20210531133438.3511-7-stephan@gerhold.net/

Interestingly enough the register set (and especially the interrupts)
also look *very* similar to Richtek RT8973A (extcon-rt8973a) but
I didn't investigate this further.

Note that the changes in this patch are mostly based on guesswork
based on a SM5504 driver from Nitin Chaudhary [1] used in some Samsung
vendor kernels, since I was not able to find a public datasheet for SM5504.

[1]: https://github.com/NitinChaudharyUSC/MSM8x16_8x26/blob/master/drivers/misc/sm5504.c
---
 drivers/extcon/Kconfig         |   2 +-
 drivers/extcon/extcon-sm5502.c | 132 +++++++++++++++++++++++++++++++--
 drivers/extcon/extcon-sm5502.h |  78 +++++++++++++++++++
 3 files changed, 204 insertions(+), 8 deletions(-)

diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index e3db936becfd..c69d40ae5619 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -154,7 +154,7 @@ config EXTCON_RT8973A
 	  from abnormal high input voltage (up to 28V).
 
 config EXTCON_SM5502
-	tristate "Silicon Mitus SM5502 EXTCON support"
+	tristate "Silicon Mitus SM5502/SM5504 EXTCON support"
 	depends on I2C
 	select IRQ_DOMAIN
 	select REGMAP_I2C
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index 951f6ca4c479..af44c1e2f368 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -66,6 +66,7 @@ struct sm5502_type {
 	struct reg_data *reg_data;
 	unsigned int num_reg_data;
 
+	unsigned int otg_dev_type1;
 	int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
 };
 
@@ -97,6 +98,33 @@ static struct reg_data sm5502_reg_data[] = {
 	},
 };
 
+/* Default value of SM5504 register to bring up MUIC device. */
+static struct reg_data sm5504_reg_data[] = {
+	{
+		.reg = SM5502_REG_RESET,
+		.val = SM5502_REG_RESET_MASK,
+		.invert = true,
+	}, {
+		.reg = SM5502_REG_INTMASK1,
+		.val = SM5504_REG_INTM1_ATTACH_MASK
+			| SM5504_REG_INTM1_DETACH_MASK,
+		.invert = false,
+	}, {
+		.reg = SM5502_REG_INTMASK2,
+		.val = SM5504_REG_INTM2_RID_CHG_MASK
+			| SM5504_REG_INTM2_UVLO_MASK
+			| SM5504_REG_INTM2_POR_MASK,
+		.invert = true,
+	}, {
+		.reg = SM5502_REG_CONTROL,
+		.val = SM5502_REG_CONTROL_MANUAL_SW_MASK
+			| SM5504_REG_CONTROL_CHGTYP_MASK
+			| SM5504_REG_CONTROL_USBCHDEN_MASK
+			| SM5504_REG_CONTROL_ADC_EN_MASK,
+		.invert = true,
+	},
+};
+
 /* List of detectable cables */
 static const unsigned int sm5502_extcon_cable[] = {
 	EXTCON_USB,
@@ -205,6 +233,55 @@ static const struct regmap_irq_chip sm5502_muic_irq_chip = {
 	.num_irqs		= ARRAY_SIZE(sm5502_irqs),
 };
 
+/* List of supported interrupt for SM5504 */
+static struct muic_irq sm5504_muic_irqs[] = {
+	{ SM5504_IRQ_INT1_ATTACH,	"muic-attach" },
+	{ SM5504_IRQ_INT1_DETACH,	"muic-detach" },
+	{ SM5504_IRQ_INT1_CHG_DET,	"muic-chg-det" },
+	{ SM5504_IRQ_INT1_DCD_OUT,	"muic-dcd-out" },
+	{ SM5504_IRQ_INT1_OVP_EVENT,	"muic-ovp-event" },
+	{ SM5504_IRQ_INT1_CONNECT,	"muic-connect" },
+	{ SM5504_IRQ_INT1_ADC_CHG,	"muic-adc-chg" },
+	{ SM5504_IRQ_INT2_RID_CHG,	"muic-rid-chg" },
+	{ SM5504_IRQ_INT2_UVLO,		"muic-uvlo" },
+	{ SM5504_IRQ_INT2_POR,		"muic-por" },
+	{ SM5504_IRQ_INT2_OVP_FET,	"muic-ovp-fet" },
+	{ SM5504_IRQ_INT2_OCP_LATCH,	"muic-ocp-latch" },
+	{ SM5504_IRQ_INT2_OCP_EVENT,	"muic-ocp-event" },
+	{ SM5504_IRQ_INT2_OVP_OCP_EVENT, "muic-ovp-ocp-event" },
+};
+
+/* Define interrupt list of SM5504 to register regmap_irq */
+static const struct regmap_irq sm5504_irqs[] = {
+	/* INT1 interrupts */
+	{ .reg_offset = 0, .mask = SM5504_IRQ_INT1_ATTACH_MASK, },
+	{ .reg_offset = 0, .mask = SM5504_IRQ_INT1_DETACH_MASK, },
+	{ .reg_offset = 0, .mask = SM5504_IRQ_INT1_CHG_DET_MASK, },
+	{ .reg_offset = 0, .mask = SM5504_IRQ_INT1_DCD_OUT_MASK, },
+	{ .reg_offset = 0, .mask = SM5504_IRQ_INT1_OVP_MASK, },
+	{ .reg_offset = 0, .mask = SM5504_IRQ_INT1_CONNECT_MASK, },
+	{ .reg_offset = 0, .mask = SM5504_IRQ_INT1_ADC_CHG_MASK, },
+
+	/* INT2 interrupts */
+	{ .reg_offset = 1, .mask = SM5504_IRQ_INT2_RID_CHG_MASK,},
+	{ .reg_offset = 1, .mask = SM5504_IRQ_INT2_UVLO_MASK, },
+	{ .reg_offset = 1, .mask = SM5504_IRQ_INT2_POR_MASK, },
+	{ .reg_offset = 1, .mask = SM5504_IRQ_INT2_OVP_FET_MASK, },
+	{ .reg_offset = 1, .mask = SM5504_IRQ_INT2_OCP_LATCH_MASK, },
+	{ .reg_offset = 1, .mask = SM5504_IRQ_INT2_OCP_EVENT_MASK, },
+	{ .reg_offset = 1, .mask = SM5504_IRQ_INT2_OVP_OCP_EVENT_MASK, },
+};
+
+static const struct regmap_irq_chip sm5504_muic_irq_chip = {
+	.name			= "sm5504",
+	.status_base		= SM5502_REG_INT1,
+	.mask_base		= SM5502_REG_INTMASK1,
+	.mask_invert		= false,
+	.num_regs		= 2,
+	.irqs			= sm5504_irqs,
+	.num_irqs		= ARRAY_SIZE(sm5504_irqs),
+};
+
 /* Define regmap configuration of SM5502 for I2C communication  */
 static bool sm5502_muic_volatile_reg(struct device *dev, unsigned int reg)
 {
@@ -308,11 +385,9 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
 			return ret;
 		}
 
-		switch (dev_type1) {
-		case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
+		if (dev_type1 == info->type->otg_dev_type1) {
 			cable_type = SM5502_MUIC_ADC_GROUND_USB_OTG;
-			break;
-		default:
+		} else {
 			dev_dbg(info->dev,
 				"cannot identify the cable type: adc(0x%x), dev_type1(0x%x)\n",
 				adc, dev_type1);
@@ -365,6 +440,11 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
 			return ret;
 		}
 
+		if (dev_type1 == info->type->otg_dev_type1) {
+			cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
+			break;
+		}
+
 		switch (dev_type1) {
 		case SM5502_REG_DEV_TYPE1_USB_SDP_MASK:
 			cable_type = SM5502_MUIC_ADC_OPEN_USB;
@@ -372,9 +452,6 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
 		case SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK:
 			cable_type = SM5502_MUIC_ADC_OPEN_TA;
 			break;
-		case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
-			cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
-			break;
 		default:
 			dev_dbg(info->dev,
 				"cannot identify the cable type: adc(0x%x)\n",
@@ -504,6 +581,34 @@ static int sm5502_parse_irq(struct sm5502_muic_info *info, int irq_type)
 	return 0;
 }
 
+static int sm5504_parse_irq(struct sm5502_muic_info *info, int irq_type)
+{
+	switch (irq_type) {
+	case SM5504_IRQ_INT1_ATTACH:
+		info->irq_attach = true;
+		break;
+	case SM5504_IRQ_INT1_DETACH:
+		info->irq_detach = true;
+		break;
+	case SM5504_IRQ_INT1_CHG_DET:
+	case SM5504_IRQ_INT1_DCD_OUT:
+	case SM5504_IRQ_INT1_OVP_EVENT:
+	case SM5504_IRQ_INT1_CONNECT:
+	case SM5504_IRQ_INT1_ADC_CHG:
+	case SM5504_IRQ_INT2_RID_CHG:
+	case SM5504_IRQ_INT2_UVLO:
+	case SM5504_IRQ_INT2_POR:
+	case SM5504_IRQ_INT2_OVP_FET:
+	case SM5504_IRQ_INT2_OCP_LATCH:
+	case SM5504_IRQ_INT2_OCP_EVENT:
+	case SM5504_IRQ_INT2_OVP_OCP_EVENT:
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
 {
 	struct sm5502_muic_info *info = data;
@@ -672,11 +777,23 @@ static const struct sm5502_type sm5502_data = {
 	.irq_chip = &sm5502_muic_irq_chip,
 	.reg_data = sm5502_reg_data,
 	.num_reg_data = ARRAY_SIZE(sm5502_reg_data),
+	.otg_dev_type1 = SM5502_REG_DEV_TYPE1_USB_OTG_MASK,
 	.parse_irq = sm5502_parse_irq,
 };
 
+static const struct sm5502_type sm5504_data = {
+	.muic_irqs = sm5504_muic_irqs,
+	.num_muic_irqs = ARRAY_SIZE(sm5504_muic_irqs),
+	.irq_chip = &sm5504_muic_irq_chip,
+	.reg_data = sm5504_reg_data,
+	.num_reg_data = ARRAY_SIZE(sm5504_reg_data),
+	.otg_dev_type1 = SM5504_REG_DEV_TYPE1_USB_OTG_MASK,
+	.parse_irq = sm5504_parse_irq,
+};
+
 static const struct of_device_id sm5502_dt_match[] = {
 	{ .compatible = "siliconmitus,sm5502-muic", .data = &sm5502_data },
+	{ .compatible = "siliconmitus,sm5504-muic", .data = &sm5504_data },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, sm5502_dt_match);
@@ -708,6 +825,7 @@ static SIMPLE_DEV_PM_OPS(sm5502_muic_pm_ops,
 
 static const struct i2c_device_id sm5502_i2c_id[] = {
 	{ "sm5502", (kernel_ulong_t)&sm5502_data },
+	{ "sm5504", (kernel_ulong_t)&sm5504_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, sm5502_i2c_id);
diff --git a/drivers/extcon/extcon-sm5502.h b/drivers/extcon/extcon-sm5502.h
index d187205df7b3..9c04315d48e2 100644
--- a/drivers/extcon/extcon-sm5502.h
+++ b/drivers/extcon/extcon-sm5502.h
@@ -89,6 +89,13 @@ enum sm5502_reg {
 #define SM5502_REG_CONTROL_RAW_DATA_MASK	(0x1 << SM5502_REG_CONTROL_RAW_DATA_SHIFT)
 #define SM5502_REG_CONTROL_SW_OPEN_MASK		(0x1 << SM5502_REG_CONTROL_SW_OPEN_SHIFT)
 
+#define SM5504_REG_CONTROL_CHGTYP_SHIFT		5
+#define SM5504_REG_CONTROL_USBCHDEN_SHIFT	6
+#define SM5504_REG_CONTROL_ADC_EN_SHIFT		7
+#define SM5504_REG_CONTROL_CHGTYP_MASK		(0x1 << SM5504_REG_CONTROL_CHGTYP_SHIFT)
+#define SM5504_REG_CONTROL_USBCHDEN_MASK	(0x1 << SM5504_REG_CONTROL_USBCHDEN_SHIFT)
+#define SM5504_REG_CONTROL_ADC_EN_MASK		(0x1 << SM5504_REG_CONTROL_ADC_EN_SHIFT)
+
 #define SM5502_REG_INTM1_ATTACH_SHIFT		0
 #define SM5502_REG_INTM1_DETACH_SHIFT		1
 #define SM5502_REG_INTM1_KP_SHIFT		2
@@ -119,6 +126,36 @@ enum sm5502_reg {
 #define SM5502_REG_INTM2_STUCK_KEY_RCV_MASK	(0x1 << SM5502_REG_INTM2_STUCK_KEY_RCV_SHIFT)
 #define SM5502_REG_INTM2_MHL_MASK		(0x1 << SM5502_REG_INTM2_MHL_SHIFT)
 
+#define SM5504_REG_INTM1_ATTACH_SHIFT		0
+#define SM5504_REG_INTM1_DETACH_SHIFT		1
+#define SM5504_REG_INTM1_CHG_DET_SHIFT		2
+#define SM5504_REG_INTM1_DCD_OUT_SHIFT		3
+#define SM5504_REG_INTM1_OVP_EVENT_SHIFT	4
+#define SM5504_REG_INTM1_CONNECT_SHIFT		5
+#define SM5504_REG_INTM1_ADC_CHG_SHIFT		6
+#define SM5504_REG_INTM1_ATTACH_MASK		(0x1 << SM5504_REG_INTM1_ATTACH_SHIFT)
+#define SM5504_REG_INTM1_DETACH_MASK		(0x1 << SM5504_REG_INTM1_DETACH_SHIFT)
+#define SM5504_REG_INTM1_CHG_DET_MASK		(0x1 << SM5504_REG_INTM1_CHG_DET_SHIFT)
+#define SM5504_REG_INTM1_DCD_OUT_MASK		(0x1 << SM5504_REG_INTM1_DCD_OUT_SHIFT)
+#define SM5504_REG_INTM1_OVP_EVENT_MASK		(0x1 << SM5504_REG_INTM1_OVP_EVENT_SHIFT)
+#define SM5504_REG_INTM1_CONNECT_MASK		(0x1 << SM5504_REG_INTM1_CONNECT_SHIFT)
+#define SM5504_REG_INTM1_ADC_CHG_MASK		(0x1 << SM5504_REG_INTM1_ADC_CHG_SHIFT)
+
+#define SM5504_REG_INTM2_RID_CHG_SHIFT		0
+#define SM5504_REG_INTM2_UVLO_SHIFT		1
+#define SM5504_REG_INTM2_POR_SHIFT		2
+#define SM5504_REG_INTM2_OVP_FET_SHIFT		4
+#define SM5504_REG_INTM2_OCP_LATCH_SHIFT	5
+#define SM5504_REG_INTM2_OCP_EVENT_SHIFT	6
+#define SM5504_REG_INTM2_OVP_OCP_EVENT_SHIFT	7
+#define SM5504_REG_INTM2_RID_CHG_MASK		(0x1 << SM5504_REG_INTM2_RID_CHG_SHIFT)
+#define SM5504_REG_INTM2_UVLO_MASK		(0x1 << SM5504_REG_INTM2_UVLO_SHIFT)
+#define SM5504_REG_INTM2_POR_MASK		(0x1 << SM5504_REG_INTM2_POR_SHIFT)
+#define SM5504_REG_INTM2_OVP_FET_MASK		(0x1 << SM5504_REG_INTM2_OVP_FET_SHIFT)
+#define SM5504_REG_INTM2_OCP_LATCH_MASK		(0x1 << SM5504_REG_INTM2_OCP_LATCH_SHIFT)
+#define SM5504_REG_INTM2_OCP_EVENT_MASK		(0x1 << SM5504_REG_INTM2_OCP_EVENT_SHIFT)
+#define SM5504_REG_INTM2_OVP_OCP_EVENT_MASK	(0x1 << SM5504_REG_INTM2_OVP_OCP_EVENT_SHIFT)
+
 #define SM5502_REG_ADC_SHIFT			0
 #define SM5502_REG_ADC_MASK			(0x1f << SM5502_REG_ADC_SHIFT)
 
@@ -195,6 +232,9 @@ enum sm5502_reg {
 #define SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK		(0x1 << SM5502_REG_DEV_TYPE1_DEDICATED_CHG_SHIFT)
 #define SM5502_REG_DEV_TYPE1_USB_OTG_MASK		(0x1 << SM5502_REG_DEV_TYPE1_USB_OTG_SHIFT)
 
+#define SM5504_REG_DEV_TYPE1_USB_OTG_SHIFT		0
+#define SM5504_REG_DEV_TYPE1_USB_OTG_MASK		(0x1 << SM5504_REG_DEV_TYPE1_USB_OTG_SHIFT)
+
 #define SM5502_REG_DEV_TYPE2_JIG_USB_ON_SHIFT		0
 #define SM5502_REG_DEV_TYPE2_JIG_USB_OFF_SHIFT		1
 #define SM5502_REG_DEV_TYPE2_JIG_UART_ON_SHIFT		2
@@ -273,4 +313,42 @@ enum sm5502_irq {
 #define SM5502_IRQ_INT2_STUCK_KEY_RCV_MASK	BIT(4)
 #define SM5502_IRQ_INT2_MHL_MASK		BIT(5)
 
+/* SM5504 Interrupts */
+enum sm5504_irq {
+	/* INT1 */
+	SM5504_IRQ_INT1_ATTACH,
+	SM5504_IRQ_INT1_DETACH,
+	SM5504_IRQ_INT1_CHG_DET,
+	SM5504_IRQ_INT1_DCD_OUT,
+	SM5504_IRQ_INT1_OVP_EVENT,
+	SM5504_IRQ_INT1_CONNECT,
+	SM5504_IRQ_INT1_ADC_CHG,
+
+	/* INT2 */
+	SM5504_IRQ_INT2_RID_CHG,
+	SM5504_IRQ_INT2_UVLO,
+	SM5504_IRQ_INT2_POR,
+	SM5504_IRQ_INT2_OVP_FET,
+	SM5504_IRQ_INT2_OCP_LATCH,
+	SM5504_IRQ_INT2_OCP_EVENT,
+	SM5504_IRQ_INT2_OVP_OCP_EVENT,
+
+	SM5504_IRQ_NUM,
+};
+
+#define SM5504_IRQ_INT1_ATTACH_MASK		BIT(0)
+#define SM5504_IRQ_INT1_DETACH_MASK		BIT(1)
+#define SM5504_IRQ_INT1_CHG_DET_MASK		BIT(2)
+#define SM5504_IRQ_INT1_DCD_OUT_MASK		BIT(3)
+#define SM5504_IRQ_INT1_OVP_MASK		BIT(4)
+#define SM5504_IRQ_INT1_CONNECT_MASK		BIT(5)
+#define SM5504_IRQ_INT1_ADC_CHG_MASK		BIT(6)
+#define SM5504_IRQ_INT2_RID_CHG_MASK		BIT(0)
+#define SM5504_IRQ_INT2_UVLO_MASK		BIT(1)
+#define SM5504_IRQ_INT2_POR_MASK		BIT(2)
+#define SM5504_IRQ_INT2_OVP_FET_MASK		BIT(4)
+#define SM5504_IRQ_INT2_OCP_LATCH_MASK		BIT(5)
+#define SM5504_IRQ_INT2_OCP_EVENT_MASK		BIT(6)
+#define SM5504_IRQ_INT2_OVP_OCP_EVENT_MASK	BIT(7)
+
 #endif /*  __LINUX_EXTCON_SM5502_H */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct
  2021-06-01 20:00 ` [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct Stephan Gerhold
@ 2021-06-02 15:13   ` Chanwoo Choi
  2021-06-02 15:20     ` Stephan Gerhold
  0 siblings, 1 reply; 11+ messages in thread
From: Chanwoo Choi @ 2021-06-02 15:13 UTC (permalink / raw)
  To: Stephan Gerhold, Chanwoo Choi, MyungJoo Ham
  Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
	~postmarketos/upstreaming

On 21. 6. 2. 오전 5:00, Stephan Gerhold wrote:
> Prepare for supporting SM5504 in the extcon-sm5502 driver by replacing
> enum sm5504_types with a struct sm5504_type that stores the chip-specific
> definitions. This struct can then be defined separately for SM5504
> without having to add if (type == TYPE_SM5504) everywhere in the code.
> 
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> ---
> Changes in v3: New patch to simplify diff on next patch
> ---
>   drivers/extcon/extcon-sm5502.c | 64 +++++++++++++++++++++-------------
>   drivers/extcon/extcon-sm5502.h |  4 ---
>   2 files changed, 40 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
> index 9f40bb9f1f81..951f6ca4c479 100644
> --- a/drivers/extcon/extcon-sm5502.c
> +++ b/drivers/extcon/extcon-sm5502.c
> @@ -40,17 +40,13 @@ struct sm5502_muic_info {
>   	struct i2c_client *i2c;
>   	struct regmap *regmap;
>   
> +	const struct sm5502_type *type;
>   	struct regmap_irq_chip_data *irq_data;
> -	struct muic_irq *muic_irqs;
> -	unsigned int num_muic_irqs;
>   	int irq;
>   	bool irq_attach;
>   	bool irq_detach;
>   	struct work_struct irq_work;
>   
> -	struct reg_data *reg_data;
> -	unsigned int num_reg_data;
> -
>   	struct mutex mutex;
>   
>   	/*
> @@ -62,6 +58,17 @@ struct sm5502_muic_info {
>   	struct delayed_work wq_detcable;
>   };
>   
> +struct sm5502_type {
> +	struct muic_irq *muic_irqs;
> +	unsigned int num_muic_irqs;
> +	const struct regmap_irq_chip *irq_chip;
> +
> +	struct reg_data *reg_data;
> +	unsigned int num_reg_data;
> +
> +	int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
> +};
> +
>   /* Default value of SM5502 register to bring up MUIC device. */
>   static struct reg_data sm5502_reg_data[] = {
>   	{
> @@ -502,11 +509,11 @@ static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
>   	struct sm5502_muic_info *info = data;
>   	int i, irq_type = -1, ret;
>   
> -	for (i = 0; i < info->num_muic_irqs; i++)
> -		if (irq == info->muic_irqs[i].virq)
> -			irq_type = info->muic_irqs[i].irq;
> +	for (i = 0; i < info->type->num_muic_irqs; i++)
> +		if (irq == info->type->muic_irqs[i].virq)
> +			irq_type = info->type->muic_irqs[i].irq;
>   
> -	ret = sm5502_parse_irq(info, irq_type);
> +	ret = info->type->parse_irq(info, irq_type);

Looks good to me. But there is only one comment.
Need to check the 'parse_irq' as following:

If you agree this suggestion, I'll apply with following changes by myself:

	if (!info->type->parse_irq) {
		dev_err(info->dev, "failed to handle irq due to parse_irq\n",
		return IRQ_NONE;
	}


(snip)

-- 
Best Regards,
Samsung Electronics
Chanwoo Choi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct
  2021-06-02 15:13   ` Chanwoo Choi
@ 2021-06-02 15:20     ` Stephan Gerhold
  2021-06-02 15:30       ` Chanwoo Choi
  0 siblings, 1 reply; 11+ messages in thread
From: Stephan Gerhold @ 2021-06-02 15:20 UTC (permalink / raw)
  To: Chanwoo Choi
  Cc: Chanwoo Choi, MyungJoo Ham, Rob Herring, devicetree,
	linux-kernel, Nikita Travkin, ~postmarketos/upstreaming

On Thu, Jun 03, 2021 at 12:13:18AM +0900, Chanwoo Choi wrote:
> On 21. 6. 2. 오전 5:00, Stephan Gerhold wrote:
> > Prepare for supporting SM5504 in the extcon-sm5502 driver by replacing
> > enum sm5504_types with a struct sm5504_type that stores the chip-specific
> > definitions. This struct can then be defined separately for SM5504
> > without having to add if (type == TYPE_SM5504) everywhere in the code.
> > 
> > Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> > ---
> > Changes in v3: New patch to simplify diff on next patch
> > ---
> >   drivers/extcon/extcon-sm5502.c | 64 +++++++++++++++++++++-------------
> >   drivers/extcon/extcon-sm5502.h |  4 ---
> >   2 files changed, 40 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
> > index 9f40bb9f1f81..951f6ca4c479 100644
> > --- a/drivers/extcon/extcon-sm5502.c
> > +++ b/drivers/extcon/extcon-sm5502.c
> > @@ -40,17 +40,13 @@ struct sm5502_muic_info {
> >   	struct i2c_client *i2c;
> >   	struct regmap *regmap;
> > +	const struct sm5502_type *type;
> >   	struct regmap_irq_chip_data *irq_data;
> > -	struct muic_irq *muic_irqs;
> > -	unsigned int num_muic_irqs;
> >   	int irq;
> >   	bool irq_attach;
> >   	bool irq_detach;
> >   	struct work_struct irq_work;
> > -	struct reg_data *reg_data;
> > -	unsigned int num_reg_data;
> > -
> >   	struct mutex mutex;
> >   	/*
> > @@ -62,6 +58,17 @@ struct sm5502_muic_info {
> >   	struct delayed_work wq_detcable;
> >   };
> > +struct sm5502_type {
> > +	struct muic_irq *muic_irqs;
> > +	unsigned int num_muic_irqs;
> > +	const struct regmap_irq_chip *irq_chip;
> > +
> > +	struct reg_data *reg_data;
> > +	unsigned int num_reg_data;
> > +
> > +	int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
> > +};
> > +
> >   /* Default value of SM5502 register to bring up MUIC device. */
> >   static struct reg_data sm5502_reg_data[] = {
> >   	{
> > @@ -502,11 +509,11 @@ static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
> >   	struct sm5502_muic_info *info = data;
> >   	int i, irq_type = -1, ret;
> > -	for (i = 0; i < info->num_muic_irqs; i++)
> > -		if (irq == info->muic_irqs[i].virq)
> > -			irq_type = info->muic_irqs[i].irq;
> > +	for (i = 0; i < info->type->num_muic_irqs; i++)
> > +		if (irq == info->type->muic_irqs[i].virq)
> > +			irq_type = info->type->muic_irqs[i].irq;
> > -	ret = sm5502_parse_irq(info, irq_type);
> > +	ret = info->type->parse_irq(info, irq_type);
> 
> Looks good to me. But there is only one comment.
> Need to check the 'parse_irq' as following:
> 
> If you agree this suggestion, I'll apply with following changes by myself:
> 
> 	if (!info->type->parse_irq) {
> 		dev_err(info->dev, "failed to handle irq due to parse_irq\n",
> 		return IRQ_NONE;
> 	}
> 
> 

This condition should be impossible, since .parse_irq is set for both
SM5502 and SM5504:

static const struct sm5502_type sm5502_data = {
	/* ... */
	.parse_irq = sm5502_parse_irq,
};

static const struct sm5502_type sm5504_data = {
	/* ... */
	.parse_irq = sm5504_parse_irq,
};

Which failure case are you trying to handle with that if statement?

Thanks!
Stephan

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct
  2021-06-02 15:20     ` Stephan Gerhold
@ 2021-06-02 15:30       ` Chanwoo Choi
  2021-06-02 15:35         ` Chanwoo Choi
  0 siblings, 1 reply; 11+ messages in thread
From: Chanwoo Choi @ 2021-06-02 15:30 UTC (permalink / raw)
  To: Stephan Gerhold
  Cc: Chanwoo Choi, MyungJoo Ham, Rob Herring, devicetree,
	linux-kernel, Nikita Travkin, ~postmarketos/upstreaming

On 21. 6. 3. 오전 12:20, Stephan Gerhold wrote:
> On Thu, Jun 03, 2021 at 12:13:18AM +0900, Chanwoo Choi wrote:
>> On 21. 6. 2. 오전 5:00, Stephan Gerhold wrote:
>>> Prepare for supporting SM5504 in the extcon-sm5502 driver by replacing
>>> enum sm5504_types with a struct sm5504_type that stores the chip-specific
>>> definitions. This struct can then be defined separately for SM5504
>>> without having to add if (type == TYPE_SM5504) everywhere in the code.
>>>
>>> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
>>> ---
>>> Changes in v3: New patch to simplify diff on next patch
>>> ---
>>>    drivers/extcon/extcon-sm5502.c | 64 +++++++++++++++++++++-------------
>>>    drivers/extcon/extcon-sm5502.h |  4 ---
>>>    2 files changed, 40 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
>>> index 9f40bb9f1f81..951f6ca4c479 100644
>>> --- a/drivers/extcon/extcon-sm5502.c
>>> +++ b/drivers/extcon/extcon-sm5502.c
>>> @@ -40,17 +40,13 @@ struct sm5502_muic_info {
>>>    	struct i2c_client *i2c;
>>>    	struct regmap *regmap;
>>> +	const struct sm5502_type *type;
>>>    	struct regmap_irq_chip_data *irq_data;
>>> -	struct muic_irq *muic_irqs;
>>> -	unsigned int num_muic_irqs;
>>>    	int irq;
>>>    	bool irq_attach;
>>>    	bool irq_detach;
>>>    	struct work_struct irq_work;
>>> -	struct reg_data *reg_data;
>>> -	unsigned int num_reg_data;
>>> -
>>>    	struct mutex mutex;
>>>    	/*
>>> @@ -62,6 +58,17 @@ struct sm5502_muic_info {
>>>    	struct delayed_work wq_detcable;
>>>    };
>>> +struct sm5502_type {
>>> +	struct muic_irq *muic_irqs;
>>> +	unsigned int num_muic_irqs;
>>> +	const struct regmap_irq_chip *irq_chip;
>>> +
>>> +	struct reg_data *reg_data;
>>> +	unsigned int num_reg_data;
>>> +
>>> +	int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
>>> +};
>>> +
>>>    /* Default value of SM5502 register to bring up MUIC device. */
>>>    static struct reg_data sm5502_reg_data[] = {
>>>    	{
>>> @@ -502,11 +509,11 @@ static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
>>>    	struct sm5502_muic_info *info = data;
>>>    	int i, irq_type = -1, ret;
>>> -	for (i = 0; i < info->num_muic_irqs; i++)
>>> -		if (irq == info->muic_irqs[i].virq)
>>> -			irq_type = info->muic_irqs[i].irq;
>>> +	for (i = 0; i < info->type->num_muic_irqs; i++)
>>> +		if (irq == info->type->muic_irqs[i].virq)
>>> +			irq_type = info->type->muic_irqs[i].irq;
>>> -	ret = sm5502_parse_irq(info, irq_type);
>>> +	ret = info->type->parse_irq(info, irq_type);
>>
>> Looks good to me. But there is only one comment.
>> Need to check the 'parse_irq' as following:
>>
>> If you agree this suggestion, I'll apply with following changes by myself:
>>
>> 	if (!info->type->parse_irq) {
>> 		dev_err(info->dev, "failed to handle irq due to parse_irq\n",
>> 		return IRQ_NONE;
>> 	}
>>
>>
> 
> This condition should be impossible, since .parse_irq is set for both
> SM5502 and SM5504:
> 
> static const struct sm5502_type sm5502_data = {
> 	/* ... */
> 	.parse_irq = sm5502_parse_irq,
> };
> 
> static const struct sm5502_type sm5504_data = {
> 	/* ... */
> 	.parse_irq = sm5504_parse_irq,
> };
> 
> Which failure case are you trying to handle with that if statement?

There is not failure case of this patchset. But, this refactoring 
suggestion has the potential problem without checking whether mandatory 
function pointer is NULL or not. When adding new chip by using this 
driver, the author might have the human error without parse_irq 
initialization even if the mandatory.

> 
> Thanks!
> Stephan
> 


-- 
Best Regards,
Samsung Electronics
Chanwoo Choi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct
  2021-06-02 15:30       ` Chanwoo Choi
@ 2021-06-02 15:35         ` Chanwoo Choi
  2021-06-02 15:42           ` Stephan Gerhold
  0 siblings, 1 reply; 11+ messages in thread
From: Chanwoo Choi @ 2021-06-02 15:35 UTC (permalink / raw)
  To: Stephan Gerhold
  Cc: Chanwoo Choi, MyungJoo Ham, Rob Herring, devicetree,
	linux-kernel, Nikita Travkin, ~postmarketos/upstreaming

On 21. 6. 3. 오전 12:30, Chanwoo Choi wrote:
> On 21. 6. 3. 오전 12:20, Stephan Gerhold wrote:
>> On Thu, Jun 03, 2021 at 12:13:18AM +0900, Chanwoo Choi wrote:
>>> On 21. 6. 2. 오전 5:00, Stephan Gerhold wrote:
>>>> Prepare for supporting SM5504 in the extcon-sm5502 driver by replacing
>>>> enum sm5504_types with a struct sm5504_type that stores the 
>>>> chip-specific
>>>> definitions. This struct can then be defined separately for SM5504
>>>> without having to add if (type == TYPE_SM5504) everywhere in the code.
>>>>
>>>> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
>>>> ---
>>>> Changes in v3: New patch to simplify diff on next patch
>>>> ---
>>>>    drivers/extcon/extcon-sm5502.c | 64 
>>>> +++++++++++++++++++++-------------
>>>>    drivers/extcon/extcon-sm5502.h |  4 ---
>>>>    2 files changed, 40 insertions(+), 28 deletions(-)
>>>>
>>>> diff --git a/drivers/extcon/extcon-sm5502.c 
>>>> b/drivers/extcon/extcon-sm5502.c
>>>> index 9f40bb9f1f81..951f6ca4c479 100644
>>>> --- a/drivers/extcon/extcon-sm5502.c
>>>> +++ b/drivers/extcon/extcon-sm5502.c
>>>> @@ -40,17 +40,13 @@ struct sm5502_muic_info {
>>>>        struct i2c_client *i2c;
>>>>        struct regmap *regmap;
>>>> +    const struct sm5502_type *type;
>>>>        struct regmap_irq_chip_data *irq_data;
>>>> -    struct muic_irq *muic_irqs;
>>>> -    unsigned int num_muic_irqs;
>>>>        int irq;
>>>>        bool irq_attach;
>>>>        bool irq_detach;
>>>>        struct work_struct irq_work;
>>>> -    struct reg_data *reg_data;
>>>> -    unsigned int num_reg_data;
>>>> -
>>>>        struct mutex mutex;
>>>>        /*
>>>> @@ -62,6 +58,17 @@ struct sm5502_muic_info {
>>>>        struct delayed_work wq_detcable;
>>>>    };
>>>> +struct sm5502_type {
>>>> +    struct muic_irq *muic_irqs;
>>>> +    unsigned int num_muic_irqs;
>>>> +    const struct regmap_irq_chip *irq_chip;
>>>> +
>>>> +    struct reg_data *reg_data;
>>>> +    unsigned int num_reg_data;
>>>> +
>>>> +    int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
>>>> +};
>>>> +
>>>>    /* Default value of SM5502 register to bring up MUIC device. */
>>>>    static struct reg_data sm5502_reg_data[] = {
>>>>        {
>>>> @@ -502,11 +509,11 @@ static irqreturn_t sm5502_muic_irq_handler(int 
>>>> irq, void *data)
>>>>        struct sm5502_muic_info *info = data;
>>>>        int i, irq_type = -1, ret;
>>>> -    for (i = 0; i < info->num_muic_irqs; i++)
>>>> -        if (irq == info->muic_irqs[i].virq)
>>>> -            irq_type = info->muic_irqs[i].irq;
>>>> +    for (i = 0; i < info->type->num_muic_irqs; i++)
>>>> +        if (irq == info->type->muic_irqs[i].virq)
>>>> +            irq_type = info->type->muic_irqs[i].irq;
>>>> -    ret = sm5502_parse_irq(info, irq_type);
>>>> +    ret = info->type->parse_irq(info, irq_type);
>>>
>>> Looks good to me. But there is only one comment.
>>> Need to check the 'parse_irq' as following:
>>>
>>> If you agree this suggestion, I'll apply with following changes by 
>>> myself:
>>>
>>>     if (!info->type->parse_irq) {
>>>         dev_err(info->dev, "failed to handle irq due to parse_irq\n",
>>>         return IRQ_NONE;
>>>     }
>>>
>>>
>>
>> This condition should be impossible, since .parse_irq is set for both
>> SM5502 and SM5504:
>>
>> static const struct sm5502_type sm5502_data = {
>>     /* ... */
>>     .parse_irq = sm5502_parse_irq,
>> };
>>
>> static const struct sm5502_type sm5504_data = {
>>     /* ... */
>>     .parse_irq = sm5504_parse_irq,
>> };
>>
>> Which failure case are you trying to handle with that if statement?
> 
> There is not failure case of this patchset. But, this refactoring 
> suggestion has the potential problem without checking whether mandatory 
> function pointer is NULL or not. When adding new chip by using this 
> driver, the author might have the human error without parse_irq 
> initialization even if the mandatory.
> 

Instead, it is better to check whether parser_irq is NULL or not
on probe function in order to reduce the unnecessary repetitive checking.

>>
>> Thanks!
>> Stephan
>>
> 
> 


-- 
Best Regards,
Samsung Electronics
Chanwoo Choi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct
  2021-06-02 15:35         ` Chanwoo Choi
@ 2021-06-02 15:42           ` Stephan Gerhold
  2021-06-03  3:05             ` Chanwoo Choi
  0 siblings, 1 reply; 11+ messages in thread
From: Stephan Gerhold @ 2021-06-02 15:42 UTC (permalink / raw)
  To: Chanwoo Choi
  Cc: Chanwoo Choi, MyungJoo Ham, Rob Herring, devicetree,
	linux-kernel, Nikita Travkin, ~postmarketos/upstreaming

On Thu, Jun 03, 2021 at 12:35:58AM +0900, Chanwoo Choi wrote:
> On 21. 6. 3. 오전 12:30, Chanwoo Choi wrote:
> > On 21. 6. 3. 오전 12:20, Stephan Gerhold wrote:
> > > On Thu, Jun 03, 2021 at 12:13:18AM +0900, Chanwoo Choi wrote:
> > > > On 21. 6. 2. 오전 5:00, Stephan Gerhold wrote:
> > > > > Prepare for supporting SM5504 in the extcon-sm5502 driver by replacing
> > > > > enum sm5504_types with a struct sm5504_type that stores the
> > > > > chip-specific
> > > > > definitions. This struct can then be defined separately for SM5504
> > > > > without having to add if (type == TYPE_SM5504) everywhere in the code.
> > > > > 
> > > > > Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> > > > > ---
> > > > > Changes in v3: New patch to simplify diff on next patch
> > > > > ---
> > > > >    drivers/extcon/extcon-sm5502.c | 64
> > > > > +++++++++++++++++++++-------------
> > > > >    drivers/extcon/extcon-sm5502.h |  4 ---
> > > > >    2 files changed, 40 insertions(+), 28 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/extcon/extcon-sm5502.c
> > > > > b/drivers/extcon/extcon-sm5502.c
> > > > > index 9f40bb9f1f81..951f6ca4c479 100644
> > > > > --- a/drivers/extcon/extcon-sm5502.c
> > > > > +++ b/drivers/extcon/extcon-sm5502.c
> > > > > @@ -40,17 +40,13 @@ struct sm5502_muic_info {
> > > > >        struct i2c_client *i2c;
> > > > >        struct regmap *regmap;
> > > > > +    const struct sm5502_type *type;
> > > > >        struct regmap_irq_chip_data *irq_data;
> > > > > -    struct muic_irq *muic_irqs;
> > > > > -    unsigned int num_muic_irqs;
> > > > >        int irq;
> > > > >        bool irq_attach;
> > > > >        bool irq_detach;
> > > > >        struct work_struct irq_work;
> > > > > -    struct reg_data *reg_data;
> > > > > -    unsigned int num_reg_data;
> > > > > -
> > > > >        struct mutex mutex;
> > > > >        /*
> > > > > @@ -62,6 +58,17 @@ struct sm5502_muic_info {
> > > > >        struct delayed_work wq_detcable;
> > > > >    };
> > > > > +struct sm5502_type {
> > > > > +    struct muic_irq *muic_irqs;
> > > > > +    unsigned int num_muic_irqs;
> > > > > +    const struct regmap_irq_chip *irq_chip;
> > > > > +
> > > > > +    struct reg_data *reg_data;
> > > > > +    unsigned int num_reg_data;
> > > > > +
> > > > > +    int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
> > > > > +};
> > > > > +
> > > > >    /* Default value of SM5502 register to bring up MUIC device. */
> > > > >    static struct reg_data sm5502_reg_data[] = {
> > > > >        {
> > > > > @@ -502,11 +509,11 @@ static irqreturn_t
> > > > > sm5502_muic_irq_handler(int irq, void *data)
> > > > >        struct sm5502_muic_info *info = data;
> > > > >        int i, irq_type = -1, ret;
> > > > > -    for (i = 0; i < info->num_muic_irqs; i++)
> > > > > -        if (irq == info->muic_irqs[i].virq)
> > > > > -            irq_type = info->muic_irqs[i].irq;
> > > > > +    for (i = 0; i < info->type->num_muic_irqs; i++)
> > > > > +        if (irq == info->type->muic_irqs[i].virq)
> > > > > +            irq_type = info->type->muic_irqs[i].irq;
> > > > > -    ret = sm5502_parse_irq(info, irq_type);
> > > > > +    ret = info->type->parse_irq(info, irq_type);
> > > > 
> > > > Looks good to me. But there is only one comment.
> > > > Need to check the 'parse_irq' as following:
> > > > 
> > > > If you agree this suggestion, I'll apply with following changes
> > > > by myself:
> > > > 
> > > >     if (!info->type->parse_irq) {
> > > >         dev_err(info->dev, "failed to handle irq due to parse_irq\n",
> > > >         return IRQ_NONE;
> > > >     }
> > > > 
> > > > 
> > > 
> > > This condition should be impossible, since .parse_irq is set for both
> > > SM5502 and SM5504:
> > > 
> > > static const struct sm5502_type sm5502_data = {
> > >     /* ... */
> > >     .parse_irq = sm5502_parse_irq,
> > > };
> > > 
> > > static const struct sm5502_type sm5504_data = {
> > >     /* ... */
> > >     .parse_irq = sm5504_parse_irq,
> > > };
> > > 
> > > Which failure case are you trying to handle with that if statement?
> > 
> > There is not failure case of this patchset. But, this refactoring
> > suggestion has the potential problem without checking whether mandatory
> > function pointer is NULL or not. When adding new chip by using this
> > driver, the author might have the human error without parse_irq
> > initialization even if the mandatory.
> > 
> 
> Instead, it is better to check whether parser_irq is NULL or not
> on probe function in order to reduce the unnecessary repetitive checking.
> 

Thanks for the explanation. This suggestion sounds better to me.
(Although I consider it unlikely that someone would forget to define
 .parse_irq when adding a new chip...)

Feel free to add something like the below when applying.
Or let me know if I should re-send with this change:

diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index af44c1e2f368..93da2d8379b1 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -694,6 +694,10 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
 	info->type = device_get_match_data(info->dev);
 	if (!info->type)
 		return -EINVAL;
+	if (!info->type->parse_irq) {
+		dev_err(info->dev, "parse_irq missing in struct sm5502_type\n");
+		return -EINVAL;
+	}
 
 	mutex_init(&info->mutex);
 

Thanks for your review!
Stephan

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 1/3] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic
  2021-06-01 20:00 ` [PATCH v3 1/3] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
@ 2021-06-02 19:37   ` Rob Herring
  0 siblings, 0 replies; 11+ messages in thread
From: Rob Herring @ 2021-06-02 19:37 UTC (permalink / raw)
  To: Stephan Gerhold
  Cc: MyungJoo Ham, linux-kernel, Nikita Travkin, Chanwoo Choi,
	Rob Herring, devicetree, ~postmarketos/upstreaming

On Tue, 01 Jun 2021 22:00:05 +0200, Stephan Gerhold wrote:
> Document support for SM5504 with the new siliconmitus,sm5504-muic
> compatible.
> 
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> ---
>  .../bindings/extcon/siliconmitus,sm5502-muic.yaml           | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct
  2021-06-02 15:42           ` Stephan Gerhold
@ 2021-06-03  3:05             ` Chanwoo Choi
  0 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2021-06-03  3:05 UTC (permalink / raw)
  To: Stephan Gerhold, Chanwoo Choi
  Cc: MyungJoo Ham, Rob Herring, devicetree, linux-kernel,
	Nikita Travkin, ~postmarketos/upstreaming

On 6/3/21 12:42 AM, Stephan Gerhold wrote:
> On Thu, Jun 03, 2021 at 12:35:58AM +0900, Chanwoo Choi wrote:
>> On 21. 6. 3. 오전 12:30, Chanwoo Choi wrote:
>>> On 21. 6. 3. 오전 12:20, Stephan Gerhold wrote:
>>>> On Thu, Jun 03, 2021 at 12:13:18AM +0900, Chanwoo Choi wrote:
>>>>> On 21. 6. 2. 오전 5:00, Stephan Gerhold wrote:
>>>>>> Prepare for supporting SM5504 in the extcon-sm5502 driver by replacing
>>>>>> enum sm5504_types with a struct sm5504_type that stores the
>>>>>> chip-specific
>>>>>> definitions. This struct can then be defined separately for SM5504
>>>>>> without having to add if (type == TYPE_SM5504) everywhere in the code.
>>>>>>
>>>>>> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
>>>>>> ---
>>>>>> Changes in v3: New patch to simplify diff on next patch
>>>>>> ---
>>>>>>    drivers/extcon/extcon-sm5502.c | 64
>>>>>> +++++++++++++++++++++-------------
>>>>>>    drivers/extcon/extcon-sm5502.h |  4 ---
>>>>>>    2 files changed, 40 insertions(+), 28 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/extcon/extcon-sm5502.c
>>>>>> b/drivers/extcon/extcon-sm5502.c
>>>>>> index 9f40bb9f1f81..951f6ca4c479 100644
>>>>>> --- a/drivers/extcon/extcon-sm5502.c
>>>>>> +++ b/drivers/extcon/extcon-sm5502.c
>>>>>> @@ -40,17 +40,13 @@ struct sm5502_muic_info {
>>>>>>        struct i2c_client *i2c;
>>>>>>        struct regmap *regmap;
>>>>>> +    const struct sm5502_type *type;
>>>>>>        struct regmap_irq_chip_data *irq_data;
>>>>>> -    struct muic_irq *muic_irqs;
>>>>>> -    unsigned int num_muic_irqs;
>>>>>>        int irq;
>>>>>>        bool irq_attach;
>>>>>>        bool irq_detach;
>>>>>>        struct work_struct irq_work;
>>>>>> -    struct reg_data *reg_data;
>>>>>> -    unsigned int num_reg_data;
>>>>>> -
>>>>>>        struct mutex mutex;
>>>>>>        /*
>>>>>> @@ -62,6 +58,17 @@ struct sm5502_muic_info {
>>>>>>        struct delayed_work wq_detcable;
>>>>>>    };
>>>>>> +struct sm5502_type {
>>>>>> +    struct muic_irq *muic_irqs;
>>>>>> +    unsigned int num_muic_irqs;
>>>>>> +    const struct regmap_irq_chip *irq_chip;
>>>>>> +
>>>>>> +    struct reg_data *reg_data;
>>>>>> +    unsigned int num_reg_data;
>>>>>> +
>>>>>> +    int (*parse_irq)(struct sm5502_muic_info *info, int irq_type);
>>>>>> +};
>>>>>> +
>>>>>>    /* Default value of SM5502 register to bring up MUIC device. */
>>>>>>    static struct reg_data sm5502_reg_data[] = {
>>>>>>        {
>>>>>> @@ -502,11 +509,11 @@ static irqreturn_t
>>>>>> sm5502_muic_irq_handler(int irq, void *data)
>>>>>>        struct sm5502_muic_info *info = data;
>>>>>>        int i, irq_type = -1, ret;
>>>>>> -    for (i = 0; i < info->num_muic_irqs; i++)
>>>>>> -        if (irq == info->muic_irqs[i].virq)
>>>>>> -            irq_type = info->muic_irqs[i].irq;
>>>>>> +    for (i = 0; i < info->type->num_muic_irqs; i++)
>>>>>> +        if (irq == info->type->muic_irqs[i].virq)
>>>>>> +            irq_type = info->type->muic_irqs[i].irq;
>>>>>> -    ret = sm5502_parse_irq(info, irq_type);
>>>>>> +    ret = info->type->parse_irq(info, irq_type);
>>>>>
>>>>> Looks good to me. But there is only one comment.
>>>>> Need to check the 'parse_irq' as following:
>>>>>
>>>>> If you agree this suggestion, I'll apply with following changes
>>>>> by myself:
>>>>>
>>>>>     if (!info->type->parse_irq) {
>>>>>         dev_err(info->dev, "failed to handle irq due to parse_irq\n",
>>>>>         return IRQ_NONE;
>>>>>     }
>>>>>
>>>>>
>>>>
>>>> This condition should be impossible, since .parse_irq is set for both
>>>> SM5502 and SM5504:
>>>>
>>>> static const struct sm5502_type sm5502_data = {
>>>>     /* ... */
>>>>     .parse_irq = sm5502_parse_irq,
>>>> };
>>>>
>>>> static const struct sm5502_type sm5504_data = {
>>>>     /* ... */
>>>>     .parse_irq = sm5504_parse_irq,
>>>> };
>>>>
>>>> Which failure case are you trying to handle with that if statement?
>>>
>>> There is not failure case of this patchset. But, this refactoring
>>> suggestion has the potential problem without checking whether mandatory
>>> function pointer is NULL or not. When adding new chip by using this
>>> driver, the author might have the human error without parse_irq
>>> initialization even if the mandatory.
>>>
>>
>> Instead, it is better to check whether parser_irq is NULL or not
>> on probe function in order to reduce the unnecessary repetitive checking.
>>
> 
> Thanks for the explanation. This suggestion sounds better to me.
> (Although I consider it unlikely that someone would forget to define
>  .parse_irq when adding a new chip...)
> 
> Feel free to add something like the below when applying.
> Or let me know if I should re-send with this change:

Please resend them. Thanks.

> 
> diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
> index af44c1e2f368..93da2d8379b1 100644
> --- a/drivers/extcon/extcon-sm5502.c
> +++ b/drivers/extcon/extcon-sm5502.c
> @@ -694,6 +694,10 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
>  	info->type = device_get_match_data(info->dev);
>  	if (!info->type)
>  		return -EINVAL;
> +	if (!info->type->parse_irq) {
> +		dev_err(info->dev, "parse_irq missing in struct sm5502_type\n");
> +		return -EINVAL;
> +	}
>  
>  	mutex_init(&info->mutex);
>  
> 
> Thanks for your review!
> Stephan
> 
> 


-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-06-03  2:46 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-01 20:00 [PATCH v3 0/3] extcon: sm5502: Add support for SM5504 Stephan Gerhold
2021-06-01 20:00 ` [PATCH v3 1/3] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
2021-06-02 19:37   ` Rob Herring
2021-06-01 20:00 ` [PATCH v3 2/3] extcon: sm5502: Refactor driver to use chip-specific struct Stephan Gerhold
2021-06-02 15:13   ` Chanwoo Choi
2021-06-02 15:20     ` Stephan Gerhold
2021-06-02 15:30       ` Chanwoo Choi
2021-06-02 15:35         ` Chanwoo Choi
2021-06-02 15:42           ` Stephan Gerhold
2021-06-03  3:05             ` Chanwoo Choi
2021-06-01 20:00 ` [PATCH v3 3/3] extcon: sm5502: Add support for SM5504 Stephan Gerhold

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.